From f67b3e766436ba2b070be8c29d66f7e72d0e1bbb Mon Sep 17 00:00:00 2001 From: Benjamin Bennett Date: Tue, 9 Jan 2024 11:19:37 +0000 Subject: [PATCH 01/29] Adding StateCheck interface (#266) * Configuring when state checks are executed. * Testing that state checks are executed. --- helper/resource/state_checks.go | 29 +++++ helper/resource/state_checks_test.go | 22 ++++ helper/resource/testing.go | 12 ++ helper/resource/testing_new_config.go | 20 ++++ helper/resource/testing_new_config_test.go | 124 +++++++++++++++++++++ statecheck/doc.go | 5 + statecheck/state_check.go | 30 +++++ 7 files changed, 242 insertions(+) create mode 100644 helper/resource/state_checks.go create mode 100644 helper/resource/state_checks_test.go create mode 100644 statecheck/doc.go create mode 100644 statecheck/state_check.go diff --git a/helper/resource/state_checks.go b/helper/resource/state_checks.go new file mode 100644 index 000000000..66c850eae --- /dev/null +++ b/helper/resource/state_checks.go @@ -0,0 +1,29 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package resource + +import ( + "context" + "errors" + + tfjson "github.com/hashicorp/terraform-json" + "github.com/mitchellh/go-testing-interface" + + "github.com/hashicorp/terraform-plugin-testing/statecheck" +) + +func runStateChecks(ctx context.Context, t testing.T, state *tfjson.State, stateChecks []statecheck.StateCheck) error { + t.Helper() + + var result []error + + for _, stateCheck := range stateChecks { + resp := statecheck.CheckStateResponse{} + stateCheck.CheckState(ctx, statecheck.CheckStateRequest{State: state}, &resp) + + result = append(result, resp.Error) + } + + return errors.Join(result...) +} diff --git a/helper/resource/state_checks_test.go b/helper/resource/state_checks_test.go new file mode 100644 index 000000000..e8ab33753 --- /dev/null +++ b/helper/resource/state_checks_test.go @@ -0,0 +1,22 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package resource + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-testing/statecheck" +) + +var _ statecheck.StateCheck = &stateCheckSpy{} + +type stateCheckSpy struct { + err error + called bool +} + +func (s *stateCheckSpy) CheckState(ctx context.Context, req statecheck.CheckStateRequest, resp *statecheck.CheckStateResponse) { + s.called = true + resp.Error = s.err +} diff --git a/helper/resource/testing.go b/helper/resource/testing.go index 581152f72..5abda4eaa 100644 --- a/helper/resource/testing.go +++ b/helper/resource/testing.go @@ -24,6 +24,7 @@ import ( "github.com/hashicorp/terraform-plugin-testing/config" "github.com/hashicorp/terraform-plugin-testing/plancheck" + "github.com/hashicorp/terraform-plugin-testing/statecheck" "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/hashicorp/terraform-plugin-testing/tfversion" @@ -590,6 +591,13 @@ type TestStep struct { // [plancheck]: https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/plancheck RefreshPlanChecks RefreshPlanChecks + // ConfigStateChecks allow assertions to be made against the state file at different points of a Config (apply) test using a state check. + // Custom state checks can be created by implementing the [StateCheck] interface, or by using a StateCheck implementation from the provided [statecheck] package + // + // [StateCheck]: https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/statecheck#StateCheck + // [statecheck]: https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/statecheck + ConfigStateChecks ConfigStateChecks + // PlanOnly can be set to only run `plan` with this configuration, and not // actually apply it. This is useful for ensuring config changes result in // no-op plans @@ -795,6 +803,10 @@ type RefreshPlanChecks struct { PostRefresh []plancheck.PlanCheck } +// ConfigStateChecks runs all state checks in the slice. This occurs after the apply and refresh of a Config test are run. +// All errors by state checks in this slice are aggregated, reported, and will result in a test failure. +type ConfigStateChecks []statecheck.StateCheck + // ParallelTest performs an acceptance test on a resource, allowing concurrency // with other ParallelTest. The number of concurrent tests is controlled by the // "go test" command -parallel flag. diff --git a/helper/resource/testing_new_config.go b/helper/resource/testing_new_config.go index 35e605c1d..17d3745fa 100644 --- a/helper/resource/testing_new_config.go +++ b/helper/resource/testing_new_config.go @@ -313,6 +313,26 @@ func testStepNewConfig(ctx context.Context, t testing.T, c TestCase, wd *plugint } } + // Run post-apply, post-refresh state checks + if len(step.ConfigStateChecks) > 0 { + var state *tfjson.State + + err = runProviderCommand(ctx, t, func() error { + var err error + state, err = wd.State(ctx) + return err + }, wd, providers) + + if err != nil { + return fmt.Errorf("Error retrieving post-apply, post-refresh state: %w", err) + } + + err = runStateChecks(ctx, t, state, step.ConfigStateChecks) + if err != nil { + return fmt.Errorf("Post-apply refresh state check(s) failed:\n%w", err) + } + } + // check if plan is empty if !planIsEmpty(plan, helper.TerraformVersion()) && !step.ExpectNonEmptyPlan { var stdout string diff --git a/helper/resource/testing_new_config_test.go b/helper/resource/testing_new_config_test.go index b54eb4282..fe0eb707e 100644 --- a/helper/resource/testing_new_config_test.go +++ b/helper/resource/testing_new_config_test.go @@ -10,6 +10,7 @@ import ( "github.com/hashicorp/terraform-plugin-go/tfprotov6" "github.com/hashicorp/terraform-plugin-go/tftypes" + "github.com/hashicorp/terraform-plugin-testing/internal/testing/testprovider" "github.com/hashicorp/terraform-plugin-testing/internal/testing/testsdk/providerserver" "github.com/hashicorp/terraform-plugin-testing/internal/testing/testsdk/resource" @@ -717,3 +718,126 @@ func Test_ConfigPlanChecks_PostApplyPostRefresh_Errors(t *testing.T) { }, }) } + +func Test_ConfigStateChecks_Called(t *testing.T) { + t.Parallel() + + spy1 := &stateCheckSpy{} + spy2 := &stateCheckSpy{} + UnitTest(t, TestCase{ + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_0_0), // ProtoV6ProviderFactories + }, + ProtoV6ProviderFactories: map[string]func() (tfprotov6.ProviderServer, error){ + "test": providerserver.NewProviderServer(testprovider.Provider{ + Resources: map[string]testprovider.Resource{ + "test_resource": { + CreateResponse: &resource.CreateResponse{ + NewState: tftypes.NewValue( + tftypes.Object{ + AttributeTypes: map[string]tftypes.Type{ + "id": tftypes.String, + }, + }, + map[string]tftypes.Value{ + "id": tftypes.NewValue(tftypes.String, "test"), + }, + ), + }, + SchemaResponse: &resource.SchemaResponse{ + Schema: &tfprotov6.Schema{ + Block: &tfprotov6.SchemaBlock{ + Attributes: []*tfprotov6.SchemaAttribute{ + { + Name: "id", + Type: tftypes.String, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + }), + }, + Steps: []TestStep{ + { + Config: `resource "test_resource" "test" {}`, + ConfigStateChecks: ConfigStateChecks{ + spy1, + spy2, + }, + }, + }, + }) + + if !spy1.called { + t.Error("expected ConfigStateChecks spy1 to be called at least once") + } + + if !spy2.called { + t.Error("expected ConfigStateChecks spy2 to be called at least once") + } +} + +func Test_ConfigStateChecks_Errors(t *testing.T) { + t.Parallel() + + spy1 := &stateCheckSpy{} + spy2 := &stateCheckSpy{ + err: errors.New("spy2 check failed"), + } + spy3 := &stateCheckSpy{ + err: errors.New("spy3 check failed"), + } + UnitTest(t, TestCase{ + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_0_0), // ProtoV6ProviderFactories + }, + ProtoV6ProviderFactories: map[string]func() (tfprotov6.ProviderServer, error){ + "test": providerserver.NewProviderServer(testprovider.Provider{ + Resources: map[string]testprovider.Resource{ + "test_resource": { + CreateResponse: &resource.CreateResponse{ + NewState: tftypes.NewValue( + tftypes.Object{ + AttributeTypes: map[string]tftypes.Type{ + "id": tftypes.String, + }, + }, + map[string]tftypes.Value{ + "id": tftypes.NewValue(tftypes.String, "test"), + }, + ), + }, + SchemaResponse: &resource.SchemaResponse{ + Schema: &tfprotov6.Schema{ + Block: &tfprotov6.SchemaBlock{ + Attributes: []*tfprotov6.SchemaAttribute{ + { + Name: "id", + Type: tftypes.String, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + }), + }, + Steps: []TestStep{ + { + Config: `resource "test_resource" "test" {}`, + ConfigStateChecks: ConfigStateChecks{ + spy1, + spy2, + spy3, + }, + ExpectError: regexp.MustCompile(`.*?(spy2 check failed)\n.*?(spy3 check failed)`), + }, + }, + }) +} diff --git a/statecheck/doc.go b/statecheck/doc.go new file mode 100644 index 000000000..eba32447d --- /dev/null +++ b/statecheck/doc.go @@ -0,0 +1,5 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package statecheck contains the state check interface, request/response structs, and common state check implementations. +package statecheck diff --git a/statecheck/state_check.go b/statecheck/state_check.go new file mode 100644 index 000000000..cfd2da6b1 --- /dev/null +++ b/statecheck/state_check.go @@ -0,0 +1,30 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package statecheck + +import ( + "context" + + tfjson "github.com/hashicorp/terraform-json" +) + +// StateCheck defines an interface for implementing test logic that checks a state file and then returns an error +// if the state file does not match what is expected. +type StateCheck interface { + // CheckState should perform the state check. + CheckState(context.Context, CheckStateRequest, *CheckStateResponse) +} + +// CheckStateRequest is a request for an invoke of the CheckState function. +type CheckStateRequest struct { + // State represents a parsed state file, retrieved via the `terraform show -json` command. + State *tfjson.State +} + +// CheckStateResponse is a response to an invoke of the CheckState function. +type CheckStateResponse struct { + // Error is used to report the failure of a state check assertion and is combined with other StateCheck errors + // to be reported as a test failure. + Error error +} From eed2a1287574bd92cae6e1b601a70f030a8e9186 Mon Sep 17 00:00:00 2001 From: Benjamin Bennett Date: Tue, 9 Jan 2024 11:29:11 +0000 Subject: [PATCH 02/29] Adding validation to ensure state checks are only defined for config (apply) tests (#266) --- helper/resource/teststep_validate.go | 8 +++++++- helper/resource/teststep_validate_test.go | 10 ++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/helper/resource/teststep_validate.go b/helper/resource/teststep_validate.go index d63db4dc8..8590ca466 100644 --- a/helper/resource/teststep_validate.go +++ b/helper/resource/teststep_validate.go @@ -15,7 +15,7 @@ import ( // testStepValidateRequest contains data for the (TestStep).validate() method. type testStepValidateRequest struct { // StepConfiguration contains the TestStep configuration derived from - // TestStep.Config or TestStep.ConfigDirectory. + // TestStep.Config, TestStep.ConfigDirectory, or TestStep.ConfigFile. StepConfiguration teststep.Config // StepNumber is the index of the TestStep in the TestCase.Steps. @@ -235,5 +235,11 @@ func (s TestStep) validate(ctx context.Context, req testStepValidateRequest) err return err } + if len(s.ConfigStateChecks) > 0 && req.StepConfiguration == nil { + err := fmt.Errorf("TestStep ConfigStateChecks must only be specified with Config, ConfigDirectory or ConfigFile") + logging.HelperResourceError(ctx, "TestStep validation error", map[string]interface{}{logging.KeyError: err}) + return err + } + return nil } diff --git a/helper/resource/teststep_validate_test.go b/helper/resource/teststep_validate_test.go index c5f19a60e..6a326e003 100644 --- a/helper/resource/teststep_validate_test.go +++ b/helper/resource/teststep_validate_test.go @@ -466,6 +466,16 @@ func TestTestStepValidate(t *testing.T) { testStepValidateRequest: testStepValidateRequest{TestCaseHasProviders: true}, expectedError: errors.New("TestStep ConfigPlanChecks.PostApplyPostRefresh must only be specified with Config"), }, + "configstatechecks-not-config-mode": { + testStep: TestStep{ + ConfigStateChecks: ConfigStateChecks{ + &stateCheckSpy{}, + }, + RefreshState: true, + }, + testStepValidateRequest: testStepValidateRequest{TestCaseHasProviders: true}, + expectedError: errors.New("TestStep ConfigStateChecks must only be specified with Config"), + }, "refreshplanchecks-postrefresh-not-refresh-mode": { testStep: TestStep{ RefreshPlanChecks: RefreshPlanChecks{ From d4e31d3babd2d9cb019b343bf2c99b6d4906abf4 Mon Sep 17 00:00:00 2001 From: Benjamin Bennett Date: Tue, 9 Jan 2024 11:58:57 +0000 Subject: [PATCH 03/29] Adding ExpectKnownValue state check (#266) --- statecheck/expect_known_value.go | 94 ++ statecheck/expect_known_value_test.go | 1412 +++++++++++++++++++++++++ 2 files changed, 1506 insertions(+) create mode 100644 statecheck/expect_known_value.go create mode 100644 statecheck/expect_known_value_test.go diff --git a/statecheck/expect_known_value.go b/statecheck/expect_known_value.go new file mode 100644 index 000000000..2f073f15c --- /dev/null +++ b/statecheck/expect_known_value.go @@ -0,0 +1,94 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package statecheck + +import ( + "context" + "fmt" + "reflect" + + tfjson "github.com/hashicorp/terraform-json" + + "github.com/hashicorp/terraform-plugin-testing/knownvalue" + "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" +) + +// Resource State Check +var _ StateCheck = expectKnownValue{} + +type expectKnownValue struct { + resourceAddress string + attributePath tfjsonpath.Path + knownValue knownvalue.Check +} + +// CheckState implements the state check logic. +func (e expectKnownValue) CheckState(ctx context.Context, req CheckStateRequest, resp *CheckStateResponse) { + var rc *tfjson.StateResource + + if req.State.Values == nil { + resp.Error = fmt.Errorf("state does not contain any state values") + } + + if req.State.Values.RootModule == nil { + resp.Error = fmt.Errorf("state does not contain a root module") + } + + for _, resourceChange := range req.State.Values.RootModule.Resources { + if e.resourceAddress == resourceChange.Address { + rc = resourceChange + + break + } + } + + if rc == nil { + resp.Error = fmt.Errorf("%s - Resource not found in state", e.resourceAddress) + + return + } + + result, err := tfjsonpath.Traverse(rc.AttributeValues, e.attributePath) + + if err != nil { + resp.Error = err + + return + } + + if result == nil { + resp.Error = fmt.Errorf("value is null") + + return + } + + switch reflect.TypeOf(result).Kind() { + case reflect.Bool, + reflect.Map, + reflect.Slice, + reflect.String: + if err := e.knownValue.CheckValue(result); err != nil { + resp.Error = err + + return + } + default: + errorStr := fmt.Sprintf("unrecognised attribute type: %T, known value type is %T", result, e.knownValue) + errorStr += "\n\nThis is an error in statecheck.ExpectKnownValue.\nPlease report this to the maintainers." + + resp.Error = fmt.Errorf(errorStr) + + return + } +} + +// ExpectKnownValue returns a state check that asserts that the specified attribute at the given resource +// has a known type and value. +func ExpectKnownValue(resourceAddress string, attributePath tfjsonpath.Path, knownValue knownvalue.Check) StateCheck { + return expectKnownValue{ + resourceAddress: resourceAddress, + attributePath: attributePath, + knownValue: knownValue, + } +} diff --git a/statecheck/expect_known_value_test.go b/statecheck/expect_known_value_test.go new file mode 100644 index 000000000..bd1024891 --- /dev/null +++ b/statecheck/expect_known_value_test.go @@ -0,0 +1,1412 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package statecheck_test + +import ( + "context" + "fmt" + "math/big" + "regexp" + "testing" + + "github.com/google/go-cmp/cmp" + tfjson "github.com/hashicorp/terraform-json" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + r "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/knownvalue" + "github.com/hashicorp/terraform-plugin-testing/statecheck" + "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" +) + +func TestExpectKnownValue_CheckState_ResourceNotFound(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + bool_attribute = true + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.two", + tfjsonpath.New("bool_attribute"), + knownvalue.BoolValueExact(true), + ), + }, + ExpectError: regexp.MustCompile("test_resource.two - Resource not found in state"), + }, + }, + }) +} + +func TestExpectKnownValue_CheckState_AttributeValueNull(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" {}`, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("bool_attribute"), + knownvalue.BoolValueExact(true), + ), + }, + ExpectError: regexp.MustCompile("value is null"), + }, + }, + }) +} + +func TestExpectKnownValue_CheckState_Bool(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + bool_attribute = true + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("bool_attribute"), + knownvalue.BoolValueExact(true), + ), + }, + }, + }, + }) +} + +func TestExpectKnownValue_CheckState_Bool_KnownValueWrongType(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + bool_attribute = true + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("bool_attribute"), + knownvalue.Float64ValueExact(1.23), + ), + }, + ExpectError: regexp.MustCompile(`expected json\.Number value for Float64Value check, got: bool`), + }, + }, + }) +} + +func TestExpectKnownValue_CheckState_Bool_KnownValueWrongValue(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + bool_attribute = true + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("bool_attribute"), + knownvalue.BoolValueExact(false), + ), + }, + ExpectError: regexp.MustCompile("expected value false for BoolValue check, got: true"), + }, + }, + }) +} + +func TestExpectKnownValue_CheckState_Float64(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + float_attribute = 1.23 + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("float_attribute"), + knownvalue.Float64ValueExact(1.23), + ), + }, + }, + }, + }) +} + +// We do not need equivalent tests for Int64 and Number as they all test the same logic. +func TestExpectKnownValue_CheckState_Float64_KnownValueWrongType(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + float_attribute = 1.23 + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("float_attribute"), + knownvalue.StringValueExact("str"), + ), + }, + ExpectError: regexp.MustCompile(`expected string value for StringValue check, got: json\.Number`), + }, + }, + }) +} + +func TestExpectKnownValue_CheckState_Float64_KnownValueWrongValue(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + float_attribute = 1.23 + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("float_attribute"), + knownvalue.Float64ValueExact(3.21), + ), + }, + ExpectError: regexp.MustCompile("expected value 3.21 for Float64Value check, got: 1.23"), + }, + }, + }) +} + +func TestExpectKnownValue_CheckState_Int64(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + int_attribute = 123 + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("int_attribute"), + knownvalue.Int64ValueExact(123), + ), + }, + }, + }, + }) +} + +func TestExpectKnownValue_CheckState_Int64_KnownValueWrongValue(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + int_attribute = 123 + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("int_attribute"), + knownvalue.Int64ValueExact(321), + ), + }, + ExpectError: regexp.MustCompile("expected value 321 for Int64Value check, got: 123"), + }, + }, + }) +} + +func TestExpectKnownValue_CheckState_List(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + list_attribute = [ + "value1", + "value2" + ] + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("list_attribute"), + knownvalue.ListValueExact([]knownvalue.Check{ + knownvalue.StringValueExact("value1"), + knownvalue.StringValueExact("value2"), + }), + ), + }, + }, + }, + }) +} + +func TestExpectKnownValue_CheckState_List_KnownValueWrongType(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + list_attribute = [ + "value1", + "value2" + ] + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("list_attribute"), + knownvalue.MapValueExact(map[string]knownvalue.Check{}), + ), + }, + ExpectError: regexp.MustCompile(`expected map\[string\]any value for MapValue check, got: \[\]interface {}`), + }, + }, + }) +} + +func TestExpectKnownValue_CheckState_List_KnownValueWrongValue(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + list_attribute = [ + "value1", + "value2" + ] + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("list_attribute"), + knownvalue.ListValueExact([]knownvalue.Check{ + knownvalue.StringValueExact("value3"), + knownvalue.StringValueExact("value4"), + }), + ), + }, + ExpectError: regexp.MustCompile(`list element index 0: expected value value3 for StringValue check, got: value1`), + }, + }, + }) +} + +func TestExpectKnownValue_CheckState_ListPartial(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + list_attribute = [ + "value1", + "value2" + ] + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("list_attribute"), + knownvalue.ListValuePartialMatch(map[int]knownvalue.Check{ + 0: knownvalue.StringValueExact("value1"), + }), + ), + }, + }, + }, + }) +} + +// No need to check KnownValueWrongType for ListPartial as all lists, and sets are []any in +// tfjson.State. +func TestExpectKnownValue_CheckState_ListPartial_KnownValueWrongValue(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + list_attribute = [ + "value1", + "value2" + ] + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("list_attribute"), + knownvalue.ListValuePartialMatch(map[int]knownvalue.Check{ + 0: knownvalue.StringValueExact("value3"), + }), + ), + }, + ExpectError: regexp.MustCompile(`list element 0: expected value value3 for StringValue check, got: value1`), + }, + }, + }) +} + +func TestExpectKnownValue_CheckState_ListElements(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + list_attribute = [ + "value1", + "value2" + ] + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("list_attribute"), + knownvalue.ListElementsExact(2), + ), + }, + }, + }, + }) +} + +func TestExpectKnownValue_CheckState_ListElements_WrongNum(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + list_attribute = [ + "value1", + "value2" + ] + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("list_attribute"), + knownvalue.ListElementsExact(3), + ), + }, + ExpectError: regexp.MustCompile("expected 3 elements for ListElements check, got 2 elements"), + }, + }, + }) +} + +func TestExpectKnownValue_CheckState_ListNestedBlock(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + list_nested_block { + list_nested_block_attribute = "str" + } + list_nested_block { + list_nested_block_attribute = "rts" + } + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("list_nested_block"), + knownvalue.ListValueExact([]knownvalue.Check{ + knownvalue.MapValueExact(map[string]knownvalue.Check{ + "list_nested_block_attribute": knownvalue.StringValueExact("str"), + }), + knownvalue.MapValueExact(map[string]knownvalue.Check{ + "list_nested_block_attribute": knownvalue.StringValueExact("rts"), + }), + }), + ), + }, + }, + }, + }) +} + +func TestExpectKnownValue_CheckState_ListNestedBlockPartial(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + list_nested_block { + list_nested_block_attribute = "str" + } + list_nested_block { + list_nested_block_attribute = "rts" + } + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("list_nested_block"), + knownvalue.ListValuePartialMatch(map[int]knownvalue.Check{ + 1: knownvalue.MapValueExact(map[string]knownvalue.Check{ + "list_nested_block_attribute": knownvalue.StringValueExact("rts"), + }), + }), + ), + }, + }, + }, + }) +} + +func TestExpectKnownValue_CheckState_ListNestedBlockElements(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + list_nested_block { + list_nested_block_attribute = "str" + } + list_nested_block { + list_nested_block_attribute = "rts" + } + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("list_nested_block"), + knownvalue.ListElementsExact(2), + ), + }, + }, + }, + }) +} + +func TestExpectKnownValue_CheckState_Map(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + map_attribute = { + key1 = "value1" + key2 = "value2" + } + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("map_attribute"), + knownvalue.MapValueExact(map[string]knownvalue.Check{ + "key1": knownvalue.StringValueExact("value1"), + "key2": knownvalue.StringValueExact("value2"), + }), + ), + }, + }, + }, + }) +} + +func TestExpectKnownValue_CheckState_Map_KnownValueWrongType(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + map_attribute = { + key1 = "value1" + key2 = "value2" + } + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("map_attribute"), + knownvalue.ListValueExact([]knownvalue.Check{}), + ), + }, + ExpectError: regexp.MustCompile(`expected \[\]any value for ListValue check, got: map\[string\]interface {}`), + }, + }, + }) +} + +func TestExpectKnownValue_CheckState_Map_KnownValueWrongValue(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + map_attribute = { + key1 = "value1" + key2 = "value2" + } + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("map_attribute"), + knownvalue.MapValueExact(map[string]knownvalue.Check{ + "key3": knownvalue.StringValueExact("value3"), + "key4": knownvalue.StringValueExact("value4"), + }), + ), + }, + ExpectError: regexp.MustCompile(`missing element key3 for MapValue check`), + }, + }, + }) +} + +func TestExpectKnownValue_CheckState_MapPartial(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + map_attribute = { + key1 = "value1" + key2 = "value2" + } + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("map_attribute"), + knownvalue.MapValuePartialMatch(map[string]knownvalue.Check{ + "key1": knownvalue.StringValueExact("value1"), + }), + ), + }, + }, + }, + }) +} + +func TestExpectKnownValue_CheckState_MapPartial_KnownValueWrongValue(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + map_attribute = { + key1 = "value1" + key2 = "value2" + } + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("map_attribute"), + knownvalue.MapValuePartialMatch(map[string]knownvalue.Check{ + "key3": knownvalue.StringValueExact("value1"), + }), + ), + }, + ExpectError: regexp.MustCompile(`missing element key3 for MapValuePartial check`), + }, + }, + }) +} + +func TestExpectKnownValue_CheckState_MapElements(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + map_attribute = { + key1 = "value1" + key2 = "value2" + } + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("map_attribute"), + knownvalue.MapElementsExact(2), + ), + }, + }, + }, + }) +} + +func TestExpectKnownValue_CheckState_MapElements_WrongNum(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + map_attribute = { + key1 = "value1" + key2 = "value2" + } + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("map_attribute"), + knownvalue.MapElementsExact(3), + ), + }, + ExpectError: regexp.MustCompile("expected 3 elements for MapElements check, got 2 elements"), + }, + }, + }) +} + +func TestExpectKnownValue_CheckState_Number(t *testing.T) { + t.Parallel() + + f, _, err := big.ParseFloat("123", 10, 512, big.ToNearestEven) + + if err != nil { + t.Errorf("%s", err) + } + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + int_attribute = 123 + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("int_attribute"), + knownvalue.NumberValueExact(f), + ), + }, + }, + }, + }) +} + +func TestExpectKnownValue_CheckState_Number_KnownValueWrongValue(t *testing.T) { + t.Parallel() + + f, _, err := big.ParseFloat("321", 10, 512, big.ToNearestEven) + + if err != nil { + t.Errorf("%s", err) + } + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + int_attribute = 123 + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("int_attribute"), + knownvalue.NumberValueExact(f), + ), + }, + ExpectError: regexp.MustCompile("expected value 321 for NumberValue check, got: 123"), + }, + }, + }) +} + +func TestExpectKnownValue_CheckState_Set(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + set_attribute = [ + "value1", + "value2" + ] + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("set_attribute"), + knownvalue.SetValueExact([]knownvalue.Check{ + knownvalue.StringValueExact("value2"), + knownvalue.StringValueExact("value1"), + }), + ), + }, + }, + }, + }) +} + +func TestExpectKnownValue_CheckState_Set_KnownValueWrongValue(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + set_attribute = [ + "value1", + "value2" + ] + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("set_attribute"), + knownvalue.SetValueExact([]knownvalue.Check{ + knownvalue.StringValueExact("value1"), + knownvalue.StringValueExact("value3"), + }), + ), + }, + ExpectError: regexp.MustCompile(`missing value value3 for SetValue check`), + }, + }, + }) +} + +func TestExpectKnownValue_CheckState_SetPartial(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + set_attribute = [ + "value1", + "value2" + ] + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("set_attribute"), + knownvalue.SetValuePartialMatch([]knownvalue.Check{ + knownvalue.StringValueExact("value2"), + }), + ), + }, + }, + }, + }) +} + +func TestExpectKnownValue_CheckState_SetPartial_KnownValueWrongValue(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + set_attribute = [ + "value1", + "value2" + ] + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("set_attribute"), + knownvalue.SetValuePartialMatch([]knownvalue.Check{ + knownvalue.StringValueExact("value3"), + }), + ), + }, + ExpectError: regexp.MustCompile(`missing value value3 for SetValuePartial check`), + }, + }, + }) +} + +func TestExpectKnownValue_CheckState_SetElements(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + set_attribute = [ + "value1", + "value2" + ] + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("set_attribute"), + knownvalue.SetElementsExact(2), + ), + }, + }, + }, + }) +} + +func TestExpectKnownValue_CheckState_SetNestedBlock(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + set_nested_block { + set_nested_block_attribute = "str" + } + set_nested_block { + set_nested_block_attribute = "rts" + } + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("set_nested_block"), + knownvalue.SetValueExact([]knownvalue.Check{ + knownvalue.MapValueExact(map[string]knownvalue.Check{ + "set_nested_block_attribute": knownvalue.StringValueExact("str"), + }), + knownvalue.MapValueExact(map[string]knownvalue.Check{ + "set_nested_block_attribute": knownvalue.StringValueExact("rts"), + }), + }), + ), + }, + }, + }, + }) +} + +func TestExpectKnownValue_CheckState_SetNestedBlockPartial(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + set_nested_block { + set_nested_block_attribute = "str" + } + set_nested_block { + set_nested_block_attribute = "rts" + } + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("set_nested_block"), + knownvalue.SetValuePartialMatch([]knownvalue.Check{ + knownvalue.MapValueExact(map[string]knownvalue.Check{ + "set_nested_block_attribute": knownvalue.StringValueExact("rts"), + }), + }), + ), + }, + }, + }, + }) +} + +func TestExpectKnownValue_CheckState_SetNestedBlockElements(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + set_nested_block { + set_nested_block_attribute = "str" + } + set_nested_block { + set_nested_block_attribute = "rts" + } + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("set_nested_block"), + knownvalue.SetElementsExact(2), + ), + }, + }, + }, + }) +} + +func TestExpectKnownValue_CheckState_String(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + string_attribute = "str" + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("string_attribute"), + knownvalue.StringValueExact("str")), + }, + }, + }, + }) +} + +func TestExpectKnownValue_CheckState_String_KnownValueWrongType(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + string_attribute = "str" + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("string_attribute"), + knownvalue.BoolValueExact(true)), + }, + ExpectError: regexp.MustCompile("expected bool value for BoolValue check, got: string"), + }, + }, + }) +} + +func TestExpectKnownValue_CheckState_String_KnownValueWrongValue(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + string_attribute = "str" + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("string_attribute"), + knownvalue.StringValueExact("rts")), + }, + ExpectError: regexp.MustCompile("expected value rts for StringValue check, got: str"), + }, + }, + }) +} + +func TestExpectKnownValue_CheckState_UnknownAttributeType(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + knownValue knownvalue.Check + req statecheck.CheckStateRequest + expectedErr error + }{ + "unrecognised-type": { + knownValue: knownvalue.Int64ValueExact(123), + req: statecheck.CheckStateRequest{ + State: &tfjson.State{ + Values: &tfjson.StateValues{ + RootModule: &tfjson.StateModule{ + Resources: []*tfjson.StateResource{ + { + Address: "example_resource.test", + AttributeValues: map[string]any{ + "attribute": float32(123), + }, + }, + }, + }, + }, + }, + }, + expectedErr: fmt.Errorf("unrecognised attribute type: float32, known value type is knownvalue.Int64Value\n\nThis is an error in statecheck.ExpectKnownValue.\nPlease report this to the maintainers."), + }, + } + + for name, testCase := range testCases { + name, testCase := name, testCase + + t.Run(name, func(t *testing.T) { + t.Parallel() + + e := statecheck.ExpectKnownValue("example_resource.test", tfjsonpath.New("attribute"), testCase.knownValue) + + resp := statecheck.CheckStateResponse{} + + e.CheckState(context.Background(), testCase.req, &resp) + + if diff := cmp.Diff(resp.Error, testCase.expectedErr, equateErrorMessage); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +var equateErrorMessage = cmp.Comparer(func(x, y error) bool { + if x == nil || y == nil { + return x == nil && y == nil + } + + return x.Error() == y.Error() +}) + +func testProvider() *schema.Provider { + return &schema.Provider{ + ResourcesMap: map[string]*schema.Resource{ + "test_resource": { + CreateContext: func(_ context.Context, d *schema.ResourceData, _ interface{}) diag.Diagnostics { + d.SetId("test") + return nil + }, + UpdateContext: func(_ context.Context, _ *schema.ResourceData, _ interface{}) diag.Diagnostics { + 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{ + "bool_attribute": { + Optional: true, + Type: schema.TypeBool, + }, + "float_attribute": { + Optional: true, + Type: schema.TypeFloat, + }, + "int_attribute": { + Optional: true, + Type: schema.TypeInt, + }, + "list_attribute": { + Type: schema.TypeList, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Optional: true, + }, + "list_nested_block": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "list_nested_block_attribute": { + Type: schema.TypeString, + Optional: true, + }, + }, + }, + }, + "map_attribute": { + Type: schema.TypeMap, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Optional: true, + }, + "set_attribute": { + Type: schema.TypeSet, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Optional: true, + }, + "set_nested_block": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "set_nested_block_attribute": { + Type: schema.TypeString, + Optional: true, + }, + }, + }, + }, + "string_attribute": { + Optional: true, + Type: schema.TypeString, + }, + }, + }, + }, + } +} From 4e3ca3ab02664ef0c018688994ad2b92acd810de Mon Sep 17 00:00:00 2001 From: Benjamin Bennett Date: Tue, 9 Jan 2024 13:34:14 +0000 Subject: [PATCH 04/29] Adding ExpectKnownOutputValue state check (#266) --- statecheck/expect_known_output_value.go | 92 ++ statecheck/expect_known_output_value_test.go | 1432 ++++++++++++++++++ statecheck/expect_known_value.go | 4 + 3 files changed, 1528 insertions(+) create mode 100644 statecheck/expect_known_output_value.go create mode 100644 statecheck/expect_known_output_value_test.go diff --git a/statecheck/expect_known_output_value.go b/statecheck/expect_known_output_value.go new file mode 100644 index 000000000..2809dff46 --- /dev/null +++ b/statecheck/expect_known_output_value.go @@ -0,0 +1,92 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package statecheck + +import ( + "context" + "fmt" + "reflect" + + tfjson "github.com/hashicorp/terraform-json" + + "github.com/hashicorp/terraform-plugin-testing/knownvalue" + "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" +) + +// Resource State Check +var _ StateCheck = expectKnownOutputValue{} + +type expectKnownOutputValue struct { + outputAddress string + knownValue knownvalue.Check +} + +// CheckState implements the state check logic. +func (e expectKnownOutputValue) CheckState(ctx context.Context, req CheckStateRequest, resp *CheckStateResponse) { + var output *tfjson.StateOutput + + if req.State == nil { + resp.Error = fmt.Errorf("state is nil") + } + + if req.State.Values == nil { + resp.Error = fmt.Errorf("state does not contain any state values") + } + + for address, oc := range req.State.Values.Outputs { + if e.outputAddress == address { + output = oc + + break + } + } + + if output == nil { + resp.Error = fmt.Errorf("%s - Output not found in state", e.outputAddress) + + return + } + + result, err := tfjsonpath.Traverse(output.Value, tfjsonpath.Path{}) + + if err != nil { + resp.Error = err + + return + } + + if result == nil { + resp.Error = fmt.Errorf("value is null") + + return + } + + switch reflect.TypeOf(result).Kind() { + case reflect.Bool, + reflect.Map, + reflect.Slice, + reflect.String: + if err := e.knownValue.CheckValue(result); err != nil { + resp.Error = err + + return + } + default: + errorStr := fmt.Sprintf("unrecognised output type: %T, known value type is %T", result, e.knownValue) + errorStr += "\n\nThis is an error in statecheck.ExpectKnownOutputValue.\nPlease report this to the maintainers." + + resp.Error = fmt.Errorf(errorStr) + + return + } +} + +// ExpectKnownOutputValue returns a state check that asserts that the specified value +// has a known type, and value. +func ExpectKnownOutputValue(outputAddress string, knownValue knownvalue.Check) StateCheck { + return expectKnownOutputValue{ + outputAddress: outputAddress, + knownValue: knownValue, + } +} diff --git a/statecheck/expect_known_output_value_test.go b/statecheck/expect_known_output_value_test.go new file mode 100644 index 000000000..1c1cfcaa7 --- /dev/null +++ b/statecheck/expect_known_output_value_test.go @@ -0,0 +1,1432 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package statecheck_test + +import ( + "context" + "fmt" + "math/big" + "regexp" + "testing" + + "github.com/google/go-cmp/cmp" + tfjson "github.com/hashicorp/terraform-json" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + r "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/knownvalue" + "github.com/hashicorp/terraform-plugin-testing/statecheck" +) + +func TestExpectKnownOutputValue_CheckState_OutputNotFound(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + bool_attribute = true + } + + output bool_output { + value = test_resource.one.bool_attribute + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "bool_not_found", + knownvalue.BoolValueExact(true), + ), + }, + ExpectError: regexp.MustCompile("bool_not_found - Output not found in state"), + }, + }, + }) +} + +func TestExpectKnownOutputValue_CheckState_AttributeValueNull(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" {} + output bool_output { + value = test_resource.one.bool_attribute + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "bool_output", + knownvalue.BoolValueExact(true), + ), + }, + ExpectError: regexp.MustCompile("bool_output - Output not found in state"), + }, + }, + }) +} + +func TestExpectKnownOutputValue_CheckState_Bool(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + bool_attribute = true + } + + output bool_output { + value = test_resource.one.bool_attribute + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "bool_output", + knownvalue.BoolValueExact(true), + ), + }, + }, + }, + }) +} + +func TestExpectKnownOutputValue_CheckState_Bool_KnownValueWrongType(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + bool_attribute = true + } + + output bool_output { + value = test_resource.one.bool_attribute + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "bool_output", + knownvalue.Float64ValueExact(1.23), + ), + }, + ExpectError: regexp.MustCompile(`expected json\.Number value for Float64Value check, got: bool`), + }, + }, + }) +} + +func TestExpectKnownOutputValue_CheckState_Bool_KnownValueWrongValue(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + bool_attribute = true + } + + output bool_output { + value = test_resource.one.bool_attribute + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "bool_output", + knownvalue.BoolValueExact(false), + ), + }, + ExpectError: regexp.MustCompile("expected value false for BoolValue check, got: true"), + }, + }, + }) +} + +func TestExpectKnownOutputValue_CheckState_Float64(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + float_attribute = 1.23 + } + + output float64_output { + value = test_resource.one.float_attribute + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "float64_output", + knownvalue.Float64ValueExact(1.23), + ), + }, + }, + }, + }) +} + +// We do not need equivalent tests for Int64 and Number as they all test the same logic. +func TestExpectKnownOutputValue_CheckState_Float64_KnownValueWrongType(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + float_attribute = 1.23 + } + + output float64_output { + value = test_resource.one.float_attribute + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "float64_output", + knownvalue.StringValueExact("str"), + ), + }, + ExpectError: regexp.MustCompile(`expected string value for StringValue check, got: json\.Number`), + }, + }, + }) +} + +func TestExpectKnownOutputValue_CheckState_Float64_KnownValueWrongValue(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + float_attribute = 1.23 + } + + output float64_output { + value = test_resource.one.float_attribute + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "float64_output", + knownvalue.Float64ValueExact(3.21), + ), + }, + ExpectError: regexp.MustCompile("expected value 3.21 for Float64Value check, got: 1.23"), + }, + }, + }) +} + +func TestExpectKnownOutputValue_CheckState_Int64(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + int_attribute = 123 + } + + output int64_output { + value = test_resource.one.int_attribute + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "int64_output", + knownvalue.Int64ValueExact(123), + ), + }, + }, + }, + }) +} + +func TestExpectKnownOutputValue_CheckState_Int64_KnownValueWrongValue(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + int_attribute = 123 + } + + output int64_output { + value = test_resource.one.int_attribute + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "int64_output", + knownvalue.Int64ValueExact(321), + ), + }, + ExpectError: regexp.MustCompile("expected value 321 for Int64Value check, got: 123"), + }, + }, + }) +} + +func TestExpectKnownOutputValue_CheckState_List(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + list_attribute = [ + "value1", + "value2" + ] + } + + output list_output { + value = test_resource.one.list_attribute + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "list_output", + knownvalue.ListValueExact([]knownvalue.Check{ + knownvalue.StringValueExact("value1"), + knownvalue.StringValueExact("value2"), + }), + ), + }, + }, + }, + }) +} + +func TestExpectKnownOutputValue_CheckState_List_KnownValueWrongType(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + list_attribute = [ + "value1", + "value2" + ] + } + + output list_output { + value = test_resource.one.list_attribute + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "list_output", + knownvalue.MapValueExact(map[string]knownvalue.Check{}), + ), + }, + ExpectError: regexp.MustCompile(`expected map\[string\]any value for MapValue check, got: \[\]interface {}`), + }, + }, + }) +} + +func TestExpectKnownOutputValue_CheckState_List_KnownValueWrongValue(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + list_attribute = [ + "value1", + "value2" + ] + } + + output list_output { + value = test_resource.one.list_attribute + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "list_output", + knownvalue.ListValueExact([]knownvalue.Check{ + knownvalue.StringValueExact("value3"), + knownvalue.StringValueExact("value4"), + }), + ), + }, + ExpectError: regexp.MustCompile(`list element index 0: expected value value3 for StringValue check, got: value1`), + }, + }, + }) +} + +func TestExpectKnownOutputValue_CheckState_ListPartial(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + list_attribute = [ + "value1", + "value2" + ] + } + + output list_output { + value = test_resource.one.list_attribute + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "list_output", + knownvalue.ListValuePartialMatch(map[int]knownvalue.Check{ + 0: knownvalue.StringValueExact("value1"), + }), + ), + }, + }, + }, + }) +} + +// No need to check KnownValueWrongType for ListPartial as all lists, and sets are []any in +// tfjson.State. +func TestExpectKnownOutputValue_CheckState_ListPartial_KnownValueWrongValue(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + list_attribute = [ + "value1", + "value2" + ] + } + + output list_output { + value = test_resource.one.list_attribute + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "list_output", + knownvalue.ListValuePartialMatch(map[int]knownvalue.Check{ + 0: knownvalue.StringValueExact("value3"), + }), + ), + }, + ExpectError: regexp.MustCompile(`list element 0: expected value value3 for StringValue check, got: value1`), + }, + }, + }) +} + +func TestExpectKnownOutputValue_CheckState_ListElements(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + list_attribute = [ + "value1", + "value2" + ] + } + + output list_output { + value = test_resource.one.list_attribute + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "list_output", + knownvalue.ListElementsExact(2), + ), + }, + }, + }, + }) +} + +func TestExpectKnownOutputValue_CheckState_ListElements_WrongNum(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + list_attribute = [ + "value1", + "value2" + ] + } + + output list_output { + value = test_resource.one.list_attribute + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "list_output", + knownvalue.ListElementsExact(3), + ), + }, + ExpectError: regexp.MustCompile("expected 3 elements for ListElements check, got 2 elements"), + }, + }, + }) +} + +func TestExpectKnownOutputValue_CheckState_ListNestedBlock(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + list_nested_block { + list_nested_block_attribute = "str" + } + list_nested_block { + list_nested_block_attribute = "rts" + } + } + + output list_nested_block_output { + value = test_resource.one.list_nested_block + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "list_nested_block_output", + knownvalue.ListValueExact([]knownvalue.Check{ + knownvalue.MapValueExact(map[string]knownvalue.Check{ + "list_nested_block_attribute": knownvalue.StringValueExact("str"), + }), + knownvalue.MapValueExact(map[string]knownvalue.Check{ + "list_nested_block_attribute": knownvalue.StringValueExact("rts"), + }), + }), + ), + }, + }, + }, + }) +} + +func TestExpectKnownOutputValue_CheckState_ListNestedBlockPartial(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + list_nested_block { + list_nested_block_attribute = "str" + } + list_nested_block { + list_nested_block_attribute = "rts" + } + } + + output list_nested_block_output { + value = test_resource.one.list_nested_block + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "list_nested_block_output", + knownvalue.ListValuePartialMatch(map[int]knownvalue.Check{ + 1: knownvalue.MapValueExact(map[string]knownvalue.Check{ + "list_nested_block_attribute": knownvalue.StringValueExact("rts"), + }), + }), + ), + }, + }, + }, + }) +} + +func TestExpectKnownOutputValue_CheckState_ListNestedBlockElements(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + list_nested_block { + list_nested_block_attribute = "str" + } + list_nested_block { + list_nested_block_attribute = "rts" + } + } + + output list_nested_block_output { + value = test_resource.one.list_nested_block + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "list_nested_block_output", + knownvalue.ListElementsExact(2), + ), + }, + }, + }, + }) +} + +func TestExpectKnownOutputValue_CheckState_Map(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + map_attribute = { + key1 = "value1" + key2 = "value2" + } + } + + output map_output { + value = test_resource.one.map_attribute + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "map_output", + knownvalue.MapValueExact(map[string]knownvalue.Check{ + "key1": knownvalue.StringValueExact("value1"), + "key2": knownvalue.StringValueExact("value2"), + }), + ), + }, + }, + }, + }) +} + +func TestExpectKnownOutputValue_CheckState_Map_KnownValueWrongType(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + map_attribute = { + key1 = "value1" + key2 = "value2" + } + } + + output map_output { + value = test_resource.one.map_attribute + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "map_output", + knownvalue.ListValueExact([]knownvalue.Check{}), + ), + }, + ExpectError: regexp.MustCompile(`expected \[\]any value for ListValue check, got: map\[string\]interface {}`), + }, + }, + }) +} + +func TestExpectKnownOutputValue_CheckState_Map_KnownValueWrongValue(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + map_attribute = { + key1 = "value1" + key2 = "value2" + } + } + + output map_output { + value = test_resource.one.map_attribute + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "map_output", + knownvalue.MapValueExact(map[string]knownvalue.Check{ + "key3": knownvalue.StringValueExact("value3"), + "key4": knownvalue.StringValueExact("value4"), + }), + ), + }, + ExpectError: regexp.MustCompile(`missing element key3 for MapValue check`), + }, + }, + }) +} + +func TestExpectKnownOutputValue_CheckState_MapPartial(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + map_attribute = { + key1 = "value1" + key2 = "value2" + } + } + + output map_output { + value = test_resource.one.map_attribute + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "map_output", + knownvalue.MapValuePartialMatch(map[string]knownvalue.Check{ + "key1": knownvalue.StringValueExact("value1"), + }), + ), + }, + }, + }, + }) +} + +func TestExpectKnownOutputValue_CheckState_MapPartial_KnownValueWrongValue(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + map_attribute = { + key1 = "value1" + key2 = "value2" + } + } + + output map_output { + value = test_resource.one.map_attribute + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "map_output", + knownvalue.MapValuePartialMatch(map[string]knownvalue.Check{ + "key3": knownvalue.StringValueExact("value1"), + }), + ), + }, + ExpectError: regexp.MustCompile(`missing element key3 for MapValuePartial check`), + }, + }, + }) +} + +func TestExpectKnownOutputValue_CheckState_MapElements(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + map_attribute = { + key1 = "value1" + key2 = "value2" + } + } + + output map_output { + value = test_resource.one.map_attribute + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "map_output", + knownvalue.MapElementsExact(2), + ), + }, + }, + }, + }) +} + +func TestExpectKnownOutputValue_CheckState_MapElements_WrongNum(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + map_attribute = { + key1 = "value1" + key2 = "value2" + } + } + + output map_output { + value = test_resource.one.map_attribute + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "map_output", + knownvalue.MapElementsExact(3), + ), + }, + ExpectError: regexp.MustCompile("expected 3 elements for MapElements check, got 2 elements"), + }, + }, + }) +} + +func TestExpectKnownOutputValue_CheckState_Number(t *testing.T) { + t.Parallel() + + f, _, err := big.ParseFloat("123", 10, 512, big.ToNearestEven) + + if err != nil { + t.Errorf("%s", err) + } + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + int_attribute = 123 + } + + output int64_output { + value = test_resource.one.int_attribute + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "int64_output", + knownvalue.NumberValueExact(f), + ), + }, + }, + }, + }) +} + +func TestExpectKnownOutputValue_CheckState_Number_KnownValueWrongValue(t *testing.T) { + t.Parallel() + + f, _, err := big.ParseFloat("321", 10, 512, big.ToNearestEven) + + if err != nil { + t.Errorf("%s", err) + } + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + int_attribute = 123 + } + + output int64_output { + value = test_resource.one.int_attribute + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "int64_output", + knownvalue.NumberValueExact(f), + ), + }, + ExpectError: regexp.MustCompile("expected value 321 for NumberValue check, got: 123"), + }, + }, + }) +} + +func TestExpectKnownOutputValue_CheckState_Set(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + set_attribute = [ + "value1", + "value2" + ] + } + + output set_output { + value = test_resource.one.set_attribute + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "set_output", + knownvalue.SetValueExact([]knownvalue.Check{ + knownvalue.StringValueExact("value1"), + knownvalue.StringValueExact("value2"), + }), + ), + }, + }, + }, + }) +} + +func TestExpectKnownOutputValue_CheckState_Set_KnownValueWrongValue(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + set_attribute = [ + "value1", + "value2" + ] + } + + output set_output { + value = test_resource.one.set_attribute + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "set_output", + knownvalue.SetValueExact([]knownvalue.Check{ + knownvalue.StringValueExact("value1"), + knownvalue.StringValueExact("value3"), + }), + ), + }, + ExpectError: regexp.MustCompile(`missing value value3 for SetValue check`), + }, + }, + }) +} + +func TestExpectKnownOutputValue_CheckState_SetPartial(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + set_attribute = [ + "value1", + "value2" + ] + } + + output set_output { + value = test_resource.one.set_attribute + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "set_output", + knownvalue.SetValuePartialMatch([]knownvalue.Check{ + knownvalue.StringValueExact("value2"), + }), + ), + }, + }, + }, + }) +} + +func TestExpectKnownOutputValue_CheckState_SetPartial_KnownValueWrongValue(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + set_attribute = [ + "value1", + "value2" + ] + } + + output set_output { + value = test_resource.one.set_attribute + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "set_output", + knownvalue.SetValuePartialMatch([]knownvalue.Check{ + knownvalue.StringValueExact("value3"), + }), + ), + }, + ExpectError: regexp.MustCompile(`missing value value3 for SetValuePartial check`), + }, + }, + }) +} + +func TestExpectKnownOutputValue_CheckState_SetElements(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + set_attribute = [ + "value1", + "value2" + ] + } + + output set_output { + value = test_resource.one.set_attribute + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "set_output", + knownvalue.SetElementsExact(2), + ), + }, + }, + }, + }) +} + +func TestExpectKnownOutputValue_CheckState_SetNestedBlock(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + set_nested_block { + set_nested_block_attribute = "str" + } + set_nested_block { + set_nested_block_attribute = "rts" + } + } + + output set_nested_block_output { + value = test_resource.one.set_nested_block + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "set_nested_block_output", + knownvalue.SetValueExact([]knownvalue.Check{ + knownvalue.MapValueExact(map[string]knownvalue.Check{ + "set_nested_block_attribute": knownvalue.StringValueExact("str"), + }), + knownvalue.MapValueExact(map[string]knownvalue.Check{ + "set_nested_block_attribute": knownvalue.StringValueExact("rts"), + }), + }), + ), + }, + }, + }, + }) +} + +func TestExpectKnownOutputValue_CheckState_SetNestedBlockPartial(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + set_nested_block { + set_nested_block_attribute = "str" + } + set_nested_block { + set_nested_block_attribute = "rts" + } + } + + output set_nested_block_output { + value = test_resource.one.set_nested_block + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "set_nested_block_output", + knownvalue.SetValuePartialMatch([]knownvalue.Check{ + knownvalue.MapValueExact(map[string]knownvalue.Check{ + "set_nested_block_attribute": knownvalue.StringValueExact("rts"), + }), + }), + ), + }, + }, + }, + }) +} + +func TestExpectKnownOutputValue_CheckState_SetNestedBlockElements(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + set_nested_block { + set_nested_block_attribute = "str" + } + set_nested_block { + set_nested_block_attribute = "rts" + } + } + + output set_nested_block_output { + value = test_resource.one.set_nested_block + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "set_nested_block_output", + knownvalue.SetElementsExact(2), + ), + }, + }, + }, + }) +} + +func TestExpectKnownOutputValue_CheckState_String(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + string_attribute = "str" + } + + output string_output { + value = test_resource.one.string_attribute + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "string_output", + knownvalue.StringValueExact("str")), + }, + }, + }, + }) +} + +func TestExpectKnownOutputValue_CheckState_String_KnownValueWrongType(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + string_attribute = "str" + } + + output string_output { + value = test_resource.one.string_attribute + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "string_output", + knownvalue.BoolValueExact(true)), + }, + ExpectError: regexp.MustCompile("expected bool value for BoolValue check, got: string"), + }, + }, + }) +} + +func TestExpectKnownOutputValue_CheckState_String_KnownValueWrongValue(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + string_attribute = "str" + } + + output string_output { + value = test_resource.one.string_attribute + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "string_output", + knownvalue.StringValueExact("rts")), + }, + ExpectError: regexp.MustCompile("expected value rts for StringValue check, got: str"), + }, + }, + }) +} + +func TestExpectKnownOutputValue_CheckState_UnknownAttributeType(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + knownValue knownvalue.Check + req statecheck.CheckStateRequest + expectedErr error + }{ + "unrecognised-type": { + knownValue: knownvalue.Int64ValueExact(123), + req: statecheck.CheckStateRequest{ + State: &tfjson.State{ + Values: &tfjson.StateValues{ + Outputs: map[string]*tfjson.StateOutput{ + "float32_output": { + Value: float32(123), + }, + }, + }, + }, + }, + expectedErr: fmt.Errorf("unrecognised output type: float32, known value type is knownvalue.Int64Value\n\nThis is an error in statecheck.ExpectKnownOutputValue.\nPlease report this to the maintainers."), + }, + } + + for name, testCase := range testCases { + name, testCase := name, testCase + + t.Run(name, func(t *testing.T) { + t.Parallel() + + e := statecheck.ExpectKnownOutputValue("float32_output", testCase.knownValue) + + resp := statecheck.CheckStateResponse{} + + e.CheckState(context.Background(), testCase.req, &resp) + + if diff := cmp.Diff(resp.Error, testCase.expectedErr, equateErrorMessage); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/statecheck/expect_known_value.go b/statecheck/expect_known_value.go index 2f073f15c..b8d5a6157 100644 --- a/statecheck/expect_known_value.go +++ b/statecheck/expect_known_value.go @@ -27,6 +27,10 @@ type expectKnownValue struct { func (e expectKnownValue) CheckState(ctx context.Context, req CheckStateRequest, resp *CheckStateResponse) { var rc *tfjson.StateResource + if req.State == nil { + resp.Error = fmt.Errorf("state is nil") + } + if req.State.Values == nil { resp.Error = fmt.Errorf("state does not contain any state values") } From d93aa8209edf3836a627e8dfbcf432bf9263e2e8 Mon Sep 17 00:00:00 2001 From: Benjamin Bennett Date: Tue, 9 Jan 2024 13:48:21 +0000 Subject: [PATCH 05/29] Adding ExpectKnownOutputValueAtPath state check (#266) --- .../expect_known_output_value_at_path.go | 94 + .../expect_known_output_value_at_path_test.go | 1755 +++++++++++++++++ 2 files changed, 1849 insertions(+) create mode 100644 statecheck/expect_known_output_value_at_path.go create mode 100644 statecheck/expect_known_output_value_at_path_test.go diff --git a/statecheck/expect_known_output_value_at_path.go b/statecheck/expect_known_output_value_at_path.go new file mode 100644 index 000000000..31d4516b1 --- /dev/null +++ b/statecheck/expect_known_output_value_at_path.go @@ -0,0 +1,94 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package statecheck + +import ( + "context" + "fmt" + "reflect" + + tfjson "github.com/hashicorp/terraform-json" + + "github.com/hashicorp/terraform-plugin-testing/knownvalue" + "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" +) + +// Resource State Check +var _ StateCheck = expectKnownOutputValueAtPath{} + +type expectKnownOutputValueAtPath struct { + outputAddress string + outputPath tfjsonpath.Path + knownValue knownvalue.Check +} + +// CheckState implements the state check logic. +func (e expectKnownOutputValueAtPath) CheckState(ctx context.Context, req CheckStateRequest, resp *CheckStateResponse) { + var output *tfjson.StateOutput + + if req.State == nil { + resp.Error = fmt.Errorf("state is nil") + } + + if req.State.Values == nil { + resp.Error = fmt.Errorf("state does not contain any state values") + } + + for address, oc := range req.State.Values.Outputs { + if e.outputAddress == address { + output = oc + + break + } + } + + if output == nil { + resp.Error = fmt.Errorf("%s - Output not found in state", e.outputAddress) + + return + } + + result, err := tfjsonpath.Traverse(output.Value, e.outputPath) + + if err != nil { + resp.Error = err + + return + } + + if result == nil { + resp.Error = fmt.Errorf("value is null") + + return + } + + switch reflect.TypeOf(result).Kind() { + case reflect.Bool, + reflect.Map, + reflect.Slice, + reflect.String: + if err := e.knownValue.CheckValue(result); err != nil { + resp.Error = err + + return + } + default: + errorStr := fmt.Sprintf("unrecognised output type: %T, known value type is %T", result, e.knownValue) + errorStr += "\n\nThis is an error in statecheck.ExpectKnownOutputValueAtPath.\nPlease report this to the maintainers." + + resp.Error = fmt.Errorf(errorStr) + + return + } +} + +// ExpectKnownOutputValueAtPath returns a state check that asserts that the specified output at the given path +// has a known type and value. +func ExpectKnownOutputValueAtPath(outputAddress string, outputPath tfjsonpath.Path, knownValue knownvalue.Check) StateCheck { + return expectKnownOutputValueAtPath{ + outputAddress: outputAddress, + outputPath: outputPath, + knownValue: knownValue, + } +} diff --git a/statecheck/expect_known_output_value_at_path_test.go b/statecheck/expect_known_output_value_at_path_test.go new file mode 100644 index 000000000..6b9795f90 --- /dev/null +++ b/statecheck/expect_known_output_value_at_path_test.go @@ -0,0 +1,1755 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package statecheck_test + +import ( + "context" + "fmt" + "math/big" + "regexp" + "testing" + + "github.com/google/go-cmp/cmp" + tfjson "github.com/hashicorp/terraform-json" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + r "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/knownvalue" + "github.com/hashicorp/terraform-plugin-testing/statecheck" + "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" + "github.com/hashicorp/terraform-plugin-testing/tfversion" +) + +func TestExpectKnownOutputValueAtPath_CheckState_ResourceNotFound(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + // Prior to Terraform v1.3.0 a statened output is marked as fully unknown + // if any attribute is unknown. The id attribute within the test provider + // is unknown. + // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_3_0), + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + bool_attribute = true + } + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_two_output", + tfjsonpath.New("bool_attribute"), + knownvalue.BoolValueExact(true), + ), + }, + ExpectError: regexp.MustCompile("test_resource_two_output - Output not found in state"), + }, + }, + }) +} + +func TestExpectKnownOutputValueAtPath_CheckState_AttributeValueNull(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + // Prior to Terraform v1.3.0 a statened output is marked as fully unknown + // if any attribute is unknown. The id attribute within the test provider + // is unknown. + // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_3_0), + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" {} + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("bool_attribute"), + knownvalue.BoolValueExact(true), + ), + }, + ExpectError: regexp.MustCompile("value is null"), + }, + }, + }) +} + +func TestExpectKnownOutputValueAtPath_CheckState_Bool(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + // Prior to Terraform v1.3.0 a statened output is marked as fully unknown + // if any attribute is unknown. The id attribute within the test provider + // is unknown. + // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_3_0), + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + bool_attribute = true + } + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("bool_attribute"), + knownvalue.BoolValueExact(true), + ), + }, + }, + }, + }) +} + +func TestExpectKnownOutputValueAtPath_CheckState_Bool_KnownValueWrongType(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + // Prior to Terraform v1.3.0 a statened output is marked as fully unknown + // if any attribute is unknown. The id attribute within the test provider + // is unknown. + // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_3_0), + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + bool_attribute = true + } + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("bool_attribute"), + knownvalue.Float64ValueExact(1.23), + ), + }, + ExpectError: regexp.MustCompile(`expected json\.Number value for Float64Value check, got: bool`), + }, + }, + }) +} + +func TestExpectKnownOutputValueAtPath_CheckState_Bool_KnownValueWrongValue(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + // Prior to Terraform v1.3.0 a statened output is marked as fully unknown + // if any attribute is unknown. The id attribute within the test provider + // is unknown. + // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_3_0), + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + bool_attribute = true + } + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("bool_attribute"), + knownvalue.BoolValueExact(false), + ), + }, + ExpectError: regexp.MustCompile("expected value false for BoolValue check, got: true"), + }, + }, + }) +} + +func TestExpectKnownOutputValueAtPath_CheckState_Float64(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + // Prior to Terraform v1.3.0 a statened output is marked as fully unknown + // if any attribute is unknown. The id attribute within the test provider + // is unknown. + // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_3_0), + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + float_attribute = 1.23 + } + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("float_attribute"), + knownvalue.Float64ValueExact(1.23), + ), + }, + }, + }, + }) +} + +// We do not need equivalent tests for Int64 and Number as they all test the same logic. +func TestExpectKnownOutputValueAtPath_CheckState_Float64_KnownValueWrongType(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + // Prior to Terraform v1.3.0 a statened output is marked as fully unknown + // if any attribute is unknown. The id attribute within the test provider + // is unknown. + // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_3_0), + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + float_attribute = 1.23 + } + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("float_attribute"), + knownvalue.StringValueExact("str"), + ), + }, + ExpectError: regexp.MustCompile(`expected string value for StringValue check, got: json\.Number`), + }, + }, + }) +} + +func TestExpectKnownOutputValueAtPath_CheckState_Float64_KnownValueWrongValue(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + // Prior to Terraform v1.3.0 a statened output is marked as fully unknown + // if any attribute is unknown. The id attribute within the test provider + // is unknown. + // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_3_0), + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + float_attribute = 1.23 + } + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("float_attribute"), + knownvalue.Float64ValueExact(3.21), + ), + }, + ExpectError: regexp.MustCompile("expected value 3.21 for Float64Value check, got: 1.23"), + }, + }, + }) +} + +func TestExpectKnownOutputValueAtPath_CheckState_Int64(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + // Prior to Terraform v1.3.0 a statened output is marked as fully unknown + // if any attribute is unknown. The id attribute within the test provider + // is unknown. + // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_3_0), + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + int_attribute = 123 + } + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("int_attribute"), + knownvalue.Int64ValueExact(123), + ), + }, + }, + }, + }) +} + +func TestExpectKnownOutputValueAtPath_CheckState_Int64_KnownValueWrongValue(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + // Prior to Terraform v1.3.0 a statened output is marked as fully unknown + // if any attribute is unknown. The id attribute within the test provider + // is unknown. + // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_3_0), + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + int_attribute = 123 + } + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("int_attribute"), + knownvalue.Int64ValueExact(321), + ), + }, + ExpectError: regexp.MustCompile("expected value 321 for Int64Value check, got: 123"), + }, + }, + }) +} + +func TestExpectKnownOutputValueAtPath_CheckState_List(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + // Prior to Terraform v1.3.0 a statened output is marked as fully unknown + // if any attribute is unknown. The id attribute within the test provider + // is unknown. + // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_3_0), + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + list_attribute = [ + "value1", + "value2" + ] + } + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("list_attribute"), + knownvalue.ListValueExact([]knownvalue.Check{ + knownvalue.StringValueExact("value1"), + knownvalue.StringValueExact("value2"), + }), + ), + }, + }, + }, + }) +} + +func TestExpectKnownOutputValueAtPath_CheckState_List_KnownValueWrongType(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + // Prior to Terraform v1.3.0 a statened output is marked as fully unknown + // if any attribute is unknown. The id attribute within the test provider + // is unknown. + // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_3_0), + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + list_attribute = [ + "value1", + "value2" + ] + } + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("list_attribute"), + knownvalue.MapValueExact(map[string]knownvalue.Check{}), + ), + }, + ExpectError: regexp.MustCompile(`expected map\[string\]any value for MapValue check, got: \[\]interface {}`), + }, + }, + }) +} + +func TestExpectKnownOutputValueAtPath_CheckState_List_KnownValueWrongValue(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + // Prior to Terraform v1.3.0 a statened output is marked as fully unknown + // if any attribute is unknown. The id attribute within the test provider + // is unknown. + // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_3_0), + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + list_attribute = [ + "value1", + "value2" + ] + } + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("list_attribute"), + knownvalue.ListValueExact([]knownvalue.Check{ + knownvalue.StringValueExact("value3"), + knownvalue.StringValueExact("value4"), + }), + ), + }, + ExpectError: regexp.MustCompile(`list element index 0: expected value value3 for StringValue check, got: value1`), + }, + }, + }) +} + +func TestExpectKnownOutputValueAtPath_CheckState_ListPartial(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + // Prior to Terraform v1.3.0 a statened output is marked as fully unknown + // if any attribute is unknown. The id attribute within the test provider + // is unknown. + // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_3_0), + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + list_attribute = [ + "value1", + "value2" + ] + } + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("list_attribute"), + knownvalue.ListValuePartialMatch(map[int]knownvalue.Check{ + 0: knownvalue.StringValueExact("value1"), + }), + ), + }, + }, + }, + }) +} + +// No need to check KnownValueWrongType for ListPartial as all lists, and sets are []any in +// tfjson.State. +func TestExpectKnownOutputValueAtPath_CheckState_ListPartial_KnownValueWrongValue(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + // Prior to Terraform v1.3.0 a statened output is marked as fully unknown + // if any attribute is unknown. The id attribute within the test provider + // is unknown. + // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_3_0), + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + list_attribute = [ + "value1", + "value2" + ] + } + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("list_attribute"), + knownvalue.ListValuePartialMatch(map[int]knownvalue.Check{ + 0: knownvalue.StringValueExact("value3"), + }), + ), + }, + ExpectError: regexp.MustCompile(`list element 0: expected value value3 for StringValue check, got: value1`), + }, + }, + }) +} + +func TestExpectKnownOutputValueAtPath_CheckState_ListElements(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + // Prior to Terraform v1.3.0 a statened output is marked as fully unknown + // if any attribute is unknown. The id attribute within the test provider + // is unknown. + // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_3_0), + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + list_attribute = [ + "value1", + "value2" + ] + } + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("list_attribute"), + knownvalue.ListElementsExact(2), + ), + }, + }, + }, + }) +} + +func TestExpectKnownOutputValueAtPath_CheckState_ListElements_WrongNum(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + // Prior to Terraform v1.3.0 a statened output is marked as fully unknown + // if any attribute is unknown. The id attribute within the test provider + // is unknown. + // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_3_0), + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + list_attribute = [ + "value1", + "value2" + ] + } + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("list_attribute"), + knownvalue.ListElementsExact(3), + ), + }, + ExpectError: regexp.MustCompile("expected 3 elements for ListElements check, got 2 elements"), + }, + }, + }) +} + +func TestExpectKnownOutputValueAtPath_CheckState_ListNestedBlock(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + // Prior to Terraform v1.3.0 a statened output is marked as fully unknown + // if any attribute is unknown. The id attribute within the test provider + // is unknown. + // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_3_0), + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + list_nested_block { + list_nested_block_attribute = "str" + } + list_nested_block { + list_nested_block_attribute = "rts" + } + } + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("list_nested_block"), + knownvalue.ListValueExact([]knownvalue.Check{ + knownvalue.MapValueExact(map[string]knownvalue.Check{ + "list_nested_block_attribute": knownvalue.StringValueExact("str"), + }), + knownvalue.MapValueExact(map[string]knownvalue.Check{ + "list_nested_block_attribute": knownvalue.StringValueExact("rts"), + }), + }), + ), + }, + }, + }, + }) +} + +func TestExpectKnownOutputValueAtPath_CheckState_ListNestedBlockPartial(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + // Prior to Terraform v1.3.0 a statened output is marked as fully unknown + // if any attribute is unknown. The id attribute within the test provider + // is unknown. + // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_3_0), + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + list_nested_block { + list_nested_block_attribute = "str" + } + list_nested_block { + list_nested_block_attribute = "rts" + } + } + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("list_nested_block"), + knownvalue.ListValuePartialMatch(map[int]knownvalue.Check{ + 1: knownvalue.MapValueExact(map[string]knownvalue.Check{ + "list_nested_block_attribute": knownvalue.StringValueExact("rts"), + }), + }), + ), + }, + }, + }, + }) +} + +func TestExpectKnownOutputValueAtPath_CheckState_ListNestedBlockElements(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + // Prior to Terraform v1.3.0 a statened output is marked as fully unknown + // if any attribute is unknown. The id attribute within the test provider + // is unknown. + // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_3_0), + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + list_nested_block { + list_nested_block_attribute = "str" + } + list_nested_block { + list_nested_block_attribute = "rts" + } + } + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("list_nested_block"), + knownvalue.ListElementsExact(2), + ), + }, + }, + }, + }) +} + +func TestExpectKnownOutputValueAtPath_CheckState_Map(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + // Prior to Terraform v1.3.0 a statened output is marked as fully unknown + // if any attribute is unknown. The id attribute within the test provider + // is unknown. + // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_3_0), + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + map_attribute = { + key1 = "value1" + key2 = "value2" + } + } + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("map_attribute"), + knownvalue.MapValueExact(map[string]knownvalue.Check{ + "key1": knownvalue.StringValueExact("value1"), + "key2": knownvalue.StringValueExact("value2"), + }), + ), + }, + }, + }, + }) +} + +func TestExpectKnownOutputValueAtPath_CheckState_Map_KnownValueWrongType(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + // Prior to Terraform v1.3.0 a statened output is marked as fully unknown + // if any attribute is unknown. The id attribute within the test provider + // is unknown. + // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_3_0), + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + map_attribute = { + key1 = "value1" + key2 = "value2" + } + } + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("map_attribute"), + knownvalue.ListValueExact([]knownvalue.Check{}), + ), + }, + ExpectError: regexp.MustCompile(`expected \[\]any value for ListValue check, got: map\[string\]interface {}`), + }, + }, + }) +} + +func TestExpectKnownOutputValueAtPath_CheckState_Map_KnownValueWrongValue(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + // Prior to Terraform v1.3.0 a statened output is marked as fully unknown + // if any attribute is unknown. The id attribute within the test provider + // is unknown. + // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_3_0), + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + map_attribute = { + key1 = "value1" + key2 = "value2" + } + } + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("map_attribute"), + knownvalue.MapValueExact(map[string]knownvalue.Check{ + "key3": knownvalue.StringValueExact("value3"), + "key4": knownvalue.StringValueExact("value4"), + }), + ), + }, + ExpectError: regexp.MustCompile(`missing element key3 for MapValue check`), + }, + }, + }) +} + +func TestExpectKnownOutputValueAtPath_CheckState_MapPartial(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + // Prior to Terraform v1.3.0 a statened output is marked as fully unknown + // if any attribute is unknown. The id attribute within the test provider + // is unknown. + // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_3_0), + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + map_attribute = { + key1 = "value1" + key2 = "value2" + } + } + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("map_attribute"), + knownvalue.MapValuePartialMatch(map[string]knownvalue.Check{ + "key1": knownvalue.StringValueExact("value1"), + }), + ), + }, + }, + }, + }) +} + +func TestExpectKnownOutputValueAtPath_CheckState_MapPartial_KnownValueWrongValue(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + // Prior to Terraform v1.3.0 a statened output is marked as fully unknown + // if any attribute is unknown. The id attribute within the test provider + // is unknown. + // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_3_0), + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + map_attribute = { + key1 = "value1" + key2 = "value2" + } + } + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("map_attribute"), + knownvalue.MapValuePartialMatch(map[string]knownvalue.Check{ + "key3": knownvalue.StringValueExact("value1"), + }), + ), + }, + ExpectError: regexp.MustCompile(`missing element key3 for MapValuePartial check`), + }, + }, + }) +} + +func TestExpectKnownOutputValueAtPath_CheckState_MapElements(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + // Prior to Terraform v1.3.0 a statened output is marked as fully unknown + // if any attribute is unknown. The id attribute within the test provider + // is unknown. + // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_3_0), + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + map_attribute = { + key1 = "value1" + key2 = "value2" + } + } + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("map_attribute"), + knownvalue.MapElementsExact(2), + ), + }, + }, + }, + }) +} + +func TestExpectKnownOutputValueAtPath_CheckState_MapElements_WrongNum(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + // Prior to Terraform v1.3.0 a statened output is marked as fully unknown + // if any attribute is unknown. The id attribute within the test provider + // is unknown. + // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_3_0), + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + map_attribute = { + key1 = "value1" + key2 = "value2" + } + } + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("map_attribute"), + knownvalue.MapElementsExact(3), + ), + }, + ExpectError: regexp.MustCompile("expected 3 elements for MapElements check, got 2 elements"), + }, + }, + }) +} + +func TestExpectKnownOutputValueAtPath_CheckState_Number(t *testing.T) { + t.Parallel() + + f, _, err := big.ParseFloat("123", 10, 512, big.ToNearestEven) + + if err != nil { + t.Errorf("%s", err) + } + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + // Prior to Terraform v1.3.0 a statened output is marked as fully unknown + // if any attribute is unknown. The id attribute within the test provider + // is unknown. + // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_3_0), + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + int_attribute = 123 + } + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("int_attribute"), + knownvalue.NumberValueExact(f), + ), + }, + }, + }, + }) +} + +func TestExpectKnownOutputValueAtPath_CheckState_Number_KnownValueWrongValue(t *testing.T) { + t.Parallel() + + f, _, err := big.ParseFloat("321", 10, 512, big.ToNearestEven) + + if err != nil { + t.Errorf("%s", err) + } + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + // Prior to Terraform v1.3.0 a statened output is marked as fully unknown + // if any attribute is unknown. The id attribute within the test provider + // is unknown. + // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_3_0), + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + int_attribute = 123 + } + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("int_attribute"), + knownvalue.NumberValueExact(f), + ), + }, + ExpectError: regexp.MustCompile("expected value 321 for NumberValue check, got: 123"), + }, + }, + }) +} + +func TestExpectKnownOutputValueAtPath_CheckState_Set(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + // Prior to Terraform v1.3.0 a statened output is marked as fully unknown + // if any attribute is unknown. The id attribute within the test provider + // is unknown. + // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_3_0), + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + set_attribute = [ + "value1", + "value2" + ] + } + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("set_attribute"), + knownvalue.SetValueExact([]knownvalue.Check{ + knownvalue.StringValueExact("value1"), + knownvalue.StringValueExact("value2"), + }), + ), + }, + }, + }, + }) +} + +func TestExpectKnownOutputValueAtPath_CheckState_Set_KnownValueWrongValue(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + // Prior to Terraform v1.3.0 a statened output is marked as fully unknown + // if any attribute is unknown. The id attribute within the test provider + // is unknown. + // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_3_0), + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + set_attribute = [ + "value1", + "value2" + ] + } + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("set_attribute"), + knownvalue.SetValueExact([]knownvalue.Check{ + knownvalue.StringValueExact("value1"), + knownvalue.StringValueExact("value3"), + }), + ), + }, + ExpectError: regexp.MustCompile(`missing value value3 for SetValue check`), + }, + }, + }) +} + +func TestExpectKnownOutputValueAtPath_CheckState_SetPartial(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + // Prior to Terraform v1.3.0 a statened output is marked as fully unknown + // if any attribute is unknown. The id attribute within the test provider + // is unknown. + // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_3_0), + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + set_attribute = [ + "value1", + "value2" + ] + } + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("set_attribute"), + knownvalue.SetValuePartialMatch([]knownvalue.Check{ + knownvalue.StringValueExact("value2"), + }), + ), + }, + }, + }, + }) +} + +func TestExpectKnownOutputValueAtPath_CheckState_SetPartial_KnownValueWrongValue(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + // Prior to Terraform v1.3.0 a statened output is marked as fully unknown + // if any attribute is unknown. The id attribute within the test provider + // is unknown. + // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_3_0), + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + set_attribute = [ + "value1", + "value2" + ] + } + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("set_attribute"), + knownvalue.SetValuePartialMatch([]knownvalue.Check{ + knownvalue.StringValueExact("value3"), + }), + ), + }, + ExpectError: regexp.MustCompile(`missing value value3 for SetValuePartial check`), + }, + }, + }) +} + +func TestExpectKnownOutputValueAtPath_CheckState_SetElements(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + // Prior to Terraform v1.3.0 a statened output is marked as fully unknown + // if any attribute is unknown. The id attribute within the test provider + // is unknown. + // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_3_0), + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + set_attribute = [ + "value1", + "value2" + ] + } + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("set_attribute"), + knownvalue.SetElementsExact(2), + ), + }, + }, + }, + }) +} + +func TestExpectKnownOutputValueAtPath_CheckState_SetNestedBlock(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + // Prior to Terraform v1.3.0 a statened output is marked as fully unknown + // if any attribute is unknown. The id attribute within the test provider + // is unknown. + // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_3_0), + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + set_nested_block { + set_nested_block_attribute = "str" + } + set_nested_block { + set_nested_block_attribute = "rts" + } + } + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("set_nested_block"), + knownvalue.SetValueExact([]knownvalue.Check{ + knownvalue.MapValueExact(map[string]knownvalue.Check{ + "set_nested_block_attribute": knownvalue.StringValueExact("str"), + }), + knownvalue.MapValueExact(map[string]knownvalue.Check{ + "set_nested_block_attribute": knownvalue.StringValueExact("rts"), + }), + }), + ), + }, + }, + }, + }) +} + +func TestExpectKnownOutputValueAtPath_CheckState_SetNestedBlockPartial(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + // Prior to Terraform v1.3.0 a statened output is marked as fully unknown + // if any attribute is unknown. The id attribute within the test provider + // is unknown. + // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_3_0), + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + set_nested_block { + set_nested_block_attribute = "str" + } + set_nested_block { + set_nested_block_attribute = "rts" + } + } + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("set_nested_block"), + knownvalue.SetValuePartialMatch([]knownvalue.Check{ + knownvalue.MapValueExact(map[string]knownvalue.Check{ + "set_nested_block_attribute": knownvalue.StringValueExact("rts"), + }), + }), + ), + }, + }, + }, + }) +} + +func TestExpectKnownOutputValueAtPath_CheckState_SetNestedBlockElements(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + // Prior to Terraform v1.3.0 a statened output is marked as fully unknown + // if any attribute is unknown. The id attribute within the test provider + // is unknown. + // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_3_0), + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + set_nested_block { + set_nested_block_attribute = "str" + } + set_nested_block { + set_nested_block_attribute = "rts" + } + } + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("set_nested_block"), + knownvalue.SetElementsExact(2), + ), + }, + }, + }, + }) +} + +func TestExpectKnownOutputValueAtPath_CheckState_String(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + // Prior to Terraform v1.3.0 a statened output is marked as fully unknown + // if any attribute is unknown. The id attribute within the test provider + // is unknown. + // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_3_0), + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + string_attribute = "str" + } + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("string_attribute"), + knownvalue.StringValueExact("str")), + }, + }, + }, + }) +} + +func TestExpectKnownOutputValueAtPath_CheckState_String_KnownValueWrongType(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + // Prior to Terraform v1.3.0 a statened output is marked as fully unknown + // if any attribute is unknown. The id attribute within the test provider + // is unknown. + // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_3_0), + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + string_attribute = "str" + } + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("string_attribute"), + knownvalue.BoolValueExact(true)), + }, + ExpectError: regexp.MustCompile("expected bool value for BoolValue check, got: string"), + }, + }, + }) +} + +func TestExpectKnownOutputValueAtPath_CheckState_String_KnownValueWrongValue(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProvider(), nil + }, + }, + // Prior to Terraform v1.3.0 a statened output is marked as fully unknown + // if any attribute is unknown. The id attribute within the test provider + // is unknown. + // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_3_0), + }, + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + string_attribute = "str" + } + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("string_attribute"), + knownvalue.StringValueExact("rts")), + }, + ExpectError: regexp.MustCompile("expected value rts for StringValue check, got: str"), + }, + }, + }) +} + +func TestExpectKnownOutputValueAtPath_CheckState_UnknownAttributeType(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + knownValue knownvalue.Check + req statecheck.CheckStateRequest + expectedErr error + }{ + "unrecognised-type": { + knownValue: knownvalue.Int64ValueExact(123), + req: statecheck.CheckStateRequest{ + State: &tfjson.State{ + Values: &tfjson.StateValues{ + Outputs: map[string]*tfjson.StateOutput{ + "float32_output": { + Value: float32(123), + }, + }, + }, + }, + }, + expectedErr: fmt.Errorf("unrecognised output type: float32, known value type is knownvalue.Int64Value\n\nThis is an error in statecheck.ExpectKnownOutputValueAtPath.\nPlease report this to the maintainers."), + }, + } + + for name, testCase := range testCases { + name, testCase := name, testCase + + t.Run(name, func(t *testing.T) { + t.Parallel() + + e := statecheck.ExpectKnownOutputValueAtPath("float32_output", tfjsonpath.Path{}, testCase.knownValue) + + resp := statecheck.CheckStateResponse{} + + e.CheckState(context.Background(), testCase.req, &resp) + + if diff := cmp.Diff(resp.Error, testCase.expectedErr, equateErrorMessage); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} From 598dac8246003c5c0aef3714f345493cfec3fc25 Mon Sep 17 00:00:00 2001 From: Benjamin Bennett Date: Wed, 10 Jan 2024 10:45:42 +0000 Subject: [PATCH 06/29] Modifying ExpectKnown to allow for checking of null values (#266) --- knownvalue/null.go | 34 +++ knownvalue/null_test.go | 61 ++++ statecheck/expect_known_output_value.go | 24 +- .../expect_known_output_value_at_path.go | 24 +- .../expect_known_output_value_at_path_test.go | 286 +----------------- statecheck/expect_known_output_value_test.go | 6 +- statecheck/expect_known_value.go | 26 +- statecheck/expect_known_value_test.go | 5 +- 8 files changed, 110 insertions(+), 356 deletions(-) create mode 100644 knownvalue/null.go create mode 100644 knownvalue/null_test.go diff --git a/knownvalue/null.go b/knownvalue/null.go new file mode 100644 index 000000000..93e773cb0 --- /dev/null +++ b/knownvalue/null.go @@ -0,0 +1,34 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package knownvalue + +import ( + "fmt" +) + +var _ Check = NullValue{} + +// NullValue is a Check for asserting equality between the value supplied +// to NullValueExact and the value passed to the CheckValue method. +type NullValue struct{} + +// CheckValue determines whether the passed value is of nil. +func (v NullValue) CheckValue(other any) error { + if other != nil { + return fmt.Errorf("expected value nil for NullValue check, got: %T", other) + } + + return nil +} + +// String returns the string representation of nil. +func (v NullValue) String() string { + return "nil" +} + +// NullValueExact returns a Check for asserting equality nil +// and the value passed to the CheckValue method. +func NullValueExact() NullValue { + return NullValue{} +} diff --git a/knownvalue/null_test.go b/knownvalue/null_test.go new file mode 100644 index 000000000..b185ca220 --- /dev/null +++ b/knownvalue/null_test.go @@ -0,0 +1,61 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package knownvalue_test + +import ( + "fmt" + "testing" + + "github.com/google/go-cmp/cmp" + + "github.com/hashicorp/terraform-plugin-testing/knownvalue" +) + +func TestNullValue_CheckValue(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + self knownvalue.NullValue + other any + expectedError error + }{ + "zero-nil": {}, + "zero-other": { + other: nil, // checking against the underlying value field zero-value + }, + "not-nil": { + self: knownvalue.NullValueExact(), + other: false, + expectedError: fmt.Errorf("expected value nil for NullValue check, got: bool"), + }, + "equal": { + self: knownvalue.NullValueExact(), + other: nil, + }, + } + + for name, testCase := range testCases { + name, testCase := name, testCase + + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.self.CheckValue(testCase.other) + + if diff := cmp.Diff(got, testCase.expectedError, equateErrorMessage); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestNullValue_String(t *testing.T) { + t.Parallel() + + got := knownvalue.NullValueExact().String() + + if diff := cmp.Diff(got, "nil"); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } +} diff --git a/statecheck/expect_known_output_value.go b/statecheck/expect_known_output_value.go index 2809dff46..1cf6b69e8 100644 --- a/statecheck/expect_known_output_value.go +++ b/statecheck/expect_known_output_value.go @@ -6,7 +6,6 @@ package statecheck import ( "context" "fmt" - "reflect" tfjson "github.com/hashicorp/terraform-json" @@ -56,27 +55,8 @@ func (e expectKnownOutputValue) CheckState(ctx context.Context, req CheckStateRe return } - if result == nil { - resp.Error = fmt.Errorf("value is null") - - return - } - - switch reflect.TypeOf(result).Kind() { - case reflect.Bool, - reflect.Map, - reflect.Slice, - reflect.String: - if err := e.knownValue.CheckValue(result); err != nil { - resp.Error = err - - return - } - default: - errorStr := fmt.Sprintf("unrecognised output type: %T, known value type is %T", result, e.knownValue) - errorStr += "\n\nThis is an error in statecheck.ExpectKnownOutputValue.\nPlease report this to the maintainers." - - resp.Error = fmt.Errorf(errorStr) + if err := e.knownValue.CheckValue(result); err != nil { + resp.Error = err return } diff --git a/statecheck/expect_known_output_value_at_path.go b/statecheck/expect_known_output_value_at_path.go index 31d4516b1..7ff704b06 100644 --- a/statecheck/expect_known_output_value_at_path.go +++ b/statecheck/expect_known_output_value_at_path.go @@ -6,7 +6,6 @@ package statecheck import ( "context" "fmt" - "reflect" tfjson "github.com/hashicorp/terraform-json" @@ -57,27 +56,8 @@ func (e expectKnownOutputValueAtPath) CheckState(ctx context.Context, req CheckS return } - if result == nil { - resp.Error = fmt.Errorf("value is null") - - return - } - - switch reflect.TypeOf(result).Kind() { - case reflect.Bool, - reflect.Map, - reflect.Slice, - reflect.String: - if err := e.knownValue.CheckValue(result); err != nil { - resp.Error = err - - return - } - default: - errorStr := fmt.Sprintf("unrecognised output type: %T, known value type is %T", result, e.knownValue) - errorStr += "\n\nThis is an error in statecheck.ExpectKnownOutputValueAtPath.\nPlease report this to the maintainers." - - resp.Error = fmt.Errorf(errorStr) + if err := e.knownValue.CheckValue(result); err != nil { + resp.Error = err return } diff --git a/statecheck/expect_known_output_value_at_path_test.go b/statecheck/expect_known_output_value_at_path_test.go index 6b9795f90..371847b69 100644 --- a/statecheck/expect_known_output_value_at_path_test.go +++ b/statecheck/expect_known_output_value_at_path_test.go @@ -18,7 +18,6 @@ import ( "github.com/hashicorp/terraform-plugin-testing/knownvalue" "github.com/hashicorp/terraform-plugin-testing/statecheck" "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" - "github.com/hashicorp/terraform-plugin-testing/tfversion" ) func TestExpectKnownOutputValueAtPath_CheckState_ResourceNotFound(t *testing.T) { @@ -30,13 +29,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_ResourceNotFound(t *testing.T) return testProvider(), nil }, }, - // Prior to Terraform v1.3.0 a statened output is marked as fully unknown - // if any attribute is unknown. The id attribute within the test provider - // is unknown. - // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 - TerraformVersionChecks: []tfversion.TerraformVersionCheck{ - tfversion.SkipBelow(tfversion.Version1_3_0), - }, Steps: []r.TestStep{ { Config: `resource "test_resource" "one" { @@ -69,13 +61,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_AttributeValueNull(t *testing.T return testProvider(), nil }, }, - // Prior to Terraform v1.3.0 a statened output is marked as fully unknown - // if any attribute is unknown. The id attribute within the test provider - // is unknown. - // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 - TerraformVersionChecks: []tfversion.TerraformVersionCheck{ - tfversion.SkipBelow(tfversion.Version1_3_0), - }, Steps: []r.TestStep{ { Config: `resource "test_resource" "one" {} @@ -88,10 +73,9 @@ func TestExpectKnownOutputValueAtPath_CheckState_AttributeValueNull(t *testing.T statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("bool_attribute"), - knownvalue.BoolValueExact(true), + knownvalue.NullValueExact(), ), }, - ExpectError: regexp.MustCompile("value is null"), }, }, }) @@ -106,13 +90,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_Bool(t *testing.T) { return testProvider(), nil }, }, - // Prior to Terraform v1.3.0 a statened output is marked as fully unknown - // if any attribute is unknown. The id attribute within the test provider - // is unknown. - // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 - TerraformVersionChecks: []tfversion.TerraformVersionCheck{ - tfversion.SkipBelow(tfversion.Version1_3_0), - }, Steps: []r.TestStep{ { Config: `resource "test_resource" "one" { @@ -144,13 +121,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_Bool_KnownValueWrongType(t *tes return testProvider(), nil }, }, - // Prior to Terraform v1.3.0 a statened output is marked as fully unknown - // if any attribute is unknown. The id attribute within the test provider - // is unknown. - // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 - TerraformVersionChecks: []tfversion.TerraformVersionCheck{ - tfversion.SkipBelow(tfversion.Version1_3_0), - }, Steps: []r.TestStep{ { Config: `resource "test_resource" "one" { @@ -183,13 +153,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_Bool_KnownValueWrongValue(t *te return testProvider(), nil }, }, - // Prior to Terraform v1.3.0 a statened output is marked as fully unknown - // if any attribute is unknown. The id attribute within the test provider - // is unknown. - // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 - TerraformVersionChecks: []tfversion.TerraformVersionCheck{ - tfversion.SkipBelow(tfversion.Version1_3_0), - }, Steps: []r.TestStep{ { Config: `resource "test_resource" "one" { @@ -222,13 +185,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_Float64(t *testing.T) { return testProvider(), nil }, }, - // Prior to Terraform v1.3.0 a statened output is marked as fully unknown - // if any attribute is unknown. The id attribute within the test provider - // is unknown. - // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 - TerraformVersionChecks: []tfversion.TerraformVersionCheck{ - tfversion.SkipBelow(tfversion.Version1_3_0), - }, Steps: []r.TestStep{ { Config: `resource "test_resource" "one" { @@ -261,13 +217,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_Float64_KnownValueWrongType(t * return testProvider(), nil }, }, - // Prior to Terraform v1.3.0 a statened output is marked as fully unknown - // if any attribute is unknown. The id attribute within the test provider - // is unknown. - // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 - TerraformVersionChecks: []tfversion.TerraformVersionCheck{ - tfversion.SkipBelow(tfversion.Version1_3_0), - }, Steps: []r.TestStep{ { Config: `resource "test_resource" "one" { @@ -300,13 +249,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_Float64_KnownValueWrongValue(t return testProvider(), nil }, }, - // Prior to Terraform v1.3.0 a statened output is marked as fully unknown - // if any attribute is unknown. The id attribute within the test provider - // is unknown. - // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 - TerraformVersionChecks: []tfversion.TerraformVersionCheck{ - tfversion.SkipBelow(tfversion.Version1_3_0), - }, Steps: []r.TestStep{ { Config: `resource "test_resource" "one" { @@ -339,13 +281,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_Int64(t *testing.T) { return testProvider(), nil }, }, - // Prior to Terraform v1.3.0 a statened output is marked as fully unknown - // if any attribute is unknown. The id attribute within the test provider - // is unknown. - // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 - TerraformVersionChecks: []tfversion.TerraformVersionCheck{ - tfversion.SkipBelow(tfversion.Version1_3_0), - }, Steps: []r.TestStep{ { Config: `resource "test_resource" "one" { @@ -377,13 +312,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_Int64_KnownValueWrongValue(t *t return testProvider(), nil }, }, - // Prior to Terraform v1.3.0 a statened output is marked as fully unknown - // if any attribute is unknown. The id attribute within the test provider - // is unknown. - // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 - TerraformVersionChecks: []tfversion.TerraformVersionCheck{ - tfversion.SkipBelow(tfversion.Version1_3_0), - }, Steps: []r.TestStep{ { Config: `resource "test_resource" "one" { @@ -416,13 +344,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_List(t *testing.T) { return testProvider(), nil }, }, - // Prior to Terraform v1.3.0 a statened output is marked as fully unknown - // if any attribute is unknown. The id attribute within the test provider - // is unknown. - // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 - TerraformVersionChecks: []tfversion.TerraformVersionCheck{ - tfversion.SkipBelow(tfversion.Version1_3_0), - }, Steps: []r.TestStep{ { Config: `resource "test_resource" "one" { @@ -460,13 +381,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_List_KnownValueWrongType(t *tes return testProvider(), nil }, }, - // Prior to Terraform v1.3.0 a statened output is marked as fully unknown - // if any attribute is unknown. The id attribute within the test provider - // is unknown. - // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 - TerraformVersionChecks: []tfversion.TerraformVersionCheck{ - tfversion.SkipBelow(tfversion.Version1_3_0), - }, Steps: []r.TestStep{ { Config: `resource "test_resource" "one" { @@ -502,13 +416,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_List_KnownValueWrongValue(t *te return testProvider(), nil }, }, - // Prior to Terraform v1.3.0 a statened output is marked as fully unknown - // if any attribute is unknown. The id attribute within the test provider - // is unknown. - // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 - TerraformVersionChecks: []tfversion.TerraformVersionCheck{ - tfversion.SkipBelow(tfversion.Version1_3_0), - }, Steps: []r.TestStep{ { Config: `resource "test_resource" "one" { @@ -547,13 +454,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_ListPartial(t *testing.T) { return testProvider(), nil }, }, - // Prior to Terraform v1.3.0 a statened output is marked as fully unknown - // if any attribute is unknown. The id attribute within the test provider - // is unknown. - // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 - TerraformVersionChecks: []tfversion.TerraformVersionCheck{ - tfversion.SkipBelow(tfversion.Version1_3_0), - }, Steps: []r.TestStep{ { Config: `resource "test_resource" "one" { @@ -592,13 +492,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_ListPartial_KnownValueWrongValu return testProvider(), nil }, }, - // Prior to Terraform v1.3.0 a statened output is marked as fully unknown - // if any attribute is unknown. The id attribute within the test provider - // is unknown. - // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 - TerraformVersionChecks: []tfversion.TerraformVersionCheck{ - tfversion.SkipBelow(tfversion.Version1_3_0), - }, Steps: []r.TestStep{ { Config: `resource "test_resource" "one" { @@ -636,13 +529,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_ListElements(t *testing.T) { return testProvider(), nil }, }, - // Prior to Terraform v1.3.0 a statened output is marked as fully unknown - // if any attribute is unknown. The id attribute within the test provider - // is unknown. - // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 - TerraformVersionChecks: []tfversion.TerraformVersionCheck{ - tfversion.SkipBelow(tfversion.Version1_3_0), - }, Steps: []r.TestStep{ { Config: `resource "test_resource" "one" { @@ -677,13 +563,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_ListElements_WrongNum(t *testin return testProvider(), nil }, }, - // Prior to Terraform v1.3.0 a statened output is marked as fully unknown - // if any attribute is unknown. The id attribute within the test provider - // is unknown. - // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 - TerraformVersionChecks: []tfversion.TerraformVersionCheck{ - tfversion.SkipBelow(tfversion.Version1_3_0), - }, Steps: []r.TestStep{ { Config: `resource "test_resource" "one" { @@ -719,13 +598,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_ListNestedBlock(t *testing.T) { return testProvider(), nil }, }, - // Prior to Terraform v1.3.0 a statened output is marked as fully unknown - // if any attribute is unknown. The id attribute within the test provider - // is unknown. - // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 - TerraformVersionChecks: []tfversion.TerraformVersionCheck{ - tfversion.SkipBelow(tfversion.Version1_3_0), - }, Steps: []r.TestStep{ { Config: `resource "test_resource" "one" { @@ -769,13 +641,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_ListNestedBlockPartial(t *testi return testProvider(), nil }, }, - // Prior to Terraform v1.3.0 a statened output is marked as fully unknown - // if any attribute is unknown. The id attribute within the test provider - // is unknown. - // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 - TerraformVersionChecks: []tfversion.TerraformVersionCheck{ - tfversion.SkipBelow(tfversion.Version1_3_0), - }, Steps: []r.TestStep{ { Config: `resource "test_resource" "one" { @@ -816,13 +681,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_ListNestedBlockElements(t *test return testProvider(), nil }, }, - // Prior to Terraform v1.3.0 a statened output is marked as fully unknown - // if any attribute is unknown. The id attribute within the test provider - // is unknown. - // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 - TerraformVersionChecks: []tfversion.TerraformVersionCheck{ - tfversion.SkipBelow(tfversion.Version1_3_0), - }, Steps: []r.TestStep{ { Config: `resource "test_resource" "one" { @@ -859,13 +717,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_Map(t *testing.T) { return testProvider(), nil }, }, - // Prior to Terraform v1.3.0 a statened output is marked as fully unknown - // if any attribute is unknown. The id attribute within the test provider - // is unknown. - // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 - TerraformVersionChecks: []tfversion.TerraformVersionCheck{ - tfversion.SkipBelow(tfversion.Version1_3_0), - }, Steps: []r.TestStep{ { Config: `resource "test_resource" "one" { @@ -903,13 +754,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_Map_KnownValueWrongType(t *test return testProvider(), nil }, }, - // Prior to Terraform v1.3.0 a statened output is marked as fully unknown - // if any attribute is unknown. The id attribute within the test provider - // is unknown. - // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 - TerraformVersionChecks: []tfversion.TerraformVersionCheck{ - tfversion.SkipBelow(tfversion.Version1_3_0), - }, Steps: []r.TestStep{ { Config: `resource "test_resource" "one" { @@ -945,13 +789,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_Map_KnownValueWrongValue(t *tes return testProvider(), nil }, }, - // Prior to Terraform v1.3.0 a statened output is marked as fully unknown - // if any attribute is unknown. The id attribute within the test provider - // is unknown. - // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 - TerraformVersionChecks: []tfversion.TerraformVersionCheck{ - tfversion.SkipBelow(tfversion.Version1_3_0), - }, Steps: []r.TestStep{ { Config: `resource "test_resource" "one" { @@ -990,13 +827,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_MapPartial(t *testing.T) { return testProvider(), nil }, }, - // Prior to Terraform v1.3.0 a statened output is marked as fully unknown - // if any attribute is unknown. The id attribute within the test provider - // is unknown. - // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 - TerraformVersionChecks: []tfversion.TerraformVersionCheck{ - tfversion.SkipBelow(tfversion.Version1_3_0), - }, Steps: []r.TestStep{ { Config: `resource "test_resource" "one" { @@ -1033,13 +863,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_MapPartial_KnownValueWrongValue return testProvider(), nil }, }, - // Prior to Terraform v1.3.0 a statened output is marked as fully unknown - // if any attribute is unknown. The id attribute within the test provider - // is unknown. - // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 - TerraformVersionChecks: []tfversion.TerraformVersionCheck{ - tfversion.SkipBelow(tfversion.Version1_3_0), - }, Steps: []r.TestStep{ { Config: `resource "test_resource" "one" { @@ -1077,13 +900,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_MapElements(t *testing.T) { return testProvider(), nil }, }, - // Prior to Terraform v1.3.0 a statened output is marked as fully unknown - // if any attribute is unknown. The id attribute within the test provider - // is unknown. - // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 - TerraformVersionChecks: []tfversion.TerraformVersionCheck{ - tfversion.SkipBelow(tfversion.Version1_3_0), - }, Steps: []r.TestStep{ { Config: `resource "test_resource" "one" { @@ -1118,13 +934,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_MapElements_WrongNum(t *testing return testProvider(), nil }, }, - // Prior to Terraform v1.3.0 a statened output is marked as fully unknown - // if any attribute is unknown. The id attribute within the test provider - // is unknown. - // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 - TerraformVersionChecks: []tfversion.TerraformVersionCheck{ - tfversion.SkipBelow(tfversion.Version1_3_0), - }, Steps: []r.TestStep{ { Config: `resource "test_resource" "one" { @@ -1166,13 +975,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_Number(t *testing.T) { return testProvider(), nil }, }, - // Prior to Terraform v1.3.0 a statened output is marked as fully unknown - // if any attribute is unknown. The id attribute within the test provider - // is unknown. - // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 - TerraformVersionChecks: []tfversion.TerraformVersionCheck{ - tfversion.SkipBelow(tfversion.Version1_3_0), - }, Steps: []r.TestStep{ { Config: `resource "test_resource" "one" { @@ -1210,13 +1012,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_Number_KnownValueWrongValue(t * return testProvider(), nil }, }, - // Prior to Terraform v1.3.0 a statened output is marked as fully unknown - // if any attribute is unknown. The id attribute within the test provider - // is unknown. - // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 - TerraformVersionChecks: []tfversion.TerraformVersionCheck{ - tfversion.SkipBelow(tfversion.Version1_3_0), - }, Steps: []r.TestStep{ { Config: `resource "test_resource" "one" { @@ -1249,13 +1044,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_Set(t *testing.T) { return testProvider(), nil }, }, - // Prior to Terraform v1.3.0 a statened output is marked as fully unknown - // if any attribute is unknown. The id attribute within the test provider - // is unknown. - // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 - TerraformVersionChecks: []tfversion.TerraformVersionCheck{ - tfversion.SkipBelow(tfversion.Version1_3_0), - }, Steps: []r.TestStep{ { Config: `resource "test_resource" "one" { @@ -1293,13 +1081,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_Set_KnownValueWrongValue(t *tes return testProvider(), nil }, }, - // Prior to Terraform v1.3.0 a statened output is marked as fully unknown - // if any attribute is unknown. The id attribute within the test provider - // is unknown. - // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 - TerraformVersionChecks: []tfversion.TerraformVersionCheck{ - tfversion.SkipBelow(tfversion.Version1_3_0), - }, Steps: []r.TestStep{ { Config: `resource "test_resource" "one" { @@ -1338,13 +1119,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_SetPartial(t *testing.T) { return testProvider(), nil }, }, - // Prior to Terraform v1.3.0 a statened output is marked as fully unknown - // if any attribute is unknown. The id attribute within the test provider - // is unknown. - // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 - TerraformVersionChecks: []tfversion.TerraformVersionCheck{ - tfversion.SkipBelow(tfversion.Version1_3_0), - }, Steps: []r.TestStep{ { Config: `resource "test_resource" "one" { @@ -1381,13 +1155,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_SetPartial_KnownValueWrongValue return testProvider(), nil }, }, - // Prior to Terraform v1.3.0 a statened output is marked as fully unknown - // if any attribute is unknown. The id attribute within the test provider - // is unknown. - // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 - TerraformVersionChecks: []tfversion.TerraformVersionCheck{ - tfversion.SkipBelow(tfversion.Version1_3_0), - }, Steps: []r.TestStep{ { Config: `resource "test_resource" "one" { @@ -1425,13 +1192,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_SetElements(t *testing.T) { return testProvider(), nil }, }, - // Prior to Terraform v1.3.0 a statened output is marked as fully unknown - // if any attribute is unknown. The id attribute within the test provider - // is unknown. - // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 - TerraformVersionChecks: []tfversion.TerraformVersionCheck{ - tfversion.SkipBelow(tfversion.Version1_3_0), - }, Steps: []r.TestStep{ { Config: `resource "test_resource" "one" { @@ -1466,13 +1226,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_SetNestedBlock(t *testing.T) { return testProvider(), nil }, }, - // Prior to Terraform v1.3.0 a statened output is marked as fully unknown - // if any attribute is unknown. The id attribute within the test provider - // is unknown. - // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 - TerraformVersionChecks: []tfversion.TerraformVersionCheck{ - tfversion.SkipBelow(tfversion.Version1_3_0), - }, Steps: []r.TestStep{ { Config: `resource "test_resource" "one" { @@ -1516,13 +1269,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_SetNestedBlockPartial(t *testin return testProvider(), nil }, }, - // Prior to Terraform v1.3.0 a statened output is marked as fully unknown - // if any attribute is unknown. The id attribute within the test provider - // is unknown. - // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 - TerraformVersionChecks: []tfversion.TerraformVersionCheck{ - tfversion.SkipBelow(tfversion.Version1_3_0), - }, Steps: []r.TestStep{ { Config: `resource "test_resource" "one" { @@ -1563,13 +1309,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_SetNestedBlockElements(t *testi return testProvider(), nil }, }, - // Prior to Terraform v1.3.0 a statened output is marked as fully unknown - // if any attribute is unknown. The id attribute within the test provider - // is unknown. - // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 - TerraformVersionChecks: []tfversion.TerraformVersionCheck{ - tfversion.SkipBelow(tfversion.Version1_3_0), - }, Steps: []r.TestStep{ { Config: `resource "test_resource" "one" { @@ -1606,13 +1345,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_String(t *testing.T) { return testProvider(), nil }, }, - // Prior to Terraform v1.3.0 a statened output is marked as fully unknown - // if any attribute is unknown. The id attribute within the test provider - // is unknown. - // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 - TerraformVersionChecks: []tfversion.TerraformVersionCheck{ - tfversion.SkipBelow(tfversion.Version1_3_0), - }, Steps: []r.TestStep{ { Config: `resource "test_resource" "one" { @@ -1643,13 +1375,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_String_KnownValueWrongType(t *t return testProvider(), nil }, }, - // Prior to Terraform v1.3.0 a statened output is marked as fully unknown - // if any attribute is unknown. The id attribute within the test provider - // is unknown. - // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 - TerraformVersionChecks: []tfversion.TerraformVersionCheck{ - tfversion.SkipBelow(tfversion.Version1_3_0), - }, Steps: []r.TestStep{ { Config: `resource "test_resource" "one" { @@ -1681,13 +1406,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_String_KnownValueWrongValue(t * return testProvider(), nil }, }, - // Prior to Terraform v1.3.0 a statened output is marked as fully unknown - // if any attribute is unknown. The id attribute within the test provider - // is unknown. - // Reference: https://github.com/hashicorp/terraform/blob/v1.3/CHANGELOG.md#130-september-21-2022 - TerraformVersionChecks: []tfversion.TerraformVersionCheck{ - tfversion.SkipBelow(tfversion.Version1_3_0), - }, Steps: []r.TestStep{ { Config: `resource "test_resource" "one" { @@ -1731,7 +1449,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_UnknownAttributeType(t *testing }, }, }, - expectedErr: fmt.Errorf("unrecognised output type: float32, known value type is knownvalue.Int64Value\n\nThis is an error in statecheck.ExpectKnownOutputValueAtPath.\nPlease report this to the maintainers."), + expectedErr: fmt.Errorf("expected json.Number value for Int64Value check, got: float32"), }, } diff --git a/statecheck/expect_known_output_value_test.go b/statecheck/expect_known_output_value_test.go index 1c1cfcaa7..e081b0716 100644 --- a/statecheck/expect_known_output_value_test.go +++ b/statecheck/expect_known_output_value_test.go @@ -50,6 +50,10 @@ func TestExpectKnownOutputValue_CheckState_OutputNotFound(t *testing.T) { }) } +// TestExpectKnownOutputValue_CheckState_AttributeValueNull shows that outputs that reference +// null values do not appear in state. Indicating that there is no way to discriminate +// between null outputs and non-existent outputs. +// Reference: https://github.com/hashicorp/terraform/issues/34080 func TestExpectKnownOutputValue_CheckState_AttributeValueNull(t *testing.T) { t.Parallel() @@ -1408,7 +1412,7 @@ func TestExpectKnownOutputValue_CheckState_UnknownAttributeType(t *testing.T) { }, }, }, - expectedErr: fmt.Errorf("unrecognised output type: float32, known value type is knownvalue.Int64Value\n\nThis is an error in statecheck.ExpectKnownOutputValue.\nPlease report this to the maintainers."), + expectedErr: fmt.Errorf("expected json.Number value for Int64Value check, got: float32"), }, } diff --git a/statecheck/expect_known_value.go b/statecheck/expect_known_value.go index b8d5a6157..096699cba 100644 --- a/statecheck/expect_known_value.go +++ b/statecheck/expect_known_value.go @@ -6,7 +6,6 @@ package statecheck import ( "context" "fmt" - "reflect" tfjson "github.com/hashicorp/terraform-json" @@ -61,29 +60,8 @@ func (e expectKnownValue) CheckState(ctx context.Context, req CheckStateRequest, return } - if result == nil { - resp.Error = fmt.Errorf("value is null") - - return - } - - switch reflect.TypeOf(result).Kind() { - case reflect.Bool, - reflect.Map, - reflect.Slice, - reflect.String: - if err := e.knownValue.CheckValue(result); err != nil { - resp.Error = err - - return - } - default: - errorStr := fmt.Sprintf("unrecognised attribute type: %T, known value type is %T", result, e.knownValue) - errorStr += "\n\nThis is an error in statecheck.ExpectKnownValue.\nPlease report this to the maintainers." - - resp.Error = fmt.Errorf(errorStr) - - return + if err := e.knownValue.CheckValue(result); err != nil { + resp.Error = err } } diff --git a/statecheck/expect_known_value_test.go b/statecheck/expect_known_value_test.go index bd1024891..ce2d0a5c9 100644 --- a/statecheck/expect_known_value_test.go +++ b/statecheck/expect_known_value_test.go @@ -65,10 +65,9 @@ func TestExpectKnownValue_CheckState_AttributeValueNull(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("bool_attribute"), - knownvalue.BoolValueExact(true), + knownvalue.NullValueExact(), ), }, - ExpectError: regexp.MustCompile("value is null"), }, }, }) @@ -1295,7 +1294,7 @@ func TestExpectKnownValue_CheckState_UnknownAttributeType(t *testing.T) { }, }, }, - expectedErr: fmt.Errorf("unrecognised attribute type: float32, known value type is knownvalue.Int64Value\n\nThis is an error in statecheck.ExpectKnownValue.\nPlease report this to the maintainers."), + expectedErr: fmt.Errorf("expected json.Number value for Int64Value check, got: float32"), }, } From c78e3e8743c621bb8155edcacbc98989b4b0f828 Mon Sep 17 00:00:00 2001 From: Benjamin Bennett Date: Wed, 10 Jan 2024 12:07:10 +0000 Subject: [PATCH 07/29] Adding ExpectSensitiveValue state check (#266) --- statecheck/expect_sensitive_value.go | 95 +++++++ statecheck/expect_sensitive_value_test.go | 308 ++++++++++++++++++++++ tfversion/versions.go | 1 + 3 files changed, 404 insertions(+) create mode 100644 statecheck/expect_sensitive_value.go create mode 100644 statecheck/expect_sensitive_value_test.go diff --git a/statecheck/expect_sensitive_value.go b/statecheck/expect_sensitive_value.go new file mode 100644 index 000000000..7e8ec7325 --- /dev/null +++ b/statecheck/expect_sensitive_value.go @@ -0,0 +1,95 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package statecheck + +import ( + "context" + "encoding/json" + "fmt" + + tfjson "github.com/hashicorp/terraform-json" + + "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" +) + +var _ StateCheck = expectSensitiveValue{} + +type expectSensitiveValue struct { + resourceAddress string + attributePath tfjsonpath.Path +} + +// CheckState implements the state check logic. +func (e expectSensitiveValue) CheckState(ctx context.Context, req CheckStateRequest, resp *CheckStateResponse) { + var rc *tfjson.StateResource + + if req.State == nil { + resp.Error = fmt.Errorf("state is nil") + } + + if req.State.Values == nil { + resp.Error = fmt.Errorf("state does not contain any state values") + } + + if req.State.Values.RootModule == nil { + resp.Error = fmt.Errorf("state does not contain a root module") + } + + for _, resourceChange := range req.State.Values.RootModule.Resources { + if e.resourceAddress == resourceChange.Address { + rc = resourceChange + + break + } + } + + if rc == nil { + resp.Error = fmt.Errorf("%s - Resource not found in state", e.resourceAddress) + + return + } + + var data map[string]any + + err := json.Unmarshal(rc.SensitiveValues, &data) + + if err != nil { + resp.Error = fmt.Errorf("could not unmarshal SensitiveValues: %s", err) + + return + } + + result, err := tfjsonpath.Traverse(data, e.attributePath) + + if err != nil { + resp.Error = err + + return + } + + isSensitive, ok := result.(bool) + if !ok { + resp.Error = fmt.Errorf("invalid path: the path value cannot be asserted as bool") + return + } + + if !isSensitive { + resp.Error = fmt.Errorf("attribute at path is not sensitive") + return + } + + return +} + +// ExpectSensitiveValue returns a state check that asserts that the specified attribute at the given resource has a sensitive value. +// +// Due to implementation differences between the terraform-plugin-sdk and the terraform-plugin-framework, representation of sensitive +// values may differ. For example, terraform-plugin-sdk based providers may have less precise representations of sensitive values, such +// as marking whole maps as sensitive rather than individual element values. +func ExpectSensitiveValue(resourceAddress string, attributePath tfjsonpath.Path) StateCheck { + return expectSensitiveValue{ + resourceAddress: resourceAddress, + attributePath: attributePath, + } +} diff --git a/statecheck/expect_sensitive_value_test.go b/statecheck/expect_sensitive_value_test.go new file mode 100644 index 000000000..5723d73b4 --- /dev/null +++ b/statecheck/expect_sensitive_value_test.go @@ -0,0 +1,308 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package statecheck_test + +import ( + "context" + "regexp" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + r "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/statecheck" + "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" + "github.com/hashicorp/terraform-plugin-testing/tfversion" +) + +func Test_ExpectSensitiveValue_SensitiveStringAttribute(t *testing.T) { + t.Parallel() + + r.UnitTest(t, r.TestCase{ + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_4_6), // StateResource.SensitiveValues + }, + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProviderSensitive(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: ` + resource "test_resource" "one" { + sensitive_string_attribute = "test" + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectSensitiveValue("test_resource.one", + tfjsonpath.New("sensitive_string_attribute")), + }, + }, + }, + }) +} + +func Test_ExpectSensitiveValue_SensitiveListAttribute(t *testing.T) { + t.Parallel() + + r.UnitTest(t, r.TestCase{ + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_4_6), // StateResource.SensitiveValues + }, + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProviderSensitive(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: ` + resource "test_resource" "one" { + sensitive_list_attribute = ["value1"] + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectSensitiveValue("test_resource.one", + tfjsonpath.New("sensitive_list_attribute")), + }, + }, + }, + }) +} + +func Test_ExpectSensitiveValue_SensitiveSetAttribute(t *testing.T) { + t.Parallel() + + r.UnitTest(t, r.TestCase{ + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_4_6), // StateResource.SensitiveValues + }, + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProviderSensitive(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: ` + resource "test_resource" "one" { + sensitive_set_attribute = ["value1"] + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectSensitiveValue("test_resource.one", + tfjsonpath.New("sensitive_set_attribute")), + }, + }, + }, + }) +} + +func Test_ExpectSensitiveValue_SensitiveMapAttribute(t *testing.T) { + t.Parallel() + + r.UnitTest(t, r.TestCase{ + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_4_6), // StateResource.SensitiveValues + }, + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProviderSensitive(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: ` + resource "test_resource" "one" { + sensitive_map_attribute = { + key1 = "value1", + } + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectSensitiveValue("test_resource.one", + tfjsonpath.New("sensitive_map_attribute")), + }, + }, + }, + }) +} + +func Test_ExpectSensitiveValue_ListNestedBlock_SensitiveAttribute(t *testing.T) { + t.Parallel() + + r.UnitTest(t, r.TestCase{ + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_4_6), // StateResource.SensitiveValues + }, + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProviderSensitive(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: ` + resource "test_resource" "one" { + list_nested_block_sensitive_attribute { + sensitive_list_nested_block_attribute = "sensitive-test" + list_nested_block_attribute = "test" + } + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectSensitiveValue("test_resource.one", + tfjsonpath.New("list_nested_block_sensitive_attribute").AtSliceIndex(0). + AtMapKey("sensitive_list_nested_block_attribute")), + }, + }, + }, + }) +} + +func Test_ExpectSensitiveValue_SetNestedBlock_SensitiveAttribute(t *testing.T) { + t.Parallel() + + r.UnitTest(t, r.TestCase{ + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_4_6), // StateResource.SensitiveValues + }, + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProviderSensitive(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: ` + resource "test_resource" "one" { + set_nested_block_sensitive_attribute { + sensitive_set_nested_block_attribute = "sensitive-test" + set_nested_block_attribute = "test" + } + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectSensitiveValue("test_resource.one", + tfjsonpath.New("set_nested_block_sensitive_attribute")), + }, + }, + }, + }) +} + +func Test_ExpectSensitiveValue_ExpectError_ResourceNotFound(t *testing.T) { + t.Parallel() + + r.UnitTest(t, r.TestCase{ + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_4_6), // StateResource.SensitiveValues + }, + ProviderFactories: map[string]func() (*schema.Provider, error){ + "test": func() (*schema.Provider, error) { //nolint:unparam // required signature + return testProviderSensitive(), nil + }, + }, + Steps: []r.TestStep{ + { + Config: ` + resource "test_resource" "one" {} + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectSensitiveValue("test_resource.two", tfjsonpath.New("set_attribute")), + }, + ExpectError: regexp.MustCompile(`test_resource.two - Resource not found in state`), + }, + }, + }) +} + +func testProviderSensitive() *schema.Provider { + return &schema.Provider{ + ResourcesMap: map[string]*schema.Resource{ + "test_resource": { + CreateContext: func(_ context.Context, d *schema.ResourceData, _ interface{}) diag.Diagnostics { + d.SetId("test") + return nil + }, + UpdateContext: func(_ context.Context, _ *schema.ResourceData, _ interface{}) diag.Diagnostics { + 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{ + "sensitive_string_attribute": { + Sensitive: true, + Optional: true, + Type: schema.TypeString, + }, + "sensitive_list_attribute": { + Sensitive: true, + Type: schema.TypeList, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Optional: true, + }, + "sensitive_set_attribute": { + Sensitive: true, + Type: schema.TypeSet, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Optional: true, + }, + "sensitive_map_attribute": { + Sensitive: true, + Type: schema.TypeMap, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Optional: true, + }, + "list_nested_block_sensitive_attribute": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "list_nested_block_attribute": { + Type: schema.TypeString, + Optional: true, + }, + "sensitive_list_nested_block_attribute": { + Sensitive: true, + Type: schema.TypeString, + Optional: true, + }, + }, + }, + }, + "set_nested_block_sensitive_attribute": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "set_nested_block_attribute": { + Type: schema.TypeString, + Optional: true, + }, + "sensitive_set_nested_block_attribute": { + Sensitive: true, + Type: schema.TypeString, + Optional: true, + }, + }, + }, + }, + }, + }, + }, + } +} diff --git a/tfversion/versions.go b/tfversion/versions.go index 77f384b5e..f405bd766 100644 --- a/tfversion/versions.go +++ b/tfversion/versions.go @@ -28,6 +28,7 @@ var ( Version1_2_0 *version.Version = version.Must(version.NewVersion("1.2.0")) Version1_3_0 *version.Version = version.Must(version.NewVersion("1.3.0")) Version1_4_0 *version.Version = version.Must(version.NewVersion("1.4.0")) + Version1_4_6 *version.Version = version.Must(version.NewVersion("1.4.6")) Version1_5_0 *version.Version = version.Must(version.NewVersion("1.5.0")) Version1_6_0 *version.Version = version.Must(version.NewVersion("1.6.0")) Version1_7_0 *version.Version = version.Must(version.NewVersion("1.7.0")) From 1e516931f719d54ab6a84fc7f42c019b8a86b2aa Mon Sep 17 00:00:00 2001 From: Benjamin Bennett Date: Wed, 10 Jan 2024 17:03:54 +0000 Subject: [PATCH 08/29] Adding documentation for state checks and null known value check type (#266) --- website/data/plugin-testing-nav-data.json | 25 ++++ .../known-value-checks/null.mdx | 39 ++++++ .../acceptance-tests/state-checks/custom.mdx | 119 ++++++++++++++++++ .../acceptance-tests/state-checks/index.mdx | 20 +++ .../acceptance-tests/state-checks/output.mdx | 84 +++++++++++++ .../state-checks/resource.mdx | 78 ++++++++++++ 6 files changed, 365 insertions(+) create mode 100644 website/docs/plugin/testing/acceptance-tests/known-value-checks/null.mdx create mode 100644 website/docs/plugin/testing/acceptance-tests/state-checks/custom.mdx create mode 100644 website/docs/plugin/testing/acceptance-tests/state-checks/index.mdx create mode 100644 website/docs/plugin/testing/acceptance-tests/state-checks/output.mdx create mode 100644 website/docs/plugin/testing/acceptance-tests/state-checks/resource.mdx diff --git a/website/data/plugin-testing-nav-data.json b/website/data/plugin-testing-nav-data.json index 7e581b6c3..40fc85629 100644 --- a/website/data/plugin-testing-nav-data.json +++ b/website/data/plugin-testing-nav-data.json @@ -50,6 +50,27 @@ } ] }, + { + "title": "State Checks", + "routes": [ + { + "title": "Overview", + "path": "acceptance-tests/state-checks" + }, + { + "title": "Resource State Checks", + "path": "acceptance-tests/state-checks/resource" + }, + { + "title": "Output State Checks", + "path": "acceptance-tests/state-checks/output" + }, + { + "title": "Custom State Checks", + "path": "acceptance-tests/state-checks/custom" + } + ] + }, { "title": "Known Value Checks", "routes": [ @@ -85,6 +106,10 @@ "title": "Number", "path": "acceptance-tests/known-value-checks/number" }, + { + "title": "Null ", + "path": "acceptance-tests/known-value-checks/null" + }, { "title": "Object", "path": "acceptance-tests/known-value-checks/object" diff --git a/website/docs/plugin/testing/acceptance-tests/known-value-checks/null.mdx b/website/docs/plugin/testing/acceptance-tests/known-value-checks/null.mdx new file mode 100644 index 000000000..9d50ee65e --- /dev/null +++ b/website/docs/plugin/testing/acceptance-tests/known-value-checks/null.mdx @@ -0,0 +1,39 @@ +--- +page_title: 'Plugin Development - Acceptance Testing: Known Values' +description: >- + Null Value Checks for use with Plan Checks or State Checks. +--- + +# Null Known Value Checks + +The known value checks that are available for null values are: + +* [NullValueExact](/terraform/plugin/testing/acceptance-tests/known-value-checks/null#nullvalueexact-check) + +## `NullValueExact` Check + +The [NullValueExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#NullValueExact) check tests that a resource attribute, or output value has an exactly matching null value. + +Example usage of [NullValueExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#NullValueExact) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/state-checks/resource) state check. + +```go +func TestExpectKnownValue_CheckState_AttributeValueNull(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + // Provider definition omitted. + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" {}`, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("bool_attribute"), + knownvalue.NullValueExact(), + ), + }, + }, + }, + }) +} +``` diff --git a/website/docs/plugin/testing/acceptance-tests/state-checks/custom.mdx b/website/docs/plugin/testing/acceptance-tests/state-checks/custom.mdx new file mode 100644 index 000000000..f3b3461b0 --- /dev/null +++ b/website/docs/plugin/testing/acceptance-tests/state-checks/custom.mdx @@ -0,0 +1,119 @@ +--- +page_title: 'Plugin Development - Acceptance Testing: State Checks' +description: >- + State Checks are test assertions that can inspect state during a TestStep. Custom State Checks can be implemented. +--- + +# Custom State Checks + +The package [`statecheck`](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/statecheck) also provides the [`StateCheck`](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/statecheck#StateCheck) interface, which can be implemented for a custom state check. + +The [`statecheck.CheckStateRequest`](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/statecheck#CheckStateRequest) contains the current state file, parsed by the [terraform-json package](https://pkg.go.dev/github.com/hashicorp/terraform-json#State). + +Here is an example implementation of a state check that asserts that a specific resource attribute has a known type and value: + +```go +package example_test + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-testing/statecheck" +) + +var _ StateCheck = expectKnownValue{} + +type expectKnownValue struct { + resourceAddress string + attributePath tfjsonpath.Path + knownValue knownvalue.Check +} + +func (e expectKnownValue) CheckState(ctx context.Context, req CheckStateRequest, resp *CheckStateResponse) { + var rc *tfjson.StateResource + + if req.State == nil { + resp.Error = fmt.Errorf("state is nil") + } + + if req.State.Values == nil { + resp.Error = fmt.Errorf("state does not contain any state values") + } + + if req.State.Values.RootModule == nil { + resp.Error = fmt.Errorf("state does not contain a root module") + } + + for _, resourceChange := range req.State.Values.RootModule.Resources { + if e.resourceAddress == resourceChange.Address { + rc = resourceChange + + break + } + } + + if rc == nil { + resp.Error = fmt.Errorf("%s - Resource not found in state", e.resourceAddress) + + return + } + + result, err := tfjsonpath.Traverse(rc.AttributeValues, e.attributePath) + + if err != nil { + resp.Error = err + + return + } + + if err := e.knownValue.CheckValue(result); err != nil { + resp.Error = err + } +} + +func ExpectKnownValue(resourceAddress string, attributePath tfjsonpath.Path, knownValue knownvalue.Check) StateCheck { + return expectKnownValue{ + resourceAddress: resourceAddress, + attributePath: attributePath, + knownValue: knownValue, + } +} +``` + +And example usage: +```go +package example_test + +import ( + "testing" + + r "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/knownvalue" + "github.com/hashicorp/terraform-plugin-testing/statecheck" + "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" +) + +func TestExpectKnownValue_CheckState_Bool(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + // Provider definition omitted. + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + bool_attribute = true + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("bool_attribute"), + knownvalue.BoolValueExact(true), + ), + }, + }, + }, + }) +} +``` diff --git a/website/docs/plugin/testing/acceptance-tests/state-checks/index.mdx b/website/docs/plugin/testing/acceptance-tests/state-checks/index.mdx new file mode 100644 index 000000000..36304e388 --- /dev/null +++ b/website/docs/plugin/testing/acceptance-tests/state-checks/index.mdx @@ -0,0 +1,20 @@ +--- +page_title: 'Plugin Development - Acceptance Testing: State Checks' +description: >- + State Checks are test assertions that can inspect state during a TestStep. The testing module + provides built-in State Checks for common use-cases, and custom State Checks can also be implemented. +--- + +# State Checks + +During the **Lifecycle (config)** [mode](/terraform/plugin/testing/acceptance-tests/teststep#test-modes) of a `TestStep`, the testing framework will run `terraform apply`. + +The execution of `terraform apply` results in a [state file](/terraform/language/state), and can be represented by this [JSON format](/terraform/internals/json-format#state-representation). + +A **state check** is a test assertion that inspects the state file. Multiple state checks can be run, all assertion errors returned are aggregated, reported as a test failure, and all test cleanup logic is executed. + +Refer to: + +- [Resource State Checks](/terraform/plugin/testing/acceptance-tests/state-checks/resource) for built-in managed resource and data source state checks. +- [Output State Checks](/terraform/plugin/testing/acceptance-tests/state-checks/output) for built-in output-related state checks. +- [Custom State Checks](/terraform/plugin/testing/acceptance-tests/state-checks/custom) for defining bespoke state checks. diff --git a/website/docs/plugin/testing/acceptance-tests/state-checks/output.mdx b/website/docs/plugin/testing/acceptance-tests/state-checks/output.mdx new file mode 100644 index 000000000..01caccdae --- /dev/null +++ b/website/docs/plugin/testing/acceptance-tests/state-checks/output.mdx @@ -0,0 +1,84 @@ +--- +page_title: 'Plugin Development - Acceptance Testing: State Checks' +description: >- + State Checks are test assertions that can inspect state during a TestStep. The testing module + provides built-in Output Value State Checks for common use-cases. +--- + +# Output State Checks + +The `terraform-plugin-testing` module provides a package [`statecheck`](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/statecheck) with built-in output value state checks for common use-cases: + +| Check | Description | +|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------| +| [`statecheck.ExpectKnownOutputValue(address, value)`](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/statecheck#ExpectKnownOutputValue) | Asserts the output at the specified address has the specified type, and value. | +| [`statecheck.ExpectKnownOutputValueAtPath(address, path, value)`](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/statecheck#ExpectKnownOutputValueAtPath) | Asserts the output at the specified address, and path has the specified type, and value. | + +## Example using `statecheck.ExpectKnownOutputValue` + +The [`statecheck.ExpectKnownOutputValue(address, value)`](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/statecheck#ExpectKnownOutputValue) state check verifies that a specific output value has a known type, and value. + +Refer to [Known Value Checks](/terraform/plugin/testing/acceptance-tests/known-value-checks) for details, and examples of the available [knownvalue.Check](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#Check) types that can be used with the `ExpectKnownOutputValue` state check. + +```go +func TestExpectKnownOutputValue_CheckState_Bool(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + // Provider definition omitted. + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + bool_attribute = true + } + + output bool_output { + value = test_resource.one.bool_attribute + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValue( + "bool_output", + knownvalue.BoolValueExact(true), + ), + }, + }, + }, + }) +} +``` + +## Example using `statecheck.ExpectKnownOutputValueAtPath` + +The [`statecheck.ExpectKnownOutputValueAtPath(address, path, value)`](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/statecheck#ExpectKnownOutputValueAtPath) state check verifies that a specific output value at a defined path has a known type, and value. + +Refer to [Known Value Checks](/terraform/plugin/testing/acceptance-tests/known-value-checks) for details, and examples of the available [knownvalue.Check](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#Check) types that can be used with the `ExpectKnownOutputValueAtPath` state check. + +```go +func TestExpectKnownOutputValueAtPath_CheckState_Bool(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + // Provider definition omitted. + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + bool_attribute = true + } + + output test_resource_one_output { + value = test_resource.one + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("bool_attribute"), + knownvalue.BoolValueExact(true), + ), + }, + }, + }, + }) +} +``` \ No newline at end of file diff --git a/website/docs/plugin/testing/acceptance-tests/state-checks/resource.mdx b/website/docs/plugin/testing/acceptance-tests/state-checks/resource.mdx new file mode 100644 index 000000000..990fd828b --- /dev/null +++ b/website/docs/plugin/testing/acceptance-tests/state-checks/resource.mdx @@ -0,0 +1,78 @@ +--- +page_title: 'Plugin Development - Acceptance Testing: State Checks' +description: >- + State Checks are test assertions that can inspect state during a TestStep. The testing module + provides built-in Managed Resource and Data Source State Checks for common use-cases. +--- + +# Resource State Checks + +The `terraform-plugin-testing` module provides a package [`statecheck`](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/statecheck) with built-in managed resource, and data source state checks for common use-cases: + +| Check | Description | +|------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------| +| [`statecheck.ExpectKnownValue(address, path, value)`](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/statecheck#ExpectKnownValue) | Asserts the specified attribute at the given managed resource, or data source, has the specified type, and value. | +| [`statecheck.ExpectSensitiveValue(address, path)`](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/statecheck#ExpectSensitiveValue) | Asserts the specified attribute at the given managed resource, or data source, has a sensitive value. | + +## Example using `statecheck.ExpectKnownValue` + +The [`statecheck.ExpectKnownValue(address, path, value)`](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/statecheck#ExpectKnownValue) state check provides a basis for asserting that a specific resource attribute has a known type, and value. + +Refer to [Known Value Checks](/terraform/plugin/testing/acceptance-tests/known-value-checks) for details, and examples of the available [knownvalue.Check](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#Check) types that can be used with the `ExpectKnownValue` state check. + +```go +func TestExpectKnownValue_CheckState_Bool(t *testing.T) { + t.Parallel() + + r.Test(t, r.TestCase{ + // Provider definition omitted. + Steps: []r.TestStep{ + { + Config: `resource "test_resource" "one" { + bool_attribute = true + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("bool_attribute"), + knownvalue.BoolValueExact(true), + ), + }, + }, + }, + }) +} +``` + +## Example using `statecheck.ExpectSensitiveValue` + +The [`statecheck.ExpectSensitiveValue(address, path)`](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/statecheck#ExpectSensitiveValue) state check provides a basis for asserting that a specific resource attribute is marked as sensitive. + +-> **Note:** In this example, a [TerraformVersionCheck](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/tfversion#TerraformVersionCheck) is being used to prevent execution of this test prior to Terraform version `1.4.6` (refer to the release notes for Terraform [v1.4.6](https://github.com/hashicorp/terraform/releases/tag/v1.4.6)). + +```go +func Test_ExpectSensitiveValue_SensitiveStringAttribute(t *testing.T) { + t.Parallel() + + r.UnitTest(t, r.TestCase{ + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.SkipBelow(tfversion.Version1_4_6), // StateResource.SensitiveValues + }, + // Provider definition omitted. + Steps: []r.TestStep{ + { + Config: ` + resource "test_resource" "one" { + sensitive_string_attribute = "test" + } + `, + ConfigStateChecks: r.ConfigStateChecks{ + statecheck.ExpectSensitiveValue("test_resource.one", + tfjsonpath.New("sensitive_string_attribute")), + }, + }, + }, + }) +} +``` From 3d4acf4ff30976989935bbdad88fb716a8c8d22b Mon Sep 17 00:00:00 2001 From: Benjamin Bennett Date: Thu, 11 Jan 2024 08:11:23 +0000 Subject: [PATCH 09/29] Adding to the documentation for the custom known value check (#266) --- .../known-value-checks/custom.mdx | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/website/docs/plugin/testing/acceptance-tests/known-value-checks/custom.mdx b/website/docs/plugin/testing/acceptance-tests/known-value-checks/custom.mdx index ee48caa62..b9f69de1e 100644 --- a/website/docs/plugin/testing/acceptance-tests/known-value-checks/custom.mdx +++ b/website/docs/plugin/testing/acceptance-tests/known-value-checks/custom.mdx @@ -48,3 +48,26 @@ func StringValueMatch(value string) StringValue { } } ``` + +## `CheckValue` Method Implementation + +The `other` parameter passed to the `CheckValue` method is one of the following types: + +* bool +* map[string]any +* []any +* string + +-> **Note:** Numerical values will be of type `json.Number`, with an underlying type of `string`. + +Refer to the following built-in known value checks for implementations that handle the different types that can be passed to the `CheckValue` method in the `other` parameter: + +* [BoolValueExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#BoolValueExact) +* [Float64ValueExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#Float64ValueExact) +* [Int64ValueExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#Int64ValueExact) +* [ListValueExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#ListValueExact) +* [MapValueExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#MapValueExact) +* [NumberValueExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#NumberValueExact) +* [ObjectValueExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#ObjectValueExact) +* [SetValueExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#SetValueExact) +* [StringValueExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#StringValueExact) From 01fe9a9bc5ce887a2709b4dbc495e4e8a9b48eeb Mon Sep 17 00:00:00 2001 From: Benjamin Bennett Date: Thu, 11 Jan 2024 14:29:54 +0000 Subject: [PATCH 10/29] Adding changelog entries (#266) --- .changes/unreleased/FEATURES-20240111-142126.yaml | 6 ++++++ .changes/unreleased/FEATURES-20240111-142223.yaml | 6 ++++++ .changes/unreleased/FEATURES-20240111-142314.yaml | 6 ++++++ .changes/unreleased/FEATURES-20240111-142353.yaml | 6 ++++++ .changes/unreleased/FEATURES-20240111-142544.yaml | 6 ++++++ 5 files changed, 30 insertions(+) create mode 100644 .changes/unreleased/FEATURES-20240111-142126.yaml create mode 100644 .changes/unreleased/FEATURES-20240111-142223.yaml create mode 100644 .changes/unreleased/FEATURES-20240111-142314.yaml create mode 100644 .changes/unreleased/FEATURES-20240111-142353.yaml create mode 100644 .changes/unreleased/FEATURES-20240111-142544.yaml diff --git a/.changes/unreleased/FEATURES-20240111-142126.yaml b/.changes/unreleased/FEATURES-20240111-142126.yaml new file mode 100644 index 000000000..99c271b7c --- /dev/null +++ b/.changes/unreleased/FEATURES-20240111-142126.yaml @@ -0,0 +1,6 @@ +kind: FEATURES +body: 'statecheck: Introduced new `statecheck` package with interface and built-in + state check functionality' +time: 2024-01-11T14:21:26.261094Z +custom: + Issue: "273" diff --git a/.changes/unreleased/FEATURES-20240111-142223.yaml b/.changes/unreleased/FEATURES-20240111-142223.yaml new file mode 100644 index 000000000..ca6a2a386 --- /dev/null +++ b/.changes/unreleased/FEATURES-20240111-142223.yaml @@ -0,0 +1,6 @@ +kind: FEATURES +body: 'statecheck: Added `ExpectKnownValue` state check, which asserts that a given + resource attribute has a defined type, and value' +time: 2024-01-11T14:22:23.072321Z +custom: + Issue: "273" diff --git a/.changes/unreleased/FEATURES-20240111-142314.yaml b/.changes/unreleased/FEATURES-20240111-142314.yaml new file mode 100644 index 000000000..3d683c564 --- /dev/null +++ b/.changes/unreleased/FEATURES-20240111-142314.yaml @@ -0,0 +1,6 @@ +kind: FEATURES +body: 'statecheck: Added `ExpectKnownOutputValue` state check, which asserts that + a given output value has a defined type, and value' +time: 2024-01-11T14:23:14.025585Z +custom: + Issue: "273" diff --git a/.changes/unreleased/FEATURES-20240111-142353.yaml b/.changes/unreleased/FEATURES-20240111-142353.yaml new file mode 100644 index 000000000..eaa67ae05 --- /dev/null +++ b/.changes/unreleased/FEATURES-20240111-142353.yaml @@ -0,0 +1,6 @@ +kind: FEATURES +body: 'statecheck: Added `ExpectKnownOutputValueAtPath` plan check, which asserts + that a given output value at a specified path has a defined type, and value' +time: 2024-01-11T14:23:53.633255Z +custom: + Issue: "273" diff --git a/.changes/unreleased/FEATURES-20240111-142544.yaml b/.changes/unreleased/FEATURES-20240111-142544.yaml new file mode 100644 index 000000000..42bf8aa03 --- /dev/null +++ b/.changes/unreleased/FEATURES-20240111-142544.yaml @@ -0,0 +1,6 @@ +kind: FEATURES +body: 'statecheck: Added `ExpectSensitiveValue` built-in state check, which asserts + that a given attribute has a sensitive value' +time: 2024-01-11T14:25:44.598583Z +custom: + Issue: "273" From fb9fed8fc9649aec0047ed57fe6d45082e1834e5 Mon Sep 17 00:00:00 2001 From: Benjamin Bennett Date: Thu, 11 Jan 2024 14:40:05 +0000 Subject: [PATCH 11/29] Refactoring to use updated known value check types (#266) --- .../expect_known_output_value_at_path_test.go | 50 +++++++++---------- statecheck/expect_known_output_value_test.go | 50 +++++++++---------- statecheck/expect_known_value_test.go | 50 +++++++++---------- statecheck/expect_sensitive_value.go | 2 - 4 files changed, 75 insertions(+), 77 deletions(-) diff --git a/statecheck/expect_known_output_value_at_path_test.go b/statecheck/expect_known_output_value_at_path_test.go index 371847b69..3fcd64637 100644 --- a/statecheck/expect_known_output_value_at_path_test.go +++ b/statecheck/expect_known_output_value_at_path_test.go @@ -138,7 +138,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_Bool_KnownValueWrongType(t *tes knownvalue.Float64ValueExact(1.23), ), }, - ExpectError: regexp.MustCompile(`expected json\.Number value for Float64Value check, got: bool`), + ExpectError: regexp.MustCompile(`expected json\.Number value for Float64ValueExact check, got: bool`), }, }, }) @@ -170,7 +170,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_Bool_KnownValueWrongValue(t *te knownvalue.BoolValueExact(false), ), }, - ExpectError: regexp.MustCompile("expected value false for BoolValue check, got: true"), + ExpectError: regexp.MustCompile("expected value false for BoolValueExact check, got: true"), }, }, }) @@ -234,7 +234,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_Float64_KnownValueWrongType(t * knownvalue.StringValueExact("str"), ), }, - ExpectError: regexp.MustCompile(`expected string value for StringValue check, got: json\.Number`), + ExpectError: regexp.MustCompile(`expected string value for StringValueExact check, got: json\.Number`), }, }, }) @@ -266,7 +266,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_Float64_KnownValueWrongValue(t knownvalue.Float64ValueExact(3.21), ), }, - ExpectError: regexp.MustCompile("expected value 3.21 for Float64Value check, got: 1.23"), + ExpectError: regexp.MustCompile("expected value 3.21 for Float64ValueExact check, got: 1.23"), }, }, }) @@ -329,7 +329,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_Int64_KnownValueWrongValue(t *t knownvalue.Int64ValueExact(321), ), }, - ExpectError: regexp.MustCompile("expected value 321 for Int64Value check, got: 123"), + ExpectError: regexp.MustCompile("expected value 321 for Int64ValueExact check, got: 123"), }, }, }) @@ -401,7 +401,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_List_KnownValueWrongType(t *tes knownvalue.MapValueExact(map[string]knownvalue.Check{}), ), }, - ExpectError: regexp.MustCompile(`expected map\[string\]any value for MapValue check, got: \[\]interface {}`), + ExpectError: regexp.MustCompile(`expected map\[string\]any value for MapValueExact check, got: \[\]interface {}`), }, }, }) @@ -439,7 +439,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_List_KnownValueWrongValue(t *te }), ), }, - ExpectError: regexp.MustCompile(`list element index 0: expected value value3 for StringValue check, got: value1`), + ExpectError: regexp.MustCompile(`list element index 0: expected value value3 for StringValueExact check, got: value1`), }, }, }) @@ -471,7 +471,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_ListPartial(t *testing.T) { statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("list_attribute"), - knownvalue.ListValuePartialMatch(map[int]knownvalue.Check{ + knownvalue.ListValuePartial(map[int]knownvalue.Check{ 0: knownvalue.StringValueExact("value1"), }), ), @@ -509,12 +509,12 @@ func TestExpectKnownOutputValueAtPath_CheckState_ListPartial_KnownValueWrongValu statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("list_attribute"), - knownvalue.ListValuePartialMatch(map[int]knownvalue.Check{ + knownvalue.ListValuePartial(map[int]knownvalue.Check{ 0: knownvalue.StringValueExact("value3"), }), ), }, - ExpectError: regexp.MustCompile(`list element 0: expected value value3 for StringValue check, got: value1`), + ExpectError: regexp.MustCompile(`list element 0: expected value value3 for StringValueExact check, got: value1`), }, }, }) @@ -583,7 +583,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_ListElements_WrongNum(t *testin knownvalue.ListElementsExact(3), ), }, - ExpectError: regexp.MustCompile("expected 3 elements for ListElements check, got 2 elements"), + ExpectError: regexp.MustCompile("expected 3 elements for ListElementsExact check, got 2 elements"), }, }, }) @@ -660,7 +660,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_ListNestedBlockPartial(t *testi statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("list_nested_block"), - knownvalue.ListValuePartialMatch(map[int]knownvalue.Check{ + knownvalue.ListValuePartial(map[int]knownvalue.Check{ 1: knownvalue.MapValueExact(map[string]knownvalue.Check{ "list_nested_block_attribute": knownvalue.StringValueExact("rts"), }), @@ -774,7 +774,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_Map_KnownValueWrongType(t *test knownvalue.ListValueExact([]knownvalue.Check{}), ), }, - ExpectError: regexp.MustCompile(`expected \[\]any value for ListValue check, got: map\[string\]interface {}`), + ExpectError: regexp.MustCompile(`expected \[\]any value for ListValueExact check, got: map\[string\]interface {}`), }, }, }) @@ -812,7 +812,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_Map_KnownValueWrongValue(t *tes }), ), }, - ExpectError: regexp.MustCompile(`missing element key3 for MapValue check`), + ExpectError: regexp.MustCompile(`missing element key3 for MapValueExact check`), }, }, }) @@ -844,7 +844,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_MapPartial(t *testing.T) { statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("map_attribute"), - knownvalue.MapValuePartialMatch(map[string]knownvalue.Check{ + knownvalue.MapValuePartial(map[string]knownvalue.Check{ "key1": knownvalue.StringValueExact("value1"), }), ), @@ -880,7 +880,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_MapPartial_KnownValueWrongValue statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("map_attribute"), - knownvalue.MapValuePartialMatch(map[string]knownvalue.Check{ + knownvalue.MapValuePartial(map[string]knownvalue.Check{ "key3": knownvalue.StringValueExact("value1"), }), ), @@ -954,7 +954,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_MapElements_WrongNum(t *testing knownvalue.MapElementsExact(3), ), }, - ExpectError: regexp.MustCompile("expected 3 elements for MapElements check, got 2 elements"), + ExpectError: regexp.MustCompile("expected 3 elements for MapElementsExact check, got 2 elements"), }, }, }) @@ -1029,7 +1029,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_Number_KnownValueWrongValue(t * knownvalue.NumberValueExact(f), ), }, - ExpectError: regexp.MustCompile("expected value 321 for NumberValue check, got: 123"), + ExpectError: regexp.MustCompile("expected value 321 for NumberValueExact check, got: 123"), }, }, }) @@ -1104,7 +1104,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_Set_KnownValueWrongValue(t *tes }), ), }, - ExpectError: regexp.MustCompile(`missing value value3 for SetValue check`), + ExpectError: regexp.MustCompile(`missing value value3 for SetValueExact check`), }, }, }) @@ -1136,7 +1136,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_SetPartial(t *testing.T) { statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("set_attribute"), - knownvalue.SetValuePartialMatch([]knownvalue.Check{ + knownvalue.SetValuePartial([]knownvalue.Check{ knownvalue.StringValueExact("value2"), }), ), @@ -1172,7 +1172,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_SetPartial_KnownValueWrongValue statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("set_attribute"), - knownvalue.SetValuePartialMatch([]knownvalue.Check{ + knownvalue.SetValuePartial([]knownvalue.Check{ knownvalue.StringValueExact("value3"), }), ), @@ -1288,7 +1288,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_SetNestedBlockPartial(t *testin statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("set_nested_block"), - knownvalue.SetValuePartialMatch([]knownvalue.Check{ + knownvalue.SetValuePartial([]knownvalue.Check{ knownvalue.MapValueExact(map[string]knownvalue.Check{ "set_nested_block_attribute": knownvalue.StringValueExact("rts"), }), @@ -1391,7 +1391,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_String_KnownValueWrongType(t *t tfjsonpath.New("string_attribute"), knownvalue.BoolValueExact(true)), }, - ExpectError: regexp.MustCompile("expected bool value for BoolValue check, got: string"), + ExpectError: regexp.MustCompile("expected bool value for BoolValueExact check, got: string"), }, }, }) @@ -1422,7 +1422,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_String_KnownValueWrongValue(t * tfjsonpath.New("string_attribute"), knownvalue.StringValueExact("rts")), }, - ExpectError: regexp.MustCompile("expected value rts for StringValue check, got: str"), + ExpectError: regexp.MustCompile("expected value rts for StringValueExact check, got: str"), }, }, }) @@ -1449,7 +1449,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_UnknownAttributeType(t *testing }, }, }, - expectedErr: fmt.Errorf("expected json.Number value for Int64Value check, got: float32"), + expectedErr: fmt.Errorf("expected json.Number value for Int64ValueExact check, got: float32"), }, } diff --git a/statecheck/expect_known_output_value_test.go b/statecheck/expect_known_output_value_test.go index e081b0716..e4af792d5 100644 --- a/statecheck/expect_known_output_value_test.go +++ b/statecheck/expect_known_output_value_test.go @@ -137,7 +137,7 @@ func TestExpectKnownOutputValue_CheckState_Bool_KnownValueWrongType(t *testing.T knownvalue.Float64ValueExact(1.23), ), }, - ExpectError: regexp.MustCompile(`expected json\.Number value for Float64Value check, got: bool`), + ExpectError: regexp.MustCompile(`expected json\.Number value for Float64ValueExact check, got: bool`), }, }, }) @@ -168,7 +168,7 @@ func TestExpectKnownOutputValue_CheckState_Bool_KnownValueWrongValue(t *testing. knownvalue.BoolValueExact(false), ), }, - ExpectError: regexp.MustCompile("expected value false for BoolValue check, got: true"), + ExpectError: regexp.MustCompile("expected value false for BoolValueExact check, got: true"), }, }, }) @@ -230,7 +230,7 @@ func TestExpectKnownOutputValue_CheckState_Float64_KnownValueWrongType(t *testin knownvalue.StringValueExact("str"), ), }, - ExpectError: regexp.MustCompile(`expected string value for StringValue check, got: json\.Number`), + ExpectError: regexp.MustCompile(`expected string value for StringValueExact check, got: json\.Number`), }, }, }) @@ -261,7 +261,7 @@ func TestExpectKnownOutputValue_CheckState_Float64_KnownValueWrongValue(t *testi knownvalue.Float64ValueExact(3.21), ), }, - ExpectError: regexp.MustCompile("expected value 3.21 for Float64Value check, got: 1.23"), + ExpectError: regexp.MustCompile("expected value 3.21 for Float64ValueExact check, got: 1.23"), }, }, }) @@ -322,7 +322,7 @@ func TestExpectKnownOutputValue_CheckState_Int64_KnownValueWrongValue(t *testing knownvalue.Int64ValueExact(321), ), }, - ExpectError: regexp.MustCompile("expected value 321 for Int64Value check, got: 123"), + ExpectError: regexp.MustCompile("expected value 321 for Int64ValueExact check, got: 123"), }, }, }) @@ -392,7 +392,7 @@ func TestExpectKnownOutputValue_CheckState_List_KnownValueWrongType(t *testing.T knownvalue.MapValueExact(map[string]knownvalue.Check{}), ), }, - ExpectError: regexp.MustCompile(`expected map\[string\]any value for MapValue check, got: \[\]interface {}`), + ExpectError: regexp.MustCompile(`expected map\[string\]any value for MapValueExact check, got: \[\]interface {}`), }, }, }) @@ -429,7 +429,7 @@ func TestExpectKnownOutputValue_CheckState_List_KnownValueWrongValue(t *testing. }), ), }, - ExpectError: regexp.MustCompile(`list element index 0: expected value value3 for StringValue check, got: value1`), + ExpectError: regexp.MustCompile(`list element index 0: expected value value3 for StringValueExact check, got: value1`), }, }, }) @@ -460,7 +460,7 @@ func TestExpectKnownOutputValue_CheckState_ListPartial(t *testing.T) { ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "list_output", - knownvalue.ListValuePartialMatch(map[int]knownvalue.Check{ + knownvalue.ListValuePartial(map[int]knownvalue.Check{ 0: knownvalue.StringValueExact("value1"), }), ), @@ -497,12 +497,12 @@ func TestExpectKnownOutputValue_CheckState_ListPartial_KnownValueWrongValue(t *t ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "list_output", - knownvalue.ListValuePartialMatch(map[int]knownvalue.Check{ + knownvalue.ListValuePartial(map[int]knownvalue.Check{ 0: knownvalue.StringValueExact("value3"), }), ), }, - ExpectError: regexp.MustCompile(`list element 0: expected value value3 for StringValue check, got: value1`), + ExpectError: regexp.MustCompile(`list element 0: expected value value3 for StringValueExact check, got: value1`), }, }, }) @@ -569,7 +569,7 @@ func TestExpectKnownOutputValue_CheckState_ListElements_WrongNum(t *testing.T) { knownvalue.ListElementsExact(3), ), }, - ExpectError: regexp.MustCompile("expected 3 elements for ListElements check, got 2 elements"), + ExpectError: regexp.MustCompile("expected 3 elements for ListElementsExact check, got 2 elements"), }, }, }) @@ -644,7 +644,7 @@ func TestExpectKnownOutputValue_CheckState_ListNestedBlockPartial(t *testing.T) ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "list_nested_block_output", - knownvalue.ListValuePartialMatch(map[int]knownvalue.Check{ + knownvalue.ListValuePartial(map[int]knownvalue.Check{ 1: knownvalue.MapValueExact(map[string]knownvalue.Check{ "list_nested_block_attribute": knownvalue.StringValueExact("rts"), }), @@ -755,7 +755,7 @@ func TestExpectKnownOutputValue_CheckState_Map_KnownValueWrongType(t *testing.T) knownvalue.ListValueExact([]knownvalue.Check{}), ), }, - ExpectError: regexp.MustCompile(`expected \[\]any value for ListValue check, got: map\[string\]interface {}`), + ExpectError: regexp.MustCompile(`expected \[\]any value for ListValueExact check, got: map\[string\]interface {}`), }, }, }) @@ -792,7 +792,7 @@ func TestExpectKnownOutputValue_CheckState_Map_KnownValueWrongValue(t *testing.T }), ), }, - ExpectError: regexp.MustCompile(`missing element key3 for MapValue check`), + ExpectError: regexp.MustCompile(`missing element key3 for MapValueExact check`), }, }, }) @@ -823,7 +823,7 @@ func TestExpectKnownOutputValue_CheckState_MapPartial(t *testing.T) { ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "map_output", - knownvalue.MapValuePartialMatch(map[string]knownvalue.Check{ + knownvalue.MapValuePartial(map[string]knownvalue.Check{ "key1": knownvalue.StringValueExact("value1"), }), ), @@ -858,7 +858,7 @@ func TestExpectKnownOutputValue_CheckState_MapPartial_KnownValueWrongValue(t *te ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "map_output", - knownvalue.MapValuePartialMatch(map[string]knownvalue.Check{ + knownvalue.MapValuePartial(map[string]knownvalue.Check{ "key3": knownvalue.StringValueExact("value1"), }), ), @@ -930,7 +930,7 @@ func TestExpectKnownOutputValue_CheckState_MapElements_WrongNum(t *testing.T) { knownvalue.MapElementsExact(3), ), }, - ExpectError: regexp.MustCompile("expected 3 elements for MapElements check, got 2 elements"), + ExpectError: regexp.MustCompile("expected 3 elements for MapElementsExact check, got 2 elements"), }, }, }) @@ -1003,7 +1003,7 @@ func TestExpectKnownOutputValue_CheckState_Number_KnownValueWrongValue(t *testin knownvalue.NumberValueExact(f), ), }, - ExpectError: regexp.MustCompile("expected value 321 for NumberValue check, got: 123"), + ExpectError: regexp.MustCompile("expected value 321 for NumberValueExact check, got: 123"), }, }, }) @@ -1076,7 +1076,7 @@ func TestExpectKnownOutputValue_CheckState_Set_KnownValueWrongValue(t *testing.T }), ), }, - ExpectError: regexp.MustCompile(`missing value value3 for SetValue check`), + ExpectError: regexp.MustCompile(`missing value value3 for SetValueExact check`), }, }, }) @@ -1107,7 +1107,7 @@ func TestExpectKnownOutputValue_CheckState_SetPartial(t *testing.T) { ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "set_output", - knownvalue.SetValuePartialMatch([]knownvalue.Check{ + knownvalue.SetValuePartial([]knownvalue.Check{ knownvalue.StringValueExact("value2"), }), ), @@ -1142,7 +1142,7 @@ func TestExpectKnownOutputValue_CheckState_SetPartial_KnownValueWrongValue(t *te ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "set_output", - knownvalue.SetValuePartialMatch([]knownvalue.Check{ + knownvalue.SetValuePartial([]knownvalue.Check{ knownvalue.StringValueExact("value3"), }), ), @@ -1255,7 +1255,7 @@ func TestExpectKnownOutputValue_CheckState_SetNestedBlockPartial(t *testing.T) { ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "set_nested_block_output", - knownvalue.SetValuePartialMatch([]knownvalue.Check{ + knownvalue.SetValuePartial([]knownvalue.Check{ knownvalue.MapValueExact(map[string]knownvalue.Check{ "set_nested_block_attribute": knownvalue.StringValueExact("rts"), }), @@ -1355,7 +1355,7 @@ func TestExpectKnownOutputValue_CheckState_String_KnownValueWrongType(t *testing "string_output", knownvalue.BoolValueExact(true)), }, - ExpectError: regexp.MustCompile("expected bool value for BoolValue check, got: string"), + ExpectError: regexp.MustCompile("expected bool value for BoolValueExact check, got: string"), }, }, }) @@ -1385,7 +1385,7 @@ func TestExpectKnownOutputValue_CheckState_String_KnownValueWrongValue(t *testin "string_output", knownvalue.StringValueExact("rts")), }, - ExpectError: regexp.MustCompile("expected value rts for StringValue check, got: str"), + ExpectError: regexp.MustCompile("expected value rts for StringValueExact check, got: str"), }, }, }) @@ -1412,7 +1412,7 @@ func TestExpectKnownOutputValue_CheckState_UnknownAttributeType(t *testing.T) { }, }, }, - expectedErr: fmt.Errorf("expected json.Number value for Int64Value check, got: float32"), + expectedErr: fmt.Errorf("expected json.Number value for Int64ValueExact check, got: float32"), }, } diff --git a/statecheck/expect_known_value_test.go b/statecheck/expect_known_value_test.go index ce2d0a5c9..c95086d4b 100644 --- a/statecheck/expect_known_value_test.go +++ b/statecheck/expect_known_value_test.go @@ -122,7 +122,7 @@ func TestExpectKnownValue_CheckState_Bool_KnownValueWrongType(t *testing.T) { knownvalue.Float64ValueExact(1.23), ), }, - ExpectError: regexp.MustCompile(`expected json\.Number value for Float64Value check, got: bool`), + ExpectError: regexp.MustCompile(`expected json\.Number value for Float64ValueExact check, got: bool`), }, }, }) @@ -150,7 +150,7 @@ func TestExpectKnownValue_CheckState_Bool_KnownValueWrongValue(t *testing.T) { knownvalue.BoolValueExact(false), ), }, - ExpectError: regexp.MustCompile("expected value false for BoolValue check, got: true"), + ExpectError: regexp.MustCompile("expected value false for BoolValueExact check, got: true"), }, }, }) @@ -206,7 +206,7 @@ func TestExpectKnownValue_CheckState_Float64_KnownValueWrongType(t *testing.T) { knownvalue.StringValueExact("str"), ), }, - ExpectError: regexp.MustCompile(`expected string value for StringValue check, got: json\.Number`), + ExpectError: regexp.MustCompile(`expected string value for StringValueExact check, got: json\.Number`), }, }, }) @@ -234,7 +234,7 @@ func TestExpectKnownValue_CheckState_Float64_KnownValueWrongValue(t *testing.T) knownvalue.Float64ValueExact(3.21), ), }, - ExpectError: regexp.MustCompile("expected value 3.21 for Float64Value check, got: 1.23"), + ExpectError: regexp.MustCompile("expected value 3.21 for Float64ValueExact check, got: 1.23"), }, }, }) @@ -289,7 +289,7 @@ func TestExpectKnownValue_CheckState_Int64_KnownValueWrongValue(t *testing.T) { knownvalue.Int64ValueExact(321), ), }, - ExpectError: regexp.MustCompile("expected value 321 for Int64Value check, got: 123"), + ExpectError: regexp.MustCompile("expected value 321 for Int64ValueExact check, got: 123"), }, }, }) @@ -353,7 +353,7 @@ func TestExpectKnownValue_CheckState_List_KnownValueWrongType(t *testing.T) { knownvalue.MapValueExact(map[string]knownvalue.Check{}), ), }, - ExpectError: regexp.MustCompile(`expected map\[string\]any value for MapValue check, got: \[\]interface {}`), + ExpectError: regexp.MustCompile(`expected map\[string\]any value for MapValueExact check, got: \[\]interface {}`), }, }, }) @@ -387,7 +387,7 @@ func TestExpectKnownValue_CheckState_List_KnownValueWrongValue(t *testing.T) { }), ), }, - ExpectError: regexp.MustCompile(`list element index 0: expected value value3 for StringValue check, got: value1`), + ExpectError: regexp.MustCompile(`list element index 0: expected value value3 for StringValueExact check, got: value1`), }, }, }) @@ -415,7 +415,7 @@ func TestExpectKnownValue_CheckState_ListPartial(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("list_attribute"), - knownvalue.ListValuePartialMatch(map[int]knownvalue.Check{ + knownvalue.ListValuePartial(map[int]knownvalue.Check{ 0: knownvalue.StringValueExact("value1"), }), ), @@ -449,12 +449,12 @@ func TestExpectKnownValue_CheckState_ListPartial_KnownValueWrongValue(t *testing statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("list_attribute"), - knownvalue.ListValuePartialMatch(map[int]knownvalue.Check{ + knownvalue.ListValuePartial(map[int]knownvalue.Check{ 0: knownvalue.StringValueExact("value3"), }), ), }, - ExpectError: regexp.MustCompile(`list element 0: expected value value3 for StringValue check, got: value1`), + ExpectError: regexp.MustCompile(`list element 0: expected value value3 for StringValueExact check, got: value1`), }, }, }) @@ -515,7 +515,7 @@ func TestExpectKnownValue_CheckState_ListElements_WrongNum(t *testing.T) { knownvalue.ListElementsExact(3), ), }, - ExpectError: regexp.MustCompile("expected 3 elements for ListElements check, got 2 elements"), + ExpectError: regexp.MustCompile("expected 3 elements for ListElementsExact check, got 2 elements"), }, }, }) @@ -584,7 +584,7 @@ func TestExpectKnownValue_CheckState_ListNestedBlockPartial(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("list_nested_block"), - knownvalue.ListValuePartialMatch(map[int]knownvalue.Check{ + knownvalue.ListValuePartial(map[int]knownvalue.Check{ 1: knownvalue.MapValueExact(map[string]knownvalue.Check{ "list_nested_block_attribute": knownvalue.StringValueExact("rts"), }), @@ -686,7 +686,7 @@ func TestExpectKnownValue_CheckState_Map_KnownValueWrongType(t *testing.T) { knownvalue.ListValueExact([]knownvalue.Check{}), ), }, - ExpectError: regexp.MustCompile(`expected \[\]any value for ListValue check, got: map\[string\]interface {}`), + ExpectError: regexp.MustCompile(`expected \[\]any value for ListValueExact check, got: map\[string\]interface {}`), }, }, }) @@ -720,7 +720,7 @@ func TestExpectKnownValue_CheckState_Map_KnownValueWrongValue(t *testing.T) { }), ), }, - ExpectError: regexp.MustCompile(`missing element key3 for MapValue check`), + ExpectError: regexp.MustCompile(`missing element key3 for MapValueExact check`), }, }, }) @@ -748,7 +748,7 @@ func TestExpectKnownValue_CheckState_MapPartial(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("map_attribute"), - knownvalue.MapValuePartialMatch(map[string]knownvalue.Check{ + knownvalue.MapValuePartial(map[string]knownvalue.Check{ "key1": knownvalue.StringValueExact("value1"), }), ), @@ -780,7 +780,7 @@ func TestExpectKnownValue_CheckState_MapPartial_KnownValueWrongValue(t *testing. statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("map_attribute"), - knownvalue.MapValuePartialMatch(map[string]knownvalue.Check{ + knownvalue.MapValuePartial(map[string]knownvalue.Check{ "key3": knownvalue.StringValueExact("value1"), }), ), @@ -846,7 +846,7 @@ func TestExpectKnownValue_CheckState_MapElements_WrongNum(t *testing.T) { knownvalue.MapElementsExact(3), ), }, - ExpectError: regexp.MustCompile("expected 3 elements for MapElements check, got 2 elements"), + ExpectError: regexp.MustCompile("expected 3 elements for MapElementsExact check, got 2 elements"), }, }, }) @@ -913,7 +913,7 @@ func TestExpectKnownValue_CheckState_Number_KnownValueWrongValue(t *testing.T) { knownvalue.NumberValueExact(f), ), }, - ExpectError: regexp.MustCompile("expected value 321 for NumberValue check, got: 123"), + ExpectError: regexp.MustCompile("expected value 321 for NumberValueExact check, got: 123"), }, }, }) @@ -980,7 +980,7 @@ func TestExpectKnownValue_CheckState_Set_KnownValueWrongValue(t *testing.T) { }), ), }, - ExpectError: regexp.MustCompile(`missing value value3 for SetValue check`), + ExpectError: regexp.MustCompile(`missing value value3 for SetValueExact check`), }, }, }) @@ -1008,7 +1008,7 @@ func TestExpectKnownValue_CheckState_SetPartial(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("set_attribute"), - knownvalue.SetValuePartialMatch([]knownvalue.Check{ + knownvalue.SetValuePartial([]knownvalue.Check{ knownvalue.StringValueExact("value2"), }), ), @@ -1040,7 +1040,7 @@ func TestExpectKnownValue_CheckState_SetPartial_KnownValueWrongValue(t *testing. statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("set_attribute"), - knownvalue.SetValuePartialMatch([]knownvalue.Check{ + knownvalue.SetValuePartial([]knownvalue.Check{ knownvalue.StringValueExact("value3"), }), ), @@ -1144,7 +1144,7 @@ func TestExpectKnownValue_CheckState_SetNestedBlockPartial(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("set_nested_block"), - knownvalue.SetValuePartialMatch([]knownvalue.Check{ + knownvalue.SetValuePartial([]knownvalue.Check{ knownvalue.MapValueExact(map[string]knownvalue.Check{ "set_nested_block_attribute": knownvalue.StringValueExact("rts"), }), @@ -1235,7 +1235,7 @@ func TestExpectKnownValue_CheckState_String_KnownValueWrongType(t *testing.T) { tfjsonpath.New("string_attribute"), knownvalue.BoolValueExact(true)), }, - ExpectError: regexp.MustCompile("expected bool value for BoolValue check, got: string"), + ExpectError: regexp.MustCompile("expected bool value for BoolValueExact check, got: string"), }, }, }) @@ -1262,7 +1262,7 @@ func TestExpectKnownValue_CheckState_String_KnownValueWrongValue(t *testing.T) { tfjsonpath.New("string_attribute"), knownvalue.StringValueExact("rts")), }, - ExpectError: regexp.MustCompile("expected value rts for StringValue check, got: str"), + ExpectError: regexp.MustCompile("expected value rts for StringValueExact check, got: str"), }, }, }) @@ -1294,7 +1294,7 @@ func TestExpectKnownValue_CheckState_UnknownAttributeType(t *testing.T) { }, }, }, - expectedErr: fmt.Errorf("expected json.Number value for Int64Value check, got: float32"), + expectedErr: fmt.Errorf("expected json.Number value for Int64ValueExact check, got: float32"), }, } diff --git a/statecheck/expect_sensitive_value.go b/statecheck/expect_sensitive_value.go index 7e8ec7325..447a2cb27 100644 --- a/statecheck/expect_sensitive_value.go +++ b/statecheck/expect_sensitive_value.go @@ -78,8 +78,6 @@ func (e expectSensitiveValue) CheckState(ctx context.Context, req CheckStateRequ resp.Error = fmt.Errorf("attribute at path is not sensitive") return } - - return } // ExpectSensitiveValue returns a state check that asserts that the specified attribute at the given resource has a sensitive value. From 7ff68bcef229ef769020cb8f3bd983e7f6cc58ab Mon Sep 17 00:00:00 2001 From: Benjamin Bennett Date: Mon, 15 Jan 2024 15:24:13 +0000 Subject: [PATCH 12/29] Correcting documentation for revised naming of known value check types (#266) --- website/data/plugin-testing-nav-data.json | 4 ++ .../known-value-checks/bool.mdx | 10 +-- .../known-value-checks/float64.mdx | 10 +-- .../known-value-checks/index.mdx | 8 +-- .../known-value-checks/int64.mdx | 10 +-- .../known-value-checks/list.mdx | 48 +++++++------- .../known-value-checks/map.mdx | 50 +++++++-------- .../known-value-checks/null.mdx | 10 +-- .../known-value-checks/number.mdx | 10 +-- .../known-value-checks/object.mdx | 63 ++++--------------- .../known-value-checks/set.mdx | 48 +++++++------- .../known-value-checks/string.mdx | 10 +-- .../acceptance-tests/plan-checks/output.mdx | 4 +- .../acceptance-tests/plan-checks/resource.mdx | 2 +- .../acceptance-tests/state-checks/custom.mdx | 2 +- .../acceptance-tests/state-checks/output.mdx | 4 +- .../state-checks/resource.mdx | 2 +- 17 files changed, 131 insertions(+), 164 deletions(-) diff --git a/website/data/plugin-testing-nav-data.json b/website/data/plugin-testing-nav-data.json index 40fc85629..dce49a74f 100644 --- a/website/data/plugin-testing-nav-data.json +++ b/website/data/plugin-testing-nav-data.json @@ -102,6 +102,10 @@ "title": "Map", "path": "acceptance-tests/known-value-checks/map" }, + { + "title": "Null", + "path": "acceptance-tests/known-value-checks/null" + }, { "title": "Number", "path": "acceptance-tests/known-value-checks/number" diff --git a/website/docs/plugin/testing/acceptance-tests/known-value-checks/bool.mdx b/website/docs/plugin/testing/acceptance-tests/known-value-checks/bool.mdx index 039bc347b..1a5c09a53 100644 --- a/website/docs/plugin/testing/acceptance-tests/known-value-checks/bool.mdx +++ b/website/docs/plugin/testing/acceptance-tests/known-value-checks/bool.mdx @@ -8,13 +8,13 @@ description: >- The known value checks that are available for bool values are: -* [BoolValueExact](/terraform/plugin/testing/acceptance-tests/known-value-checks/bool#boolvalueexact-check) +* [BoolExact](/terraform/plugin/testing/acceptance-tests/known-value-checks/bool#boolexact-check) -## `BoolValueExact` Check +## `BoolExact` Check -The [BoolValueExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#BoolValueExact) check tests that a resource attribute, or output value has an exactly matching bool value. +The [BoolExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#BoolExact) check tests that a resource attribute, or output value has an exactly matching bool value. -Example usage of [BoolValueExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#BoolValueExact) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/plan-checks/resource) plan check. +Example usage of [BoolExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#BoolExact) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/plan-checks/resource) plan check. ```go func TestExpectKnownValue_CheckPlan_Bool(t *testing.T) { @@ -33,7 +33,7 @@ func TestExpectKnownValue_CheckPlan_Bool(t *testing.T) { plancheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("bool_attribute"), - knownvalue.BoolValueExact(true), + knownvalue.BoolExact(true), ), }, }, diff --git a/website/docs/plugin/testing/acceptance-tests/known-value-checks/float64.mdx b/website/docs/plugin/testing/acceptance-tests/known-value-checks/float64.mdx index d4bacb127..ebaa17d39 100644 --- a/website/docs/plugin/testing/acceptance-tests/known-value-checks/float64.mdx +++ b/website/docs/plugin/testing/acceptance-tests/known-value-checks/float64.mdx @@ -8,13 +8,13 @@ description: >- The known value checks that are available for float64 values are: -* [Float64ValueExact](/terraform/plugin/testing/acceptance-tests/known-value-checks/float64#float64valueexact-check) +* [Float64Exact](/terraform/plugin/testing/acceptance-tests/known-value-checks/float64#float64exact-check) -## `Float64ValueExact` Check +## `Float64Exact` Check -The [Float64ValueExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#Float64ValueExact) check tests that a resource attribute, or output value has an exactly matching float64 value. +The [Float64Exact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#Float64Exact) check tests that a resource attribute, or output value has an exactly matching float64 value. -Example usage of [Float64ValueExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#Float64ValueExact) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/plan-checks/resource) plan check. +Example usage of [Float64Exact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#Float64Exact) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/plan-checks/resource) plan check. ```go func TestExpectKnownValue_CheckPlan_Float64(t *testing.T) { @@ -33,7 +33,7 @@ func TestExpectKnownValue_CheckPlan_Float64(t *testing.T) { plancheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("float_attribute"), - knownvalue.Float64ValueExact(1.23), + knownvalue.Float64Exact(1.23), ), }, }, diff --git a/website/docs/plugin/testing/acceptance-tests/known-value-checks/index.mdx b/website/docs/plugin/testing/acceptance-tests/known-value-checks/index.mdx index dae04a89d..bc22d96e5 100644 --- a/website/docs/plugin/testing/acceptance-tests/known-value-checks/index.mdx +++ b/website/docs/plugin/testing/acceptance-tests/known-value-checks/index.mdx @@ -20,15 +20,15 @@ Example uses in the testing module include: The known value check types are implemented within the `terraform-plugin-testing` module in the [`knownvalue` package](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue). Known value checks are instantiated by calling the relevant constructor function. ```go -knownvalue.BoolValueExact(true) +knownvalue.BoolExact(true) ``` For known value checks that represent collections, or objects, nesting of known value checks can be used to define a "composite" known value check for use in asserting against a resource attribute, or output value that contains other values. ```go -knownvalue.ListValueExact([]knownvalue.Check{ - knownvalue.StringValueExact("value1"), - knownvalue.StringValueExact("value2"), +knownvalue.ListExact([]knownvalue.Check{ + knownvalue.StringExact("value1"), + knownvalue.StringExact("value2"), }) ``` diff --git a/website/docs/plugin/testing/acceptance-tests/known-value-checks/int64.mdx b/website/docs/plugin/testing/acceptance-tests/known-value-checks/int64.mdx index 9954cd7ec..214fcef25 100644 --- a/website/docs/plugin/testing/acceptance-tests/known-value-checks/int64.mdx +++ b/website/docs/plugin/testing/acceptance-tests/known-value-checks/int64.mdx @@ -8,13 +8,13 @@ description: >- The known value checks that are available for int64 values are: -* [Int64ValueExact](/terraform/plugin/testing/acceptance-tests/known-value-checks/float64#int64valueexact-check) +* [Int64Exact](/terraform/plugin/testing/acceptance-tests/known-value-checks/float64#int64exact-check) -## `Int64ValueExact` Check +## `Int64Exact` Check -The [Int64ValueExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#Int64ValueExact) check tests that a resource attribute, or output value has an exactly matching int64 value. +The [Int64Exact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#Int64Exact) check tests that a resource attribute, or output value has an exactly matching int64 value. -Example usage of [Int64ValueExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#Int64ValueExact) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/plan-checks/resource) plan check. +Example usage of [Int64Exact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#Int64Exact) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/plan-checks/resource) plan check. ```go func TestExpectKnownValue_CheckPlan_Int64(t *testing.T) { @@ -33,7 +33,7 @@ func TestExpectKnownValue_CheckPlan_Int64(t *testing.T) { plancheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("int_attribute"), - knownvalue.Int64ValueExact(123), + knownvalue.Int64Exact(123), ), }, }, diff --git a/website/docs/plugin/testing/acceptance-tests/known-value-checks/list.mdx b/website/docs/plugin/testing/acceptance-tests/known-value-checks/list.mdx index 774cedc02..e491e58b6 100644 --- a/website/docs/plugin/testing/acceptance-tests/known-value-checks/list.mdx +++ b/website/docs/plugin/testing/acceptance-tests/known-value-checks/list.mdx @@ -8,22 +8,22 @@ description: >- The known value checks that are available for list values are: -* [ListElementsExact](/terraform/plugin/testing/acceptance-tests/known-value-checks/list#listelementsexact-check) -* [ListValueExact](/terraform/plugin/testing/acceptance-tests/known-value-checks/list#listvalueexact-check) -* [ListValuePartialMatch](/terraform/plugin/testing/acceptance-tests/known-value-checks/list#listvaluepartialmatch-check) +* [ListExact](/terraform/plugin/testing/acceptance-tests/known-value-checks/list#listexact-check) +* [ListPartial](/terraform/plugin/testing/acceptance-tests/known-value-checks/list#listpartial-check) +* [ListSizeExact](/terraform/plugin/testing/acceptance-tests/known-value-checks/list#listsizeexact-check) -## `ListElementsExact` Check +## `ListExact` Check -The [ListElementsExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#ListElementsExact) check tests that a resource attribute, or output value contains the specified number of elements. +The [ListExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#ListExact) check tests that a resource attribute, or output value has an order-dependent, matching collection of element values. -Example usage of [ListElementsExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#ListElementsExact) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/plan-checks/resource) plan check. +Example usage of [ListExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#ListExact) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/plan-checks/resource) plan check. ```go -func TestExpectKnownValue_CheckPlan_ListElements(t *testing.T) { +func TestExpectKnownValue_CheckPlan_List(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ - // Provider definition omitted. + // Provider definition omitted. Steps: []resource.TestStep{ { Config: `resource "test_resource" "one" { @@ -38,7 +38,10 @@ func TestExpectKnownValue_CheckPlan_ListElements(t *testing.T) { plancheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("list_attribute"), - knownvalue.ListElementsExact(2), + knownvalue.ListExact([]knownvalue.Check{ + knownvalue.StringExact("value1"), + knownvalue.StringExact("value2"), + }), ), }, }, @@ -48,18 +51,18 @@ func TestExpectKnownValue_CheckPlan_ListElements(t *testing.T) { } ``` -## `ListValueExact` Check +## `ListPartial` Check -The [ListValueExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#ListValueExact) check tests that a resource attribute, or output value has an order-dependent, matching collection of element values. +The [ListPartial](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#ListPartial) check tests that a resource attribute, or output value has matching element values for the specified collection indices. -Example usage of [ListValueExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#ListValueExact) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/plan-checks/resource) plan check. +Example usage of [ListPartial](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#ListPartial) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/plan-checks/resource) plan check. In this example, only the first element within the list, the element defined at index `0`, is checked. ```go -func TestExpectKnownValue_CheckPlan_List(t *testing.T) { +func TestExpectKnownValue_CheckPlan_ListPartial(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ - // Provider definition omitted. + // Provider definition omitted. Steps: []resource.TestStep{ { Config: `resource "test_resource" "one" { @@ -74,9 +77,8 @@ func TestExpectKnownValue_CheckPlan_List(t *testing.T) { plancheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("list_attribute"), - knownvalue.ListValueExact([]knownvalue.Check{ - knownvalue.StringValueExact("value1"), - knownvalue.StringValueExact("value2"), + knownvalue.ListPartial(map[int]knownvalue.Check{ + 0: knownvalue.StringExact("value1"), }), ), }, @@ -87,14 +89,14 @@ func TestExpectKnownValue_CheckPlan_List(t *testing.T) { } ``` -## `ListValuePartialMatch` Check +## `ListSizeExact` Check -The [ListValuePartialMatch](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#ListValuePartialMatch) check tests that a resource attribute, or output value has matching element values for the specified collection indices. +The [ListSizeExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#ListSizeExact) check tests that a resource attribute, or output value contains the specified number of elements. -Example usage of [ListValuePartialMatch](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#ListValuePartialMatch) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/plan-checks/resource) plan check. In this example, only the first element within the list, the element defined at index `0`, is checked. +Example usage of [ListSizeExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#ListSizeExact) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/plan-checks/resource) plan check. ```go -func TestExpectKnownValue_CheckPlan_ListPartial(t *testing.T) { +func TestExpectKnownValue_CheckPlan_ListElements(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ @@ -113,9 +115,7 @@ func TestExpectKnownValue_CheckPlan_ListPartial(t *testing.T) { plancheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("list_attribute"), - knownvalue.ListValuePartialMatch(map[int]knownvalue.Check{ - 0: knownvalue.StringValueExact("value1"), - }), + knownvalue.ListSizeExact(2), ), }, }, diff --git a/website/docs/plugin/testing/acceptance-tests/known-value-checks/map.mdx b/website/docs/plugin/testing/acceptance-tests/known-value-checks/map.mdx index ea1a5c252..fc04c2f80 100644 --- a/website/docs/plugin/testing/acceptance-tests/known-value-checks/map.mdx +++ b/website/docs/plugin/testing/acceptance-tests/known-value-checks/map.mdx @@ -8,18 +8,18 @@ description: >- The known value checks that are available for map values are: -* [MapElementsExact](/terraform/plugin/testing/acceptance-tests/known-value-checks/map#mapelementsexact-check) -* [MapValueExact](/terraform/plugin/testing/acceptance-tests/known-value-checks/map#mapvalueexact-check) -* [MapValuePartialMatch](/terraform/plugin/testing/acceptance-tests/known-value-checks/map#mapvaluepartialmatch-check) +* [MapExact](/terraform/plugin/testing/acceptance-tests/known-value-checks/map#mapexact-check) +* [MapPartial](/terraform/plugin/testing/acceptance-tests/known-value-checks/map#mappartial-check) +* [MapSizeExact](/terraform/plugin/testing/acceptance-tests/known-value-checks/map#mapsizeexact-check) -## `MapElementsExact` Check +## `MapExact` Check -The [MapElementsExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#MapElementsExact) check tests that a resource attribute, or output value contains the specified number of elements. +The [MapExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#MapExact) check tests that a resource attribute, or output value has a key-specified, matching collection of element values. -Example usage of [MapElementsExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#MapElementsExact) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/plan-checks/resource) plan check. +Example usage of [MapExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#MapExact) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/plan-checks/resource) plan check. ```go -func TestExpectKnownValue_CheckPlan_MapElements(t *testing.T) { +func TestExpectKnownValue_CheckPlan_Map(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ @@ -38,7 +38,10 @@ func TestExpectKnownValue_CheckPlan_MapElements(t *testing.T) { plancheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("map_attribute"), - knownvalue.MapElementsExact(2), + knownvalue.MapExact(map[string]knownvalue.Check{ + "key1": knownvalue.StringExact("value1"), + "key2": knownvalue.StringExact("value2"), + }), ), }, }, @@ -48,14 +51,16 @@ func TestExpectKnownValue_CheckPlan_MapElements(t *testing.T) { } ``` -## `MapValueExact` Check +## `MapPartial` Check -The [MapValueExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#MapValueExact) check tests that a resource attribute, or output value has a key-specified, matching collection of element values. +The [MapPartial](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#MapPartial) check tests that a resource attribute, or output value has matching element values for the specified keys. -Example usage of [MapValueExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#MapValueExact) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/plan-checks/resource) plan check. +Example usage of [MapPartial](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#MapPartial) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/plan-checks/resource) plan check. + +In this example, only the element associated with `key1` within the map is checked. ```go -func TestExpectKnownValue_CheckPlan_Map(t *testing.T) { +func TestExpectKnownValue_CheckPlan_MapPartial(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ @@ -74,9 +79,8 @@ func TestExpectKnownValue_CheckPlan_Map(t *testing.T) { plancheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("map_attribute"), - knownvalue.MapValueExact(map[string]knownvalue.Check{ - "key1": knownvalue.StringValueExact("value1"), - "key2": knownvalue.StringValueExact("value2"), + knownvalue.MapPartial(map[string]knownvalue.Check{ + "key1": knownvalue.StringExact("value1"), }), ), }, @@ -87,16 +91,14 @@ func TestExpectKnownValue_CheckPlan_Map(t *testing.T) { } ``` -## `MapValuePartialMatch` Check +## `MapSizeExact` Check -The [MapValuePartialMatch](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#MapValuePartialMatch) check tests that a resource attribute, or output value has matching element values for the specified keys. +The [MapSizeExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#MapSizeExact) check tests that a resource attribute, or output value contains the specified number of elements. -Example usage of [MapValuePartialMatch](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#MapValuePartialMatch) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/plan-checks/resource) plan check. - -In this example, only the element associated with `key1` within the map is checked. +Example usage of [MapSizeExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#MapSizeExact) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/plan-checks/resource) plan check. ```go -func TestExpectKnownValue_CheckPlan_MapPartial(t *testing.T) { +func TestExpectKnownValue_CheckPlan_MapElements(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ @@ -115,9 +117,7 @@ func TestExpectKnownValue_CheckPlan_MapPartial(t *testing.T) { plancheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("map_attribute"), - knownvalue.MapValuePartialMatch(map[string]knownvalue.Check{ - "key1": knownvalue.StringValueExact("value1"), - }), + knownvalue.MapSizeExact(2), ), }, }, @@ -125,4 +125,4 @@ func TestExpectKnownValue_CheckPlan_MapPartial(t *testing.T) { }, }) } -``` +``` \ No newline at end of file diff --git a/website/docs/plugin/testing/acceptance-tests/known-value-checks/null.mdx b/website/docs/plugin/testing/acceptance-tests/known-value-checks/null.mdx index 9d50ee65e..58d95ce8d 100644 --- a/website/docs/plugin/testing/acceptance-tests/known-value-checks/null.mdx +++ b/website/docs/plugin/testing/acceptance-tests/known-value-checks/null.mdx @@ -8,13 +8,13 @@ description: >- The known value checks that are available for null values are: -* [NullValueExact](/terraform/plugin/testing/acceptance-tests/known-value-checks/null#nullvalueexact-check) +* [NullExact](/terraform/plugin/testing/acceptance-tests/known-value-checks/null#nullexact-check) -## `NullValueExact` Check +## `NullExact` Check -The [NullValueExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#NullValueExact) check tests that a resource attribute, or output value has an exactly matching null value. +The [NullExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#NullExact) check tests that a resource attribute, or output value has an exactly matching null value. -Example usage of [NullValueExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#NullValueExact) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/state-checks/resource) state check. +Example usage of [NullExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#NullExact) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/state-checks/resource) state check. ```go func TestExpectKnownValue_CheckState_AttributeValueNull(t *testing.T) { @@ -29,7 +29,7 @@ func TestExpectKnownValue_CheckState_AttributeValueNull(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("bool_attribute"), - knownvalue.NullValueExact(), + knownvalue.NullExact(), ), }, }, diff --git a/website/docs/plugin/testing/acceptance-tests/known-value-checks/number.mdx b/website/docs/plugin/testing/acceptance-tests/known-value-checks/number.mdx index 784146c06..fe5345727 100644 --- a/website/docs/plugin/testing/acceptance-tests/known-value-checks/number.mdx +++ b/website/docs/plugin/testing/acceptance-tests/known-value-checks/number.mdx @@ -8,13 +8,13 @@ description: >- The known value checks that are available for number values are: -* [NumberValueExact](/terraform/plugin/testing/acceptance-tests/known-value-checks/number#numbervalueexact-check) +* [NumberExact](/terraform/plugin/testing/acceptance-tests/known-value-checks/number#numberexact-check) -## `NumberValueExact` Check +## `NumberExact` Check -The [NumberValueExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#NumberValueExact) check tests that a resource attribute, or output value has an exactly matching number value. +The [NumberExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#NumberExact) check tests that a resource attribute, or output value has an exactly matching number value. -Example usage of [NumberValueExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#NumberValueExact) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/plan-checks/resource) plan check. +Example usage of [NumberExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#NumberExact) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/plan-checks/resource) plan check. ```go func TestExpectKnownValue_CheckPlan_Number(t *testing.T) { @@ -39,7 +39,7 @@ func TestExpectKnownValue_CheckPlan_Number(t *testing.T) { plancheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("number_attribute"), - knownvalue.NumberValueExact(num), + knownvalue.NumberExact(num), ), }, }, diff --git a/website/docs/plugin/testing/acceptance-tests/known-value-checks/object.mdx b/website/docs/plugin/testing/acceptance-tests/known-value-checks/object.mdx index 55e4b923b..86e62a786 100644 --- a/website/docs/plugin/testing/acceptance-tests/known-value-checks/object.mdx +++ b/website/docs/plugin/testing/acceptance-tests/known-value-checks/object.mdx @@ -8,51 +8,14 @@ description: >- The known value checks that are available for object values are: -* [ObjectElementsExact](/terraform/plugin/testing/acceptance-tests/known-value-checks/object#objectelementsexact-check) -* [ObjectValueExact](/terraform/plugin/testing/acceptance-tests/known-value-checks/object#objectvalueexact-check) -* [ObjectValuePartialMatch](/terraform/plugin/testing/acceptance-tests/known-value-checks/object#objectvaluepartialmatch-check) +* [ObjectExact](/terraform/plugin/testing/acceptance-tests/known-value-checks/object#objectexact-check) +* [ObjectPartial](/terraform/plugin/testing/acceptance-tests/known-value-checks/object#objectpartial-check) -## `ObjectElementsExact` Check +## `ObjectExact` Check -The [ObjectElementsExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#ObjectElementsExact) check tests that a resource attribute, or output value contains the specified number of attributes. +The [ObjectExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#ObjectExact) check tests that a resource attribute, or output value has a matching collection of attribute name, and attribute values. -Example usage of [ObjectElementsExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#ObjectElementsExact) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/plan-checks/resource) plan check. - -```go -func TestExpectKnownValue_CheckPlan_ObjectElements(t *testing.T) { - t.Parallel() - - resource.Test(t, resource.TestCase{ - // Provider definition omitted. - Steps: []resource.TestStep{ - { - Config: `resource "test_resource" "one" { - object_attribute = { - key1 = "value1" - key2 = "value2" - } - } - `, - ConfigPlanChecks: resource.ConfigPlanChecks{ - PreApply: []plancheck.PlanCheck{ - plancheck.ExpectKnownValue( - "test_resource.one", - tfjsonpath.New("object_attribute"), - knownvalue.ObjectElementsExact(2), - ), - }, - }, - }, - }, - }) -} -``` - -## `ObjectValueExact` Check - -The [ObjectValueExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#ObjectValueExact) check tests that a resource attribute, or output value has a matching collection of attribute name, and attribute values. - -Example usage of [ObjectValueExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#ObjectValueExact) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/plan-checks/resource) plan check. +Example usage of [ObjectExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#ObjectExact) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/plan-checks/resource) plan check. ```go func TestExpectKnownValue_CheckPlan_Object(t *testing.T) { @@ -74,9 +37,9 @@ func TestExpectKnownValue_CheckPlan_Object(t *testing.T) { plancheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("object_attribute"), - knownvalue.ObjectValueExact(map[string]knownvalue.Check{ - "attr1": knownvalue.StringValueExact("value1"), - "attr2": knownvalue.StringValueExact("value2"), + knownvalue.ObjectExact(map[string]knownvalue.Check{ + "attr1": knownvalue.StringExact("value1"), + "attr2": knownvalue.StringExact("value2"), }), ), }, @@ -87,11 +50,11 @@ func TestExpectKnownValue_CheckPlan_Object(t *testing.T) { } ``` -## `ObjectValuePartialMatch` Check +## `ObjectPartial` Check -The [ObjectValuePartialMatch](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#ObjectValuePartialMatch) check tests that a resource attribute, or output value has matching attribute values for the specified attribute names. +The [ObjectPartial](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#ObjectPartial) check tests that a resource attribute, or output value has matching attribute values for the specified attribute names. -Example usage of [ObjectValuePartialMatch](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#ObjectValuePartialMatch) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/plan-checks/resource) plan check. +Example usage of [ObjectPartial](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#ObjectPartial) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/plan-checks/resource) plan check. In this example, only the attribute value associated with the attribute name `attr1` within the object is checked. @@ -115,8 +78,8 @@ func TestExpectKnownValue_CheckPlan_ObjectPartial(t *testing.T) { plancheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("object_attribute"), - knownvalue.ObjectValuePartialMatch(map[string]knownvalue.Check{ - "attr1": knownvalue.StringValueExact("value1"), + knownvalue.ObjectPartial(map[string]knownvalue.Check{ + "attr1": knownvalue.StringExact("value1"), }), ), }, diff --git a/website/docs/plugin/testing/acceptance-tests/known-value-checks/set.mdx b/website/docs/plugin/testing/acceptance-tests/known-value-checks/set.mdx index 64d646a2b..f4bf5730f 100644 --- a/website/docs/plugin/testing/acceptance-tests/known-value-checks/set.mdx +++ b/website/docs/plugin/testing/acceptance-tests/known-value-checks/set.mdx @@ -8,22 +8,22 @@ description: >- The known value checks that are available for set values are: -* [SetElementsExact](/terraform/plugin/testing/acceptance-tests/known-value-checks/set#setelementsexact-check) -* [SetValueExact](/terraform/plugin/testing/acceptance-tests/known-value-checks/set#setvalueexact-check) -* [SetValuePartialMatch](/terraform/plugin/testing/acceptance-tests/known-value-checks/set#setvaluepartialmatch-check) +* [SetExact](/terraform/plugin/testing/acceptance-tests/known-value-checks/set#setexact-check) +* [SetPartial](/terraform/plugin/testing/acceptance-tests/known-value-checks/set#setpartial-check) +* [SetSizeExact](/terraform/plugin/testing/acceptance-tests/known-value-checks/set#setsizeexact-check) -## `SetElementsExact` Check +## `SetExact` Check -The [SetElementsExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#SetElementsExact) check tests that a resource attribute, or output value contains the specified number of elements. +The [SetExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#SetExact) check tests that a resource attribute, or output value has an order-independent, matching collection of element values. -Example usage of [SetElementsExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#SetElementsExact) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/plan-checks/resource) plan check. +Example usage of [SetExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#SetExact) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/plan-checks/resource) plan check. ```go -func TestExpectKnownValue_CheckPlan_SetElements(t *testing.T) { +func TestExpectKnownValue_CheckPlan_Set(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ - // Provider definition omitted. + // Provider definition omitted. Steps: []resource.TestStep{ { Config: `resource "test_resource" "one" { @@ -38,7 +38,10 @@ func TestExpectKnownValue_CheckPlan_SetElements(t *testing.T) { plancheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("set_attribute"), - knownvalue.SetElementsExact(2), + knownvalue.SetExact([]knownvalue.Check{ + knownvalue.StringExact("value2"), + knownvalue.StringExact("value1"), + }), ), }, }, @@ -48,18 +51,18 @@ func TestExpectKnownValue_CheckPlan_SetElements(t *testing.T) { } ``` -## `SetValueExact` Check +## `SetPartial` Check -The [SetValueExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#SetValueExact) check tests that a resource attribute, or output value has an order-independent, matching collection of element values. +The [SetPartial](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#SetPartial) check tests that a resource attribute, or output value contains matching element values. -Example usage of [SetValueExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#SetValueExact) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/plan-checks/resource) plan check. +Example usage of [SetPartial](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#SetPartial) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/plan-checks/resource) plan check. In this example, only the one element within the set is checked. ```go -func TestExpectKnownValue_CheckPlan_Set(t *testing.T) { +func TestExpectKnownValue_CheckPlan_SetPartial(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ - // Provider definition omitted. + // Provider definition omitted. Steps: []resource.TestStep{ { Config: `resource "test_resource" "one" { @@ -74,9 +77,8 @@ func TestExpectKnownValue_CheckPlan_Set(t *testing.T) { plancheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("set_attribute"), - knownvalue.SetValueExact([]knownvalue.Check{ - knownvalue.StringValueExact("value2"), - knownvalue.StringValueExact("value1"), + knownvalue.SetPartial([]knownvalue.Check{ + knownvalue.StringExact("value2"), }), ), }, @@ -87,14 +89,14 @@ func TestExpectKnownValue_CheckPlan_Set(t *testing.T) { } ``` -## `SetValuePartialMatch` Check +## `SetSizeExact` Check -The [SetValuePartialMatch](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#SetValuePartialMatch) check tests that a resource attribute, or output value contains matching element values. +The [SetSizeExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#SetSizeExact) check tests that a resource attribute, or output value contains the specified number of elements. -Example usage of [SetValuePartialMatch](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#SetValuePartialMatch) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/plan-checks/resource) plan check. In this example, only the one element within the set is checked. +Example usage of [SetSizeExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#SetSizeExact) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/plan-checks/resource) plan check. ```go -func TestExpectKnownValue_CheckPlan_SetPartial(t *testing.T) { +func TestExpectKnownValue_CheckPlan_SetElements(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ @@ -113,9 +115,7 @@ func TestExpectKnownValue_CheckPlan_SetPartial(t *testing.T) { plancheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("set_attribute"), - knownvalue.SetValuePartialMatch([]knownvalue.Check{ - knownvalue.StringValueExact("value2"), - }), + knownvalue.SetSizeExact(2), ), }, }, diff --git a/website/docs/plugin/testing/acceptance-tests/known-value-checks/string.mdx b/website/docs/plugin/testing/acceptance-tests/known-value-checks/string.mdx index 2d771964b..f25a66907 100644 --- a/website/docs/plugin/testing/acceptance-tests/known-value-checks/string.mdx +++ b/website/docs/plugin/testing/acceptance-tests/known-value-checks/string.mdx @@ -8,13 +8,13 @@ description: >- The known value checks that are available for string values are: -* [StringValueExact](/terraform/plugin/testing/acceptance-tests/known-value-checks/string#stringvalueexact-check) +* [StringExact](/terraform/plugin/testing/acceptance-tests/known-value-checks/string#stringexact-check) -## `StringValueExact` Check +## `StringExact` Check -The [StringValueExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#StringValueExact) check tests that a resource attribute, or output value has an exactly matching string value. +The [StringExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#StringExact) check tests that a resource attribute, or output value has an exactly matching string value. -Example usage of [StringValueExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#StringValueExact) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/plan-checks/resource) plan check. +Example usage of [StringExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#StringExact) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/plan-checks/resource) plan check. ```go func TestExpectKnownValue_CheckPlan_String(t *testing.T) { @@ -33,7 +33,7 @@ func TestExpectKnownValue_CheckPlan_String(t *testing.T) { plancheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("string_attribute"), - knownvalue.StringValueExact("str")), + knownvalue.StringExact("str")), }, }, }, diff --git a/website/docs/plugin/testing/acceptance-tests/plan-checks/output.mdx b/website/docs/plugin/testing/acceptance-tests/plan-checks/output.mdx index 146ea2de7..6dd2121cd 100644 --- a/website/docs/plugin/testing/acceptance-tests/plan-checks/output.mdx +++ b/website/docs/plugin/testing/acceptance-tests/plan-checks/output.mdx @@ -44,7 +44,7 @@ func TestExpectKnownOutputValue_CheckPlan_Bool(t *testing.T) { PreApply: []plancheck.PlanCheck{ plancheck.ExpectKnownOutputValue( "bool_output", - knownvalue.BoolValueExact(true), + knownvalue.BoolExact(true), ), }, }, @@ -80,7 +80,7 @@ func TestExpectKnownOutputValue_CheckPlan_Bool(t *testing.T) { PreApply: []plancheck.PlanCheck{ plancheck.ExpectKnownOutputValue( "bool_output", - knownvalue.BoolValueExact(true), + knownvalue.BoolExact(true), ), }, }, diff --git a/website/docs/plugin/testing/acceptance-tests/plan-checks/resource.mdx b/website/docs/plugin/testing/acceptance-tests/plan-checks/resource.mdx index c0f93b6e7..2ef10e073 100644 --- a/website/docs/plugin/testing/acceptance-tests/plan-checks/resource.mdx +++ b/website/docs/plugin/testing/acceptance-tests/plan-checks/resource.mdx @@ -39,7 +39,7 @@ func TestExpectKnownValue_CheckPlan_String(t *testing.T) { plancheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("string_attribute"), - knownvalue.StringValueExact("str")), + knownvalue.StringExact("str")), }, }, }, diff --git a/website/docs/plugin/testing/acceptance-tests/state-checks/custom.mdx b/website/docs/plugin/testing/acceptance-tests/state-checks/custom.mdx index f3b3461b0..817be30fb 100644 --- a/website/docs/plugin/testing/acceptance-tests/state-checks/custom.mdx +++ b/website/docs/plugin/testing/acceptance-tests/state-checks/custom.mdx @@ -109,7 +109,7 @@ func TestExpectKnownValue_CheckState_Bool(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("bool_attribute"), - knownvalue.BoolValueExact(true), + knownvalue.BoolExact(true), ), }, }, diff --git a/website/docs/plugin/testing/acceptance-tests/state-checks/output.mdx b/website/docs/plugin/testing/acceptance-tests/state-checks/output.mdx index 01caccdae..b1e02da1f 100644 --- a/website/docs/plugin/testing/acceptance-tests/state-checks/output.mdx +++ b/website/docs/plugin/testing/acceptance-tests/state-checks/output.mdx @@ -39,7 +39,7 @@ func TestExpectKnownOutputValue_CheckState_Bool(t *testing.T) { ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "bool_output", - knownvalue.BoolValueExact(true), + knownvalue.BoolExact(true), ), }, }, @@ -74,7 +74,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_Bool(t *testing.T) { statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("bool_attribute"), - knownvalue.BoolValueExact(true), + knownvalue.BoolExact(true), ), }, }, diff --git a/website/docs/plugin/testing/acceptance-tests/state-checks/resource.mdx b/website/docs/plugin/testing/acceptance-tests/state-checks/resource.mdx index 990fd828b..582afbcdf 100644 --- a/website/docs/plugin/testing/acceptance-tests/state-checks/resource.mdx +++ b/website/docs/plugin/testing/acceptance-tests/state-checks/resource.mdx @@ -36,7 +36,7 @@ func TestExpectKnownValue_CheckState_Bool(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("bool_attribute"), - knownvalue.BoolValueExact(true), + knownvalue.BoolExact(true), ), }, }, From 5d0485957b026bb9e9adbf514adca914d0520779 Mon Sep 17 00:00:00 2001 From: Benjamin Bennett Date: Mon, 15 Jan 2024 15:35:29 +0000 Subject: [PATCH 13/29] Renaming nul known value check (#266) --- knownvalue/null.go | 18 ++++++++---------- knownvalue/null_test.go | 15 +++++++++------ 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/knownvalue/null.go b/knownvalue/null.go index 93e773cb0..f10c5a3f5 100644 --- a/knownvalue/null.go +++ b/knownvalue/null.go @@ -7,28 +7,26 @@ import ( "fmt" ) -var _ Check = NullValue{} +var _ Check = nullExact{} -// NullValue is a Check for asserting equality between the value supplied -// to NullValueExact and the value passed to the CheckValue method. -type NullValue struct{} +type nullExact struct{} // CheckValue determines whether the passed value is of nil. -func (v NullValue) CheckValue(other any) error { +func (v nullExact) CheckValue(other any) error { if other != nil { - return fmt.Errorf("expected value nil for NullValue check, got: %T", other) + return fmt.Errorf("expected value nil for NullExact check, got: %T", other) } return nil } // String returns the string representation of nil. -func (v NullValue) String() string { +func (v nullExact) String() string { return "nil" } -// NullValueExact returns a Check for asserting equality nil +// NullExact returns a Check for asserting equality nil // and the value passed to the CheckValue method. -func NullValueExact() NullValue { - return NullValue{} +func NullExact() nullExact { + return nullExact{} } diff --git a/knownvalue/null_test.go b/knownvalue/null_test.go index b185ca220..94682ed7b 100644 --- a/knownvalue/null_test.go +++ b/knownvalue/null_test.go @@ -16,21 +16,24 @@ func TestNullValue_CheckValue(t *testing.T) { t.Parallel() testCases := map[string]struct { - self knownvalue.NullValue + self knownvalue.Check other any expectedError error }{ - "zero-nil": {}, + "zero-nil": { + self: knownvalue.NullExact(), + }, "zero-other": { + self: knownvalue.NullExact(), other: nil, // checking against the underlying value field zero-value }, "not-nil": { - self: knownvalue.NullValueExact(), + self: knownvalue.NullExact(), other: false, - expectedError: fmt.Errorf("expected value nil for NullValue check, got: bool"), + expectedError: fmt.Errorf("expected value nil for NullExact check, got: bool"), }, "equal": { - self: knownvalue.NullValueExact(), + self: knownvalue.NullExact(), other: nil, }, } @@ -53,7 +56,7 @@ func TestNullValue_CheckValue(t *testing.T) { func TestNullValue_String(t *testing.T) { t.Parallel() - got := knownvalue.NullValueExact().String() + got := knownvalue.NullExact().String() if diff := cmp.Diff(got, "nil"); diff != "" { t.Errorf("unexpected difference: %s", diff) From a79aea8a152fdebd6d7699d709a073a16413e9ae Mon Sep 17 00:00:00 2001 From: Benjamin Bennett Date: Mon, 15 Jan 2024 15:35:38 +0000 Subject: [PATCH 14/29] Fixing tests (#266) --- .../expect_known_output_value_at_path_test.go | 180 +++++++++--------- statecheck/expect_known_output_value_test.go | 180 +++++++++--------- statecheck/expect_known_value_test.go | 180 +++++++++--------- 3 files changed, 270 insertions(+), 270 deletions(-) diff --git a/statecheck/expect_known_output_value_at_path_test.go b/statecheck/expect_known_output_value_at_path_test.go index 3fcd64637..018deb31b 100644 --- a/statecheck/expect_known_output_value_at_path_test.go +++ b/statecheck/expect_known_output_value_at_path_test.go @@ -43,7 +43,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_ResourceNotFound(t *testing.T) statecheck.ExpectKnownOutputValueAtPath( "test_resource_two_output", tfjsonpath.New("bool_attribute"), - knownvalue.BoolValueExact(true), + knownvalue.BoolExact(true), ), }, ExpectError: regexp.MustCompile("test_resource_two_output - Output not found in state"), @@ -73,7 +73,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_AttributeValueNull(t *testing.T statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("bool_attribute"), - knownvalue.NullValueExact(), + knownvalue.NullExact(), ), }, }, @@ -104,7 +104,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_Bool(t *testing.T) { statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("bool_attribute"), - knownvalue.BoolValueExact(true), + knownvalue.BoolExact(true), ), }, }, @@ -135,10 +135,10 @@ func TestExpectKnownOutputValueAtPath_CheckState_Bool_KnownValueWrongType(t *tes statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("bool_attribute"), - knownvalue.Float64ValueExact(1.23), + knownvalue.Float64Exact(1.23), ), }, - ExpectError: regexp.MustCompile(`expected json\.Number value for Float64ValueExact check, got: bool`), + ExpectError: regexp.MustCompile(`expected json\.Number value for Float64Exact check, got: bool`), }, }, }) @@ -167,10 +167,10 @@ func TestExpectKnownOutputValueAtPath_CheckState_Bool_KnownValueWrongValue(t *te statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("bool_attribute"), - knownvalue.BoolValueExact(false), + knownvalue.BoolExact(false), ), }, - ExpectError: regexp.MustCompile("expected value false for BoolValueExact check, got: true"), + ExpectError: regexp.MustCompile("expected value false for BoolExact check, got: true"), }, }, }) @@ -199,7 +199,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_Float64(t *testing.T) { statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("float_attribute"), - knownvalue.Float64ValueExact(1.23), + knownvalue.Float64Exact(1.23), ), }, }, @@ -231,10 +231,10 @@ func TestExpectKnownOutputValueAtPath_CheckState_Float64_KnownValueWrongType(t * statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("float_attribute"), - knownvalue.StringValueExact("str"), + knownvalue.StringExact("str"), ), }, - ExpectError: regexp.MustCompile(`expected string value for StringValueExact check, got: json\.Number`), + ExpectError: regexp.MustCompile(`expected string value for StringExact check, got: json\.Number`), }, }, }) @@ -263,10 +263,10 @@ func TestExpectKnownOutputValueAtPath_CheckState_Float64_KnownValueWrongValue(t statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("float_attribute"), - knownvalue.Float64ValueExact(3.21), + knownvalue.Float64Exact(3.21), ), }, - ExpectError: regexp.MustCompile("expected value 3.21 for Float64ValueExact check, got: 1.23"), + ExpectError: regexp.MustCompile("expected value 3.21 for Float64Exact check, got: 1.23"), }, }, }) @@ -295,7 +295,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_Int64(t *testing.T) { statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("int_attribute"), - knownvalue.Int64ValueExact(123), + knownvalue.Int64Exact(123), ), }, }, @@ -326,10 +326,10 @@ func TestExpectKnownOutputValueAtPath_CheckState_Int64_KnownValueWrongValue(t *t statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("int_attribute"), - knownvalue.Int64ValueExact(321), + knownvalue.Int64Exact(321), ), }, - ExpectError: regexp.MustCompile("expected value 321 for Int64ValueExact check, got: 123"), + ExpectError: regexp.MustCompile("expected value 321 for Int64Exact check, got: 123"), }, }, }) @@ -361,9 +361,9 @@ func TestExpectKnownOutputValueAtPath_CheckState_List(t *testing.T) { statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("list_attribute"), - knownvalue.ListValueExact([]knownvalue.Check{ - knownvalue.StringValueExact("value1"), - knownvalue.StringValueExact("value2"), + knownvalue.ListExact([]knownvalue.Check{ + knownvalue.StringExact("value1"), + knownvalue.StringExact("value2"), }), ), }, @@ -398,10 +398,10 @@ func TestExpectKnownOutputValueAtPath_CheckState_List_KnownValueWrongType(t *tes statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("list_attribute"), - knownvalue.MapValueExact(map[string]knownvalue.Check{}), + knownvalue.MapExact(map[string]knownvalue.Check{}), ), }, - ExpectError: regexp.MustCompile(`expected map\[string\]any value for MapValueExact check, got: \[\]interface {}`), + ExpectError: regexp.MustCompile(`expected map\[string\]any value for MapExact check, got: \[\]interface {}`), }, }, }) @@ -433,13 +433,13 @@ func TestExpectKnownOutputValueAtPath_CheckState_List_KnownValueWrongValue(t *te statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("list_attribute"), - knownvalue.ListValueExact([]knownvalue.Check{ - knownvalue.StringValueExact("value3"), - knownvalue.StringValueExact("value4"), + knownvalue.ListExact([]knownvalue.Check{ + knownvalue.StringExact("value3"), + knownvalue.StringExact("value4"), }), ), }, - ExpectError: regexp.MustCompile(`list element index 0: expected value value3 for StringValueExact check, got: value1`), + ExpectError: regexp.MustCompile(`list element index 0: expected value value3 for StringExact check, got: value1`), }, }, }) @@ -471,8 +471,8 @@ func TestExpectKnownOutputValueAtPath_CheckState_ListPartial(t *testing.T) { statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("list_attribute"), - knownvalue.ListValuePartial(map[int]knownvalue.Check{ - 0: knownvalue.StringValueExact("value1"), + knownvalue.ListPartial(map[int]knownvalue.Check{ + 0: knownvalue.StringExact("value1"), }), ), }, @@ -509,12 +509,12 @@ func TestExpectKnownOutputValueAtPath_CheckState_ListPartial_KnownValueWrongValu statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("list_attribute"), - knownvalue.ListValuePartial(map[int]knownvalue.Check{ - 0: knownvalue.StringValueExact("value3"), + knownvalue.ListPartial(map[int]knownvalue.Check{ + 0: knownvalue.StringExact("value3"), }), ), }, - ExpectError: regexp.MustCompile(`list element 0: expected value value3 for StringValueExact check, got: value1`), + ExpectError: regexp.MustCompile(`list element 0: expected value value3 for StringExact check, got: value1`), }, }, }) @@ -546,7 +546,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_ListElements(t *testing.T) { statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("list_attribute"), - knownvalue.ListElementsExact(2), + knownvalue.ListSizeExact(2), ), }, }, @@ -580,10 +580,10 @@ func TestExpectKnownOutputValueAtPath_CheckState_ListElements_WrongNum(t *testin statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("list_attribute"), - knownvalue.ListElementsExact(3), + knownvalue.ListSizeExact(3), ), }, - ExpectError: regexp.MustCompile("expected 3 elements for ListElementsExact check, got 2 elements"), + ExpectError: regexp.MustCompile("expected 3 elements for ListSizeExact check, got 2 elements"), }, }, }) @@ -617,12 +617,12 @@ func TestExpectKnownOutputValueAtPath_CheckState_ListNestedBlock(t *testing.T) { statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("list_nested_block"), - knownvalue.ListValueExact([]knownvalue.Check{ - knownvalue.MapValueExact(map[string]knownvalue.Check{ - "list_nested_block_attribute": knownvalue.StringValueExact("str"), + knownvalue.ListExact([]knownvalue.Check{ + knownvalue.MapExact(map[string]knownvalue.Check{ + "list_nested_block_attribute": knownvalue.StringExact("str"), }), - knownvalue.MapValueExact(map[string]knownvalue.Check{ - "list_nested_block_attribute": knownvalue.StringValueExact("rts"), + knownvalue.MapExact(map[string]knownvalue.Check{ + "list_nested_block_attribute": knownvalue.StringExact("rts"), }), }), ), @@ -660,9 +660,9 @@ func TestExpectKnownOutputValueAtPath_CheckState_ListNestedBlockPartial(t *testi statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("list_nested_block"), - knownvalue.ListValuePartial(map[int]knownvalue.Check{ - 1: knownvalue.MapValueExact(map[string]knownvalue.Check{ - "list_nested_block_attribute": knownvalue.StringValueExact("rts"), + knownvalue.ListPartial(map[int]knownvalue.Check{ + 1: knownvalue.MapExact(map[string]knownvalue.Check{ + "list_nested_block_attribute": knownvalue.StringExact("rts"), }), }), ), @@ -700,7 +700,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_ListNestedBlockElements(t *test statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("list_nested_block"), - knownvalue.ListElementsExact(2), + knownvalue.ListSizeExact(2), ), }, }, @@ -734,9 +734,9 @@ func TestExpectKnownOutputValueAtPath_CheckState_Map(t *testing.T) { statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("map_attribute"), - knownvalue.MapValueExact(map[string]knownvalue.Check{ - "key1": knownvalue.StringValueExact("value1"), - "key2": knownvalue.StringValueExact("value2"), + knownvalue.MapExact(map[string]knownvalue.Check{ + "key1": knownvalue.StringExact("value1"), + "key2": knownvalue.StringExact("value2"), }), ), }, @@ -771,10 +771,10 @@ func TestExpectKnownOutputValueAtPath_CheckState_Map_KnownValueWrongType(t *test statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("map_attribute"), - knownvalue.ListValueExact([]knownvalue.Check{}), + knownvalue.ListExact([]knownvalue.Check{}), ), }, - ExpectError: regexp.MustCompile(`expected \[\]any value for ListValueExact check, got: map\[string\]interface {}`), + ExpectError: regexp.MustCompile(`expected \[\]any value for ListExact check, got: map\[string\]interface {}`), }, }, }) @@ -806,13 +806,13 @@ func TestExpectKnownOutputValueAtPath_CheckState_Map_KnownValueWrongValue(t *tes statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("map_attribute"), - knownvalue.MapValueExact(map[string]knownvalue.Check{ - "key3": knownvalue.StringValueExact("value3"), - "key4": knownvalue.StringValueExact("value4"), + knownvalue.MapExact(map[string]knownvalue.Check{ + "key3": knownvalue.StringExact("value3"), + "key4": knownvalue.StringExact("value4"), }), ), }, - ExpectError: regexp.MustCompile(`missing element key3 for MapValueExact check`), + ExpectError: regexp.MustCompile(`missing element key3 for MapExact check`), }, }, }) @@ -844,8 +844,8 @@ func TestExpectKnownOutputValueAtPath_CheckState_MapPartial(t *testing.T) { statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("map_attribute"), - knownvalue.MapValuePartial(map[string]knownvalue.Check{ - "key1": knownvalue.StringValueExact("value1"), + knownvalue.MapPartial(map[string]knownvalue.Check{ + "key1": knownvalue.StringExact("value1"), }), ), }, @@ -880,12 +880,12 @@ func TestExpectKnownOutputValueAtPath_CheckState_MapPartial_KnownValueWrongValue statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("map_attribute"), - knownvalue.MapValuePartial(map[string]knownvalue.Check{ - "key3": knownvalue.StringValueExact("value1"), + knownvalue.MapPartial(map[string]knownvalue.Check{ + "key3": knownvalue.StringExact("value1"), }), ), }, - ExpectError: regexp.MustCompile(`missing element key3 for MapValuePartial check`), + ExpectError: regexp.MustCompile(`missing element key3 for MapPartial check`), }, }, }) @@ -917,7 +917,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_MapElements(t *testing.T) { statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("map_attribute"), - knownvalue.MapElementsExact(2), + knownvalue.MapSizeExact(2), ), }, }, @@ -951,10 +951,10 @@ func TestExpectKnownOutputValueAtPath_CheckState_MapElements_WrongNum(t *testing statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("map_attribute"), - knownvalue.MapElementsExact(3), + knownvalue.MapSizeExact(3), ), }, - ExpectError: regexp.MustCompile("expected 3 elements for MapElementsExact check, got 2 elements"), + ExpectError: regexp.MustCompile("expected 3 elements for MapSizeExact check, got 2 elements"), }, }, }) @@ -989,7 +989,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_Number(t *testing.T) { statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("int_attribute"), - knownvalue.NumberValueExact(f), + knownvalue.NumberExact(f), ), }, }, @@ -1026,10 +1026,10 @@ func TestExpectKnownOutputValueAtPath_CheckState_Number_KnownValueWrongValue(t * statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("int_attribute"), - knownvalue.NumberValueExact(f), + knownvalue.NumberExact(f), ), }, - ExpectError: regexp.MustCompile("expected value 321 for NumberValueExact check, got: 123"), + ExpectError: regexp.MustCompile("expected value 321 for NumberExact check, got: 123"), }, }, }) @@ -1061,9 +1061,9 @@ func TestExpectKnownOutputValueAtPath_CheckState_Set(t *testing.T) { statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("set_attribute"), - knownvalue.SetValueExact([]knownvalue.Check{ - knownvalue.StringValueExact("value1"), - knownvalue.StringValueExact("value2"), + knownvalue.SetExact([]knownvalue.Check{ + knownvalue.StringExact("value1"), + knownvalue.StringExact("value2"), }), ), }, @@ -1098,13 +1098,13 @@ func TestExpectKnownOutputValueAtPath_CheckState_Set_KnownValueWrongValue(t *tes statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("set_attribute"), - knownvalue.SetValueExact([]knownvalue.Check{ - knownvalue.StringValueExact("value1"), - knownvalue.StringValueExact("value3"), + knownvalue.SetExact([]knownvalue.Check{ + knownvalue.StringExact("value1"), + knownvalue.StringExact("value3"), }), ), }, - ExpectError: regexp.MustCompile(`missing value value3 for SetValueExact check`), + ExpectError: regexp.MustCompile(`missing value value3 for SetExact check`), }, }, }) @@ -1136,8 +1136,8 @@ func TestExpectKnownOutputValueAtPath_CheckState_SetPartial(t *testing.T) { statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("set_attribute"), - knownvalue.SetValuePartial([]knownvalue.Check{ - knownvalue.StringValueExact("value2"), + knownvalue.SetPartial([]knownvalue.Check{ + knownvalue.StringExact("value2"), }), ), }, @@ -1172,12 +1172,12 @@ func TestExpectKnownOutputValueAtPath_CheckState_SetPartial_KnownValueWrongValue statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("set_attribute"), - knownvalue.SetValuePartial([]knownvalue.Check{ - knownvalue.StringValueExact("value3"), + knownvalue.SetPartial([]knownvalue.Check{ + knownvalue.StringExact("value3"), }), ), }, - ExpectError: regexp.MustCompile(`missing value value3 for SetValuePartial check`), + ExpectError: regexp.MustCompile(`missing value value3 for SetPartial check`), }, }, }) @@ -1209,7 +1209,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_SetElements(t *testing.T) { statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("set_attribute"), - knownvalue.SetElementsExact(2), + knownvalue.SetSizeExact(2), ), }, }, @@ -1245,12 +1245,12 @@ func TestExpectKnownOutputValueAtPath_CheckState_SetNestedBlock(t *testing.T) { statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("set_nested_block"), - knownvalue.SetValueExact([]knownvalue.Check{ - knownvalue.MapValueExact(map[string]knownvalue.Check{ - "set_nested_block_attribute": knownvalue.StringValueExact("str"), + knownvalue.SetExact([]knownvalue.Check{ + knownvalue.MapExact(map[string]knownvalue.Check{ + "set_nested_block_attribute": knownvalue.StringExact("str"), }), - knownvalue.MapValueExact(map[string]knownvalue.Check{ - "set_nested_block_attribute": knownvalue.StringValueExact("rts"), + knownvalue.MapExact(map[string]knownvalue.Check{ + "set_nested_block_attribute": knownvalue.StringExact("rts"), }), }), ), @@ -1288,9 +1288,9 @@ func TestExpectKnownOutputValueAtPath_CheckState_SetNestedBlockPartial(t *testin statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("set_nested_block"), - knownvalue.SetValuePartial([]knownvalue.Check{ - knownvalue.MapValueExact(map[string]knownvalue.Check{ - "set_nested_block_attribute": knownvalue.StringValueExact("rts"), + knownvalue.SetPartial([]knownvalue.Check{ + knownvalue.MapExact(map[string]knownvalue.Check{ + "set_nested_block_attribute": knownvalue.StringExact("rts"), }), }), ), @@ -1328,7 +1328,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_SetNestedBlockElements(t *testi statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("set_nested_block"), - knownvalue.SetElementsExact(2), + knownvalue.SetSizeExact(2), ), }, }, @@ -1359,7 +1359,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_String(t *testing.T) { statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("string_attribute"), - knownvalue.StringValueExact("str")), + knownvalue.StringExact("str")), }, }, }, @@ -1389,9 +1389,9 @@ func TestExpectKnownOutputValueAtPath_CheckState_String_KnownValueWrongType(t *t statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("string_attribute"), - knownvalue.BoolValueExact(true)), + knownvalue.BoolExact(true)), }, - ExpectError: regexp.MustCompile("expected bool value for BoolValueExact check, got: string"), + ExpectError: regexp.MustCompile("expected bool value for BoolExact check, got: string"), }, }, }) @@ -1420,9 +1420,9 @@ func TestExpectKnownOutputValueAtPath_CheckState_String_KnownValueWrongValue(t * statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("string_attribute"), - knownvalue.StringValueExact("rts")), + knownvalue.StringExact("rts")), }, - ExpectError: regexp.MustCompile("expected value rts for StringValueExact check, got: str"), + ExpectError: regexp.MustCompile("expected value rts for StringExact check, got: str"), }, }, }) @@ -1437,7 +1437,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_UnknownAttributeType(t *testing expectedErr error }{ "unrecognised-type": { - knownValue: knownvalue.Int64ValueExact(123), + knownValue: knownvalue.Int64Exact(123), req: statecheck.CheckStateRequest{ State: &tfjson.State{ Values: &tfjson.StateValues{ @@ -1449,7 +1449,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_UnknownAttributeType(t *testing }, }, }, - expectedErr: fmt.Errorf("expected json.Number value for Int64ValueExact check, got: float32"), + expectedErr: fmt.Errorf("expected json.Number value for Int64Exact check, got: float32"), }, } diff --git a/statecheck/expect_known_output_value_test.go b/statecheck/expect_known_output_value_test.go index e4af792d5..612891f74 100644 --- a/statecheck/expect_known_output_value_test.go +++ b/statecheck/expect_known_output_value_test.go @@ -41,7 +41,7 @@ func TestExpectKnownOutputValue_CheckState_OutputNotFound(t *testing.T) { ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "bool_not_found", - knownvalue.BoolValueExact(true), + knownvalue.BoolExact(true), ), }, ExpectError: regexp.MustCompile("bool_not_found - Output not found in state"), @@ -73,7 +73,7 @@ func TestExpectKnownOutputValue_CheckState_AttributeValueNull(t *testing.T) { ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "bool_output", - knownvalue.BoolValueExact(true), + knownvalue.BoolExact(true), ), }, ExpectError: regexp.MustCompile("bool_output - Output not found in state"), @@ -104,7 +104,7 @@ func TestExpectKnownOutputValue_CheckState_Bool(t *testing.T) { ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "bool_output", - knownvalue.BoolValueExact(true), + knownvalue.BoolExact(true), ), }, }, @@ -134,10 +134,10 @@ func TestExpectKnownOutputValue_CheckState_Bool_KnownValueWrongType(t *testing.T ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "bool_output", - knownvalue.Float64ValueExact(1.23), + knownvalue.Float64Exact(1.23), ), }, - ExpectError: regexp.MustCompile(`expected json\.Number value for Float64ValueExact check, got: bool`), + ExpectError: regexp.MustCompile(`expected json\.Number value for Float64Exact check, got: bool`), }, }, }) @@ -165,10 +165,10 @@ func TestExpectKnownOutputValue_CheckState_Bool_KnownValueWrongValue(t *testing. ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "bool_output", - knownvalue.BoolValueExact(false), + knownvalue.BoolExact(false), ), }, - ExpectError: regexp.MustCompile("expected value false for BoolValueExact check, got: true"), + ExpectError: regexp.MustCompile("expected value false for BoolExact check, got: true"), }, }, }) @@ -196,7 +196,7 @@ func TestExpectKnownOutputValue_CheckState_Float64(t *testing.T) { ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "float64_output", - knownvalue.Float64ValueExact(1.23), + knownvalue.Float64Exact(1.23), ), }, }, @@ -227,10 +227,10 @@ func TestExpectKnownOutputValue_CheckState_Float64_KnownValueWrongType(t *testin ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "float64_output", - knownvalue.StringValueExact("str"), + knownvalue.StringExact("str"), ), }, - ExpectError: regexp.MustCompile(`expected string value for StringValueExact check, got: json\.Number`), + ExpectError: regexp.MustCompile(`expected string value for StringExact check, got: json\.Number`), }, }, }) @@ -258,10 +258,10 @@ func TestExpectKnownOutputValue_CheckState_Float64_KnownValueWrongValue(t *testi ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "float64_output", - knownvalue.Float64ValueExact(3.21), + knownvalue.Float64Exact(3.21), ), }, - ExpectError: regexp.MustCompile("expected value 3.21 for Float64ValueExact check, got: 1.23"), + ExpectError: regexp.MustCompile("expected value 3.21 for Float64Exact check, got: 1.23"), }, }, }) @@ -289,7 +289,7 @@ func TestExpectKnownOutputValue_CheckState_Int64(t *testing.T) { ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "int64_output", - knownvalue.Int64ValueExact(123), + knownvalue.Int64Exact(123), ), }, }, @@ -319,10 +319,10 @@ func TestExpectKnownOutputValue_CheckState_Int64_KnownValueWrongValue(t *testing ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "int64_output", - knownvalue.Int64ValueExact(321), + knownvalue.Int64Exact(321), ), }, - ExpectError: regexp.MustCompile("expected value 321 for Int64ValueExact check, got: 123"), + ExpectError: regexp.MustCompile("expected value 321 for Int64Exact check, got: 123"), }, }, }) @@ -353,9 +353,9 @@ func TestExpectKnownOutputValue_CheckState_List(t *testing.T) { ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "list_output", - knownvalue.ListValueExact([]knownvalue.Check{ - knownvalue.StringValueExact("value1"), - knownvalue.StringValueExact("value2"), + knownvalue.ListExact([]knownvalue.Check{ + knownvalue.StringExact("value1"), + knownvalue.StringExact("value2"), }), ), }, @@ -389,10 +389,10 @@ func TestExpectKnownOutputValue_CheckState_List_KnownValueWrongType(t *testing.T ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "list_output", - knownvalue.MapValueExact(map[string]knownvalue.Check{}), + knownvalue.MapExact(map[string]knownvalue.Check{}), ), }, - ExpectError: regexp.MustCompile(`expected map\[string\]any value for MapValueExact check, got: \[\]interface {}`), + ExpectError: regexp.MustCompile(`expected map\[string\]any value for MapExact check, got: \[\]interface {}`), }, }, }) @@ -423,13 +423,13 @@ func TestExpectKnownOutputValue_CheckState_List_KnownValueWrongValue(t *testing. ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "list_output", - knownvalue.ListValueExact([]knownvalue.Check{ - knownvalue.StringValueExact("value3"), - knownvalue.StringValueExact("value4"), + knownvalue.ListExact([]knownvalue.Check{ + knownvalue.StringExact("value3"), + knownvalue.StringExact("value4"), }), ), }, - ExpectError: regexp.MustCompile(`list element index 0: expected value value3 for StringValueExact check, got: value1`), + ExpectError: regexp.MustCompile(`list element index 0: expected value value3 for StringExact check, got: value1`), }, }, }) @@ -460,8 +460,8 @@ func TestExpectKnownOutputValue_CheckState_ListPartial(t *testing.T) { ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "list_output", - knownvalue.ListValuePartial(map[int]knownvalue.Check{ - 0: knownvalue.StringValueExact("value1"), + knownvalue.ListPartial(map[int]knownvalue.Check{ + 0: knownvalue.StringExact("value1"), }), ), }, @@ -497,12 +497,12 @@ func TestExpectKnownOutputValue_CheckState_ListPartial_KnownValueWrongValue(t *t ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "list_output", - knownvalue.ListValuePartial(map[int]knownvalue.Check{ - 0: knownvalue.StringValueExact("value3"), + knownvalue.ListPartial(map[int]knownvalue.Check{ + 0: knownvalue.StringExact("value3"), }), ), }, - ExpectError: regexp.MustCompile(`list element 0: expected value value3 for StringValueExact check, got: value1`), + ExpectError: regexp.MustCompile(`list element 0: expected value value3 for StringExact check, got: value1`), }, }, }) @@ -533,7 +533,7 @@ func TestExpectKnownOutputValue_CheckState_ListElements(t *testing.T) { ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "list_output", - knownvalue.ListElementsExact(2), + knownvalue.ListSizeExact(2), ), }, }, @@ -566,10 +566,10 @@ func TestExpectKnownOutputValue_CheckState_ListElements_WrongNum(t *testing.T) { ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "list_output", - knownvalue.ListElementsExact(3), + knownvalue.ListSizeExact(3), ), }, - ExpectError: regexp.MustCompile("expected 3 elements for ListElementsExact check, got 2 elements"), + ExpectError: regexp.MustCompile("expected 3 elements for ListSizeExact check, got 2 elements"), }, }, }) @@ -602,12 +602,12 @@ func TestExpectKnownOutputValue_CheckState_ListNestedBlock(t *testing.T) { ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "list_nested_block_output", - knownvalue.ListValueExact([]knownvalue.Check{ - knownvalue.MapValueExact(map[string]knownvalue.Check{ - "list_nested_block_attribute": knownvalue.StringValueExact("str"), + knownvalue.ListExact([]knownvalue.Check{ + knownvalue.MapExact(map[string]knownvalue.Check{ + "list_nested_block_attribute": knownvalue.StringExact("str"), }), - knownvalue.MapValueExact(map[string]knownvalue.Check{ - "list_nested_block_attribute": knownvalue.StringValueExact("rts"), + knownvalue.MapExact(map[string]knownvalue.Check{ + "list_nested_block_attribute": knownvalue.StringExact("rts"), }), }), ), @@ -644,9 +644,9 @@ func TestExpectKnownOutputValue_CheckState_ListNestedBlockPartial(t *testing.T) ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "list_nested_block_output", - knownvalue.ListValuePartial(map[int]knownvalue.Check{ - 1: knownvalue.MapValueExact(map[string]knownvalue.Check{ - "list_nested_block_attribute": knownvalue.StringValueExact("rts"), + knownvalue.ListPartial(map[int]knownvalue.Check{ + 1: knownvalue.MapExact(map[string]knownvalue.Check{ + "list_nested_block_attribute": knownvalue.StringExact("rts"), }), }), ), @@ -683,7 +683,7 @@ func TestExpectKnownOutputValue_CheckState_ListNestedBlockElements(t *testing.T) ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "list_nested_block_output", - knownvalue.ListElementsExact(2), + knownvalue.ListSizeExact(2), ), }, }, @@ -716,9 +716,9 @@ func TestExpectKnownOutputValue_CheckState_Map(t *testing.T) { ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "map_output", - knownvalue.MapValueExact(map[string]knownvalue.Check{ - "key1": knownvalue.StringValueExact("value1"), - "key2": knownvalue.StringValueExact("value2"), + knownvalue.MapExact(map[string]knownvalue.Check{ + "key1": knownvalue.StringExact("value1"), + "key2": knownvalue.StringExact("value2"), }), ), }, @@ -752,10 +752,10 @@ func TestExpectKnownOutputValue_CheckState_Map_KnownValueWrongType(t *testing.T) ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "map_output", - knownvalue.ListValueExact([]knownvalue.Check{}), + knownvalue.ListExact([]knownvalue.Check{}), ), }, - ExpectError: regexp.MustCompile(`expected \[\]any value for ListValueExact check, got: map\[string\]interface {}`), + ExpectError: regexp.MustCompile(`expected \[\]any value for ListExact check, got: map\[string\]interface {}`), }, }, }) @@ -786,13 +786,13 @@ func TestExpectKnownOutputValue_CheckState_Map_KnownValueWrongValue(t *testing.T ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "map_output", - knownvalue.MapValueExact(map[string]knownvalue.Check{ - "key3": knownvalue.StringValueExact("value3"), - "key4": knownvalue.StringValueExact("value4"), + knownvalue.MapExact(map[string]knownvalue.Check{ + "key3": knownvalue.StringExact("value3"), + "key4": knownvalue.StringExact("value4"), }), ), }, - ExpectError: regexp.MustCompile(`missing element key3 for MapValueExact check`), + ExpectError: regexp.MustCompile(`missing element key3 for MapExact check`), }, }, }) @@ -823,8 +823,8 @@ func TestExpectKnownOutputValue_CheckState_MapPartial(t *testing.T) { ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "map_output", - knownvalue.MapValuePartial(map[string]knownvalue.Check{ - "key1": knownvalue.StringValueExact("value1"), + knownvalue.MapPartial(map[string]knownvalue.Check{ + "key1": knownvalue.StringExact("value1"), }), ), }, @@ -858,12 +858,12 @@ func TestExpectKnownOutputValue_CheckState_MapPartial_KnownValueWrongValue(t *te ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "map_output", - knownvalue.MapValuePartial(map[string]knownvalue.Check{ - "key3": knownvalue.StringValueExact("value1"), + knownvalue.MapPartial(map[string]knownvalue.Check{ + "key3": knownvalue.StringExact("value1"), }), ), }, - ExpectError: regexp.MustCompile(`missing element key3 for MapValuePartial check`), + ExpectError: regexp.MustCompile(`missing element key3 for MapPartial check`), }, }, }) @@ -894,7 +894,7 @@ func TestExpectKnownOutputValue_CheckState_MapElements(t *testing.T) { ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "map_output", - knownvalue.MapElementsExact(2), + knownvalue.MapSizeExact(2), ), }, }, @@ -927,10 +927,10 @@ func TestExpectKnownOutputValue_CheckState_MapElements_WrongNum(t *testing.T) { ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "map_output", - knownvalue.MapElementsExact(3), + knownvalue.MapSizeExact(3), ), }, - ExpectError: regexp.MustCompile("expected 3 elements for MapElementsExact check, got 2 elements"), + ExpectError: regexp.MustCompile("expected 3 elements for MapSizeExact check, got 2 elements"), }, }, }) @@ -964,7 +964,7 @@ func TestExpectKnownOutputValue_CheckState_Number(t *testing.T) { ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "int64_output", - knownvalue.NumberValueExact(f), + knownvalue.NumberExact(f), ), }, }, @@ -1000,10 +1000,10 @@ func TestExpectKnownOutputValue_CheckState_Number_KnownValueWrongValue(t *testin ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "int64_output", - knownvalue.NumberValueExact(f), + knownvalue.NumberExact(f), ), }, - ExpectError: regexp.MustCompile("expected value 321 for NumberValueExact check, got: 123"), + ExpectError: regexp.MustCompile("expected value 321 for NumberExact check, got: 123"), }, }, }) @@ -1034,9 +1034,9 @@ func TestExpectKnownOutputValue_CheckState_Set(t *testing.T) { ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "set_output", - knownvalue.SetValueExact([]knownvalue.Check{ - knownvalue.StringValueExact("value1"), - knownvalue.StringValueExact("value2"), + knownvalue.SetExact([]knownvalue.Check{ + knownvalue.StringExact("value1"), + knownvalue.StringExact("value2"), }), ), }, @@ -1070,13 +1070,13 @@ func TestExpectKnownOutputValue_CheckState_Set_KnownValueWrongValue(t *testing.T ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "set_output", - knownvalue.SetValueExact([]knownvalue.Check{ - knownvalue.StringValueExact("value1"), - knownvalue.StringValueExact("value3"), + knownvalue.SetExact([]knownvalue.Check{ + knownvalue.StringExact("value1"), + knownvalue.StringExact("value3"), }), ), }, - ExpectError: regexp.MustCompile(`missing value value3 for SetValueExact check`), + ExpectError: regexp.MustCompile(`missing value value3 for SetExact check`), }, }, }) @@ -1107,8 +1107,8 @@ func TestExpectKnownOutputValue_CheckState_SetPartial(t *testing.T) { ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "set_output", - knownvalue.SetValuePartial([]knownvalue.Check{ - knownvalue.StringValueExact("value2"), + knownvalue.SetPartial([]knownvalue.Check{ + knownvalue.StringExact("value2"), }), ), }, @@ -1142,12 +1142,12 @@ func TestExpectKnownOutputValue_CheckState_SetPartial_KnownValueWrongValue(t *te ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "set_output", - knownvalue.SetValuePartial([]knownvalue.Check{ - knownvalue.StringValueExact("value3"), + knownvalue.SetPartial([]knownvalue.Check{ + knownvalue.StringExact("value3"), }), ), }, - ExpectError: regexp.MustCompile(`missing value value3 for SetValuePartial check`), + ExpectError: regexp.MustCompile(`missing value value3 for SetPartial check`), }, }, }) @@ -1178,7 +1178,7 @@ func TestExpectKnownOutputValue_CheckState_SetElements(t *testing.T) { ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "set_output", - knownvalue.SetElementsExact(2), + knownvalue.SetSizeExact(2), ), }, }, @@ -1213,12 +1213,12 @@ func TestExpectKnownOutputValue_CheckState_SetNestedBlock(t *testing.T) { ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "set_nested_block_output", - knownvalue.SetValueExact([]knownvalue.Check{ - knownvalue.MapValueExact(map[string]knownvalue.Check{ - "set_nested_block_attribute": knownvalue.StringValueExact("str"), + knownvalue.SetExact([]knownvalue.Check{ + knownvalue.MapExact(map[string]knownvalue.Check{ + "set_nested_block_attribute": knownvalue.StringExact("str"), }), - knownvalue.MapValueExact(map[string]knownvalue.Check{ - "set_nested_block_attribute": knownvalue.StringValueExact("rts"), + knownvalue.MapExact(map[string]knownvalue.Check{ + "set_nested_block_attribute": knownvalue.StringExact("rts"), }), }), ), @@ -1255,9 +1255,9 @@ func TestExpectKnownOutputValue_CheckState_SetNestedBlockPartial(t *testing.T) { ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "set_nested_block_output", - knownvalue.SetValuePartial([]knownvalue.Check{ - knownvalue.MapValueExact(map[string]knownvalue.Check{ - "set_nested_block_attribute": knownvalue.StringValueExact("rts"), + knownvalue.SetPartial([]knownvalue.Check{ + knownvalue.MapExact(map[string]knownvalue.Check{ + "set_nested_block_attribute": knownvalue.StringExact("rts"), }), }), ), @@ -1294,7 +1294,7 @@ func TestExpectKnownOutputValue_CheckState_SetNestedBlockElements(t *testing.T) ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "set_nested_block_output", - knownvalue.SetElementsExact(2), + knownvalue.SetSizeExact(2), ), }, }, @@ -1324,7 +1324,7 @@ func TestExpectKnownOutputValue_CheckState_String(t *testing.T) { ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "string_output", - knownvalue.StringValueExact("str")), + knownvalue.StringExact("str")), }, }, }, @@ -1353,9 +1353,9 @@ func TestExpectKnownOutputValue_CheckState_String_KnownValueWrongType(t *testing ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "string_output", - knownvalue.BoolValueExact(true)), + knownvalue.BoolExact(true)), }, - ExpectError: regexp.MustCompile("expected bool value for BoolValueExact check, got: string"), + ExpectError: regexp.MustCompile("expected bool value for BoolExact check, got: string"), }, }, }) @@ -1383,9 +1383,9 @@ func TestExpectKnownOutputValue_CheckState_String_KnownValueWrongValue(t *testin ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "string_output", - knownvalue.StringValueExact("rts")), + knownvalue.StringExact("rts")), }, - ExpectError: regexp.MustCompile("expected value rts for StringValueExact check, got: str"), + ExpectError: regexp.MustCompile("expected value rts for StringExact check, got: str"), }, }, }) @@ -1400,7 +1400,7 @@ func TestExpectKnownOutputValue_CheckState_UnknownAttributeType(t *testing.T) { expectedErr error }{ "unrecognised-type": { - knownValue: knownvalue.Int64ValueExact(123), + knownValue: knownvalue.Int64Exact(123), req: statecheck.CheckStateRequest{ State: &tfjson.State{ Values: &tfjson.StateValues{ @@ -1412,7 +1412,7 @@ func TestExpectKnownOutputValue_CheckState_UnknownAttributeType(t *testing.T) { }, }, }, - expectedErr: fmt.Errorf("expected json.Number value for Int64ValueExact check, got: float32"), + expectedErr: fmt.Errorf("expected json.Number value for Int64Exact check, got: float32"), }, } diff --git a/statecheck/expect_known_value_test.go b/statecheck/expect_known_value_test.go index c95086d4b..e275212de 100644 --- a/statecheck/expect_known_value_test.go +++ b/statecheck/expect_known_value_test.go @@ -40,7 +40,7 @@ func TestExpectKnownValue_CheckState_ResourceNotFound(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.two", tfjsonpath.New("bool_attribute"), - knownvalue.BoolValueExact(true), + knownvalue.BoolExact(true), ), }, ExpectError: regexp.MustCompile("test_resource.two - Resource not found in state"), @@ -65,7 +65,7 @@ func TestExpectKnownValue_CheckState_AttributeValueNull(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("bool_attribute"), - knownvalue.NullValueExact(), + knownvalue.NullExact(), ), }, }, @@ -92,7 +92,7 @@ func TestExpectKnownValue_CheckState_Bool(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("bool_attribute"), - knownvalue.BoolValueExact(true), + knownvalue.BoolExact(true), ), }, }, @@ -119,10 +119,10 @@ func TestExpectKnownValue_CheckState_Bool_KnownValueWrongType(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("bool_attribute"), - knownvalue.Float64ValueExact(1.23), + knownvalue.Float64Exact(1.23), ), }, - ExpectError: regexp.MustCompile(`expected json\.Number value for Float64ValueExact check, got: bool`), + ExpectError: regexp.MustCompile(`expected json\.Number value for Float64Exact check, got: bool`), }, }, }) @@ -147,10 +147,10 @@ func TestExpectKnownValue_CheckState_Bool_KnownValueWrongValue(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("bool_attribute"), - knownvalue.BoolValueExact(false), + knownvalue.BoolExact(false), ), }, - ExpectError: regexp.MustCompile("expected value false for BoolValueExact check, got: true"), + ExpectError: regexp.MustCompile("expected value false for BoolExact check, got: true"), }, }, }) @@ -175,7 +175,7 @@ func TestExpectKnownValue_CheckState_Float64(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("float_attribute"), - knownvalue.Float64ValueExact(1.23), + knownvalue.Float64Exact(1.23), ), }, }, @@ -203,10 +203,10 @@ func TestExpectKnownValue_CheckState_Float64_KnownValueWrongType(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("float_attribute"), - knownvalue.StringValueExact("str"), + knownvalue.StringExact("str"), ), }, - ExpectError: regexp.MustCompile(`expected string value for StringValueExact check, got: json\.Number`), + ExpectError: regexp.MustCompile(`expected string value for StringExact check, got: json\.Number`), }, }, }) @@ -231,10 +231,10 @@ func TestExpectKnownValue_CheckState_Float64_KnownValueWrongValue(t *testing.T) statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("float_attribute"), - knownvalue.Float64ValueExact(3.21), + knownvalue.Float64Exact(3.21), ), }, - ExpectError: regexp.MustCompile("expected value 3.21 for Float64ValueExact check, got: 1.23"), + ExpectError: regexp.MustCompile("expected value 3.21 for Float64Exact check, got: 1.23"), }, }, }) @@ -259,7 +259,7 @@ func TestExpectKnownValue_CheckState_Int64(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("int_attribute"), - knownvalue.Int64ValueExact(123), + knownvalue.Int64Exact(123), ), }, }, @@ -286,10 +286,10 @@ func TestExpectKnownValue_CheckState_Int64_KnownValueWrongValue(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("int_attribute"), - knownvalue.Int64ValueExact(321), + knownvalue.Int64Exact(321), ), }, - ExpectError: regexp.MustCompile("expected value 321 for Int64ValueExact check, got: 123"), + ExpectError: regexp.MustCompile("expected value 321 for Int64Exact check, got: 123"), }, }, }) @@ -317,9 +317,9 @@ func TestExpectKnownValue_CheckState_List(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("list_attribute"), - knownvalue.ListValueExact([]knownvalue.Check{ - knownvalue.StringValueExact("value1"), - knownvalue.StringValueExact("value2"), + knownvalue.ListExact([]knownvalue.Check{ + knownvalue.StringExact("value1"), + knownvalue.StringExact("value2"), }), ), }, @@ -350,10 +350,10 @@ func TestExpectKnownValue_CheckState_List_KnownValueWrongType(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("list_attribute"), - knownvalue.MapValueExact(map[string]knownvalue.Check{}), + knownvalue.MapExact(map[string]knownvalue.Check{}), ), }, - ExpectError: regexp.MustCompile(`expected map\[string\]any value for MapValueExact check, got: \[\]interface {}`), + ExpectError: regexp.MustCompile(`expected map\[string\]any value for MapExact check, got: \[\]interface {}`), }, }, }) @@ -381,13 +381,13 @@ func TestExpectKnownValue_CheckState_List_KnownValueWrongValue(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("list_attribute"), - knownvalue.ListValueExact([]knownvalue.Check{ - knownvalue.StringValueExact("value3"), - knownvalue.StringValueExact("value4"), + knownvalue.ListExact([]knownvalue.Check{ + knownvalue.StringExact("value3"), + knownvalue.StringExact("value4"), }), ), }, - ExpectError: regexp.MustCompile(`list element index 0: expected value value3 for StringValueExact check, got: value1`), + ExpectError: regexp.MustCompile(`list element index 0: expected value value3 for StringExact check, got: value1`), }, }, }) @@ -415,8 +415,8 @@ func TestExpectKnownValue_CheckState_ListPartial(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("list_attribute"), - knownvalue.ListValuePartial(map[int]knownvalue.Check{ - 0: knownvalue.StringValueExact("value1"), + knownvalue.ListPartial(map[int]knownvalue.Check{ + 0: knownvalue.StringExact("value1"), }), ), }, @@ -449,12 +449,12 @@ func TestExpectKnownValue_CheckState_ListPartial_KnownValueWrongValue(t *testing statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("list_attribute"), - knownvalue.ListValuePartial(map[int]knownvalue.Check{ - 0: knownvalue.StringValueExact("value3"), + knownvalue.ListPartial(map[int]knownvalue.Check{ + 0: knownvalue.StringExact("value3"), }), ), }, - ExpectError: regexp.MustCompile(`list element 0: expected value value3 for StringValueExact check, got: value1`), + ExpectError: regexp.MustCompile(`list element 0: expected value value3 for StringExact check, got: value1`), }, }, }) @@ -482,7 +482,7 @@ func TestExpectKnownValue_CheckState_ListElements(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("list_attribute"), - knownvalue.ListElementsExact(2), + knownvalue.ListSizeExact(2), ), }, }, @@ -512,10 +512,10 @@ func TestExpectKnownValue_CheckState_ListElements_WrongNum(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("list_attribute"), - knownvalue.ListElementsExact(3), + knownvalue.ListSizeExact(3), ), }, - ExpectError: regexp.MustCompile("expected 3 elements for ListElementsExact check, got 2 elements"), + ExpectError: regexp.MustCompile("expected 3 elements for ListSizeExact check, got 2 elements"), }, }, }) @@ -545,12 +545,12 @@ func TestExpectKnownValue_CheckState_ListNestedBlock(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("list_nested_block"), - knownvalue.ListValueExact([]knownvalue.Check{ - knownvalue.MapValueExact(map[string]knownvalue.Check{ - "list_nested_block_attribute": knownvalue.StringValueExact("str"), + knownvalue.ListExact([]knownvalue.Check{ + knownvalue.MapExact(map[string]knownvalue.Check{ + "list_nested_block_attribute": knownvalue.StringExact("str"), }), - knownvalue.MapValueExact(map[string]knownvalue.Check{ - "list_nested_block_attribute": knownvalue.StringValueExact("rts"), + knownvalue.MapExact(map[string]knownvalue.Check{ + "list_nested_block_attribute": knownvalue.StringExact("rts"), }), }), ), @@ -584,9 +584,9 @@ func TestExpectKnownValue_CheckState_ListNestedBlockPartial(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("list_nested_block"), - knownvalue.ListValuePartial(map[int]knownvalue.Check{ - 1: knownvalue.MapValueExact(map[string]knownvalue.Check{ - "list_nested_block_attribute": knownvalue.StringValueExact("rts"), + knownvalue.ListPartial(map[int]knownvalue.Check{ + 1: knownvalue.MapExact(map[string]knownvalue.Check{ + "list_nested_block_attribute": knownvalue.StringExact("rts"), }), }), ), @@ -620,7 +620,7 @@ func TestExpectKnownValue_CheckState_ListNestedBlockElements(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("list_nested_block"), - knownvalue.ListElementsExact(2), + knownvalue.ListSizeExact(2), ), }, }, @@ -650,9 +650,9 @@ func TestExpectKnownValue_CheckState_Map(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("map_attribute"), - knownvalue.MapValueExact(map[string]knownvalue.Check{ - "key1": knownvalue.StringValueExact("value1"), - "key2": knownvalue.StringValueExact("value2"), + knownvalue.MapExact(map[string]knownvalue.Check{ + "key1": knownvalue.StringExact("value1"), + "key2": knownvalue.StringExact("value2"), }), ), }, @@ -683,10 +683,10 @@ func TestExpectKnownValue_CheckState_Map_KnownValueWrongType(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("map_attribute"), - knownvalue.ListValueExact([]knownvalue.Check{}), + knownvalue.ListExact([]knownvalue.Check{}), ), }, - ExpectError: regexp.MustCompile(`expected \[\]any value for ListValueExact check, got: map\[string\]interface {}`), + ExpectError: regexp.MustCompile(`expected \[\]any value for ListExact check, got: map\[string\]interface {}`), }, }, }) @@ -714,13 +714,13 @@ func TestExpectKnownValue_CheckState_Map_KnownValueWrongValue(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("map_attribute"), - knownvalue.MapValueExact(map[string]knownvalue.Check{ - "key3": knownvalue.StringValueExact("value3"), - "key4": knownvalue.StringValueExact("value4"), + knownvalue.MapExact(map[string]knownvalue.Check{ + "key3": knownvalue.StringExact("value3"), + "key4": knownvalue.StringExact("value4"), }), ), }, - ExpectError: regexp.MustCompile(`missing element key3 for MapValueExact check`), + ExpectError: regexp.MustCompile(`missing element key3 for MapExact check`), }, }, }) @@ -748,8 +748,8 @@ func TestExpectKnownValue_CheckState_MapPartial(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("map_attribute"), - knownvalue.MapValuePartial(map[string]knownvalue.Check{ - "key1": knownvalue.StringValueExact("value1"), + knownvalue.MapPartial(map[string]knownvalue.Check{ + "key1": knownvalue.StringExact("value1"), }), ), }, @@ -780,12 +780,12 @@ func TestExpectKnownValue_CheckState_MapPartial_KnownValueWrongValue(t *testing. statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("map_attribute"), - knownvalue.MapValuePartial(map[string]knownvalue.Check{ - "key3": knownvalue.StringValueExact("value1"), + knownvalue.MapPartial(map[string]knownvalue.Check{ + "key3": knownvalue.StringExact("value1"), }), ), }, - ExpectError: regexp.MustCompile(`missing element key3 for MapValuePartial check`), + ExpectError: regexp.MustCompile(`missing element key3 for MapPartial check`), }, }, }) @@ -813,7 +813,7 @@ func TestExpectKnownValue_CheckState_MapElements(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("map_attribute"), - knownvalue.MapElementsExact(2), + knownvalue.MapSizeExact(2), ), }, }, @@ -843,10 +843,10 @@ func TestExpectKnownValue_CheckState_MapElements_WrongNum(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("map_attribute"), - knownvalue.MapElementsExact(3), + knownvalue.MapSizeExact(3), ), }, - ExpectError: regexp.MustCompile("expected 3 elements for MapElementsExact check, got 2 elements"), + ExpectError: regexp.MustCompile("expected 3 elements for MapSizeExact check, got 2 elements"), }, }, }) @@ -877,7 +877,7 @@ func TestExpectKnownValue_CheckState_Number(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("int_attribute"), - knownvalue.NumberValueExact(f), + knownvalue.NumberExact(f), ), }, }, @@ -910,10 +910,10 @@ func TestExpectKnownValue_CheckState_Number_KnownValueWrongValue(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("int_attribute"), - knownvalue.NumberValueExact(f), + knownvalue.NumberExact(f), ), }, - ExpectError: regexp.MustCompile("expected value 321 for NumberValueExact check, got: 123"), + ExpectError: regexp.MustCompile("expected value 321 for NumberExact check, got: 123"), }, }, }) @@ -941,9 +941,9 @@ func TestExpectKnownValue_CheckState_Set(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("set_attribute"), - knownvalue.SetValueExact([]knownvalue.Check{ - knownvalue.StringValueExact("value2"), - knownvalue.StringValueExact("value1"), + knownvalue.SetExact([]knownvalue.Check{ + knownvalue.StringExact("value2"), + knownvalue.StringExact("value1"), }), ), }, @@ -974,13 +974,13 @@ func TestExpectKnownValue_CheckState_Set_KnownValueWrongValue(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("set_attribute"), - knownvalue.SetValueExact([]knownvalue.Check{ - knownvalue.StringValueExact("value1"), - knownvalue.StringValueExact("value3"), + knownvalue.SetExact([]knownvalue.Check{ + knownvalue.StringExact("value1"), + knownvalue.StringExact("value3"), }), ), }, - ExpectError: regexp.MustCompile(`missing value value3 for SetValueExact check`), + ExpectError: regexp.MustCompile(`missing value value3 for SetExact check`), }, }, }) @@ -1008,8 +1008,8 @@ func TestExpectKnownValue_CheckState_SetPartial(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("set_attribute"), - knownvalue.SetValuePartial([]knownvalue.Check{ - knownvalue.StringValueExact("value2"), + knownvalue.SetPartial([]knownvalue.Check{ + knownvalue.StringExact("value2"), }), ), }, @@ -1040,12 +1040,12 @@ func TestExpectKnownValue_CheckState_SetPartial_KnownValueWrongValue(t *testing. statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("set_attribute"), - knownvalue.SetValuePartial([]knownvalue.Check{ - knownvalue.StringValueExact("value3"), + knownvalue.SetPartial([]knownvalue.Check{ + knownvalue.StringExact("value3"), }), ), }, - ExpectError: regexp.MustCompile(`missing value value3 for SetValuePartial check`), + ExpectError: regexp.MustCompile(`missing value value3 for SetPartial check`), }, }, }) @@ -1073,7 +1073,7 @@ func TestExpectKnownValue_CheckState_SetElements(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("set_attribute"), - knownvalue.SetElementsExact(2), + knownvalue.SetSizeExact(2), ), }, }, @@ -1105,12 +1105,12 @@ func TestExpectKnownValue_CheckState_SetNestedBlock(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("set_nested_block"), - knownvalue.SetValueExact([]knownvalue.Check{ - knownvalue.MapValueExact(map[string]knownvalue.Check{ - "set_nested_block_attribute": knownvalue.StringValueExact("str"), + knownvalue.SetExact([]knownvalue.Check{ + knownvalue.MapExact(map[string]knownvalue.Check{ + "set_nested_block_attribute": knownvalue.StringExact("str"), }), - knownvalue.MapValueExact(map[string]knownvalue.Check{ - "set_nested_block_attribute": knownvalue.StringValueExact("rts"), + knownvalue.MapExact(map[string]knownvalue.Check{ + "set_nested_block_attribute": knownvalue.StringExact("rts"), }), }), ), @@ -1144,9 +1144,9 @@ func TestExpectKnownValue_CheckState_SetNestedBlockPartial(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("set_nested_block"), - knownvalue.SetValuePartial([]knownvalue.Check{ - knownvalue.MapValueExact(map[string]knownvalue.Check{ - "set_nested_block_attribute": knownvalue.StringValueExact("rts"), + knownvalue.SetPartial([]knownvalue.Check{ + knownvalue.MapExact(map[string]knownvalue.Check{ + "set_nested_block_attribute": knownvalue.StringExact("rts"), }), }), ), @@ -1180,7 +1180,7 @@ func TestExpectKnownValue_CheckState_SetNestedBlockElements(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("set_nested_block"), - knownvalue.SetElementsExact(2), + knownvalue.SetSizeExact(2), ), }, }, @@ -1207,7 +1207,7 @@ func TestExpectKnownValue_CheckState_String(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("string_attribute"), - knownvalue.StringValueExact("str")), + knownvalue.StringExact("str")), }, }, }, @@ -1233,9 +1233,9 @@ func TestExpectKnownValue_CheckState_String_KnownValueWrongType(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("string_attribute"), - knownvalue.BoolValueExact(true)), + knownvalue.BoolExact(true)), }, - ExpectError: regexp.MustCompile("expected bool value for BoolValueExact check, got: string"), + ExpectError: regexp.MustCompile("expected bool value for BoolExact check, got: string"), }, }, }) @@ -1260,9 +1260,9 @@ func TestExpectKnownValue_CheckState_String_KnownValueWrongValue(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("string_attribute"), - knownvalue.StringValueExact("rts")), + knownvalue.StringExact("rts")), }, - ExpectError: regexp.MustCompile("expected value rts for StringValueExact check, got: str"), + ExpectError: regexp.MustCompile("expected value rts for StringExact check, got: str"), }, }, }) @@ -1277,7 +1277,7 @@ func TestExpectKnownValue_CheckState_UnknownAttributeType(t *testing.T) { expectedErr error }{ "unrecognised-type": { - knownValue: knownvalue.Int64ValueExact(123), + knownValue: knownvalue.Int64Exact(123), req: statecheck.CheckStateRequest{ State: &tfjson.State{ Values: &tfjson.StateValues{ @@ -1294,7 +1294,7 @@ func TestExpectKnownValue_CheckState_UnknownAttributeType(t *testing.T) { }, }, }, - expectedErr: fmt.Errorf("expected json.Number value for Int64ValueExact check, got: float32"), + expectedErr: fmt.Errorf("expected json.Number value for Int64Exact check, got: float32"), }, } From f5abf73ec56fbc0f3609758d77985a5d054065a4 Mon Sep 17 00:00:00 2001 From: Benjamin Bennett Date: Mon, 15 Jan 2024 16:33:28 +0000 Subject: [PATCH 15/29] Adding address and path to state check errors (#266) --- statecheck/expect_known_output_value.go | 2 +- statecheck/expect_known_output_value_at_path.go | 2 +- statecheck/expect_known_output_value_at_path_test.go | 10 ++++++---- statecheck/expect_known_output_value_test.go | 2 +- statecheck/expect_known_value.go | 2 +- statecheck/expect_known_value_test.go | 2 +- 6 files changed, 11 insertions(+), 9 deletions(-) diff --git a/statecheck/expect_known_output_value.go b/statecheck/expect_known_output_value.go index 1cf6b69e8..64c47f819 100644 --- a/statecheck/expect_known_output_value.go +++ b/statecheck/expect_known_output_value.go @@ -56,7 +56,7 @@ func (e expectKnownOutputValue) CheckState(ctx context.Context, req CheckStateRe } if err := e.knownValue.CheckValue(result); err != nil { - resp.Error = err + resp.Error = fmt.Errorf("error checking value for output at path: %s, err: %s", e.outputAddress, err) return } diff --git a/statecheck/expect_known_output_value_at_path.go b/statecheck/expect_known_output_value_at_path.go index 7ff704b06..9fb8cc4f1 100644 --- a/statecheck/expect_known_output_value_at_path.go +++ b/statecheck/expect_known_output_value_at_path.go @@ -57,7 +57,7 @@ func (e expectKnownOutputValueAtPath) CheckState(ctx context.Context, req CheckS } if err := e.knownValue.CheckValue(result); err != nil { - resp.Error = err + resp.Error = fmt.Errorf("error checking value for output at path: %s.%s, err: %s", e.outputAddress, e.outputPath.String(), err) return } diff --git a/statecheck/expect_known_output_value_at_path_test.go b/statecheck/expect_known_output_value_at_path_test.go index 018deb31b..078daee04 100644 --- a/statecheck/expect_known_output_value_at_path_test.go +++ b/statecheck/expect_known_output_value_at_path_test.go @@ -1442,14 +1442,16 @@ func TestExpectKnownOutputValueAtPath_CheckState_UnknownAttributeType(t *testing State: &tfjson.State{ Values: &tfjson.StateValues{ Outputs: map[string]*tfjson.StateOutput{ - "float32_output": { - Value: float32(123), + "obj": { + Value: map[string]any{ + "float32_output": float32(123), + }, }, }, }, }, }, - expectedErr: fmt.Errorf("expected json.Number value for Int64Exact check, got: float32"), + expectedErr: fmt.Errorf("error checking value for output at path: obj.float32_output, err: expected json.Number value for Int64Exact check, got: float32"), }, } @@ -1459,7 +1461,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_UnknownAttributeType(t *testing t.Run(name, func(t *testing.T) { t.Parallel() - e := statecheck.ExpectKnownOutputValueAtPath("float32_output", tfjsonpath.Path{}, testCase.knownValue) + e := statecheck.ExpectKnownOutputValueAtPath("obj", tfjsonpath.New("float32_output"), testCase.knownValue) resp := statecheck.CheckStateResponse{} diff --git a/statecheck/expect_known_output_value_test.go b/statecheck/expect_known_output_value_test.go index 612891f74..b3f5e2ccf 100644 --- a/statecheck/expect_known_output_value_test.go +++ b/statecheck/expect_known_output_value_test.go @@ -1412,7 +1412,7 @@ func TestExpectKnownOutputValue_CheckState_UnknownAttributeType(t *testing.T) { }, }, }, - expectedErr: fmt.Errorf("expected json.Number value for Int64Exact check, got: float32"), + expectedErr: fmt.Errorf("error checking value for output at path: float32_output, err: expected json.Number value for Int64Exact check, got: float32"), }, } diff --git a/statecheck/expect_known_value.go b/statecheck/expect_known_value.go index 096699cba..96662c32a 100644 --- a/statecheck/expect_known_value.go +++ b/statecheck/expect_known_value.go @@ -61,7 +61,7 @@ func (e expectKnownValue) CheckState(ctx context.Context, req CheckStateRequest, } if err := e.knownValue.CheckValue(result); err != nil { - resp.Error = err + resp.Error = fmt.Errorf("error checking value for attribute at path: %s.%s, err: %s", e.resourceAddress, e.attributePath.String(), err) } } diff --git a/statecheck/expect_known_value_test.go b/statecheck/expect_known_value_test.go index e275212de..9625ec089 100644 --- a/statecheck/expect_known_value_test.go +++ b/statecheck/expect_known_value_test.go @@ -1294,7 +1294,7 @@ func TestExpectKnownValue_CheckState_UnknownAttributeType(t *testing.T) { }, }, }, - expectedErr: fmt.Errorf("expected json.Number value for Int64Exact check, got: float32"), + expectedErr: fmt.Errorf("error checking value for attribute at path: example_resource.test.attribute, err: expected json.Number value for Int64Exact check, got: float32"), }, } From 648730a4ea8474f51528fb1e8e90c58f0af7413c Mon Sep 17 00:00:00 2001 From: Benjamin Bennett Date: Tue, 16 Jan 2024 08:58:36 +0000 Subject: [PATCH 16/29] Fixing navigation (#266) --- website/data/plugin-testing-nav-data.json | 4 ---- .../known-value-checks/bool.mdx | 3 +-- .../known-value-checks/custom.mdx | 18 +++++++++--------- .../known-value-checks/float64.mdx | 3 +-- .../known-value-checks/int64.mdx | 3 +-- .../known-value-checks/list.mdx | 11 ++++------- .../known-value-checks/map.mdx | 9 +++------ .../known-value-checks/number.mdx | 3 +-- .../known-value-checks/object.mdx | 6 ++---- .../known-value-checks/set.mdx | 11 ++++------- .../known-value-checks/string.mdx | 3 +-- 11 files changed, 27 insertions(+), 47 deletions(-) diff --git a/website/data/plugin-testing-nav-data.json b/website/data/plugin-testing-nav-data.json index dce49a74f..f7ae6d8b5 100644 --- a/website/data/plugin-testing-nav-data.json +++ b/website/data/plugin-testing-nav-data.json @@ -110,10 +110,6 @@ "title": "Number", "path": "acceptance-tests/known-value-checks/number" }, - { - "title": "Null ", - "path": "acceptance-tests/known-value-checks/null" - }, { "title": "Object", "path": "acceptance-tests/known-value-checks/object" diff --git a/website/docs/plugin/testing/acceptance-tests/known-value-checks/bool.mdx b/website/docs/plugin/testing/acceptance-tests/known-value-checks/bool.mdx index 1a5c09a53..dfcb6e06b 100644 --- a/website/docs/plugin/testing/acceptance-tests/known-value-checks/bool.mdx +++ b/website/docs/plugin/testing/acceptance-tests/known-value-checks/bool.mdx @@ -26,8 +26,7 @@ func TestExpectKnownValue_CheckPlan_Bool(t *testing.T) { { Config: `resource "test_resource" "one" { bool_attribute = true - } - `, + }`, ConfigPlanChecks: resource.ConfigPlanChecks{ PreApply: []plancheck.PlanCheck{ plancheck.ExpectKnownValue( diff --git a/website/docs/plugin/testing/acceptance-tests/known-value-checks/custom.mdx b/website/docs/plugin/testing/acceptance-tests/known-value-checks/custom.mdx index b9f69de1e..f5ce1d1de 100644 --- a/website/docs/plugin/testing/acceptance-tests/known-value-checks/custom.mdx +++ b/website/docs/plugin/testing/acceptance-tests/known-value-checks/custom.mdx @@ -62,12 +62,12 @@ The `other` parameter passed to the `CheckValue` method is one of the following Refer to the following built-in known value checks for implementations that handle the different types that can be passed to the `CheckValue` method in the `other` parameter: -* [BoolValueExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#BoolValueExact) -* [Float64ValueExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#Float64ValueExact) -* [Int64ValueExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#Int64ValueExact) -* [ListValueExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#ListValueExact) -* [MapValueExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#MapValueExact) -* [NumberValueExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#NumberValueExact) -* [ObjectValueExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#ObjectValueExact) -* [SetValueExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#SetValueExact) -* [StringValueExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#StringValueExact) +* [BoolExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#BoolExact) +* [Float64Exact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#Float64Exact) +* [Int64Exact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#Int64Exact) +* [ListExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#ListExact) +* [MapExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#MapExact) +* [NumberExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#NumberExact) +* [ObjectExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#ObjectExact) +* [SetExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#SetExact) +* [StringExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#StringExact) diff --git a/website/docs/plugin/testing/acceptance-tests/known-value-checks/float64.mdx b/website/docs/plugin/testing/acceptance-tests/known-value-checks/float64.mdx index ebaa17d39..7a22133ef 100644 --- a/website/docs/plugin/testing/acceptance-tests/known-value-checks/float64.mdx +++ b/website/docs/plugin/testing/acceptance-tests/known-value-checks/float64.mdx @@ -26,8 +26,7 @@ func TestExpectKnownValue_CheckPlan_Float64(t *testing.T) { { Config: `resource "test_resource" "one" { float_attribute = 1.23 - } - `, + }`, ConfigPlanChecks: resource.ConfigPlanChecks{ PreApply: []plancheck.PlanCheck{ plancheck.ExpectKnownValue( diff --git a/website/docs/plugin/testing/acceptance-tests/known-value-checks/int64.mdx b/website/docs/plugin/testing/acceptance-tests/known-value-checks/int64.mdx index 214fcef25..ab3b61829 100644 --- a/website/docs/plugin/testing/acceptance-tests/known-value-checks/int64.mdx +++ b/website/docs/plugin/testing/acceptance-tests/known-value-checks/int64.mdx @@ -26,8 +26,7 @@ func TestExpectKnownValue_CheckPlan_Int64(t *testing.T) { { Config: `resource "test_resource" "one" { int_attribute = 123 - } - `, + }`, ConfigPlanChecks: resource.ConfigPlanChecks{ PreApply: []plancheck.PlanCheck{ plancheck.ExpectKnownValue( diff --git a/website/docs/plugin/testing/acceptance-tests/known-value-checks/list.mdx b/website/docs/plugin/testing/acceptance-tests/known-value-checks/list.mdx index e491e58b6..fad959b43 100644 --- a/website/docs/plugin/testing/acceptance-tests/known-value-checks/list.mdx +++ b/website/docs/plugin/testing/acceptance-tests/known-value-checks/list.mdx @@ -23,7 +23,7 @@ func TestExpectKnownValue_CheckPlan_List(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ - // Provider definition omitted. + // Provider definition omitted. Steps: []resource.TestStep{ { Config: `resource "test_resource" "one" { @@ -31,8 +31,7 @@ func TestExpectKnownValue_CheckPlan_List(t *testing.T) { "value1", "value2" ] - } - `, + }`, ConfigPlanChecks: resource.ConfigPlanChecks{ PreApply: []plancheck.PlanCheck{ plancheck.ExpectKnownValue( @@ -70,8 +69,7 @@ func TestExpectKnownValue_CheckPlan_ListPartial(t *testing.T) { "value1", "value2" ] - } - `, + }`, ConfigPlanChecks: resource.ConfigPlanChecks{ PreApply: []plancheck.PlanCheck{ plancheck.ExpectKnownValue( @@ -108,8 +106,7 @@ func TestExpectKnownValue_CheckPlan_ListElements(t *testing.T) { "value1", "value2" ] - } - `, + }`, ConfigPlanChecks: resource.ConfigPlanChecks{ PreApply: []plancheck.PlanCheck{ plancheck.ExpectKnownValue( diff --git a/website/docs/plugin/testing/acceptance-tests/known-value-checks/map.mdx b/website/docs/plugin/testing/acceptance-tests/known-value-checks/map.mdx index fc04c2f80..482686753 100644 --- a/website/docs/plugin/testing/acceptance-tests/known-value-checks/map.mdx +++ b/website/docs/plugin/testing/acceptance-tests/known-value-checks/map.mdx @@ -31,8 +31,7 @@ func TestExpectKnownValue_CheckPlan_Map(t *testing.T) { key1 = "value1" key2 = "value2" } - } - `, + }`, ConfigPlanChecks: resource.ConfigPlanChecks{ PreApply: []plancheck.PlanCheck{ plancheck.ExpectKnownValue( @@ -72,8 +71,7 @@ func TestExpectKnownValue_CheckPlan_MapPartial(t *testing.T) { key1 = "value1" key2 = "value2" } - } - `, + }`, ConfigPlanChecks: resource.ConfigPlanChecks{ PreApply: []plancheck.PlanCheck{ plancheck.ExpectKnownValue( @@ -110,8 +108,7 @@ func TestExpectKnownValue_CheckPlan_MapElements(t *testing.T) { key1 = "value1" key2 = "value2" } - } - `, + }`, ConfigPlanChecks: resource.ConfigPlanChecks{ PreApply: []plancheck.PlanCheck{ plancheck.ExpectKnownValue( diff --git a/website/docs/plugin/testing/acceptance-tests/known-value-checks/number.mdx b/website/docs/plugin/testing/acceptance-tests/known-value-checks/number.mdx index fe5345727..6aee9e7cc 100644 --- a/website/docs/plugin/testing/acceptance-tests/known-value-checks/number.mdx +++ b/website/docs/plugin/testing/acceptance-tests/known-value-checks/number.mdx @@ -32,8 +32,7 @@ func TestExpectKnownValue_CheckPlan_Number(t *testing.T) { { Config: `resource "test_resource" "one" { number_attribute = 123 - } - `, + }`, ConfigPlanChecks: resource.ConfigPlanChecks{ PreApply: []plancheck.PlanCheck{ plancheck.ExpectKnownValue( diff --git a/website/docs/plugin/testing/acceptance-tests/known-value-checks/object.mdx b/website/docs/plugin/testing/acceptance-tests/known-value-checks/object.mdx index 86e62a786..0d7229aed 100644 --- a/website/docs/plugin/testing/acceptance-tests/known-value-checks/object.mdx +++ b/website/docs/plugin/testing/acceptance-tests/known-value-checks/object.mdx @@ -30,8 +30,7 @@ func TestExpectKnownValue_CheckPlan_Object(t *testing.T) { attr1 = "value1" attr2 = "value2" } - } - `, + }`, ConfigPlanChecks: resource.ConfigPlanChecks{ PreApply: []plancheck.PlanCheck{ plancheck.ExpectKnownValue( @@ -71,8 +70,7 @@ func TestExpectKnownValue_CheckPlan_ObjectPartial(t *testing.T) { attr1 = "value1" attr2 = "value2" } - } - `, + }`, ConfigPlanChecks: resource.ConfigPlanChecks{ PreApply: []plancheck.PlanCheck{ plancheck.ExpectKnownValue( diff --git a/website/docs/plugin/testing/acceptance-tests/known-value-checks/set.mdx b/website/docs/plugin/testing/acceptance-tests/known-value-checks/set.mdx index f4bf5730f..23acb33a6 100644 --- a/website/docs/plugin/testing/acceptance-tests/known-value-checks/set.mdx +++ b/website/docs/plugin/testing/acceptance-tests/known-value-checks/set.mdx @@ -23,7 +23,7 @@ func TestExpectKnownValue_CheckPlan_Set(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ - // Provider definition omitted. + // Provider definition omitted. Steps: []resource.TestStep{ { Config: `resource "test_resource" "one" { @@ -31,8 +31,7 @@ func TestExpectKnownValue_CheckPlan_Set(t *testing.T) { "value1", "value2" ] - } - `, + }`, ConfigPlanChecks: resource.ConfigPlanChecks{ PreApply: []plancheck.PlanCheck{ plancheck.ExpectKnownValue( @@ -70,8 +69,7 @@ func TestExpectKnownValue_CheckPlan_SetPartial(t *testing.T) { "value1", "value2" ] - } - `, + }`, ConfigPlanChecks: resource.ConfigPlanChecks{ PreApply: []plancheck.PlanCheck{ plancheck.ExpectKnownValue( @@ -108,8 +106,7 @@ func TestExpectKnownValue_CheckPlan_SetElements(t *testing.T) { "value1", "value2" ] - } - `, + }`, ConfigPlanChecks: resource.ConfigPlanChecks{ PreApply: []plancheck.PlanCheck{ plancheck.ExpectKnownValue( diff --git a/website/docs/plugin/testing/acceptance-tests/known-value-checks/string.mdx b/website/docs/plugin/testing/acceptance-tests/known-value-checks/string.mdx index f25a66907..bbe2fd80c 100644 --- a/website/docs/plugin/testing/acceptance-tests/known-value-checks/string.mdx +++ b/website/docs/plugin/testing/acceptance-tests/known-value-checks/string.mdx @@ -26,8 +26,7 @@ func TestExpectKnownValue_CheckPlan_String(t *testing.T) { { Config: `resource "test_resource" "one" { string_attribute = "str" - } - `, + }`, ConfigPlanChecks: resource.ConfigPlanChecks{ PreApply: []plancheck.PlanCheck{ plancheck.ExpectKnownValue( From c74a9e8bb48edca9e89047b7bde02eb49d0aa520 Mon Sep 17 00:00:00 2001 From: Benjamin Bennett Date: Wed, 17 Jan 2024 17:07:15 +0000 Subject: [PATCH 17/29] Fixing changelog entries --- .changes/unreleased/FEATURES-20240111-142126.yaml | 2 +- .changes/unreleased/FEATURES-20240111-142223.yaml | 2 +- .changes/unreleased/FEATURES-20240111-142314.yaml | 2 +- .changes/unreleased/FEATURES-20240111-142353.yaml | 2 +- .changes/unreleased/FEATURES-20240111-142544.yaml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.changes/unreleased/FEATURES-20240111-142126.yaml b/.changes/unreleased/FEATURES-20240111-142126.yaml index 99c271b7c..b89fcbddc 100644 --- a/.changes/unreleased/FEATURES-20240111-142126.yaml +++ b/.changes/unreleased/FEATURES-20240111-142126.yaml @@ -3,4 +3,4 @@ body: 'statecheck: Introduced new `statecheck` package with interface and built- state check functionality' time: 2024-01-11T14:21:26.261094Z custom: - Issue: "273" + Issue: "275" diff --git a/.changes/unreleased/FEATURES-20240111-142223.yaml b/.changes/unreleased/FEATURES-20240111-142223.yaml index ca6a2a386..049bb81f9 100644 --- a/.changes/unreleased/FEATURES-20240111-142223.yaml +++ b/.changes/unreleased/FEATURES-20240111-142223.yaml @@ -3,4 +3,4 @@ body: 'statecheck: Added `ExpectKnownValue` state check, which asserts that a gi resource attribute has a defined type, and value' time: 2024-01-11T14:22:23.072321Z custom: - Issue: "273" + Issue: "275" diff --git a/.changes/unreleased/FEATURES-20240111-142314.yaml b/.changes/unreleased/FEATURES-20240111-142314.yaml index 3d683c564..3b602ef44 100644 --- a/.changes/unreleased/FEATURES-20240111-142314.yaml +++ b/.changes/unreleased/FEATURES-20240111-142314.yaml @@ -3,4 +3,4 @@ body: 'statecheck: Added `ExpectKnownOutputValue` state check, which asserts tha a given output value has a defined type, and value' time: 2024-01-11T14:23:14.025585Z custom: - Issue: "273" + Issue: "275" diff --git a/.changes/unreleased/FEATURES-20240111-142353.yaml b/.changes/unreleased/FEATURES-20240111-142353.yaml index eaa67ae05..2db803bd6 100644 --- a/.changes/unreleased/FEATURES-20240111-142353.yaml +++ b/.changes/unreleased/FEATURES-20240111-142353.yaml @@ -3,4 +3,4 @@ body: 'statecheck: Added `ExpectKnownOutputValueAtPath` plan check, which assert that a given output value at a specified path has a defined type, and value' time: 2024-01-11T14:23:53.633255Z custom: - Issue: "273" + Issue: "275" diff --git a/.changes/unreleased/FEATURES-20240111-142544.yaml b/.changes/unreleased/FEATURES-20240111-142544.yaml index 42bf8aa03..c8a02b9fd 100644 --- a/.changes/unreleased/FEATURES-20240111-142544.yaml +++ b/.changes/unreleased/FEATURES-20240111-142544.yaml @@ -3,4 +3,4 @@ body: 'statecheck: Added `ExpectSensitiveValue` built-in state check, which asse that a given attribute has a sensitive value' time: 2024-01-11T14:25:44.598583Z custom: - Issue: "273" + Issue: "275" From 178c2c47c2bf6d1c0fc14767c286cc4086e74081 Mon Sep 17 00:00:00 2001 From: Benjamin Bennett Date: Thu, 18 Jan 2024 11:30:21 +0000 Subject: [PATCH 18/29] Modifying ExpectKnown to handle null checking (#266) --- plancheck/expect_known_output_value.go | 30 +++++-------------- .../expect_known_output_value_at_path.go | 30 +++++-------------- .../expect_known_output_value_at_path_test.go | 7 ++--- plancheck/expect_known_output_value_test.go | 7 ++--- plancheck/expect_known_value.go | 30 +++++-------------- plancheck/expect_known_value_test.go | 7 ++--- 6 files changed, 30 insertions(+), 81 deletions(-) diff --git a/plancheck/expect_known_output_value.go b/plancheck/expect_known_output_value.go index 33a27e2f5..bc954c8ed 100644 --- a/plancheck/expect_known_output_value.go +++ b/plancheck/expect_known_output_value.go @@ -6,7 +6,6 @@ package plancheck import ( "context" "fmt" - "reflect" tfjson "github.com/hashicorp/terraform-json" @@ -26,6 +25,10 @@ type expectKnownOutputValue struct { func (e expectKnownOutputValue) CheckPlan(ctx context.Context, req CheckPlanRequest, resp *CheckPlanResponse) { var change *tfjson.Change + if req.Plan == nil { + resp.Error = fmt.Errorf("plan is nil") + } + for address, oc := range req.Plan.OutputChanges { if e.outputAddress == address { change = oc @@ -35,7 +38,7 @@ func (e expectKnownOutputValue) CheckPlan(ctx context.Context, req CheckPlanRequ } if change == nil { - resp.Error = fmt.Errorf("%s - Output not found in plan OutputChanges", e.outputAddress) + resp.Error = fmt.Errorf("%s - Output not found in plan", e.outputAddress) return } @@ -48,27 +51,8 @@ func (e expectKnownOutputValue) CheckPlan(ctx context.Context, req CheckPlanRequ return } - if result == nil { - resp.Error = fmt.Errorf("value is null for output at path: %s", e.outputAddress) - - return - } - - switch reflect.TypeOf(result).Kind() { - case reflect.Bool, - reflect.Map, - reflect.Slice, - reflect.String: - if err := e.knownValue.CheckValue(result); err != nil { - resp.Error = fmt.Errorf("error checking value for output at path: %s, err: %s", e.outputAddress, err) - - return - } - default: - errorStr := fmt.Sprintf("unrecognised output type: %T, known value type is %T", result, e.knownValue) - errorStr += "\n\nThis is an error in plancheck.ExpectKnownOutputValue.\nPlease report this to the maintainers." - - resp.Error = fmt.Errorf(errorStr) + if err := e.knownValue.CheckValue(result); err != nil { + resp.Error = fmt.Errorf("error checking value for output at path: %s, err: %s", e.outputAddress, err) return } diff --git a/plancheck/expect_known_output_value_at_path.go b/plancheck/expect_known_output_value_at_path.go index 056b7c2f7..ffb8ee334 100644 --- a/plancheck/expect_known_output_value_at_path.go +++ b/plancheck/expect_known_output_value_at_path.go @@ -6,7 +6,6 @@ package plancheck import ( "context" "fmt" - "reflect" tfjson "github.com/hashicorp/terraform-json" @@ -27,6 +26,10 @@ type expectKnownOutputValueAtPath struct { func (e expectKnownOutputValueAtPath) CheckPlan(ctx context.Context, req CheckPlanRequest, resp *CheckPlanResponse) { var change *tfjson.Change + if req.Plan == nil { + resp.Error = fmt.Errorf("plan is nil") + } + for address, oc := range req.Plan.OutputChanges { if e.outputAddress == address { change = oc @@ -36,7 +39,7 @@ func (e expectKnownOutputValueAtPath) CheckPlan(ctx context.Context, req CheckPl } if change == nil { - resp.Error = fmt.Errorf("%s - Output not found in plan OutputChanges", e.outputAddress) + resp.Error = fmt.Errorf("%s - Output not found in plan", e.outputAddress) return } @@ -49,27 +52,8 @@ func (e expectKnownOutputValueAtPath) CheckPlan(ctx context.Context, req CheckPl return } - if result == nil { - resp.Error = fmt.Errorf("value is null for output at path: %s.%s", e.outputAddress, e.outputPath.String()) - - return - } - - switch reflect.TypeOf(result).Kind() { - case reflect.Bool, - reflect.Map, - reflect.Slice, - reflect.String: - if err := e.knownValue.CheckValue(result); err != nil { - resp.Error = fmt.Errorf("error checking value for output at path: %s.%s, err: %s", e.outputAddress, e.outputPath.String(), err) - - return - } - default: - errorStr := fmt.Sprintf("unrecognised output type: %T, known value type is %T", result, e.knownValue) - errorStr += "\n\nThis is an error in plancheck.ExpectKnownOutputValueAtPath.\nPlease report this to the maintainers." - - resp.Error = fmt.Errorf(errorStr) + if err := e.knownValue.CheckValue(result); err != nil { + resp.Error = fmt.Errorf("error checking value for output at path: %s.%s, err: %s", e.outputAddress, e.outputPath.String(), err) return } diff --git a/plancheck/expect_known_output_value_at_path_test.go b/plancheck/expect_known_output_value_at_path_test.go index 564e9c39e..82505f87c 100644 --- a/plancheck/expect_known_output_value_at_path_test.go +++ b/plancheck/expect_known_output_value_at_path_test.go @@ -56,7 +56,7 @@ func TestExpectKnownOutputValueAtPath_CheckPlan_ResourceNotFound(t *testing.T) { ), }, }, - ExpectError: regexp.MustCompile("test_resource_two_output - Output not found in plan OutputChanges"), + ExpectError: regexp.MustCompile("test_resource_two_output - Output not found in plan"), }, }, }) @@ -91,11 +91,10 @@ func TestExpectKnownOutputValueAtPath_CheckPlan_AttributeValueNull(t *testing.T) plancheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("bool_attribute"), - knownvalue.BoolExact(true), + knownvalue.NullExact(), ), }, }, - ExpectError: regexp.MustCompile("value is null for output at path: test_resource_one_output.bool_attribute"), }, }, }) @@ -1809,7 +1808,7 @@ func TestExpectKnownOutputValueAtPath_CheckPlan_UnknownAttributeType(t *testing. }, }, }, - expectedErr: fmt.Errorf("unrecognised output type: float32, known value type is knownvalue.int64Exact\n\nThis is an error in plancheck.ExpectKnownOutputValueAtPath.\nPlease report this to the maintainers."), + expectedErr: fmt.Errorf("error checking value for output at path: float32_output., err: expected json.Number value for Int64Exact check, got: float32"), }, } diff --git a/plancheck/expect_known_output_value_test.go b/plancheck/expect_known_output_value_test.go index bc296a74a..626ecaab2 100644 --- a/plancheck/expect_known_output_value_test.go +++ b/plancheck/expect_known_output_value_test.go @@ -46,7 +46,7 @@ func TestExpectKnownOutputValue_CheckPlan_OutputNotFound(t *testing.T) { ), }, }, - ExpectError: regexp.MustCompile("bool_not_found - Output not found in plan OutputChanges"), + ExpectError: regexp.MustCompile("bool_not_found - Output not found in plan"), }, }, }) @@ -72,11 +72,10 @@ func TestExpectKnownOutputValue_CheckPlan_AttributeValueNull(t *testing.T) { PreApply: []plancheck.PlanCheck{ plancheck.ExpectKnownOutputValue( "bool_output", - knownvalue.BoolExact(true), + knownvalue.NullExact(), ), }, }, - ExpectError: regexp.MustCompile("value is null for output at path: bool_output"), }, }, }) @@ -1486,7 +1485,7 @@ func TestExpectKnownOutputValue_CheckPlan_UnknownAttributeType(t *testing.T) { }, }, }, - expectedErr: fmt.Errorf("unrecognised output type: float32, known value type is knownvalue.int64Exact\n\nThis is an error in plancheck.ExpectKnownOutputValue.\nPlease report this to the maintainers."), + expectedErr: fmt.Errorf("error checking value for output at path: float32_output, err: expected json.Number value for Int64Exact check, got: float32"), }, } diff --git a/plancheck/expect_known_value.go b/plancheck/expect_known_value.go index 1118b9a61..ae6ea6d8d 100644 --- a/plancheck/expect_known_value.go +++ b/plancheck/expect_known_value.go @@ -6,7 +6,6 @@ package plancheck import ( "context" "fmt" - "reflect" tfjson "github.com/hashicorp/terraform-json" @@ -27,6 +26,10 @@ type expectKnownValue struct { func (e expectKnownValue) CheckPlan(ctx context.Context, req CheckPlanRequest, resp *CheckPlanResponse) { var rc *tfjson.ResourceChange + if req.Plan == nil { + resp.Error = fmt.Errorf("plan is nil") + } + for _, resourceChange := range req.Plan.ResourceChanges { if e.resourceAddress == resourceChange.Address { rc = resourceChange @@ -36,7 +39,7 @@ func (e expectKnownValue) CheckPlan(ctx context.Context, req CheckPlanRequest, r } if rc == nil { - resp.Error = fmt.Errorf("%s - Resource not found in plan ResourceChanges", e.resourceAddress) + resp.Error = fmt.Errorf("%s - Resource not found in plan", e.resourceAddress) return } @@ -49,27 +52,8 @@ func (e expectKnownValue) CheckPlan(ctx context.Context, req CheckPlanRequest, r return } - if result == nil { - resp.Error = fmt.Errorf("value is null for attribute at path: %s.%s", e.resourceAddress, e.attributePath.String()) - - return - } - - switch reflect.TypeOf(result).Kind() { - case reflect.Bool, - reflect.Map, - reflect.Slice, - reflect.String: - if err := e.knownValue.CheckValue(result); err != nil { - resp.Error = fmt.Errorf("error checking value for attribute at path: %s.%s, err: %s", e.resourceAddress, e.attributePath.String(), err) - - return - } - default: - errorStr := fmt.Sprintf("unrecognised attribute type: %T, known value type is %T", result, e.knownValue) - errorStr += "\n\nThis is an error in plancheck.ExpectKnownValue.\nPlease report this to the maintainers." - - resp.Error = fmt.Errorf(errorStr) + if err := e.knownValue.CheckValue(result); err != nil { + resp.Error = fmt.Errorf("error checking value for attribute at path: %s.%s, err: %s", e.resourceAddress, e.attributePath.String(), err) return } diff --git a/plancheck/expect_known_value_test.go b/plancheck/expect_known_value_test.go index dc061572e..af1618076 100644 --- a/plancheck/expect_known_value_test.go +++ b/plancheck/expect_known_value_test.go @@ -44,7 +44,7 @@ func TestExpectKnownValue_CheckPlan_ResourceNotFound(t *testing.T) { ), }, }, - ExpectError: regexp.MustCompile("test_resource.two - Resource not found in plan ResourceChanges"), + ExpectError: regexp.MustCompile("test_resource.two - Resource not found in plan"), }, }, }) @@ -67,11 +67,10 @@ func TestExpectKnownValue_CheckPlan_AttributeValueNull(t *testing.T) { plancheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("bool_attribute"), - knownvalue.BoolExact(true), + knownvalue.NullExact(), ), }, }, - ExpectError: regexp.MustCompile("value is null for attribute at path: test_resource.one.bool_attribute"), }, }, }) @@ -1372,7 +1371,7 @@ func TestExpectKnownValue_CheckPlan_UnknownAttributeType(t *testing.T) { }, }, }, - expectedErr: fmt.Errorf("unrecognised attribute type: float32, known value type is knownvalue.int64Exact\n\nThis is an error in plancheck.ExpectKnownValue.\nPlease report this to the maintainers."), + expectedErr: fmt.Errorf("error checking value for attribute at path: example_resource.test.attribute, err: expected json.Number value for Int64Exact check, got: float32"), }, } From c542a70430a00dc8fb1be3fe9f8a4fb5d5240281 Mon Sep 17 00:00:00 2001 From: Benjamin Bennett Date: Thu, 18 Jan 2024 11:41:08 +0000 Subject: [PATCH 19/29] Deprecating ExpectNullOutputValue and ExpectNullOutputValueAtPath plan checks (#266) --- plancheck/expect_null_output_value.go | 6 ++++++ plancheck/expect_null_output_value_at_path.go | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/plancheck/expect_null_output_value.go b/plancheck/expect_null_output_value.go index 540462bf0..1fd27b17e 100644 --- a/plancheck/expect_null_output_value.go +++ b/plancheck/expect_null_output_value.go @@ -64,6 +64,12 @@ func (e expectNullOutputValue) CheckPlan(ctx context.Context, req CheckPlanReque // Due to implementation differences between the terraform-plugin-sdk and the terraform-plugin-framework, representation of null // values may differ. For example, terraform-plugin-sdk based providers may have less precise representations of null values, such // as marking whole maps as null rather than individual element values. +// +// Deprecated: Use ExpectKnownOutputValue with knownvalue.NullExact instead. +// ExpectNullOutputValue will be removed in the next major version release. +// +// [ExpectKnownOutputValue]: https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/plancheck#ExpectKnownOutputValue +// [NullExact]: https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#NullExact func ExpectNullOutputValue(outputAddress string) PlanCheck { return expectNullOutputValue{ outputAddress: outputAddress, diff --git a/plancheck/expect_null_output_value_at_path.go b/plancheck/expect_null_output_value_at_path.go index 17366e21a..4929ec64f 100644 --- a/plancheck/expect_null_output_value_at_path.go +++ b/plancheck/expect_null_output_value_at_path.go @@ -65,6 +65,12 @@ func (e expectNullOutputValueAtPath) CheckPlan(ctx context.Context, req CheckPla // Due to implementation differences between the terraform-plugin-sdk and the terraform-plugin-framework, representation of null // values may differ. For example, terraform-plugin-sdk based providers may have less precise representations of null values, such // as marking whole maps as null rather than individual element values. +// +// Deprecated: Use ExpectKnownOutputValueAtPath with knownvalue.NullExact instead. +// ExpectNullOutputValueAtPath will be removed in the next major version release. +// +// [ExpectKnownOutputValueAtPath]: https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/plancheck#ExpectKnownOutputValueAtPath +// [NullExact]: https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#NullExact func ExpectNullOutputValueAtPath(outputAddress string, valuePath tfjsonpath.Path) PlanCheck { return expectNullOutputValueAtPath{ outputAddress: outputAddress, From 518c94cd4235a3b0049a491fdffe958145ffe7b6 Mon Sep 17 00:00:00 2001 From: Benjamin Bennett Date: Mon, 22 Jan 2024 08:19:46 +0000 Subject: [PATCH 20/29] Adding return statements (#266) --- statecheck/expect_known_output_value.go | 4 ++++ statecheck/expect_known_output_value_at_path.go | 4 ++++ statecheck/expect_known_value.go | 8 ++++++++ statecheck/expect_sensitive_value.go | 8 ++++++++ 4 files changed, 24 insertions(+) diff --git a/statecheck/expect_known_output_value.go b/statecheck/expect_known_output_value.go index 64c47f819..951a36400 100644 --- a/statecheck/expect_known_output_value.go +++ b/statecheck/expect_known_output_value.go @@ -27,10 +27,14 @@ func (e expectKnownOutputValue) CheckState(ctx context.Context, req CheckStateRe if req.State == nil { resp.Error = fmt.Errorf("state is nil") + + return } if req.State.Values == nil { resp.Error = fmt.Errorf("state does not contain any state values") + + return } for address, oc := range req.State.Values.Outputs { diff --git a/statecheck/expect_known_output_value_at_path.go b/statecheck/expect_known_output_value_at_path.go index 9fb8cc4f1..1cdfcea79 100644 --- a/statecheck/expect_known_output_value_at_path.go +++ b/statecheck/expect_known_output_value_at_path.go @@ -28,10 +28,14 @@ func (e expectKnownOutputValueAtPath) CheckState(ctx context.Context, req CheckS if req.State == nil { resp.Error = fmt.Errorf("state is nil") + + return } if req.State.Values == nil { resp.Error = fmt.Errorf("state does not contain any state values") + + return } for address, oc := range req.State.Values.Outputs { diff --git a/statecheck/expect_known_value.go b/statecheck/expect_known_value.go index 96662c32a..86a741417 100644 --- a/statecheck/expect_known_value.go +++ b/statecheck/expect_known_value.go @@ -28,14 +28,20 @@ func (e expectKnownValue) CheckState(ctx context.Context, req CheckStateRequest, if req.State == nil { resp.Error = fmt.Errorf("state is nil") + + return } if req.State.Values == nil { resp.Error = fmt.Errorf("state does not contain any state values") + + return } if req.State.Values.RootModule == nil { resp.Error = fmt.Errorf("state does not contain a root module") + + return } for _, resourceChange := range req.State.Values.RootModule.Resources { @@ -62,6 +68,8 @@ func (e expectKnownValue) CheckState(ctx context.Context, req CheckStateRequest, if err := e.knownValue.CheckValue(result); err != nil { resp.Error = fmt.Errorf("error checking value for attribute at path: %s.%s, err: %s", e.resourceAddress, e.attributePath.String(), err) + + return } } diff --git a/statecheck/expect_sensitive_value.go b/statecheck/expect_sensitive_value.go index 447a2cb27..938238b25 100644 --- a/statecheck/expect_sensitive_value.go +++ b/statecheck/expect_sensitive_value.go @@ -26,14 +26,20 @@ func (e expectSensitiveValue) CheckState(ctx context.Context, req CheckStateRequ if req.State == nil { resp.Error = fmt.Errorf("state is nil") + + return } if req.State.Values == nil { resp.Error = fmt.Errorf("state does not contain any state values") + + return } if req.State.Values.RootModule == nil { resp.Error = fmt.Errorf("state does not contain a root module") + + return } for _, resourceChange := range req.State.Values.RootModule.Resources { @@ -71,11 +77,13 @@ func (e expectSensitiveValue) CheckState(ctx context.Context, req CheckStateRequ isSensitive, ok := result.(bool) if !ok { resp.Error = fmt.Errorf("invalid path: the path value cannot be asserted as bool") + return } if !isSensitive { resp.Error = fmt.Errorf("attribute at path is not sensitive") + return } } From 35ffc45fc5fab0339252775d4802b040ee5ed790 Mon Sep 17 00:00:00 2001 From: Benjamin Bennett Date: Mon, 22 Jan 2024 08:29:04 +0000 Subject: [PATCH 21/29] Adding change log entry for deprecation of `ExpectNullOutputValue` and `ExpectNullOutputValueAtPath` plan checks (#266) --- .changes/unreleased/NOTES-20240122-082628.yaml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changes/unreleased/NOTES-20240122-082628.yaml diff --git a/.changes/unreleased/NOTES-20240122-082628.yaml b/.changes/unreleased/NOTES-20240122-082628.yaml new file mode 100644 index 000000000..f05712299 --- /dev/null +++ b/.changes/unreleased/NOTES-20240122-082628.yaml @@ -0,0 +1,7 @@ +kind: NOTES +body: 'plancheck: Deprecated `ExpectNullOutputValue` and `ExpectNullOutputValueAtPath`. + Use `ExpectKnownOutputValue` and `ExpectKnownOutputValueAtPath` with + `knownvalue.NullExact` instead' +time: 2024-01-22T08:26:28.053303Z +custom: + Issue: "275" From 31f8d5e9785d9256279740feb34c94eaca52c09c Mon Sep 17 00:00:00 2001 From: Benjamin Bennett Date: Mon, 22 Jan 2024 08:41:47 +0000 Subject: [PATCH 22/29] Modifying return value of nullExact.String() (#266) --- knownvalue/null.go | 4 ++-- knownvalue/null_test.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/knownvalue/null.go b/knownvalue/null.go index f10c5a3f5..eaad10bef 100644 --- a/knownvalue/null.go +++ b/knownvalue/null.go @@ -20,9 +20,9 @@ func (v nullExact) CheckValue(other any) error { return nil } -// String returns the string representation of nil. +// String returns the string representation of null. func (v nullExact) String() string { - return "nil" + return "null" } // NullExact returns a Check for asserting equality nil diff --git a/knownvalue/null_test.go b/knownvalue/null_test.go index 94682ed7b..ddd688df3 100644 --- a/knownvalue/null_test.go +++ b/knownvalue/null_test.go @@ -58,7 +58,7 @@ func TestNullValue_String(t *testing.T) { got := knownvalue.NullExact().String() - if diff := cmp.Diff(got, "nil"); diff != "" { + if diff := cmp.Diff(got, "null"); diff != "" { t.Errorf("unexpected difference: %s", diff) } } From 031df218fb910365aaa56f2b8d2967390f7d9f71 Mon Sep 17 00:00:00 2001 From: Benjamin Bennett Date: Mon, 22 Jan 2024 09:09:08 +0000 Subject: [PATCH 23/29] Renaming variable (#266) --- statecheck/expect_known_value.go | 12 +++---- statecheck/expect_sensitive_value.go | 12 +++---- .../acceptance-tests/state-checks/custom.mdx | 31 +++++++++++-------- 3 files changed, 30 insertions(+), 25 deletions(-) diff --git a/statecheck/expect_known_value.go b/statecheck/expect_known_value.go index 86a741417..aca58c4d2 100644 --- a/statecheck/expect_known_value.go +++ b/statecheck/expect_known_value.go @@ -24,7 +24,7 @@ type expectKnownValue struct { // CheckState implements the state check logic. func (e expectKnownValue) CheckState(ctx context.Context, req CheckStateRequest, resp *CheckStateResponse) { - var rc *tfjson.StateResource + var resource *tfjson.StateResource if req.State == nil { resp.Error = fmt.Errorf("state is nil") @@ -44,21 +44,21 @@ func (e expectKnownValue) CheckState(ctx context.Context, req CheckStateRequest, return } - for _, resourceChange := range req.State.Values.RootModule.Resources { - if e.resourceAddress == resourceChange.Address { - rc = resourceChange + for _, r := range req.State.Values.RootModule.Resources { + if e.resourceAddress == r.Address { + resource = r break } } - if rc == nil { + if resource == nil { resp.Error = fmt.Errorf("%s - Resource not found in state", e.resourceAddress) return } - result, err := tfjsonpath.Traverse(rc.AttributeValues, e.attributePath) + result, err := tfjsonpath.Traverse(resource.AttributeValues, e.attributePath) if err != nil { resp.Error = err diff --git a/statecheck/expect_sensitive_value.go b/statecheck/expect_sensitive_value.go index 938238b25..ea4671119 100644 --- a/statecheck/expect_sensitive_value.go +++ b/statecheck/expect_sensitive_value.go @@ -22,7 +22,7 @@ type expectSensitiveValue struct { // CheckState implements the state check logic. func (e expectSensitiveValue) CheckState(ctx context.Context, req CheckStateRequest, resp *CheckStateResponse) { - var rc *tfjson.StateResource + var resource *tfjson.StateResource if req.State == nil { resp.Error = fmt.Errorf("state is nil") @@ -42,15 +42,15 @@ func (e expectSensitiveValue) CheckState(ctx context.Context, req CheckStateRequ return } - for _, resourceChange := range req.State.Values.RootModule.Resources { - if e.resourceAddress == resourceChange.Address { - rc = resourceChange + for _, r := range req.State.Values.RootModule.Resources { + if e.resourceAddress == r.Address { + resource = r break } } - if rc == nil { + if resource == nil { resp.Error = fmt.Errorf("%s - Resource not found in state", e.resourceAddress) return @@ -58,7 +58,7 @@ func (e expectSensitiveValue) CheckState(ctx context.Context, req CheckStateRequ var data map[string]any - err := json.Unmarshal(rc.SensitiveValues, &data) + err := json.Unmarshal(resource.SensitiveValues, &data) if err != nil { resp.Error = fmt.Errorf("could not unmarshal SensitiveValues: %s", err) diff --git a/website/docs/plugin/testing/acceptance-tests/state-checks/custom.mdx b/website/docs/plugin/testing/acceptance-tests/state-checks/custom.mdx index 817be30fb..a71e3d765 100644 --- a/website/docs/plugin/testing/acceptance-tests/state-checks/custom.mdx +++ b/website/docs/plugin/testing/acceptance-tests/state-checks/custom.mdx @@ -19,10 +19,14 @@ import ( "context" "fmt" + tfjson "github.com/hashicorp/terraform-json" + + "github.com/hashicorp/terraform-plugin-testing/knownvalue" "github.com/hashicorp/terraform-plugin-testing/statecheck" + "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" ) -var _ StateCheck = expectKnownValue{} +var _ statecheck.StateCheck = expectKnownValue{} type expectKnownValue struct { resourceAddress string @@ -30,8 +34,8 @@ type expectKnownValue struct { knownValue knownvalue.Check } -func (e expectKnownValue) CheckState(ctx context.Context, req CheckStateRequest, resp *CheckStateResponse) { - var rc *tfjson.StateResource +func (e expectKnownValue) CheckState(ctx context.Context, req statecheck.CheckStateRequest, resp *statecheck.CheckStateResponse) { + var resource *tfjson.StateResource if req.State == nil { resp.Error = fmt.Errorf("state is nil") @@ -45,21 +49,21 @@ func (e expectKnownValue) CheckState(ctx context.Context, req CheckStateRequest, resp.Error = fmt.Errorf("state does not contain a root module") } - for _, resourceChange := range req.State.Values.RootModule.Resources { - if e.resourceAddress == resourceChange.Address { - rc = resourceChange + for _, r := range req.State.Values.RootModule.Resources { + if e.resourceAddress == r.Address { + resource = r break } } - if rc == nil { + if resource == nil { resp.Error = fmt.Errorf("%s - Resource not found in state", e.resourceAddress) return } - result, err := tfjsonpath.Traverse(rc.AttributeValues, e.attributePath) + result, err := tfjsonpath.Traverse(resource.AttributeValues, e.attributePath) if err != nil { resp.Error = err @@ -72,7 +76,7 @@ func (e expectKnownValue) CheckState(ctx context.Context, req CheckStateRequest, } } -func ExpectKnownValue(resourceAddress string, attributePath tfjsonpath.Path, knownValue knownvalue.Check) StateCheck { +func ExpectKnownValue(resourceAddress string, attributePath tfjsonpath.Path, knownValue knownvalue.Check) statecheck.StateCheck { return expectKnownValue{ resourceAddress: resourceAddress, attributePath: attributePath, @@ -82,13 +86,14 @@ func ExpectKnownValue(resourceAddress string, attributePath tfjsonpath.Path, kno ``` And example usage: + ```go package example_test import ( "testing" - r "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/knownvalue" "github.com/hashicorp/terraform-plugin-testing/statecheck" "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" @@ -97,15 +102,15 @@ import ( func TestExpectKnownValue_CheckState_Bool(t *testing.T) { t.Parallel() - r.Test(t, r.TestCase{ + resource.Test(t, resource.TestCase{ // Provider definition omitted. - Steps: []r.TestStep{ + Steps: []resource.TestStep{ { Config: `resource "test_resource" "one" { bool_attribute = true } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: resource.ConfigStateChecks{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("bool_attribute"), From 6df33b96fb229019fdf3ecf9d7698893c4bd215f Mon Sep 17 00:00:00 2001 From: Benjamin Bennett Date: Mon, 22 Jan 2024 09:23:04 +0000 Subject: [PATCH 24/29] Adding comment for Terraform v1.4.6 (#266) --- tfversion/versions.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tfversion/versions.go b/tfversion/versions.go index f405bd766..690734892 100644 --- a/tfversion/versions.go +++ b/tfversion/versions.go @@ -28,8 +28,10 @@ var ( Version1_2_0 *version.Version = version.Must(version.NewVersion("1.2.0")) Version1_3_0 *version.Version = version.Must(version.NewVersion("1.3.0")) Version1_4_0 *version.Version = version.Must(version.NewVersion("1.4.0")) - Version1_4_6 *version.Version = version.Must(version.NewVersion("1.4.6")) - Version1_5_0 *version.Version = version.Must(version.NewVersion("1.5.0")) - Version1_6_0 *version.Version = version.Must(version.NewVersion("1.6.0")) - Version1_7_0 *version.Version = version.Must(version.NewVersion("1.7.0")) + // Version1_4_6 fixed inclusion of sensitive values in `terraform show -json` output. + // Reference: https://github.com/hashicorp/terraform/releases/tag/v1.4.6 + Version1_4_6 *version.Version = version.Must(version.NewVersion("1.4.6")) + Version1_5_0 *version.Version = version.Must(version.NewVersion("1.5.0")) + Version1_6_0 *version.Version = version.Must(version.NewVersion("1.6.0")) + Version1_7_0 *version.Version = version.Must(version.NewVersion("1.7.0")) ) From 15330e354495c59db4016f3cf9e34430d09b77a8 Mon Sep 17 00:00:00 2001 From: Benjamin Bennett Date: Mon, 22 Jan 2024 10:45:29 +0000 Subject: [PATCH 25/29] Adding further tests for null exact known value type check (#266) --- knownvalue/null.go | 2 +- .../expect_known_output_value_at_path_test.go | 40 +++++++++++++ plancheck/expect_known_output_value_test.go | 56 +++++++++++++++++++ plancheck/expect_known_value_test.go | 40 +++++++++++++ .../expect_known_output_value_at_path_test.go | 40 +++++++++++++ statecheck/expect_known_value_test.go | 40 +++++++++++++ 6 files changed, 217 insertions(+), 1 deletion(-) diff --git a/knownvalue/null.go b/knownvalue/null.go index eaad10bef..6b25d1bf4 100644 --- a/knownvalue/null.go +++ b/knownvalue/null.go @@ -11,7 +11,7 @@ var _ Check = nullExact{} type nullExact struct{} -// CheckValue determines whether the passed value is of nil. +// CheckValue determines whether the passed value is nil. func (v nullExact) CheckValue(other any) error { if other != nil { return fmt.Errorf("expected value nil for NullExact check, got: %T", other) diff --git a/plancheck/expect_known_output_value_at_path_test.go b/plancheck/expect_known_output_value_at_path_test.go index 82505f87c..cbcb256bb 100644 --- a/plancheck/expect_known_output_value_at_path_test.go +++ b/plancheck/expect_known_output_value_at_path_test.go @@ -93,6 +93,46 @@ func TestExpectKnownOutputValueAtPath_CheckPlan_AttributeValueNull(t *testing.T) tfjsonpath.New("bool_attribute"), knownvalue.NullExact(), ), + plancheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("float_attribute"), + knownvalue.NullExact(), + ), + plancheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("int_attribute"), + knownvalue.NullExact(), + ), + plancheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("list_attribute"), + knownvalue.NullExact(), + ), + plancheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("list_nested_block"), + knownvalue.ListExact([]knownvalue.Check{}), + ), + plancheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("map_attribute"), + knownvalue.NullExact(), + ), + plancheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("set_attribute"), + knownvalue.NullExact(), + ), + plancheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("set_nested_block"), + knownvalue.SetExact([]knownvalue.Check{}), + ), + plancheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("string_attribute"), + knownvalue.NullExact(), + ), }, }, }, diff --git a/plancheck/expect_known_output_value_test.go b/plancheck/expect_known_output_value_test.go index 626ecaab2..0b5315650 100644 --- a/plancheck/expect_known_output_value_test.go +++ b/plancheck/expect_known_output_value_test.go @@ -67,6 +67,30 @@ func TestExpectKnownOutputValue_CheckPlan_AttributeValueNull(t *testing.T) { output bool_output { value = test_resource.one.bool_attribute } + output float_output { + value = test_resource.one.float_attribute + } + output int_output { + value = test_resource.one.int_attribute + } + output list_output { + value = test_resource.one.list_attribute + } + output list_nested_block_output { + value = test_resource.one.list_nested_block + } + output map_output { + value = test_resource.one.map_attribute + } + output set_output { + value = test_resource.one.set_attribute + } + output set_nested_block_output { + value = test_resource.one.set_nested_block + } + output string_output { + value = test_resource.one.string_attribute + } `, ConfigPlanChecks: r.ConfigPlanChecks{ PreApply: []plancheck.PlanCheck{ @@ -74,6 +98,38 @@ func TestExpectKnownOutputValue_CheckPlan_AttributeValueNull(t *testing.T) { "bool_output", knownvalue.NullExact(), ), + plancheck.ExpectKnownOutputValue( + "float_output", + knownvalue.NullExact(), + ), + plancheck.ExpectKnownOutputValue( + "int_output", + knownvalue.NullExact(), + ), + plancheck.ExpectKnownOutputValue( + "list_output", + knownvalue.NullExact(), + ), + plancheck.ExpectKnownOutputValue( + "list_nested_block_output", + knownvalue.ListExact([]knownvalue.Check{}), + ), + plancheck.ExpectKnownOutputValue( + "map_output", + knownvalue.NullExact(), + ), + plancheck.ExpectKnownOutputValue( + "set_output", + knownvalue.NullExact(), + ), + plancheck.ExpectKnownOutputValue( + "set_nested_block_output", + knownvalue.SetExact([]knownvalue.Check{}), + ), + plancheck.ExpectKnownOutputValue( + "string_output", + knownvalue.NullExact(), + ), }, }, }, diff --git a/plancheck/expect_known_value_test.go b/plancheck/expect_known_value_test.go index af1618076..c331af94e 100644 --- a/plancheck/expect_known_value_test.go +++ b/plancheck/expect_known_value_test.go @@ -69,6 +69,46 @@ func TestExpectKnownValue_CheckPlan_AttributeValueNull(t *testing.T) { tfjsonpath.New("bool_attribute"), knownvalue.NullExact(), ), + plancheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("float_attribute"), + knownvalue.NullExact(), + ), + plancheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("int_attribute"), + knownvalue.NullExact(), + ), + plancheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("list_attribute"), + knownvalue.NullExact(), + ), + plancheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("list_nested_block"), + knownvalue.ListExact([]knownvalue.Check{}), + ), + plancheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("map_attribute"), + knownvalue.NullExact(), + ), + plancheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("set_attribute"), + knownvalue.NullExact(), + ), + plancheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("set_nested_block"), + knownvalue.SetExact([]knownvalue.Check{}), + ), + plancheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("string_attribute"), + knownvalue.NullExact(), + ), }, }, }, diff --git a/statecheck/expect_known_output_value_at_path_test.go b/statecheck/expect_known_output_value_at_path_test.go index 078daee04..918b53874 100644 --- a/statecheck/expect_known_output_value_at_path_test.go +++ b/statecheck/expect_known_output_value_at_path_test.go @@ -75,6 +75,46 @@ func TestExpectKnownOutputValueAtPath_CheckState_AttributeValueNull(t *testing.T tfjsonpath.New("bool_attribute"), knownvalue.NullExact(), ), + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("float_attribute"), + knownvalue.NullExact(), + ), + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("int_attribute"), + knownvalue.NullExact(), + ), + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("list_attribute"), + knownvalue.NullExact(), + ), + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("list_nested_block"), + knownvalue.ListExact([]knownvalue.Check{}), + ), + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("map_attribute"), + knownvalue.NullExact(), + ), + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("set_attribute"), + knownvalue.NullExact(), + ), + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("set_nested_block"), + knownvalue.SetExact([]knownvalue.Check{}), + ), + statecheck.ExpectKnownOutputValueAtPath( + "test_resource_one_output", + tfjsonpath.New("string_attribute"), + knownvalue.NullExact(), + ), }, }, }, diff --git a/statecheck/expect_known_value_test.go b/statecheck/expect_known_value_test.go index 9625ec089..3be302744 100644 --- a/statecheck/expect_known_value_test.go +++ b/statecheck/expect_known_value_test.go @@ -67,6 +67,46 @@ func TestExpectKnownValue_CheckState_AttributeValueNull(t *testing.T) { tfjsonpath.New("bool_attribute"), knownvalue.NullExact(), ), + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("float_attribute"), + knownvalue.NullExact(), + ), + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("int_attribute"), + knownvalue.NullExact(), + ), + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("list_attribute"), + knownvalue.NullExact(), + ), + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("list_nested_block"), + knownvalue.ListExact([]knownvalue.Check{}), + ), + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("map_attribute"), + knownvalue.NullExact(), + ), + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("set_attribute"), + knownvalue.NullExact(), + ), + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("set_nested_block"), + knownvalue.ListExact([]knownvalue.Check{}), + ), + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("string_attribute"), + knownvalue.NullExact(), + ), }, }, }, From a88a10dfb7c6ed1c1d6d68ca4edb3486052565f3 Mon Sep 17 00:00:00 2001 From: Benjamin Bennett Date: Mon, 22 Jan 2024 11:10:21 +0000 Subject: [PATCH 26/29] Linting (#266) --- tfversion/versions.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tfversion/versions.go b/tfversion/versions.go index bc4b87158..21f0727a9 100644 --- a/tfversion/versions.go +++ b/tfversion/versions.go @@ -34,5 +34,5 @@ var ( Version1_5_0 *version.Version = version.Must(version.NewVersion("1.5.0")) Version1_6_0 *version.Version = version.Must(version.NewVersion("1.6.0")) Version1_7_0 *version.Version = version.Must(version.NewVersion("1.7.0")) - Version1_8_0 *version.Version = version.Must(version.NewVersion("1.8.0")) + Version1_8_0 *version.Version = version.Must(version.NewVersion("1.8.0")) ) From 6d8f1124e0fca467de71d5cd1ca2026ecc246eae Mon Sep 17 00:00:00 2001 From: Benjamin Bennett Date: Tue, 23 Jan 2024 10:41:39 +0000 Subject: [PATCH 27/29] Renaming BoolExact to Bool, and NullExact to Null (#266) --- knownvalue/bool.go | 18 ++++++------- knownvalue/bool_test.go | 22 ++++++++-------- knownvalue/null.go | 16 ++++++------ knownvalue/null_test.go | 12 ++++----- .../expect_known_output_value_at_path_test.go | 26 +++++++++---------- plancheck/expect_known_output_value_test.go | 26 +++++++++---------- plancheck/expect_known_value_test.go | 26 +++++++++---------- .../expect_known_output_value_at_path_test.go | 26 +++++++++---------- statecheck/expect_known_output_value_test.go | 14 +++++----- statecheck/expect_known_value_test.go | 26 +++++++++---------- .../known-value-checks/bool.mdx | 10 +++---- .../known-value-checks/custom.mdx | 2 +- .../known-value-checks/index.mdx | 2 +- .../known-value-checks/null.mdx | 10 +++---- .../acceptance-tests/plan-checks/output.mdx | 4 +-- .../acceptance-tests/state-checks/custom.mdx | 2 +- .../acceptance-tests/state-checks/output.mdx | 4 +-- .../state-checks/resource.mdx | 2 +- 18 files changed, 124 insertions(+), 124 deletions(-) diff --git a/knownvalue/bool.go b/knownvalue/bool.go index 62521f454..fba10ee86 100644 --- a/knownvalue/bool.go +++ b/knownvalue/bool.go @@ -8,37 +8,37 @@ import ( "strconv" ) -var _ Check = boolExact{} +var _ Check = boolValue{} -type boolExact struct { +type boolValue struct { value bool } // CheckValue determines whether the passed value is of type bool, and // contains a matching bool value. -func (v boolExact) CheckValue(other any) error { +func (v boolValue) CheckValue(other any) error { otherVal, ok := other.(bool) if !ok { - return fmt.Errorf("expected bool value for BoolExact check, got: %T", other) + return fmt.Errorf("expected bool value for Bool check, got: %T", other) } if otherVal != v.value { - return fmt.Errorf("expected value %t for BoolExact check, got: %t", v.value, otherVal) + return fmt.Errorf("expected value %t for Bool check, got: %t", v.value, otherVal) } return nil } // String returns the string representation of the bool value. -func (v boolExact) String() string { +func (v boolValue) String() string { return strconv.FormatBool(v.value) } -// BoolExact returns a Check for asserting equality between the +// Bool returns a Check for asserting equality between the // supplied bool and the value passed to the CheckValue method. -func BoolExact(value bool) boolExact { - return boolExact{ +func Bool(value bool) boolValue { + return boolValue{ value: value, } } diff --git a/knownvalue/bool_test.go b/knownvalue/bool_test.go index 3c47d59a9..35ba1d40e 100644 --- a/knownvalue/bool_test.go +++ b/knownvalue/bool_test.go @@ -21,29 +21,29 @@ func TestBoolValue_CheckValue(t *testing.T) { expectedError error }{ "zero-nil": { - self: knownvalue.BoolExact(false), - expectedError: fmt.Errorf("expected bool value for BoolExact check, got: "), + self: knownvalue.Bool(false), + expectedError: fmt.Errorf("expected bool value for Bool check, got: "), }, "zero-other": { - self: knownvalue.BoolExact(false), + self: knownvalue.Bool(false), other: false, // checking against the underlying value field zero-value }, "nil": { - self: knownvalue.BoolExact(false), - expectedError: fmt.Errorf("expected bool value for BoolExact check, got: "), + self: knownvalue.Bool(false), + expectedError: fmt.Errorf("expected bool value for Bool check, got: "), }, "wrong-type": { - self: knownvalue.BoolExact(true), + self: knownvalue.Bool(true), other: 1.23, - expectedError: fmt.Errorf("expected bool value for BoolExact check, got: float64"), + expectedError: fmt.Errorf("expected bool value for Bool check, got: float64"), }, "not-equal": { - self: knownvalue.BoolExact(true), + self: knownvalue.Bool(true), other: false, - expectedError: fmt.Errorf("expected value true for BoolExact check, got: false"), + expectedError: fmt.Errorf("expected value true for Bool check, got: false"), }, "equal": { - self: knownvalue.BoolExact(true), + self: knownvalue.Bool(true), other: true, }, } @@ -66,7 +66,7 @@ func TestBoolValue_CheckValue(t *testing.T) { func TestBoolValue_String(t *testing.T) { t.Parallel() - got := knownvalue.BoolExact(true).String() + got := knownvalue.Bool(true).String() if diff := cmp.Diff(got, "true"); diff != "" { t.Errorf("unexpected difference: %s", diff) diff --git a/knownvalue/null.go b/knownvalue/null.go index 6b25d1bf4..a8bbaee9f 100644 --- a/knownvalue/null.go +++ b/knownvalue/null.go @@ -7,26 +7,26 @@ import ( "fmt" ) -var _ Check = nullExact{} +var _ Check = null{} -type nullExact struct{} +type null struct{} // CheckValue determines whether the passed value is nil. -func (v nullExact) CheckValue(other any) error { +func (v null) CheckValue(other any) error { if other != nil { - return fmt.Errorf("expected value nil for NullExact check, got: %T", other) + return fmt.Errorf("expected value nil for Null check, got: %T", other) } return nil } // String returns the string representation of null. -func (v nullExact) String() string { +func (v null) String() string { return "null" } -// NullExact returns a Check for asserting equality nil +// Null returns a Check for asserting equality nil // and the value passed to the CheckValue method. -func NullExact() nullExact { - return nullExact{} +func Null() null { + return null{} } diff --git a/knownvalue/null_test.go b/knownvalue/null_test.go index ddd688df3..e7bb5531d 100644 --- a/knownvalue/null_test.go +++ b/knownvalue/null_test.go @@ -21,19 +21,19 @@ func TestNullValue_CheckValue(t *testing.T) { expectedError error }{ "zero-nil": { - self: knownvalue.NullExact(), + self: knownvalue.Null(), }, "zero-other": { - self: knownvalue.NullExact(), + self: knownvalue.Null(), other: nil, // checking against the underlying value field zero-value }, "not-nil": { - self: knownvalue.NullExact(), + self: knownvalue.Null(), other: false, - expectedError: fmt.Errorf("expected value nil for NullExact check, got: bool"), + expectedError: fmt.Errorf("expected value nil for Null check, got: bool"), }, "equal": { - self: knownvalue.NullExact(), + self: knownvalue.Null(), other: nil, }, } @@ -56,7 +56,7 @@ func TestNullValue_CheckValue(t *testing.T) { func TestNullValue_String(t *testing.T) { t.Parallel() - got := knownvalue.NullExact().String() + got := knownvalue.Null().String() if diff := cmp.Diff(got, "null"); diff != "" { t.Errorf("unexpected difference: %s", diff) diff --git a/plancheck/expect_known_output_value_at_path_test.go b/plancheck/expect_known_output_value_at_path_test.go index cbcb256bb..fc643523d 100644 --- a/plancheck/expect_known_output_value_at_path_test.go +++ b/plancheck/expect_known_output_value_at_path_test.go @@ -52,7 +52,7 @@ func TestExpectKnownOutputValueAtPath_CheckPlan_ResourceNotFound(t *testing.T) { plancheck.ExpectKnownOutputValueAtPath( "test_resource_two_output", tfjsonpath.New("bool_attribute"), - knownvalue.BoolExact(true), + knownvalue.Bool(true), ), }, }, @@ -91,22 +91,22 @@ func TestExpectKnownOutputValueAtPath_CheckPlan_AttributeValueNull(t *testing.T) plancheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("bool_attribute"), - knownvalue.NullExact(), + knownvalue.Null(), ), plancheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("float_attribute"), - knownvalue.NullExact(), + knownvalue.Null(), ), plancheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("int_attribute"), - knownvalue.NullExact(), + knownvalue.Null(), ), plancheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("list_attribute"), - knownvalue.NullExact(), + knownvalue.Null(), ), plancheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", @@ -116,12 +116,12 @@ func TestExpectKnownOutputValueAtPath_CheckPlan_AttributeValueNull(t *testing.T) plancheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("map_attribute"), - knownvalue.NullExact(), + knownvalue.Null(), ), plancheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("set_attribute"), - knownvalue.NullExact(), + knownvalue.Null(), ), plancheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", @@ -131,7 +131,7 @@ func TestExpectKnownOutputValueAtPath_CheckPlan_AttributeValueNull(t *testing.T) plancheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("string_attribute"), - knownvalue.NullExact(), + knownvalue.Null(), ), }, }, @@ -171,7 +171,7 @@ func TestExpectKnownOutputValueAtPath_CheckPlan_Bool(t *testing.T) { plancheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("bool_attribute"), - knownvalue.BoolExact(true), + knownvalue.Bool(true), ), }, }, @@ -252,11 +252,11 @@ func TestExpectKnownOutputValueAtPath_CheckPlan_Bool_KnownValueWrongValue(t *tes plancheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("bool_attribute"), - knownvalue.BoolExact(false), + knownvalue.Bool(false), ), }, }, - ExpectError: regexp.MustCompile("error checking value for output at path: test_resource_one_output.bool_attribute, err: expected value false for BoolExact check, got: true"), + ExpectError: regexp.MustCompile("error checking value for output at path: test_resource_one_output.bool_attribute, err: expected value false for Bool check, got: true"), }, }, }) @@ -1780,10 +1780,10 @@ func TestExpectKnownOutputValueAtPath_CheckPlan_String_KnownValueWrongType(t *te plancheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("string_attribute"), - knownvalue.BoolExact(true)), + knownvalue.Bool(true)), }, }, - ExpectError: regexp.MustCompile("error checking value for output at path: test_resource_one_output.string_attribute, err: expected bool value for BoolExact check, got: string"), + ExpectError: regexp.MustCompile("error checking value for output at path: test_resource_one_output.string_attribute, err: expected bool value for Bool check, got: string"), }, }, }) diff --git a/plancheck/expect_known_output_value_test.go b/plancheck/expect_known_output_value_test.go index 0b5315650..da45a00d0 100644 --- a/plancheck/expect_known_output_value_test.go +++ b/plancheck/expect_known_output_value_test.go @@ -42,7 +42,7 @@ func TestExpectKnownOutputValue_CheckPlan_OutputNotFound(t *testing.T) { PreApply: []plancheck.PlanCheck{ plancheck.ExpectKnownOutputValue( "bool_not_found", - knownvalue.BoolExact(true), + knownvalue.Bool(true), ), }, }, @@ -96,19 +96,19 @@ func TestExpectKnownOutputValue_CheckPlan_AttributeValueNull(t *testing.T) { PreApply: []plancheck.PlanCheck{ plancheck.ExpectKnownOutputValue( "bool_output", - knownvalue.NullExact(), + knownvalue.Null(), ), plancheck.ExpectKnownOutputValue( "float_output", - knownvalue.NullExact(), + knownvalue.Null(), ), plancheck.ExpectKnownOutputValue( "int_output", - knownvalue.NullExact(), + knownvalue.Null(), ), plancheck.ExpectKnownOutputValue( "list_output", - knownvalue.NullExact(), + knownvalue.Null(), ), plancheck.ExpectKnownOutputValue( "list_nested_block_output", @@ -116,11 +116,11 @@ func TestExpectKnownOutputValue_CheckPlan_AttributeValueNull(t *testing.T) { ), plancheck.ExpectKnownOutputValue( "map_output", - knownvalue.NullExact(), + knownvalue.Null(), ), plancheck.ExpectKnownOutputValue( "set_output", - knownvalue.NullExact(), + knownvalue.Null(), ), plancheck.ExpectKnownOutputValue( "set_nested_block_output", @@ -128,7 +128,7 @@ func TestExpectKnownOutputValue_CheckPlan_AttributeValueNull(t *testing.T) { ), plancheck.ExpectKnownOutputValue( "string_output", - knownvalue.NullExact(), + knownvalue.Null(), ), }, }, @@ -160,7 +160,7 @@ func TestExpectKnownOutputValue_CheckPlan_Bool(t *testing.T) { PreApply: []plancheck.PlanCheck{ plancheck.ExpectKnownOutputValue( "bool_output", - knownvalue.BoolExact(true), + knownvalue.Bool(true), ), }, }, @@ -225,11 +225,11 @@ func TestExpectKnownOutputValue_CheckPlan_Bool_KnownValueWrongValue(t *testing.T PreApply: []plancheck.PlanCheck{ plancheck.ExpectKnownOutputValue( "bool_output", - knownvalue.BoolExact(false), + knownvalue.Bool(false), ), }, }, - ExpectError: regexp.MustCompile("error checking value for output at path: bool_output, err: expected value false for BoolExact check, got: true"), + ExpectError: regexp.MustCompile("error checking value for output at path: bool_output, err: expected value false for Bool check, got: true"), }, }, }) @@ -1481,10 +1481,10 @@ func TestExpectKnownOutputValue_CheckPlan_String_KnownValueWrongType(t *testing. PreApply: []plancheck.PlanCheck{ plancheck.ExpectKnownOutputValue( "string_output", - knownvalue.BoolExact(true)), + knownvalue.Bool(true)), }, }, - ExpectError: regexp.MustCompile("error checking value for output at path: string_output, err: expected bool value for BoolExact check, got: string"), + ExpectError: regexp.MustCompile("error checking value for output at path: string_output, err: expected bool value for Bool check, got: string"), }, }, }) diff --git a/plancheck/expect_known_value_test.go b/plancheck/expect_known_value_test.go index c331af94e..85405f1e8 100644 --- a/plancheck/expect_known_value_test.go +++ b/plancheck/expect_known_value_test.go @@ -40,7 +40,7 @@ func TestExpectKnownValue_CheckPlan_ResourceNotFound(t *testing.T) { plancheck.ExpectKnownValue( "test_resource.two", tfjsonpath.New("bool_attribute"), - knownvalue.BoolExact(true), + knownvalue.Bool(true), ), }, }, @@ -67,22 +67,22 @@ func TestExpectKnownValue_CheckPlan_AttributeValueNull(t *testing.T) { plancheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("bool_attribute"), - knownvalue.NullExact(), + knownvalue.Null(), ), plancheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("float_attribute"), - knownvalue.NullExact(), + knownvalue.Null(), ), plancheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("int_attribute"), - knownvalue.NullExact(), + knownvalue.Null(), ), plancheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("list_attribute"), - knownvalue.NullExact(), + knownvalue.Null(), ), plancheck.ExpectKnownValue( "test_resource.one", @@ -92,12 +92,12 @@ func TestExpectKnownValue_CheckPlan_AttributeValueNull(t *testing.T) { plancheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("map_attribute"), - knownvalue.NullExact(), + knownvalue.Null(), ), plancheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("set_attribute"), - knownvalue.NullExact(), + knownvalue.Null(), ), plancheck.ExpectKnownValue( "test_resource.one", @@ -107,7 +107,7 @@ func TestExpectKnownValue_CheckPlan_AttributeValueNull(t *testing.T) { plancheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("string_attribute"), - knownvalue.NullExact(), + knownvalue.Null(), ), }, }, @@ -136,7 +136,7 @@ func TestExpectKnownValue_CheckPlan_Bool(t *testing.T) { plancheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("bool_attribute"), - knownvalue.BoolExact(true), + knownvalue.Bool(true), ), }, }, @@ -195,11 +195,11 @@ func TestExpectKnownValue_CheckPlan_Bool_KnownValueWrongValue(t *testing.T) { plancheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("bool_attribute"), - knownvalue.BoolExact(false), + knownvalue.Bool(false), ), }, }, - ExpectError: regexp.MustCompile("error checking value for attribute at path: test_resource.one.bool_attribute, err: expected value false for BoolExact check, got: true"), + ExpectError: regexp.MustCompile("error checking value for attribute at path: test_resource.one.bool_attribute, err: expected value false for Bool check, got: true"), }, }, }) @@ -1349,10 +1349,10 @@ func TestExpectKnownValue_CheckPlan_String_KnownValueWrongType(t *testing.T) { plancheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("string_attribute"), - knownvalue.BoolExact(true)), + knownvalue.Bool(true)), }, }, - ExpectError: regexp.MustCompile("error checking value for attribute at path: test_resource.one.string_attribute, err: expected bool value for BoolExact check, got: string"), + ExpectError: regexp.MustCompile("error checking value for attribute at path: test_resource.one.string_attribute, err: expected bool value for Bool check, got: string"), }, }, }) diff --git a/statecheck/expect_known_output_value_at_path_test.go b/statecheck/expect_known_output_value_at_path_test.go index 918b53874..c69c59887 100644 --- a/statecheck/expect_known_output_value_at_path_test.go +++ b/statecheck/expect_known_output_value_at_path_test.go @@ -43,7 +43,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_ResourceNotFound(t *testing.T) statecheck.ExpectKnownOutputValueAtPath( "test_resource_two_output", tfjsonpath.New("bool_attribute"), - knownvalue.BoolExact(true), + knownvalue.Bool(true), ), }, ExpectError: regexp.MustCompile("test_resource_two_output - Output not found in state"), @@ -73,22 +73,22 @@ func TestExpectKnownOutputValueAtPath_CheckState_AttributeValueNull(t *testing.T statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("bool_attribute"), - knownvalue.NullExact(), + knownvalue.Null(), ), statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("float_attribute"), - knownvalue.NullExact(), + knownvalue.Null(), ), statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("int_attribute"), - knownvalue.NullExact(), + knownvalue.Null(), ), statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("list_attribute"), - knownvalue.NullExact(), + knownvalue.Null(), ), statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", @@ -98,12 +98,12 @@ func TestExpectKnownOutputValueAtPath_CheckState_AttributeValueNull(t *testing.T statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("map_attribute"), - knownvalue.NullExact(), + knownvalue.Null(), ), statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("set_attribute"), - knownvalue.NullExact(), + knownvalue.Null(), ), statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", @@ -113,7 +113,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_AttributeValueNull(t *testing.T statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("string_attribute"), - knownvalue.NullExact(), + knownvalue.Null(), ), }, }, @@ -144,7 +144,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_Bool(t *testing.T) { statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("bool_attribute"), - knownvalue.BoolExact(true), + knownvalue.Bool(true), ), }, }, @@ -207,10 +207,10 @@ func TestExpectKnownOutputValueAtPath_CheckState_Bool_KnownValueWrongValue(t *te statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("bool_attribute"), - knownvalue.BoolExact(false), + knownvalue.Bool(false), ), }, - ExpectError: regexp.MustCompile("expected value false for BoolExact check, got: true"), + ExpectError: regexp.MustCompile("expected value false for Bool check, got: true"), }, }, }) @@ -1429,9 +1429,9 @@ func TestExpectKnownOutputValueAtPath_CheckState_String_KnownValueWrongType(t *t statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("string_attribute"), - knownvalue.BoolExact(true)), + knownvalue.Bool(true)), }, - ExpectError: regexp.MustCompile("expected bool value for BoolExact check, got: string"), + ExpectError: regexp.MustCompile("expected bool value for Bool check, got: string"), }, }, }) diff --git a/statecheck/expect_known_output_value_test.go b/statecheck/expect_known_output_value_test.go index b3f5e2ccf..2eb65193e 100644 --- a/statecheck/expect_known_output_value_test.go +++ b/statecheck/expect_known_output_value_test.go @@ -41,7 +41,7 @@ func TestExpectKnownOutputValue_CheckState_OutputNotFound(t *testing.T) { ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "bool_not_found", - knownvalue.BoolExact(true), + knownvalue.Bool(true), ), }, ExpectError: regexp.MustCompile("bool_not_found - Output not found in state"), @@ -73,7 +73,7 @@ func TestExpectKnownOutputValue_CheckState_AttributeValueNull(t *testing.T) { ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "bool_output", - knownvalue.BoolExact(true), + knownvalue.Bool(true), ), }, ExpectError: regexp.MustCompile("bool_output - Output not found in state"), @@ -104,7 +104,7 @@ func TestExpectKnownOutputValue_CheckState_Bool(t *testing.T) { ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "bool_output", - knownvalue.BoolExact(true), + knownvalue.Bool(true), ), }, }, @@ -165,10 +165,10 @@ func TestExpectKnownOutputValue_CheckState_Bool_KnownValueWrongValue(t *testing. ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "bool_output", - knownvalue.BoolExact(false), + knownvalue.Bool(false), ), }, - ExpectError: regexp.MustCompile("expected value false for BoolExact check, got: true"), + ExpectError: regexp.MustCompile("expected value false for Bool check, got: true"), }, }, }) @@ -1353,9 +1353,9 @@ func TestExpectKnownOutputValue_CheckState_String_KnownValueWrongType(t *testing ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "string_output", - knownvalue.BoolExact(true)), + knownvalue.Bool(true)), }, - ExpectError: regexp.MustCompile("expected bool value for BoolExact check, got: string"), + ExpectError: regexp.MustCompile("expected bool value for Bool check, got: string"), }, }, }) diff --git a/statecheck/expect_known_value_test.go b/statecheck/expect_known_value_test.go index 3be302744..eeca817d0 100644 --- a/statecheck/expect_known_value_test.go +++ b/statecheck/expect_known_value_test.go @@ -40,7 +40,7 @@ func TestExpectKnownValue_CheckState_ResourceNotFound(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.two", tfjsonpath.New("bool_attribute"), - knownvalue.BoolExact(true), + knownvalue.Bool(true), ), }, ExpectError: regexp.MustCompile("test_resource.two - Resource not found in state"), @@ -65,22 +65,22 @@ func TestExpectKnownValue_CheckState_AttributeValueNull(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("bool_attribute"), - knownvalue.NullExact(), + knownvalue.Null(), ), statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("float_attribute"), - knownvalue.NullExact(), + knownvalue.Null(), ), statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("int_attribute"), - knownvalue.NullExact(), + knownvalue.Null(), ), statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("list_attribute"), - knownvalue.NullExact(), + knownvalue.Null(), ), statecheck.ExpectKnownValue( "test_resource.one", @@ -90,12 +90,12 @@ func TestExpectKnownValue_CheckState_AttributeValueNull(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("map_attribute"), - knownvalue.NullExact(), + knownvalue.Null(), ), statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("set_attribute"), - knownvalue.NullExact(), + knownvalue.Null(), ), statecheck.ExpectKnownValue( "test_resource.one", @@ -105,7 +105,7 @@ func TestExpectKnownValue_CheckState_AttributeValueNull(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("string_attribute"), - knownvalue.NullExact(), + knownvalue.Null(), ), }, }, @@ -132,7 +132,7 @@ func TestExpectKnownValue_CheckState_Bool(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("bool_attribute"), - knownvalue.BoolExact(true), + knownvalue.Bool(true), ), }, }, @@ -187,10 +187,10 @@ func TestExpectKnownValue_CheckState_Bool_KnownValueWrongValue(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("bool_attribute"), - knownvalue.BoolExact(false), + knownvalue.Bool(false), ), }, - ExpectError: regexp.MustCompile("expected value false for BoolExact check, got: true"), + ExpectError: regexp.MustCompile("expected value false for Bool check, got: true"), }, }, }) @@ -1273,9 +1273,9 @@ func TestExpectKnownValue_CheckState_String_KnownValueWrongType(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("string_attribute"), - knownvalue.BoolExact(true)), + knownvalue.Bool(true)), }, - ExpectError: regexp.MustCompile("expected bool value for BoolExact check, got: string"), + ExpectError: regexp.MustCompile("expected bool value for Bool check, got: string"), }, }, }) diff --git a/website/docs/plugin/testing/acceptance-tests/known-value-checks/bool.mdx b/website/docs/plugin/testing/acceptance-tests/known-value-checks/bool.mdx index dfcb6e06b..a996b569a 100644 --- a/website/docs/plugin/testing/acceptance-tests/known-value-checks/bool.mdx +++ b/website/docs/plugin/testing/acceptance-tests/known-value-checks/bool.mdx @@ -8,13 +8,13 @@ description: >- The known value checks that are available for bool values are: -* [BoolExact](/terraform/plugin/testing/acceptance-tests/known-value-checks/bool#boolexact-check) +* [Bool](/terraform/plugin/testing/acceptance-tests/known-value-checks/bool#bool-check) -## `BoolExact` Check +## `Bool` Check -The [BoolExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#BoolExact) check tests that a resource attribute, or output value has an exactly matching bool value. +The [Bool](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#Bool) check tests that a resource attribute, or output value has an exactly matching bool value. -Example usage of [BoolExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#BoolExact) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/plan-checks/resource) plan check. +Example usage of [Bool](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#Bool) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/plan-checks/resource) plan check. ```go func TestExpectKnownValue_CheckPlan_Bool(t *testing.T) { @@ -32,7 +32,7 @@ func TestExpectKnownValue_CheckPlan_Bool(t *testing.T) { plancheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("bool_attribute"), - knownvalue.BoolExact(true), + knownvalue.Bool(true), ), }, }, diff --git a/website/docs/plugin/testing/acceptance-tests/known-value-checks/custom.mdx b/website/docs/plugin/testing/acceptance-tests/known-value-checks/custom.mdx index f5ce1d1de..892433ea6 100644 --- a/website/docs/plugin/testing/acceptance-tests/known-value-checks/custom.mdx +++ b/website/docs/plugin/testing/acceptance-tests/known-value-checks/custom.mdx @@ -62,7 +62,7 @@ The `other` parameter passed to the `CheckValue` method is one of the following Refer to the following built-in known value checks for implementations that handle the different types that can be passed to the `CheckValue` method in the `other` parameter: -* [BoolExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#BoolExact) +* [Bool](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#Bool) * [Float64Exact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#Float64Exact) * [Int64Exact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#Int64Exact) * [ListExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#ListExact) diff --git a/website/docs/plugin/testing/acceptance-tests/known-value-checks/index.mdx b/website/docs/plugin/testing/acceptance-tests/known-value-checks/index.mdx index bc22d96e5..3da43b44c 100644 --- a/website/docs/plugin/testing/acceptance-tests/known-value-checks/index.mdx +++ b/website/docs/plugin/testing/acceptance-tests/known-value-checks/index.mdx @@ -20,7 +20,7 @@ Example uses in the testing module include: The known value check types are implemented within the `terraform-plugin-testing` module in the [`knownvalue` package](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue). Known value checks are instantiated by calling the relevant constructor function. ```go -knownvalue.BoolExact(true) +knownvalue.Bool(true) ``` For known value checks that represent collections, or objects, nesting of known value checks can be used to define a "composite" known value check for use in asserting against a resource attribute, or output value that contains other values. diff --git a/website/docs/plugin/testing/acceptance-tests/known-value-checks/null.mdx b/website/docs/plugin/testing/acceptance-tests/known-value-checks/null.mdx index 58d95ce8d..69dc32340 100644 --- a/website/docs/plugin/testing/acceptance-tests/known-value-checks/null.mdx +++ b/website/docs/plugin/testing/acceptance-tests/known-value-checks/null.mdx @@ -8,13 +8,13 @@ description: >- The known value checks that are available for null values are: -* [NullExact](/terraform/plugin/testing/acceptance-tests/known-value-checks/null#nullexact-check) +* [Null](/terraform/plugin/testing/acceptance-tests/known-value-checks/null#null-check) -## `NullExact` Check +## `Null` Check -The [NullExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#NullExact) check tests that a resource attribute, or output value has an exactly matching null value. +The [Null](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#Null) check tests that a resource attribute, or output value has an exactly matching null value. -Example usage of [NullExact](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#NullExact) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/state-checks/resource) state check. +Example usage of [Null](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#Null) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/state-checks/resource) state check. ```go func TestExpectKnownValue_CheckState_AttributeValueNull(t *testing.T) { @@ -29,7 +29,7 @@ func TestExpectKnownValue_CheckState_AttributeValueNull(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("bool_attribute"), - knownvalue.NullExact(), + knownvalue.Null(), ), }, }, diff --git a/website/docs/plugin/testing/acceptance-tests/plan-checks/output.mdx b/website/docs/plugin/testing/acceptance-tests/plan-checks/output.mdx index 6dd2121cd..ce8c548af 100644 --- a/website/docs/plugin/testing/acceptance-tests/plan-checks/output.mdx +++ b/website/docs/plugin/testing/acceptance-tests/plan-checks/output.mdx @@ -44,7 +44,7 @@ func TestExpectKnownOutputValue_CheckPlan_Bool(t *testing.T) { PreApply: []plancheck.PlanCheck{ plancheck.ExpectKnownOutputValue( "bool_output", - knownvalue.BoolExact(true), + knownvalue.Bool(true), ), }, }, @@ -80,7 +80,7 @@ func TestExpectKnownOutputValue_CheckPlan_Bool(t *testing.T) { PreApply: []plancheck.PlanCheck{ plancheck.ExpectKnownOutputValue( "bool_output", - knownvalue.BoolExact(true), + knownvalue.Bool(true), ), }, }, diff --git a/website/docs/plugin/testing/acceptance-tests/state-checks/custom.mdx b/website/docs/plugin/testing/acceptance-tests/state-checks/custom.mdx index a71e3d765..299b18d51 100644 --- a/website/docs/plugin/testing/acceptance-tests/state-checks/custom.mdx +++ b/website/docs/plugin/testing/acceptance-tests/state-checks/custom.mdx @@ -114,7 +114,7 @@ func TestExpectKnownValue_CheckState_Bool(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("bool_attribute"), - knownvalue.BoolExact(true), + knownvalue.Bool(true), ), }, }, diff --git a/website/docs/plugin/testing/acceptance-tests/state-checks/output.mdx b/website/docs/plugin/testing/acceptance-tests/state-checks/output.mdx index b1e02da1f..3d937acb5 100644 --- a/website/docs/plugin/testing/acceptance-tests/state-checks/output.mdx +++ b/website/docs/plugin/testing/acceptance-tests/state-checks/output.mdx @@ -39,7 +39,7 @@ func TestExpectKnownOutputValue_CheckState_Bool(t *testing.T) { ConfigStateChecks: r.ConfigStateChecks{ statecheck.ExpectKnownOutputValue( "bool_output", - knownvalue.BoolExact(true), + knownvalue.Bool(true), ), }, }, @@ -74,7 +74,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_Bool(t *testing.T) { statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("bool_attribute"), - knownvalue.BoolExact(true), + knownvalue.Bool(true), ), }, }, diff --git a/website/docs/plugin/testing/acceptance-tests/state-checks/resource.mdx b/website/docs/plugin/testing/acceptance-tests/state-checks/resource.mdx index 582afbcdf..9a5acdb0e 100644 --- a/website/docs/plugin/testing/acceptance-tests/state-checks/resource.mdx +++ b/website/docs/plugin/testing/acceptance-tests/state-checks/resource.mdx @@ -36,7 +36,7 @@ func TestExpectKnownValue_CheckState_Bool(t *testing.T) { statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("bool_attribute"), - knownvalue.BoolExact(true), + knownvalue.Bool(true), ), }, }, From 04cf3c92a288b25e675238810003c5b10ebe361d Mon Sep 17 00:00:00 2001 From: Benjamin Bennett Date: Tue, 23 Jan 2024 11:18:21 +0000 Subject: [PATCH 28/29] Removing ConfigStateChecks type (#266) --- helper/resource/testing.go | 8 +- helper/resource/testing_new_config_test.go | 5 +- helper/resource/teststep_validate_test.go | 3 +- .../expect_known_output_value_at_path_test.go | 80 +++++++++---------- statecheck/expect_known_output_value_test.go | 80 +++++++++---------- statecheck/expect_known_value_test.go | 80 +++++++++---------- statecheck/expect_sensitive_value_test.go | 14 ++-- .../known-value-checks/null.mdx | 2 +- .../acceptance-tests/state-checks/custom.mdx | 2 +- .../acceptance-tests/state-checks/output.mdx | 4 +- .../state-checks/resource.mdx | 4 +- 11 files changed, 140 insertions(+), 142 deletions(-) diff --git a/helper/resource/testing.go b/helper/resource/testing.go index 5abda4eaa..4abdce8d6 100644 --- a/helper/resource/testing.go +++ b/helper/resource/testing.go @@ -591,12 +591,12 @@ type TestStep struct { // [plancheck]: https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/plancheck RefreshPlanChecks RefreshPlanChecks - // ConfigStateChecks allow assertions to be made against the state file at different points of a Config (apply) test using a state check. + // ConfigStateChecks allow assertions to be made against the state file during a Config (apply) test using a state check. // Custom state checks can be created by implementing the [StateCheck] interface, or by using a StateCheck implementation from the provided [statecheck] package // // [StateCheck]: https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/statecheck#StateCheck // [statecheck]: https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/statecheck - ConfigStateChecks ConfigStateChecks + ConfigStateChecks []statecheck.StateCheck // PlanOnly can be set to only run `plan` with this configuration, and not // actually apply it. This is useful for ensuring config changes result in @@ -803,10 +803,6 @@ type RefreshPlanChecks struct { PostRefresh []plancheck.PlanCheck } -// ConfigStateChecks runs all state checks in the slice. This occurs after the apply and refresh of a Config test are run. -// All errors by state checks in this slice are aggregated, reported, and will result in a test failure. -type ConfigStateChecks []statecheck.StateCheck - // ParallelTest performs an acceptance test on a resource, allowing concurrency // with other ParallelTest. The number of concurrent tests is controlled by the // "go test" command -parallel flag. diff --git a/helper/resource/testing_new_config_test.go b/helper/resource/testing_new_config_test.go index fe0eb707e..147a24dfa 100644 --- a/helper/resource/testing_new_config_test.go +++ b/helper/resource/testing_new_config_test.go @@ -15,6 +15,7 @@ import ( "github.com/hashicorp/terraform-plugin-testing/internal/testing/testsdk/providerserver" "github.com/hashicorp/terraform-plugin-testing/internal/testing/testsdk/resource" "github.com/hashicorp/terraform-plugin-testing/plancheck" + "github.com/hashicorp/terraform-plugin-testing/statecheck" "github.com/hashicorp/terraform-plugin-testing/tfversion" ) @@ -764,7 +765,7 @@ func Test_ConfigStateChecks_Called(t *testing.T) { Steps: []TestStep{ { Config: `resource "test_resource" "test" {}`, - ConfigStateChecks: ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ spy1, spy2, }, @@ -831,7 +832,7 @@ func Test_ConfigStateChecks_Errors(t *testing.T) { Steps: []TestStep{ { Config: `resource "test_resource" "test" {}`, - ConfigStateChecks: ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ spy1, spy2, spy3, diff --git a/helper/resource/teststep_validate_test.go b/helper/resource/teststep_validate_test.go index 6a326e003..a4e955b39 100644 --- a/helper/resource/teststep_validate_test.go +++ b/helper/resource/teststep_validate_test.go @@ -16,6 +16,7 @@ import ( "github.com/hashicorp/terraform-plugin-testing/config" "github.com/hashicorp/terraform-plugin-testing/internal/teststep" "github.com/hashicorp/terraform-plugin-testing/plancheck" + "github.com/hashicorp/terraform-plugin-testing/statecheck" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) @@ -468,7 +469,7 @@ func TestTestStepValidate(t *testing.T) { }, "configstatechecks-not-config-mode": { testStep: TestStep{ - ConfigStateChecks: ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ &stateCheckSpy{}, }, RefreshState: true, diff --git a/statecheck/expect_known_output_value_at_path_test.go b/statecheck/expect_known_output_value_at_path_test.go index c69c59887..83df97b48 100644 --- a/statecheck/expect_known_output_value_at_path_test.go +++ b/statecheck/expect_known_output_value_at_path_test.go @@ -39,7 +39,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_ResourceNotFound(t *testing.T) value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_two_output", tfjsonpath.New("bool_attribute"), @@ -69,7 +69,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_AttributeValueNull(t *testing.T value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("bool_attribute"), @@ -140,7 +140,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_Bool(t *testing.T) { value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("bool_attribute"), @@ -171,7 +171,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_Bool_KnownValueWrongType(t *tes value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("bool_attribute"), @@ -203,7 +203,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_Bool_KnownValueWrongValue(t *te value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("bool_attribute"), @@ -235,7 +235,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_Float64(t *testing.T) { value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("float_attribute"), @@ -267,7 +267,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_Float64_KnownValueWrongType(t * value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("float_attribute"), @@ -299,7 +299,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_Float64_KnownValueWrongValue(t value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("float_attribute"), @@ -331,7 +331,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_Int64(t *testing.T) { value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("int_attribute"), @@ -362,7 +362,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_Int64_KnownValueWrongValue(t *t value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("int_attribute"), @@ -397,7 +397,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_List(t *testing.T) { value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("list_attribute"), @@ -434,7 +434,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_List_KnownValueWrongType(t *tes value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("list_attribute"), @@ -469,7 +469,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_List_KnownValueWrongValue(t *te value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("list_attribute"), @@ -507,7 +507,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_ListPartial(t *testing.T) { value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("list_attribute"), @@ -545,7 +545,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_ListPartial_KnownValueWrongValu value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("list_attribute"), @@ -582,7 +582,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_ListElements(t *testing.T) { value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("list_attribute"), @@ -616,7 +616,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_ListElements_WrongNum(t *testin value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("list_attribute"), @@ -653,7 +653,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_ListNestedBlock(t *testing.T) { value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("list_nested_block"), @@ -696,7 +696,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_ListNestedBlockPartial(t *testi value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("list_nested_block"), @@ -736,7 +736,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_ListNestedBlockElements(t *test value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("list_nested_block"), @@ -770,7 +770,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_Map(t *testing.T) { value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("map_attribute"), @@ -807,7 +807,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_Map_KnownValueWrongType(t *test value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("map_attribute"), @@ -842,7 +842,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_Map_KnownValueWrongValue(t *tes value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("map_attribute"), @@ -880,7 +880,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_MapPartial(t *testing.T) { value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("map_attribute"), @@ -916,7 +916,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_MapPartial_KnownValueWrongValue value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("map_attribute"), @@ -953,7 +953,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_MapElements(t *testing.T) { value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("map_attribute"), @@ -987,7 +987,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_MapElements_WrongNum(t *testing value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("map_attribute"), @@ -1025,7 +1025,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_Number(t *testing.T) { value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("int_attribute"), @@ -1062,7 +1062,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_Number_KnownValueWrongValue(t * value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("int_attribute"), @@ -1097,7 +1097,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_Set(t *testing.T) { value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("set_attribute"), @@ -1134,7 +1134,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_Set_KnownValueWrongValue(t *tes value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("set_attribute"), @@ -1172,7 +1172,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_SetPartial(t *testing.T) { value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("set_attribute"), @@ -1208,7 +1208,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_SetPartial_KnownValueWrongValue value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("set_attribute"), @@ -1245,7 +1245,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_SetElements(t *testing.T) { value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("set_attribute"), @@ -1281,7 +1281,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_SetNestedBlock(t *testing.T) { value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("set_nested_block"), @@ -1324,7 +1324,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_SetNestedBlockPartial(t *testin value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("set_nested_block"), @@ -1364,7 +1364,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_SetNestedBlockElements(t *testi value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("set_nested_block"), @@ -1395,7 +1395,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_String(t *testing.T) { value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("string_attribute"), @@ -1425,7 +1425,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_String_KnownValueWrongType(t *t value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("string_attribute"), @@ -1456,7 +1456,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_String_KnownValueWrongValue(t * value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("string_attribute"), diff --git a/statecheck/expect_known_output_value_test.go b/statecheck/expect_known_output_value_test.go index 2eb65193e..c1cf98cf3 100644 --- a/statecheck/expect_known_output_value_test.go +++ b/statecheck/expect_known_output_value_test.go @@ -38,7 +38,7 @@ func TestExpectKnownOutputValue_CheckState_OutputNotFound(t *testing.T) { value = test_resource.one.bool_attribute } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "bool_not_found", knownvalue.Bool(true), @@ -70,7 +70,7 @@ func TestExpectKnownOutputValue_CheckState_AttributeValueNull(t *testing.T) { value = test_resource.one.bool_attribute } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "bool_output", knownvalue.Bool(true), @@ -101,7 +101,7 @@ func TestExpectKnownOutputValue_CheckState_Bool(t *testing.T) { value = test_resource.one.bool_attribute } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "bool_output", knownvalue.Bool(true), @@ -131,7 +131,7 @@ func TestExpectKnownOutputValue_CheckState_Bool_KnownValueWrongType(t *testing.T value = test_resource.one.bool_attribute } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "bool_output", knownvalue.Float64Exact(1.23), @@ -162,7 +162,7 @@ func TestExpectKnownOutputValue_CheckState_Bool_KnownValueWrongValue(t *testing. value = test_resource.one.bool_attribute } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "bool_output", knownvalue.Bool(false), @@ -193,7 +193,7 @@ func TestExpectKnownOutputValue_CheckState_Float64(t *testing.T) { value = test_resource.one.float_attribute } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "float64_output", knownvalue.Float64Exact(1.23), @@ -224,7 +224,7 @@ func TestExpectKnownOutputValue_CheckState_Float64_KnownValueWrongType(t *testin value = test_resource.one.float_attribute } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "float64_output", knownvalue.StringExact("str"), @@ -255,7 +255,7 @@ func TestExpectKnownOutputValue_CheckState_Float64_KnownValueWrongValue(t *testi value = test_resource.one.float_attribute } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "float64_output", knownvalue.Float64Exact(3.21), @@ -286,7 +286,7 @@ func TestExpectKnownOutputValue_CheckState_Int64(t *testing.T) { value = test_resource.one.int_attribute } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "int64_output", knownvalue.Int64Exact(123), @@ -316,7 +316,7 @@ func TestExpectKnownOutputValue_CheckState_Int64_KnownValueWrongValue(t *testing value = test_resource.one.int_attribute } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "int64_output", knownvalue.Int64Exact(321), @@ -350,7 +350,7 @@ func TestExpectKnownOutputValue_CheckState_List(t *testing.T) { value = test_resource.one.list_attribute } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "list_output", knownvalue.ListExact([]knownvalue.Check{ @@ -386,7 +386,7 @@ func TestExpectKnownOutputValue_CheckState_List_KnownValueWrongType(t *testing.T value = test_resource.one.list_attribute } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "list_output", knownvalue.MapExact(map[string]knownvalue.Check{}), @@ -420,7 +420,7 @@ func TestExpectKnownOutputValue_CheckState_List_KnownValueWrongValue(t *testing. value = test_resource.one.list_attribute } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "list_output", knownvalue.ListExact([]knownvalue.Check{ @@ -457,7 +457,7 @@ func TestExpectKnownOutputValue_CheckState_ListPartial(t *testing.T) { value = test_resource.one.list_attribute } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "list_output", knownvalue.ListPartial(map[int]knownvalue.Check{ @@ -494,7 +494,7 @@ func TestExpectKnownOutputValue_CheckState_ListPartial_KnownValueWrongValue(t *t value = test_resource.one.list_attribute } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "list_output", knownvalue.ListPartial(map[int]knownvalue.Check{ @@ -530,7 +530,7 @@ func TestExpectKnownOutputValue_CheckState_ListElements(t *testing.T) { value = test_resource.one.list_attribute } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "list_output", knownvalue.ListSizeExact(2), @@ -563,7 +563,7 @@ func TestExpectKnownOutputValue_CheckState_ListElements_WrongNum(t *testing.T) { value = test_resource.one.list_attribute } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "list_output", knownvalue.ListSizeExact(3), @@ -599,7 +599,7 @@ func TestExpectKnownOutputValue_CheckState_ListNestedBlock(t *testing.T) { value = test_resource.one.list_nested_block } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "list_nested_block_output", knownvalue.ListExact([]knownvalue.Check{ @@ -641,7 +641,7 @@ func TestExpectKnownOutputValue_CheckState_ListNestedBlockPartial(t *testing.T) value = test_resource.one.list_nested_block } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "list_nested_block_output", knownvalue.ListPartial(map[int]knownvalue.Check{ @@ -680,7 +680,7 @@ func TestExpectKnownOutputValue_CheckState_ListNestedBlockElements(t *testing.T) value = test_resource.one.list_nested_block } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "list_nested_block_output", knownvalue.ListSizeExact(2), @@ -713,7 +713,7 @@ func TestExpectKnownOutputValue_CheckState_Map(t *testing.T) { value = test_resource.one.map_attribute } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "map_output", knownvalue.MapExact(map[string]knownvalue.Check{ @@ -749,7 +749,7 @@ func TestExpectKnownOutputValue_CheckState_Map_KnownValueWrongType(t *testing.T) value = test_resource.one.map_attribute } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "map_output", knownvalue.ListExact([]knownvalue.Check{}), @@ -783,7 +783,7 @@ func TestExpectKnownOutputValue_CheckState_Map_KnownValueWrongValue(t *testing.T value = test_resource.one.map_attribute } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "map_output", knownvalue.MapExact(map[string]knownvalue.Check{ @@ -820,7 +820,7 @@ func TestExpectKnownOutputValue_CheckState_MapPartial(t *testing.T) { value = test_resource.one.map_attribute } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "map_output", knownvalue.MapPartial(map[string]knownvalue.Check{ @@ -855,7 +855,7 @@ func TestExpectKnownOutputValue_CheckState_MapPartial_KnownValueWrongValue(t *te value = test_resource.one.map_attribute } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "map_output", knownvalue.MapPartial(map[string]knownvalue.Check{ @@ -891,7 +891,7 @@ func TestExpectKnownOutputValue_CheckState_MapElements(t *testing.T) { value = test_resource.one.map_attribute } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "map_output", knownvalue.MapSizeExact(2), @@ -924,7 +924,7 @@ func TestExpectKnownOutputValue_CheckState_MapElements_WrongNum(t *testing.T) { value = test_resource.one.map_attribute } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "map_output", knownvalue.MapSizeExact(3), @@ -961,7 +961,7 @@ func TestExpectKnownOutputValue_CheckState_Number(t *testing.T) { value = test_resource.one.int_attribute } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "int64_output", knownvalue.NumberExact(f), @@ -997,7 +997,7 @@ func TestExpectKnownOutputValue_CheckState_Number_KnownValueWrongValue(t *testin value = test_resource.one.int_attribute } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "int64_output", knownvalue.NumberExact(f), @@ -1031,7 +1031,7 @@ func TestExpectKnownOutputValue_CheckState_Set(t *testing.T) { value = test_resource.one.set_attribute } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "set_output", knownvalue.SetExact([]knownvalue.Check{ @@ -1067,7 +1067,7 @@ func TestExpectKnownOutputValue_CheckState_Set_KnownValueWrongValue(t *testing.T value = test_resource.one.set_attribute } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "set_output", knownvalue.SetExact([]knownvalue.Check{ @@ -1104,7 +1104,7 @@ func TestExpectKnownOutputValue_CheckState_SetPartial(t *testing.T) { value = test_resource.one.set_attribute } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "set_output", knownvalue.SetPartial([]knownvalue.Check{ @@ -1139,7 +1139,7 @@ func TestExpectKnownOutputValue_CheckState_SetPartial_KnownValueWrongValue(t *te value = test_resource.one.set_attribute } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "set_output", knownvalue.SetPartial([]knownvalue.Check{ @@ -1175,7 +1175,7 @@ func TestExpectKnownOutputValue_CheckState_SetElements(t *testing.T) { value = test_resource.one.set_attribute } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "set_output", knownvalue.SetSizeExact(2), @@ -1210,7 +1210,7 @@ func TestExpectKnownOutputValue_CheckState_SetNestedBlock(t *testing.T) { value = test_resource.one.set_nested_block } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "set_nested_block_output", knownvalue.SetExact([]knownvalue.Check{ @@ -1252,7 +1252,7 @@ func TestExpectKnownOutputValue_CheckState_SetNestedBlockPartial(t *testing.T) { value = test_resource.one.set_nested_block } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "set_nested_block_output", knownvalue.SetPartial([]knownvalue.Check{ @@ -1291,7 +1291,7 @@ func TestExpectKnownOutputValue_CheckState_SetNestedBlockElements(t *testing.T) value = test_resource.one.set_nested_block } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "set_nested_block_output", knownvalue.SetSizeExact(2), @@ -1321,7 +1321,7 @@ func TestExpectKnownOutputValue_CheckState_String(t *testing.T) { value = test_resource.one.string_attribute } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "string_output", knownvalue.StringExact("str")), @@ -1350,7 +1350,7 @@ func TestExpectKnownOutputValue_CheckState_String_KnownValueWrongType(t *testing value = test_resource.one.string_attribute } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "string_output", knownvalue.Bool(true)), @@ -1380,7 +1380,7 @@ func TestExpectKnownOutputValue_CheckState_String_KnownValueWrongValue(t *testin value = test_resource.one.string_attribute } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "string_output", knownvalue.StringExact("rts")), diff --git a/statecheck/expect_known_value_test.go b/statecheck/expect_known_value_test.go index eeca817d0..f9c89bed0 100644 --- a/statecheck/expect_known_value_test.go +++ b/statecheck/expect_known_value_test.go @@ -36,7 +36,7 @@ func TestExpectKnownValue_CheckState_ResourceNotFound(t *testing.T) { bool_attribute = true } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.two", tfjsonpath.New("bool_attribute"), @@ -61,7 +61,7 @@ func TestExpectKnownValue_CheckState_AttributeValueNull(t *testing.T) { Steps: []r.TestStep{ { Config: `resource "test_resource" "one" {}`, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("bool_attribute"), @@ -128,7 +128,7 @@ func TestExpectKnownValue_CheckState_Bool(t *testing.T) { bool_attribute = true } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("bool_attribute"), @@ -155,7 +155,7 @@ func TestExpectKnownValue_CheckState_Bool_KnownValueWrongType(t *testing.T) { bool_attribute = true } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("bool_attribute"), @@ -183,7 +183,7 @@ func TestExpectKnownValue_CheckState_Bool_KnownValueWrongValue(t *testing.T) { bool_attribute = true } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("bool_attribute"), @@ -211,7 +211,7 @@ func TestExpectKnownValue_CheckState_Float64(t *testing.T) { float_attribute = 1.23 } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("float_attribute"), @@ -239,7 +239,7 @@ func TestExpectKnownValue_CheckState_Float64_KnownValueWrongType(t *testing.T) { float_attribute = 1.23 } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("float_attribute"), @@ -267,7 +267,7 @@ func TestExpectKnownValue_CheckState_Float64_KnownValueWrongValue(t *testing.T) float_attribute = 1.23 } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("float_attribute"), @@ -295,7 +295,7 @@ func TestExpectKnownValue_CheckState_Int64(t *testing.T) { int_attribute = 123 } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("int_attribute"), @@ -322,7 +322,7 @@ func TestExpectKnownValue_CheckState_Int64_KnownValueWrongValue(t *testing.T) { int_attribute = 123 } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("int_attribute"), @@ -353,7 +353,7 @@ func TestExpectKnownValue_CheckState_List(t *testing.T) { ] } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("list_attribute"), @@ -386,7 +386,7 @@ func TestExpectKnownValue_CheckState_List_KnownValueWrongType(t *testing.T) { ] } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("list_attribute"), @@ -417,7 +417,7 @@ func TestExpectKnownValue_CheckState_List_KnownValueWrongValue(t *testing.T) { ] } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("list_attribute"), @@ -451,7 +451,7 @@ func TestExpectKnownValue_CheckState_ListPartial(t *testing.T) { ] } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("list_attribute"), @@ -485,7 +485,7 @@ func TestExpectKnownValue_CheckState_ListPartial_KnownValueWrongValue(t *testing ] } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("list_attribute"), @@ -518,7 +518,7 @@ func TestExpectKnownValue_CheckState_ListElements(t *testing.T) { ] } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("list_attribute"), @@ -548,7 +548,7 @@ func TestExpectKnownValue_CheckState_ListElements_WrongNum(t *testing.T) { ] } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("list_attribute"), @@ -581,7 +581,7 @@ func TestExpectKnownValue_CheckState_ListNestedBlock(t *testing.T) { } } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("list_nested_block"), @@ -620,7 +620,7 @@ func TestExpectKnownValue_CheckState_ListNestedBlockPartial(t *testing.T) { } } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("list_nested_block"), @@ -656,7 +656,7 @@ func TestExpectKnownValue_CheckState_ListNestedBlockElements(t *testing.T) { } } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("list_nested_block"), @@ -686,7 +686,7 @@ func TestExpectKnownValue_CheckState_Map(t *testing.T) { } } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("map_attribute"), @@ -719,7 +719,7 @@ func TestExpectKnownValue_CheckState_Map_KnownValueWrongType(t *testing.T) { } } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("map_attribute"), @@ -750,7 +750,7 @@ func TestExpectKnownValue_CheckState_Map_KnownValueWrongValue(t *testing.T) { } } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("map_attribute"), @@ -784,7 +784,7 @@ func TestExpectKnownValue_CheckState_MapPartial(t *testing.T) { } } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("map_attribute"), @@ -816,7 +816,7 @@ func TestExpectKnownValue_CheckState_MapPartial_KnownValueWrongValue(t *testing. } } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("map_attribute"), @@ -849,7 +849,7 @@ func TestExpectKnownValue_CheckState_MapElements(t *testing.T) { } } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("map_attribute"), @@ -879,7 +879,7 @@ func TestExpectKnownValue_CheckState_MapElements_WrongNum(t *testing.T) { } } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("map_attribute"), @@ -913,7 +913,7 @@ func TestExpectKnownValue_CheckState_Number(t *testing.T) { int_attribute = 123 } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("int_attribute"), @@ -946,7 +946,7 @@ func TestExpectKnownValue_CheckState_Number_KnownValueWrongValue(t *testing.T) { int_attribute = 123 } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("int_attribute"), @@ -977,7 +977,7 @@ func TestExpectKnownValue_CheckState_Set(t *testing.T) { ] } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("set_attribute"), @@ -1010,7 +1010,7 @@ func TestExpectKnownValue_CheckState_Set_KnownValueWrongValue(t *testing.T) { ] } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("set_attribute"), @@ -1044,7 +1044,7 @@ func TestExpectKnownValue_CheckState_SetPartial(t *testing.T) { ] } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("set_attribute"), @@ -1076,7 +1076,7 @@ func TestExpectKnownValue_CheckState_SetPartial_KnownValueWrongValue(t *testing. ] } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("set_attribute"), @@ -1109,7 +1109,7 @@ func TestExpectKnownValue_CheckState_SetElements(t *testing.T) { ] } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("set_attribute"), @@ -1141,7 +1141,7 @@ func TestExpectKnownValue_CheckState_SetNestedBlock(t *testing.T) { } } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("set_nested_block"), @@ -1180,7 +1180,7 @@ func TestExpectKnownValue_CheckState_SetNestedBlockPartial(t *testing.T) { } } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("set_nested_block"), @@ -1216,7 +1216,7 @@ func TestExpectKnownValue_CheckState_SetNestedBlockElements(t *testing.T) { } } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("set_nested_block"), @@ -1243,7 +1243,7 @@ func TestExpectKnownValue_CheckState_String(t *testing.T) { string_attribute = "str" } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("string_attribute"), @@ -1269,7 +1269,7 @@ func TestExpectKnownValue_CheckState_String_KnownValueWrongType(t *testing.T) { string_attribute = "str" } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("string_attribute"), @@ -1296,7 +1296,7 @@ func TestExpectKnownValue_CheckState_String_KnownValueWrongValue(t *testing.T) { string_attribute = "str" } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("string_attribute"), diff --git a/statecheck/expect_sensitive_value_test.go b/statecheck/expect_sensitive_value_test.go index 5723d73b4..55a44840a 100644 --- a/statecheck/expect_sensitive_value_test.go +++ b/statecheck/expect_sensitive_value_test.go @@ -36,7 +36,7 @@ func Test_ExpectSensitiveValue_SensitiveStringAttribute(t *testing.T) { sensitive_string_attribute = "test" } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectSensitiveValue("test_resource.one", tfjsonpath.New("sensitive_string_attribute")), }, @@ -64,7 +64,7 @@ func Test_ExpectSensitiveValue_SensitiveListAttribute(t *testing.T) { sensitive_list_attribute = ["value1"] } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectSensitiveValue("test_resource.one", tfjsonpath.New("sensitive_list_attribute")), }, @@ -92,7 +92,7 @@ func Test_ExpectSensitiveValue_SensitiveSetAttribute(t *testing.T) { sensitive_set_attribute = ["value1"] } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectSensitiveValue("test_resource.one", tfjsonpath.New("sensitive_set_attribute")), }, @@ -122,7 +122,7 @@ func Test_ExpectSensitiveValue_SensitiveMapAttribute(t *testing.T) { } } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectSensitiveValue("test_resource.one", tfjsonpath.New("sensitive_map_attribute")), }, @@ -153,7 +153,7 @@ func Test_ExpectSensitiveValue_ListNestedBlock_SensitiveAttribute(t *testing.T) } } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectSensitiveValue("test_resource.one", tfjsonpath.New("list_nested_block_sensitive_attribute").AtSliceIndex(0). AtMapKey("sensitive_list_nested_block_attribute")), @@ -185,7 +185,7 @@ func Test_ExpectSensitiveValue_SetNestedBlock_SensitiveAttribute(t *testing.T) { } } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectSensitiveValue("test_resource.one", tfjsonpath.New("set_nested_block_sensitive_attribute")), }, @@ -211,7 +211,7 @@ func Test_ExpectSensitiveValue_ExpectError_ResourceNotFound(t *testing.T) { Config: ` resource "test_resource" "one" {} `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectSensitiveValue("test_resource.two", tfjsonpath.New("set_attribute")), }, ExpectError: regexp.MustCompile(`test_resource.two - Resource not found in state`), diff --git a/website/docs/plugin/testing/acceptance-tests/known-value-checks/null.mdx b/website/docs/plugin/testing/acceptance-tests/known-value-checks/null.mdx index 69dc32340..0ab575e39 100644 --- a/website/docs/plugin/testing/acceptance-tests/known-value-checks/null.mdx +++ b/website/docs/plugin/testing/acceptance-tests/known-value-checks/null.mdx @@ -25,7 +25,7 @@ func TestExpectKnownValue_CheckState_AttributeValueNull(t *testing.T) { Steps: []r.TestStep{ { Config: `resource "test_resource" "one" {}`, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("bool_attribute"), diff --git a/website/docs/plugin/testing/acceptance-tests/state-checks/custom.mdx b/website/docs/plugin/testing/acceptance-tests/state-checks/custom.mdx index 299b18d51..230923cd2 100644 --- a/website/docs/plugin/testing/acceptance-tests/state-checks/custom.mdx +++ b/website/docs/plugin/testing/acceptance-tests/state-checks/custom.mdx @@ -110,7 +110,7 @@ func TestExpectKnownValue_CheckState_Bool(t *testing.T) { bool_attribute = true } `, - ConfigStateChecks: resource.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("bool_attribute"), diff --git a/website/docs/plugin/testing/acceptance-tests/state-checks/output.mdx b/website/docs/plugin/testing/acceptance-tests/state-checks/output.mdx index 3d937acb5..cad493698 100644 --- a/website/docs/plugin/testing/acceptance-tests/state-checks/output.mdx +++ b/website/docs/plugin/testing/acceptance-tests/state-checks/output.mdx @@ -36,7 +36,7 @@ func TestExpectKnownOutputValue_CheckState_Bool(t *testing.T) { value = test_resource.one.bool_attribute } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValue( "bool_output", knownvalue.Bool(true), @@ -70,7 +70,7 @@ func TestExpectKnownOutputValueAtPath_CheckState_Bool(t *testing.T) { value = test_resource.one } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownOutputValueAtPath( "test_resource_one_output", tfjsonpath.New("bool_attribute"), diff --git a/website/docs/plugin/testing/acceptance-tests/state-checks/resource.mdx b/website/docs/plugin/testing/acceptance-tests/state-checks/resource.mdx index 9a5acdb0e..18109b54d 100644 --- a/website/docs/plugin/testing/acceptance-tests/state-checks/resource.mdx +++ b/website/docs/plugin/testing/acceptance-tests/state-checks/resource.mdx @@ -32,7 +32,7 @@ func TestExpectKnownValue_CheckState_Bool(t *testing.T) { bool_attribute = true } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("bool_attribute"), @@ -67,7 +67,7 @@ func Test_ExpectSensitiveValue_SensitiveStringAttribute(t *testing.T) { sensitive_string_attribute = "test" } `, - ConfigStateChecks: r.ConfigStateChecks{ + ConfigStateChecks: []statecheck.StateCheck{ statecheck.ExpectSensitiveValue("test_resource.one", tfjsonpath.New("sensitive_string_attribute")), }, From 173d4b27ea75019e13eeda482a1477725179f6ea Mon Sep 17 00:00:00 2001 From: Benjamin Bennett Date: Tue, 23 Jan 2024 11:26:30 +0000 Subject: [PATCH 29/29] Move execution of ConfigStateChecks (#266) --- helper/resource/testing_new_config.go | 40 +++++++++++++-------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/helper/resource/testing_new_config.go b/helper/resource/testing_new_config.go index 17d3745fa..9747eaf6e 100644 --- a/helper/resource/testing_new_config.go +++ b/helper/resource/testing_new_config.go @@ -205,6 +205,26 @@ func testStepNewConfig(ctx context.Context, t testing.T, c TestCase, wd *plugint } } } + + // Run state checks + if len(step.ConfigStateChecks) > 0 { + var state *tfjson.State + + err = runProviderCommand(ctx, t, func() error { + var err error + state, err = wd.State(ctx) + return err + }, wd, providers) + + if err != nil { + return fmt.Errorf("Error retrieving post-apply, post-refresh state: %w", err) + } + + err = runStateChecks(ctx, t, state, step.ConfigStateChecks) + if err != nil { + return fmt.Errorf("Post-apply refresh state check(s) failed:\n%w", err) + } + } } // Test for perpetual diffs by performing a plan, a refresh, and another plan @@ -313,26 +333,6 @@ func testStepNewConfig(ctx context.Context, t testing.T, c TestCase, wd *plugint } } - // Run post-apply, post-refresh state checks - if len(step.ConfigStateChecks) > 0 { - var state *tfjson.State - - err = runProviderCommand(ctx, t, func() error { - var err error - state, err = wd.State(ctx) - return err - }, wd, providers) - - if err != nil { - return fmt.Errorf("Error retrieving post-apply, post-refresh state: %w", err) - } - - err = runStateChecks(ctx, t, state, step.ConfigStateChecks) - if err != nil { - return fmt.Errorf("Post-apply refresh state check(s) failed:\n%w", err) - } - } - // check if plan is empty if !planIsEmpty(plan, helper.TerraformVersion()) && !step.ExpectNonEmptyPlan { var stdout string