-
Notifications
You must be signed in to change notification settings - Fork 164
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
test: Converting a test case to a migration test #2081
Changes from 8 commits
1adeda8
c670c3a
c889428
9f1b7de
d74bff7
6dcd932
8e969ad
78a605e
1b76bef
7676f02
bf7bd51
cc3d909
f9bcc1e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package mig | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform-plugin-testing/helper/resource" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
// CreateTest returns a new TestCase that reuses step 1 and adds a TestStepCheckEmptyPlan | ||
EspenAlbert marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// Requires: `MONGODB_ATLAS_LAST_VERSION` to be present | ||
func CreateTest(t *testing.T, test *resource.TestCase) resource.TestCase { | ||
t.Helper() | ||
validateReusableCase(t, test) | ||
firstStep := test.Steps[0] | ||
steps := []resource.TestStep{ | ||
useExternalProvider(&firstStep, ExternalProviders()), | ||
TestStepCheckEmptyPlan(firstStep.Config), | ||
} | ||
return reuseCase(test, steps) | ||
} | ||
|
||
// CreateTestUseExternalProvider returns a new TestCase that reuses step 1 and adds a TestStepCheckEmptyPlan with the additionalProviders | ||
// Requires: `MONGODB_ATLAS_LAST_VERSION` to be present | ||
// externalProviders: e.g., ExternalProvidersWithAWS() or ExternalProviders("specific_sem_ver") | ||
// additionalProviders: e.g., acc.ExternalProvidersOnlyAWS(), can also be nil | ||
func CreateTestUseExternalProvider(t *testing.T, test *resource.TestCase, externalProviders, additionalProviders map[string]resource.ExternalProvider) resource.TestCase { | ||
EspenAlbert marked this conversation as resolved.
Show resolved
Hide resolved
|
||
t.Helper() | ||
validateReusableCase(t, test) | ||
firstStep := test.Steps[0] | ||
require.NotContains(t, additionalProviders, "mongodbatlas", "Will use the local provider, cannot specify mongodbatlas provider") | ||
emptyPlanStep := TestStepCheckEmptyPlan(firstStep.Config) | ||
steps := []resource.TestStep{ | ||
useExternalProvider(&firstStep, externalProviders), | ||
useExternalProvider(&emptyPlanStep, additionalProviders), | ||
} | ||
return reuseCase(test, steps) | ||
} | ||
|
||
func validateReusableCase(t *testing.T, test *resource.TestCase) { | ||
t.Helper() | ||
checkLastVersion(t) | ||
require.GreaterOrEqual(t, len(test.Steps), 1, "Must have at least 1 test step.") | ||
require.NotEmpty(t, test.Steps[0].Config, "First step of migration test must use Config") | ||
} | ||
|
||
func useExternalProvider(step *resource.TestStep, provider map[string]resource.ExternalProvider) resource.TestStep { | ||
step.ExternalProviders = provider | ||
return *step | ||
} | ||
|
||
// Note how we don't set ProtoV6ProviderFactories and instead specify providers on each step | ||
func reuseCase(test *resource.TestCase, steps []resource.TestStep) resource.TestCase { | ||
EspenAlbert marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return resource.TestCase{ | ||
PreCheck: test.PreCheck, | ||
CheckDestroy: test.CheckDestroy, | ||
ErrorCheck: test.ErrorCheck, | ||
Steps: steps, | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
package mig_test | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform-plugin-testing/helper/resource" | ||
"github.com/hashicorp/terraform-plugin-testing/terraform" | ||
"github.com/mongodb/terraform-provider-mongodbatlas/internal/testutil/acc" | ||
"github.com/mongodb/terraform-provider-mongodbatlas/internal/testutil/mig" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestConvertToMigration(t *testing.T) { | ||
t.Setenv("MONGODB_ATLAS_LAST_VERSION", "1.2.3") | ||
var ( | ||
preCheckCalled = false | ||
checkDestroyCalled = false | ||
config = "someTerraformConfig" | ||
) | ||
preCheck := func() { | ||
preCheckCalled = true | ||
} | ||
firstStep := resource.TestStep{ | ||
Config: config, | ||
Check: resource.TestCheckResourceAttrSet("someTarget", "someAttribute"), | ||
} | ||
|
||
asserter := assert.New(t) | ||
|
||
convertAndCall := func(test resource.TestCase) resource.TestCase { | ||
newTest := mig.CreateTest(t, &test) | ||
newTest.PreCheck() | ||
if newTest.CheckDestroy != nil { | ||
asserter.NoError(newTest.CheckDestroy(nil)) | ||
} | ||
return newTest | ||
} | ||
defaultAssertions := func(test resource.TestCase) { | ||
t.Helper() | ||
asserter.Len(test.Steps, 2, "Expected 2 steps (one extra test step)") | ||
newFirstStep := test.Steps[0] | ||
asserter.Equal(config, newFirstStep.Config) | ||
|
||
planStep := test.Steps[1] | ||
asserter.Equal(mig.TestStepCheckEmptyPlan(config), planStep) | ||
} | ||
|
||
t.Run("normal call with check and destroy", func(t *testing.T) { | ||
checkDestroy := func(*terraform.State) error { | ||
checkDestroyCalled = true | ||
return nil | ||
} | ||
test := convertAndCall(resource.TestCase{ | ||
PreCheck: preCheck, | ||
CheckDestroy: checkDestroy, | ||
Steps: []resource.TestStep{ | ||
firstStep, | ||
}, | ||
}) | ||
asserter.True(preCheckCalled) | ||
asserter.True(checkDestroyCalled) | ||
defaultAssertions(test) | ||
}) | ||
|
||
t.Run("checkDestroy=nil has no panic", func(t *testing.T) { | ||
test := convertAndCall(resource.TestCase{ | ||
PreCheck: preCheck, | ||
Steps: []resource.TestStep{ | ||
firstStep, | ||
}, | ||
}) | ||
defaultAssertions(test) | ||
}) | ||
|
||
t.Run("more than 1 step uses only 1 step", func(t *testing.T) { | ||
test := convertAndCall(resource.TestCase{ | ||
PreCheck: preCheck, | ||
Steps: []resource.TestStep{ | ||
firstStep, | ||
{ | ||
Config: "differentConfig", | ||
Check: resource.TestCheckResourceAttrSet("target", "attribute"), | ||
}, | ||
}, | ||
}) | ||
defaultAssertions(test) | ||
}) | ||
// ConvertToMigrationTestUseExternalProvider | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Put both unit test for: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it's quite a big test, don't know if some nested tests could be extracted to functions, or if a table-based test would help here |
||
|
||
t.Run("explicit ExternalProvider version an no additional providers", func(t *testing.T) { | ||
test := mig.CreateTestUseExternalProvider(t, &resource.TestCase{ | ||
PreCheck: preCheck, | ||
Steps: []resource.TestStep{firstStep}, | ||
}, acc.ExternalProviders("1.2.3"), nil) | ||
asserter.Len(test.Steps, 2, "Expected 2 steps (one extra test step)") | ||
newFirstStep := test.Steps[0] | ||
asserter.Equal(config, newFirstStep.Config) | ||
asserter.Equal("1.2.3", test.Steps[0].ExternalProviders["mongodbatlas"].VersionConstraint) | ||
}) | ||
|
||
t.Run("explicit ExternalProviders and additional providers", func(t *testing.T) { | ||
test := mig.CreateTestUseExternalProvider(t, &resource.TestCase{ | ||
PreCheck: preCheck, | ||
Steps: []resource.TestStep{firstStep}, | ||
}, acc.ExternalProvidersWithAWS("1.2.3"), acc.ExternalProvidersOnlyAWS()) | ||
asserter.Len(test.Steps, 2, "Expected 2 steps (one extra test step)") | ||
newFirstStep := test.Steps[0] | ||
asserter.Equal(config, newFirstStep.Config) | ||
|
||
asserter.Equal("1.2.3", test.Steps[0].ExternalProviders["mongodbatlas"].VersionConstraint) | ||
// must be upgraded when the aws provider version is changed | ||
EspenAlbert marked this conversation as resolved.
Show resolved
Hide resolved
|
||
asserter.Equal("5.1.0", test.Steps[0].ExternalProviders["aws"].VersionConstraint) | ||
asserter.Equal("5.1.0", test.Steps[1].ExternalProviders["aws"].VersionConstraint) | ||
}) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's great for this example. In some cases we might want to pass projectID so we get the execution project in acc tests but global project in mig, but that's specific to the tests so no changes needed in the infra