Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: multi testsacc error #594

Merged
merged 1 commit into from
Oct 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ linters:
- exportloopref # checks for pointers to enclosing loop variables [fast: false, auto-fix: false]
- forbidigo # Forbids identifiers [fast: true, auto-fix: false]
- gci # Gci controls golang package import order and makes it always deterministic. [fast: true, auto-fix: false]
- goconst # Finds repeated strings that could be replaced by a constant [fast: true, auto-fix: false]
- gocritic # Provides diagnostics that check for bugs, performance and style issues. [fast: false, auto-fix: false]
- gocyclo # Computes and checks the cyclomatic complexity of functions [fast: true, auto-fix: false]
- gofmt # Gofmt checks whether code was gofmt-ed. By default this tool runs with -s option to check for code simplification [fast: true, auto-fix: true]
Expand Down Expand Up @@ -62,6 +61,7 @@ linters:
- bodyclose # checks whether HTTP response body is closed successfully

disable:
- goconst # Finds repeated strings that could be replaced by a constant [fast: true, auto-fix: false]
- dupl # Tool for code clone detection [fast: true, auto-fix: false]
- varcheck # Finds unused global variables and constants [fast: false, auto-fix: false]
- deadcode # Finds unused code [fast: false, auto-fix: false]
Expand Down
68 changes: 48 additions & 20 deletions internal/helpers/testsacc/testsacc.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,19 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
)

var listOfDeps = make(ListOfDependencies, 0)

