Skip to content

Commit 1e0ae3e

Browse files
committed
importstate: Use ExpectNonEmptyPlan field to ignore no-op assertion for import block test kinds
1 parent f93511e commit 1e0ae3e

File tree

3 files changed

+60
-2
lines changed

3 files changed

+60
-2
lines changed

helper/resource/importstate/import_block_with_id_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,58 @@ func TestImportBlock_WithID_ExpectError(t *testing.T) {
9999
})
100100
}
101101

102+
func TestImportBlock_WithID_ExpectNonEmptyPlan(t *testing.T) {
103+
t.Parallel()
104+
105+
r.UnitTest(t, r.TestCase{
106+
TerraformVersionChecks: []tfversion.TerraformVersionCheck{
107+
tfversion.SkipBelow(tfversion.Version1_5_0), // ImportBlockWithID requires Terraform 1.5.0 or later
108+
},
109+
ProtoV6ProviderFactories: map[string]func() (tfprotov6.ProviderServer, error){
110+
"examplecloud": providerserver.NewProviderServer(testprovider.Provider{
111+
Resources: map[string]testprovider.Resource{
112+
"examplecloud_container": examplecloudResource(),
113+
},
114+
}),
115+
},
116+
Steps: []r.TestStep{
117+
{
118+
Config: `
119+
resource "examplecloud_container" "test" {
120+
location = "westeurope"
121+
name = "somevalue"
122+
}`,
123+
},
124+
{
125+
Config: `
126+
resource "examplecloud_container" "test" {
127+
location = "eastus"
128+
name = "somevalue"
129+
}
130+
131+
import {
132+
to = examplecloud_container.test
133+
id = "westeurope/somevalue"
134+
}
135+
`,
136+
ResourceName: "examplecloud_container.test",
137+
ImportState: true,
138+
ImportStateKind: r.ImportBlockWithID,
139+
ImportStateConfigExact: true,
140+
ExpectNonEmptyPlan: true,
141+
ImportPlanChecks: r.ImportPlanChecks{
142+
PreApply: []plancheck.PlanCheck{
143+
plancheck.ExpectResourceAction("examplecloud_container.test", plancheck.ResourceActionUpdate),
144+
// The location address is imported as "westeurope/somevalue", which will be updated by the config to "eastus"
145+
plancheck.ExpectKnownValue("examplecloud_container.test", tfjsonpath.New("location"), knownvalue.StringExact("eastus")),
146+
plancheck.ExpectUnknownValue("examplecloud_container.test", tfjsonpath.New("id")),
147+
},
148+
},
149+
},
150+
},
151+
})
152+
}
153+
102154
func TestImportBlock_WithID_FailWhenNotSupported(t *testing.T) {
103155
t.Parallel()
104156

helper/resource/testing.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,11 @@ type TestStep struct {
674674
// ID of that resource.
675675
ImportState bool
676676

677+
// ImportStateKind controls the method of import that is used in combination with the other import-related fields on the TestStep struct.
678+
//
679+
// - By default, ImportCommandWithID is used, which tests import by using the ID string with the `terraform import` command. This was the original behavior prior to introducing the ImportStateKind field.
680+
// - ImportBlockWithID tests import by using the ID string in an import configuration block with the `terraform plan` command.
681+
// - ImportBlockWithResourceIdentity imports the state using an import configuration block with a resource identity.
677682
ImportStateKind ImportStateKind
678683

679684
// ImportStateId is the ID to perform an ImportState operation with.

helper/resource/testing_new_import_state.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,9 @@ func testImportBlock(ctx context.Context, t testing.T, workingDir *plugintest.Wo
221221
switch {
222222
case importing == nil:
223223
return fmt.Errorf("importing resource %s: expected an import operation, got %q action with plan \nstdout:\n\n%s", resourceChangeUnderTest.Address, actions, savedPlanRawStdout(ctx, t, workingDir, providers))
224-
225-
case !actions.NoOp():
224+
// By default we want to ensure there isn't a proposed plan after importing, but for some resources this is unavoidable.
225+
// An example would be importing a resource that cannot read it's entire value back from the remote API.
226+
case !step.ExpectNonEmptyPlan && !actions.NoOp():
226227
return fmt.Errorf("importing resource %s: expected a no-op import operation, got %q action with plan \nstdout:\n\n%s", resourceChangeUnderTest.Address, actions, savedPlanRawStdout(ctx, t, workingDir, providers))
227228
}
228229

0 commit comments

Comments
 (0)