99 "reflect"
1010 "strings"
1111
12- "github.com/hashicorp/go-version"
1312 tfjson "github.com/hashicorp/terraform-json"
1413
1514 "github.com/google/go-cmp/cmp"
@@ -21,40 +20,27 @@ import (
2120 "github.com/hashicorp/terraform-plugin-testing/internal/plugintest"
2221 "github.com/hashicorp/terraform-plugin-testing/internal/teststep"
2322 "github.com/hashicorp/terraform-plugin-testing/terraform"
24- "github.com/hashicorp/terraform-plugin-testing/tfversion"
2523)
2624
27- func requirePlannableImport (t testing.T , versionUnderTest version.Version ) error {
28- t .Helper ()
29-
30- if versionUnderTest .LessThan (tfversion .Version1_5_0 ) {
31- return fmt .Errorf (
32- `ImportState steps using plannable import blocks require Terraform 1.5.0 or later. Either ` +
33- `upgrade the Terraform version running the test or add a ` + "`TerraformVersionChecks`" + ` to ` +
34- `the test case to skip this test.` + "\n \n " +
35- `https://developer.hashicorp.com/terraform/plugin/testing/acceptance-tests/tfversion-checks#skip-version-checks` )
36- }
37-
38- return nil
39- }
40-
4125func testStepNewImportState (ctx context.Context , t testing.T , helper * plugintest.Helper , wd * plugintest.WorkingDir , step TestStep , cfgRaw string , providers * providerFactories , stepNumber int ) error {
4226 t .Helper ()
4327
44- // Currently import modes `ImportBlockWithId` and `ImportBlockWithResourceIdentity` cannot support config file or directory
45- // since these modes append the import block to the configuration automatically
46- if step .ImportStateKind != ImportCommandWithId {
47- if step .ConfigFile != nil || step .ConfigDirectory != nil {
48- t .Fatalf ("ImportStateKind %q is not supported for config file or directory" , step .ImportStateKind )
49- }
50- }
51-
52- if step .ImportStateKind != ImportCommandWithId {
28+ // step.ImportStateKind implicitly defaults to the zero-value (ImportCommandWithID) for backward compatibility
29+ kind := step .ImportStateKind
30+ if kind .plannable () {
31+ // Instead of calling [t.Fatal], return an error. This package's unit tests can use [TestStep.ExpectError] to match on the error message.
32+ // An alternative, [plugintest.TestExpectTFatal], does not have access to logged error messages, so it is open to false positives on this
33+ // complex code path.
5334 if err := requirePlannableImport (t , * helper .TerraformVersion ()); err != nil {
5435 return err
5536 }
5637 }
5738
39+ resourceName := step .ResourceName
40+ if resourceName == "" {
41+ t .Fatal ("ResourceName is required for an import state test" )
42+ }
43+
5844 configRequest := teststep.PrepareConfigurationRequest {
5945 Directory : step .ConfigDirectory ,
6046 File : step .ConfigFile ,
@@ -67,10 +53,6 @@ func testStepNewImportState(ctx context.Context, t testing.T, helper *plugintest
6753
6854 testStepConfig := teststep .Configuration (configRequest )
6955
70- if step .ResourceName == "" {
71- t .Fatal ("ResourceName is required for an import state test" )
72- }
73-
7456 // get state from check sequence
7557 var state * terraform.State
7658 var err error
@@ -110,7 +92,7 @@ func testStepNewImportState(ctx context.Context, t testing.T, helper *plugintest
11092 default :
11193 logging .HelperResourceTrace (ctx , "Using resource identifier for import identifier" )
11294
113- resource , err := testResource (step , state )
95+ resource , err := testResource (resourceName , state )
11496 if err != nil {
11597 t .Fatal (err )
11698 }
@@ -125,26 +107,16 @@ func testStepNewImportState(ctx context.Context, t testing.T, helper *plugintest
125107
126108 logging .HelperResourceTrace (ctx , fmt .Sprintf ("Using import identifier: %s" , importId ))
127109
110+ // Append to previous step config unless using ConfigFile or ConfigDirectory
128111 if testStepConfig == nil || step .Config != "" {
129112 importConfig := step .Config
130113 if importConfig == "" {
131114 logging .HelperResourceTrace (ctx , "Using prior TestStep Config for import" )
132115 importConfig = cfgRaw
133116 }
134117
135- // Update the test config dependent on the kind of import test being performed
136- switch step .ImportStateKind {
137- case ImportBlockWithResourceIdentity :
138- t .Fatalf ("TODO implement me" )
139- case ImportBlockWithId :
140- importConfig += fmt .Sprintf (`
141- import {
142- to = %s
143- id = %q
144- }
145- ` , step .ResourceName , importId )
146- default :
147- // Not an import block test so nothing to do here
118+ if kind .plannable () {
119+ importConfig = appendImportBlock (importConfig , resourceName , importId )
148120 }
149121
150122 confRequest := teststep.PrepareConfigurationRequest {
@@ -170,7 +142,7 @@ func testStepNewImportState(ctx context.Context, t testing.T, helper *plugintest
170142 importWd = wd
171143 } else {
172144 importWd = helper .RequireNewWorkingDir (ctx , t , "" )
173- defer importWd .Close ()
145+ defer importWd .Close () //nolint:errcheck
174146 }
175147
176148 err = importWd .SetConfig (ctx , testStepConfig , step .ConfigVariables )
@@ -189,7 +161,7 @@ func testStepNewImportState(ctx context.Context, t testing.T, helper *plugintest
189161 }
190162
191163 var plan * tfjson.Plan
192- if step . ImportStateKind == ImportBlockWithResourceIdentity || step . ImportStateKind == ImportBlockWithId {
164+ if kind . plannable () {
193165 var opts []tfexec.PlanOption
194166
195167 err = runProviderCommand (ctx , t , func () error {
@@ -214,7 +186,7 @@ func testStepNewImportState(ctx context.Context, t testing.T, helper *plugintest
214186 logging .HelperResourceDebug (ctx , fmt .Sprintf ("ImportBlockWithId: %d resource changes" , len (plan .ResourceChanges )))
215187
216188 for _ , rc := range plan .ResourceChanges {
217- if rc .Address != step . ResourceName {
189+ if rc .Address != resourceName {
218190 // we're only interested in the changes for the resource being imported
219191 continue
220192 }
@@ -232,7 +204,7 @@ func testStepNewImportState(ctx context.Context, t testing.T, helper *plugintest
232204 return fmt .Errorf ("retrieving formatted plan output: %w" , err )
233205 }
234206
235- return fmt .Errorf ("importing resource %s should be a no-op, but got action %s with plan \\ nstdout:\\ n \ \ n%s" , rc .Address , action , stdout )
207+ return fmt .Errorf ("importing resource %s: expected a no-op resource action, got %q action with plan \n stdout:\n \n %s" , rc .Address , action , stdout )
236208 }
237209 }
238210 }
@@ -244,11 +216,9 @@ func testStepNewImportState(ctx context.Context, t testing.T, helper *plugintest
244216 if err := runPlanChecks (ctx , t , plan , step .ImportPlanChecks .PreApply ); err != nil {
245217 return err
246218 }
247-
248219 } else {
249220 err = runProviderCommand (ctx , t , func () error {
250- logging .HelperResourceDebug (ctx , "Run terraform import" )
251- return importWd .Import (ctx , step .ResourceName , importId )
221+ return importWd .Import (ctx , resourceName , importId )
252222 }, importWd , providers )
253223 if err != nil {
254224 return err
0 commit comments