type (
ResourceName string
TFData string
TestName string
ListOfDependencies []ResourceName
ResourceName string
TFData string
TestName string
ListOfDependencies []ResourceName
DependenciesConfigResponse []func() TFData

TestACC interface {
// GetResourceName returns the name of the resource under test.
GetResourceName() string

// DependenciesConfig returns the Terraform configuration used to create any dependencies of the resource under test.
DependenciesConfig() TFData
DependenciesConfig() DependenciesConfigResponse

// Tests returns the acceptance tests to run for the resource under test.
// resourceName is a concatenation of the resource name and the example name. For example, "cloudavenue_catalog.example".
Expand All @@ -47,8 +46,11 @@ type (
// Import returns the Terraform configurations to use for the import test.
Imports []TFImport

// cacheDependenciesConfig is used to cache the dependencies config.
cacheDependenciesConfig TFData
// CacheDependenciesConfig is used to cache the dependencies config.
CacheDependenciesConfig TFData

// listOfDeps is a list of dependencies.
listOfDeps ListOfDependencies
}

TFConfig struct {
Expand Down Expand Up @@ -148,6 +150,12 @@ type (
}
)

// * DependenciesConfigResponse
// Append appends the given dependencies config to the current one.
func (d *DependenciesConfigResponse) Append(tf func() TFData) {
*d = append(*d, tf)
}

// * TFAdvanced

// IsEmpty returns true if the TFAdvanced is empty.
Expand Down Expand Up @@ -219,10 +227,7 @@ func (t TFData) String() string {

// Append appends the given Terraform configuration to the current one.
func (t *TFData) Append(tf TFData) {
if !tf.IsEmpty() && !listOfDeps.Exists(ResourceName(tf.extractResourceName())) {
t.append(tf)
listOfDeps.Append(ResourceName(tf.extractResourceName()))
}
t.append(tf)
}

// AppendWithoutResourceName appends the given Terraform configuration to the current one.
Expand All @@ -248,7 +253,11 @@ func (t *TFData) append(tf TFData) {
// extractResourceName extracts the resource name and config name from the Terraform configuration.
// example: "resource "cloudavenue_catalog" "example" {}" => "cloudavenue_catalog.example"
func (t *TFData) extractResourceName() string {
x := strings.Split(t.String(), " ")
// find the first occurrence of "resource" or "data"
re := regexp.MustCompile(`(resource|data) \"(.*)\" \"(.*)\"`)
line := re.FindString(t.String())

x := strings.Split(line, " ")
// for each word remove the double quotes
for i, v := range x {
x[i] = strings.ReplaceAll(v, "\"", "")
Expand All @@ -268,6 +277,26 @@ func (t TFConfig) Generate(_ context.Context, dependencies TFData) string {

// *Test

// initListOfDeps initializes the list of dependencies.
func (t *Test) initListOfDeps() {
if t.listOfDeps == nil {
t.listOfDeps = make(ListOfDependencies, 0)
}
}

// Compute Dependencies config.
func (t *Test) ComputeDependenciesConfig(testACC TestACC) {
t.initListOfDeps()
for _, v := range testACC.DependenciesConfig() {
// tf contains terraform configuration for a dependency
tf := v()
if !tf.IsEmpty() && !t.listOfDeps.Exists(ResourceName(tf.extractResourceName())) {
t.CacheDependenciesConfig.append(tf)
t.listOfDeps.Append(ResourceName(tf.extractResourceName()))
}
}
}

// GenerateSteps generates the structure of the acceptance tests.
func (t Test) GenerateSteps(ctx context.Context, testName TestName, testACC TestACC) (steps []resource.TestStep) {
// Init Slice
Expand All @@ -277,13 +306,12 @@ func (t Test) GenerateSteps(ctx context.Context, testName TestName, testACC Test
listOfChecks := t.CommonChecks
listOfChecks = append(listOfChecks, t.Create.Checks...)

if t.cacheDependenciesConfig == "" {
t.cacheDependenciesConfig = testACC.DependenciesConfig()
}
// * Compute dependencies config
t.ComputeDependenciesConfig(testACC)

// * Create step
createTestStep := resource.TestStep{
Config: t.Create.Generate(ctx, t.cacheDependenciesConfig),
Config: t.Create.Generate(ctx, t.CacheDependenciesConfig),
Check: resource.ComposeAggregateTestCheckFunc(
listOfChecks...,
),
Expand All @@ -309,7 +337,7 @@ func (t Test) GenerateSteps(ctx context.Context, testName TestName, testACC Test
listOfChecks = append(listOfChecks, update.Checks...)

updateTestStep := resource.TestStep{
Config: update.Generate(ctx, t.cacheDependenciesConfig),
Config: update.Generate(ctx, t.CacheDependenciesConfig),
Check: resource.ComposeAggregateTestCheckFunc(
listOfChecks...,
),
Expand Down Expand Up @@ -376,7 +404,7 @@ func GenerateTests(tacc TestACC) []resource.TestStep {
// resourceName is a concatenation of the resource name and the example name. For example, "cloudavenue_catalog.example".
resourceName := testName.ComputeResourceName(tacc.GetResourceName())

steps = step(ctx, resourceName).GenerateSteps(ctx, testName, tacc)
steps = append(steps, step(ctx, resourceName).GenerateSteps(ctx, testName, tacc)...)
}

return steps
Expand Down
32 changes: 18 additions & 14 deletions internal/testsacc/acctest.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,27 +80,29 @@ type resourceConfig struct {

// GetDefaultConfig returns the create configuration for the test named "example".
func (r resourceConfig) GetDefaultConfig() testsacc.TFData {
return r.GetSpecificConfig("example")
return r.GetSpecificConfig("example")()
}

// GetSpecificConfig returns the create configuration for the test named "example".
func (r resourceConfig) GetSpecificConfig(testName string) testsacc.TFData {
var x testsacc.TFData

if test, ok := localCacheResource[r.GetResourceName()+"."+testName]; ok {
x = test.Create.TFConfig
} else {
t := r.Tests(context.Background())[testsacc.TestName(testName)](
func (r resourceConfig) GetSpecificConfig(testName string) func() testsacc.TFData {
// Load from cache
t, ok := localCacheResource[r.GetResourceName()+"."+testName]
// If not found, compute it
if !ok {
t = r.Tests(context.Background())[testsacc.TestName(testName)](
context.Background(),
r.GetResourceName()+"."+testName,
)
x = t.Create.TFConfig

t.ComputeDependenciesConfig(r.TestACC)
localCacheResource[r.GetResourceName()+"."+testName] = t
}

x.AppendWithoutResourceName(r.DependenciesConfig())
return x
x := t.Create.TFConfig
x.Append(t.CacheDependenciesConfig)

return func() testsacc.TFData {
return x
}
}

// GetDefaultChecks returns the checks for the test named "example".
Expand Down Expand Up @@ -128,8 +130,10 @@ func (r resourceConfig) GetSpecificChecks(testName string) []resource.TestCheckF
}

// AddConstantConfig returns the create configuration from constant.
func AddConstantConfig(config string) testsacc.TFData {
return testsacc.TFData(config)
func AddConstantConfig(config string) func() testsacc.TFData {
return func() testsacc.TFData {
return testsacc.TFData(config)
}
}

func NewResourceConfig(data testsacc.TestACC) func() resourceConfig {
Expand Down
4 changes: 2 additions & 2 deletions internal/testsacc/backup_datasource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ func (r *BackupDataSource) GetResourceName() string {
return BackupDataSourceName.String()
}

func (r *BackupDataSource) DependenciesConfig() (configs testsacc.TFData) {
func (r *BackupDataSource) DependenciesConfig() (resp testsacc.DependenciesConfigResponse) {
// Add dependencies config to the resource
configs.Append(GetResourceConfig()[BackupResourceName]().GetDefaultConfig())
resp.Append(GetResourceConfig()[BackupResourceName]().GetDefaultConfig)
return
}

Expand Down
Loading
Loading