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

helper/resource: Skip data source states with TestStep.ImportStateCheck #1089

Merged
merged 2 commits into from Nov 4, 2022
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/1089.txt
@@ -0,0 +1,3 @@
```release-note:bug
helper/resource: Fixed `TestStep` type `ImportStateCheck` field so that it only matches against resources following a change in behaviour in Terraform 1.3 that imports both resources and data sources into state
```
10 changes: 10 additions & 0 deletions helper/resource/testing.go
Expand Up @@ -551,6 +551,16 @@ type TestStep struct {
// ImportStateCheck checks the results of ImportState. It should be
// used to verify that the resulting value of ImportState has the
// proper resources, IDs, and attributes.
//
// Prefer ImportStateVerify over ImportStateCheck, unless the resource
// import explicitly is expected to create multiple resources (not a
// recommended resource implementation) or if attributes are imported with
// syntactically different but semantically/functionally equivalent values
// where special logic is needed.
//
// Terraform versions 1.3 and later can include data source states during
// import, which the testing framework will skip to prevent the need for
// Terraform version specific logic in provider testing.
ImportStateCheck ImportStateCheckFunc

// ImportStateVerify, if true, will also check that the state values
Expand Down
16 changes: 11 additions & 5 deletions helper/resource/testing_new_import_state.go
Expand Up @@ -137,12 +137,18 @@ func testStepNewImportState(ctx context.Context, t testing.T, helper *plugintest
logging.HelperResourceTrace(ctx, "Using TestStep ImportStateCheck")

var states []*terraform.InstanceState
for _, r := range importState.RootModule().Resources {
if r.Primary != nil {
is := r.Primary.DeepCopy()
is.Ephemeral.Type = r.Type // otherwise the check function cannot see the type
states = append(states, is)
for address, r := range importState.RootModule().Resources {
if strings.HasPrefix(address, "data.") {
continue
}

if r.Primary == nil {
continue
}

is := r.Primary.DeepCopy()
is.Ephemeral.Type = r.Type // otherwise the check function cannot see the type
states = append(states, is)
}

logging.HelperResourceDebug(ctx, "Calling TestStep ImportStateCheck")
Expand Down
82 changes: 82 additions & 0 deletions helper/resource/testing_new_import_state_test.go
@@ -0,0 +1,82 @@
package resource

import (
"context"
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
)

func TestTest_TestStep_ImportStateCheck_SkipDataSourceState(t *testing.T) {
t.Parallel()

UnitTest(t, TestCase{
ProviderFactories: map[string]func() (*schema.Provider, error){
"examplecloud": func() (*schema.Provider, error) { //nolint:unparam // required signature
return &schema.Provider{
DataSourcesMap: map[string]*schema.Resource{
"examplecloud_thing": {
ReadContext: func(_ context.Context, d *schema.ResourceData, _ interface{}) diag.Diagnostics {
d.SetId("datasource-test")

return nil
},
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
ResourcesMap: map[string]*schema.Resource{
"examplecloud_thing": {
CreateContext: func(_ context.Context, d *schema.ResourceData, _ interface{}) diag.Diagnostics {
d.SetId("resource-test")

return nil
},
DeleteContext: func(_ context.Context, _ *schema.ResourceData, _ interface{}) diag.Diagnostics {
return nil
},
ReadContext: func(_ context.Context, _ *schema.ResourceData, _ interface{}) diag.Diagnostics {
return nil
},
Schema: map[string]*schema.Schema{
"id": {
Computed: true,
Type: schema.TypeString,
},
},
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
},
},
}, nil
},
},
Steps: []TestStep{
{
Config: `
data "examplecloud_thing" "test" {}
resource "examplecloud_thing" "test" {}
`,
},
{
ResourceName: "examplecloud_thing.test",
ImportState: true,
ImportStateCheck: func(is []*terraform.InstanceState) error {
if len(is) > 1 {
return fmt.Errorf("expected 1 state, got: %d", len(is))
}

return nil
},
},
},
})
}