Skip to content

Commit e8215b2

Browse files
authored
test: Converting a test case to a migration test (#2081)
1 parent 81f01b4 commit e8215b2

File tree

5 files changed

+233
-90
lines changed

5 files changed

+233
-90
lines changed

internal/service/searchindex/resource_search_index_migration_test.go

Lines changed: 2 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -3,69 +3,13 @@ package searchindex_test
33
import (
44
"testing"
55

6-
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
7-
"github.com/mongodb/terraform-provider-mongodbatlas/internal/testutil/acc"
86
"github.com/mongodb/terraform-provider-mongodbatlas/internal/testutil/mig"
97
)
108

119
func TestMigSearchIndex_basic(t *testing.T) {
12-
var (
13-
clusterInfo = acc.GetClusterInfo(t, nil)
14-
indexName = acc.RandomName()
15-
databaseName = acc.RandomName()
16-
config = configBasic(clusterInfo.ProjectIDStr, indexName, databaseName, clusterInfo.ClusterNameStr, clusterInfo.ClusterTerraformStr, false)
17-
)
18-
resource.ParallelTest(t, resource.TestCase{
19-
PreCheck: func() { mig.PreCheckBasic(t) },
20-
CheckDestroy: acc.CheckDestroySearchIndex,
21-
Steps: []resource.TestStep{
22-
{
23-
Config: config,
24-
ExternalProviders: mig.ExternalProviders(),
25-
Check: resource.ComposeTestCheckFunc(
26-
checkExists(resourceName),
27-
resource.TestCheckResourceAttr(resourceName, "name", indexName),
28-
resource.TestCheckResourceAttrSet(resourceName, "project_id"),
29-
resource.TestCheckResourceAttr(resourceName, "cluster_name", clusterInfo.ClusterName),
30-
resource.TestCheckResourceAttr(resourceName, "database", databaseName),
31-
resource.TestCheckResourceAttr(resourceName, "collection_name", collectionName),
32-
resource.TestCheckResourceAttr(resourceName, "search_analyzer", searchAnalyzer),
33-
resource.TestCheckResourceAttr(resourceName, "type", ""),
34-
),
35-
},
36-
mig.TestStepCheckEmptyPlan(config),
37-
},
38-
})
10+
mig.CreateAndRunTest(t, basicTestCase(t))
3911
}
4012

4113
func TestMigSearchIndex_withVector(t *testing.T) {
42-
var (
43-
clusterInfo = acc.GetClusterInfo(t, nil)
44-
indexName = acc.RandomName()
45-
databaseName = acc.RandomName()
46-
config = configVector(clusterInfo.ProjectIDStr, indexName, databaseName, clusterInfo.ClusterNameStr, clusterInfo.ClusterTerraformStr)
47-
)
48-
49-
resource.ParallelTest(t, resource.TestCase{
50-
PreCheck: func() { mig.PreCheckBasic(t) },
51-
CheckDestroy: acc.CheckDestroySearchIndex,
52-
Steps: []resource.TestStep{
53-
{
54-
Config: config,
55-
ExternalProviders: mig.ExternalProviders(),
56-
Check: resource.ComposeTestCheckFunc(
57-
checkExists(resourceName),
58-
resource.TestCheckResourceAttr(resourceName, "name", indexName),
59-
resource.TestCheckResourceAttrSet(resourceName, "project_id"),
60-
resource.TestCheckResourceAttr(resourceName, "cluster_name", clusterInfo.ClusterName),
61-
resource.TestCheckResourceAttr(resourceName, "database", databaseName),
62-
resource.TestCheckResourceAttr(resourceName, "collection_name", collectionName),
63-
resource.TestCheckResourceAttr(resourceName, "type", "vectorSearch"),
64-
resource.TestCheckResourceAttrSet(resourceName, "fields"),
65-
resource.TestCheckResourceAttrWith(resourceName, "fields", acc.JSONEquals(fieldsJSON)),
66-
),
67-
},
68-
mig.TestStepCheckEmptyPlan(config),
69-
},
70-
})
14+
mig.CreateAndRunTest(t, basicVectorTestCase(t))
7115
}

internal/service/searchindex/resource_search_index_test.go

Lines changed: 43 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -12,33 +12,7 @@ import (
1212
)
1313

1414
func TestAccSearchIndex_basic(t *testing.T) {
15-
var (
16-
clusterInfo = acc.GetClusterInfo(t, nil)
17-
indexName = acc.RandomName()
18-
databaseName = acc.RandomName()
19-
indexType = ""
20-
mappingsDynamic = "true"
21-
)
22-
checks := commonChecks(indexName, indexType, mappingsDynamic, databaseName, clusterInfo)
23-
24-
resource.ParallelTest(t, resource.TestCase{
25-
PreCheck: func() { acc.PreCheckBasic(t) },
26-
ProtoV6ProviderFactories: acc.TestAccProviderV6Factories,
27-
CheckDestroy: acc.CheckDestroySearchIndex,
28-
Steps: []resource.TestStep{
29-
{
30-
Config: configBasic(clusterInfo.ProjectIDStr, indexName, databaseName, clusterInfo.ClusterNameStr, clusterInfo.ClusterTerraformStr, false),
31-
Check: resource.ComposeTestCheckFunc(checks...),
32-
},
33-
{
34-
Config: configBasic(clusterInfo.ProjectIDStr, indexName, databaseName, clusterInfo.ClusterNameStr, clusterInfo.ClusterTerraformStr, false),
35-
ResourceName: resourceName,
36-
ImportStateIdFunc: importStateIDFunc(resourceName),
37-
ImportState: true,
38-
ImportStateVerify: true,
39-
},
40-
},
41-
})
15+
resource.ParallelTest(t, *basicTestCase(t))
4216
}
4317

4418
func TestAccSearchIndex_withSearchType(t *testing.T) {
@@ -208,8 +182,44 @@ func TestAccSearchIndex_updatedToEmptyMappingsFields(t *testing.T) {
208182
}
209183

210184
func TestAccSearchIndex_withVector(t *testing.T) {
185+
resource.ParallelTest(t, *basicVectorTestCase(t))
186+
}
187+
188+
func basicTestCase(tb testing.TB) *resource.TestCase {
189+
tb.Helper()
211190
var (
212-
clusterInfo = acc.GetClusterInfo(t, nil)
191+
clusterInfo = acc.GetClusterInfo(tb, nil)
192+
indexName = acc.RandomName()
193+
databaseName = acc.RandomName()
194+
indexType = ""
195+
mappingsDynamic = "true"
196+
)
197+
checks := commonChecks(indexName, indexType, mappingsDynamic, databaseName, clusterInfo)
198+
199+
return &resource.TestCase{
200+
PreCheck: func() { acc.PreCheckBasic(tb) },
201+
ProtoV6ProviderFactories: acc.TestAccProviderV6Factories,
202+
CheckDestroy: acc.CheckDestroySearchIndex,
203+
Steps: []resource.TestStep{
204+
{
205+
Config: configBasic(clusterInfo.ProjectIDStr, indexName, databaseName, clusterInfo.ClusterNameStr, clusterInfo.ClusterTerraformStr, false),
206+
Check: resource.ComposeTestCheckFunc(checks...),
207+
},
208+
{
209+
Config: configBasic(clusterInfo.ProjectIDStr, indexName, databaseName, clusterInfo.ClusterNameStr, clusterInfo.ClusterTerraformStr, false),
210+
ResourceName: resourceName,
211+
ImportStateIdFunc: importStateIDFunc(resourceName),
212+
ImportState: true,
213+
ImportStateVerify: true,
214+
},
215+
},
216+
}
217+
}
218+
219+
func basicVectorTestCase(tb testing.TB) *resource.TestCase {
220+
tb.Helper()
221+
var (
222+
clusterInfo = acc.GetClusterInfo(tb, nil)
213223
indexName = acc.RandomName()
214224
indexType = "vectorSearch"
215225
databaseName = acc.RandomName()
@@ -225,8 +235,9 @@ func TestAccSearchIndex_withVector(t *testing.T) {
225235
checks = acc.AddAttrSetChecks(resourceName, checks, "project_id")
226236
checks = acc.AddAttrSetChecks(datasourceName, checks, "project_id", "index_id")
227237
checks = append(checks, resource.TestCheckResourceAttrWith(datasourceName, "fields", acc.JSONEquals(fieldsJSON)))
228-
resource.ParallelTest(t, resource.TestCase{
229-
PreCheck: func() { acc.PreCheckBasic(t) },
238+
239+
return &resource.TestCase{
240+
PreCheck: func() { acc.PreCheckBasic(tb) },
230241
ProtoV6ProviderFactories: acc.TestAccProviderV6Factories,
231242
CheckDestroy: acc.CheckDestroySearchIndex,
232243
Steps: []resource.TestStep{
@@ -235,8 +246,9 @@ func TestAccSearchIndex_withVector(t *testing.T) {
235246
Check: resource.ComposeTestCheckFunc(checks...),
236247
},
237248
},
238-
})
249+
}
239250
}
251+
240252
func commonChecks(indexName, indexType, mappingsDynamic, databaseName string, clusterInfo acc.ClusterInfo) []resource.TestCheckFunc {
241253
attributes := map[string]string{
242254
"name": indexName,

internal/testutil/acc/provider.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import (
44
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
55
)
66

7+
const AwsProviderVersion = "5.1.0"
8+
79
func ExternalProviders(versionAtlasProvider string) map[string]resource.ExternalProvider {
810
return map[string]resource.ExternalProvider{
911
"mongodbatlas": *providerAtlas(versionAtlasProvider),
@@ -32,7 +34,7 @@ func providerAtlas(versionAtlasProvider string) *resource.ExternalProvider {
3234

3335
func providerAWS() *resource.ExternalProvider {
3436
return &resource.ExternalProvider{
35-
VersionConstraint: "5.1.0",
37+
VersionConstraint: AwsProviderVersion,
3638
Source: "hashicorp/aws",
3739
}
3840
}

internal/testutil/mig/test_case.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package mig
2+
3+
import (
4+
"testing"
5+
6+
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
7+
"github.com/stretchr/testify/require"
8+
)
9+
10+
func CreateAndRunTest(t *testing.T, test *resource.TestCase) {
11+
t.Helper()
12+
resource.ParallelTest(t, CreateTest(t, test))
13+
}
14+
15+
func CreateTestAndRunUseExternalProvider(t *testing.T, test *resource.TestCase, externalProviders, additionalProviders map[string]resource.ExternalProvider) {
16+
t.Helper()
17+
resource.ParallelTest(t, CreateTestUseExternalProvider(t, test, externalProviders, additionalProviders))
18+
}
19+
20+
// CreateTest returns a new TestCase that reuses step 1 and adds a TestStepCheckEmptyPlan.
21+
// Requires: `MONGODB_ATLAS_LAST_VERSION` to be present.
22+
func CreateTest(t *testing.T, test *resource.TestCase) resource.TestCase {
23+
t.Helper()
24+
validateReusableCase(t, test)
25+
firstStep := test.Steps[0]
26+
steps := []resource.TestStep{
27+
useExternalProvider(&firstStep, ExternalProviders()),
28+
TestStepCheckEmptyPlan(firstStep.Config),
29+
}
30+
newTest := reuseCase(test, steps)
31+
return newTest
32+
}
33+
34+
// CreateTestUseExternalProvider returns a new TestCase that reuses step 1 and adds a TestStepCheckEmptyPlan with the additionalProviders.
35+
// Requires: `MONGODB_ATLAS_LAST_VERSION` to be present.
36+
// externalProviders: e.g., ExternalProvidersWithAWS() or ExternalProviders("specific_sem_ver").
37+
// additionalProviders: e.g., acc.ExternalProvidersOnlyAWS(), can also be nil.
38+
func CreateTestUseExternalProvider(t *testing.T, test *resource.TestCase, externalProviders, additionalProviders map[string]resource.ExternalProvider) resource.TestCase {
39+
t.Helper()
40+
validateReusableCase(t, test)
41+
firstStep := test.Steps[0]
42+
require.NotContains(t, additionalProviders, "mongodbatlas", "Will use the local provider, cannot specify mongodbatlas provider")
43+
emptyPlanStep := TestStepCheckEmptyPlan(firstStep.Config)
44+
steps := []resource.TestStep{
45+
useExternalProvider(&firstStep, externalProviders),
46+
useExternalProvider(&emptyPlanStep, additionalProviders),
47+
}
48+
return reuseCase(test, steps)
49+
}
50+
51+
func validateReusableCase(tb testing.TB, test *resource.TestCase) {
52+
tb.Helper()
53+
checkLastVersion(tb)
54+
require.GreaterOrEqual(tb, len(test.Steps), 1, "Must have at least 1 test step.")
55+
require.NotEmpty(tb, test.Steps[0].Config, "First step of migration test must use Config")
56+
}
57+
58+
func useExternalProvider(step *resource.TestStep, provider map[string]resource.ExternalProvider) resource.TestStep {
59+
step.ExternalProviders = provider
60+
return *step
61+
}
62+
63+
// Note how we don't set ProtoV6ProviderFactories and instead specify providers on each step.
64+
func reuseCase(test *resource.TestCase, steps []resource.TestStep) resource.TestCase {
65+
return resource.TestCase{
66+
PreCheck: test.PreCheck,
67+
CheckDestroy: test.CheckDestroy,
68+
ErrorCheck: test.ErrorCheck,
69+
Steps: steps,
70+
}
71+
}
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
package mig_test
2+
3+
import (
4+
"testing"
5+
6+
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
7+
"github.com/hashicorp/terraform-plugin-testing/terraform"
8+
"github.com/mongodb/terraform-provider-mongodbatlas/internal/testutil/acc"
9+
"github.com/mongodb/terraform-provider-mongodbatlas/internal/testutil/mig"
10+
"github.com/stretchr/testify/assert"
11+
)
12+
13+
func TestConvertToMigration(t *testing.T) {
14+
t.Setenv("MONGODB_ATLAS_LAST_VERSION", "1.2.3")
15+
var (
16+
preCheckCalled = false
17+
checkDestroyCalled = false
18+
config = "someTerraformConfig"
19+
)
20+
preCheck := func() {
21+
preCheckCalled = true
22+
}
23+
firstStep := resource.TestStep{
24+
Config: config,
25+
Check: resource.TestCheckResourceAttrSet("someTarget", "someAttribute"),
26+
}
27+
28+
asserter := assert.New(t)
29+
30+
convertAndCall := func(test resource.TestCase) resource.TestCase {
31+
newTest := mig.CreateTest(t, &test)
32+
newTest.PreCheck()
33+
if newTest.CheckDestroy != nil {
34+
asserter.NoError(newTest.CheckDestroy(nil))
35+
}
36+
return newTest
37+
}
38+
defaultAssertions := func(test resource.TestCase) {
39+
t.Helper()
40+
asserter.Len(test.Steps, 2, "Expected 2 steps (one extra test step)")
41+
newFirstStep := test.Steps[0]
42+
asserter.Equal(config, newFirstStep.Config)
43+
44+
planStep := test.Steps[1]
45+
asserter.Equal(mig.TestStepCheckEmptyPlan(config), planStep)
46+
}
47+
48+
t.Run("normal call with check and destroy", func(t *testing.T) {
49+
checkDestroy := func(*terraform.State) error {
50+
checkDestroyCalled = true
51+
return nil
52+
}
53+
test := convertAndCall(resource.TestCase{
54+
PreCheck: preCheck,
55+
CheckDestroy: checkDestroy,
56+
Steps: []resource.TestStep{
57+
firstStep,
58+
},
59+
})
60+
asserter.True(preCheckCalled)
61+
asserter.True(checkDestroyCalled)
62+
defaultAssertions(test)
63+
})
64+
65+
t.Run("checkDestroy=nil has no panic", func(t *testing.T) {
66+
test := convertAndCall(resource.TestCase{
67+
PreCheck: preCheck,
68+
Steps: []resource.TestStep{
69+
firstStep,
70+
},
71+
})
72+
defaultAssertions(test)
73+
})
74+
75+
t.Run("more than 1 step uses only 1 step", func(t *testing.T) {
76+
test := convertAndCall(resource.TestCase{
77+
PreCheck: preCheck,
78+
Steps: []resource.TestStep{
79+
firstStep,
80+
{
81+
Config: "differentConfig",
82+
Check: resource.TestCheckResourceAttrSet("target", "attribute"),
83+
},
84+
},
85+
})
86+
defaultAssertions(test)
87+
})
88+
// ConvertToMigrationTestUseExternalProvider
89+
90+
t.Run("explicit ExternalProvider version an no additional providers", func(t *testing.T) {
91+
test := mig.CreateTestUseExternalProvider(t, &resource.TestCase{
92+
PreCheck: preCheck,
93+
Steps: []resource.TestStep{firstStep},
94+
}, acc.ExternalProviders("1.2.3"), nil)
95+
asserter.Len(test.Steps, 2, "Expected 2 steps (one extra test step)")
96+
newFirstStep := test.Steps[0]
97+
asserter.Equal(config, newFirstStep.Config)
98+
asserter.Equal("1.2.3", test.Steps[0].ExternalProviders["mongodbatlas"].VersionConstraint)
99+
})
100+
101+
t.Run("explicit ExternalProviders and additional providers", func(t *testing.T) {
102+
test := mig.CreateTestUseExternalProvider(t, &resource.TestCase{
103+
PreCheck: preCheck,
104+
Steps: []resource.TestStep{firstStep},
105+
}, acc.ExternalProvidersWithAWS("1.2.3"), acc.ExternalProvidersOnlyAWS())
106+
asserter.Len(test.Steps, 2, "Expected 2 steps (one extra test step)")
107+
newFirstStep := test.Steps[0]
108+
asserter.Equal(config, newFirstStep.Config)
109+
110+
asserter.Equal("1.2.3", test.Steps[0].ExternalProviders["mongodbatlas"].VersionConstraint)
111+
asserter.Equal(acc.AwsProviderVersion, test.Steps[0].ExternalProviders["aws"].VersionConstraint)
112+
asserter.Equal(acc.AwsProviderVersion, test.Steps[1].ExternalProviders["aws"].VersionConstraint)
113+
})
114+
}

0 commit comments

Comments
 (0)