diff --git a/.changes/1.12.0.md b/.changes/1.12.0.md new file mode 100644 index 000000000..a7032b292 --- /dev/null +++ b/.changes/1.12.0.md @@ -0,0 +1,19 @@ +## 1.12.0 (March 18, 2025) + +NOTES: + +* all: This Go module has been updated to Go 1.23 per the [Go support policy](https://go.dev/doc/devel/release#policy). It is recommended to review the [Go 1.23 release notes](https://go.dev/doc/go1.23) before upgrading. Any consumers building on earlier Go versions may experience errors. ([#454](https://github.com/hashicorp/terraform-plugin-testing/issues/454)) + +FEATURES: + +* knownvalue: added function checks for custom validation of resource attribute or output values. ([#412](https://github.com/hashicorp/terraform-plugin-testing/issues/412)) + +ENHANCEMENTS: + +* knownvalue: Updated the `ObjectExact` error message to report extra/missing attributes from the actual object. ([#451](https://github.com/hashicorp/terraform-plugin-testing/issues/451)) +* plancheck: Improved the unknown value plan check error messages to include a known value if one exists. ([#450](https://github.com/hashicorp/terraform-plugin-testing/issues/450)) + +BUG FIXES: + +* plancheck: Fixed bug with all unknown value plan checks where a valid path would return a "path not found" error. ([#450](https://github.com/hashicorp/terraform-plugin-testing/issues/450)) + diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 922ee27f4..d51ee4eac 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1,17 @@ * @hashicorp/terraform-devex + +# engineering and web presence get notified of, and can approve changes to web tooling, but not content. + +/website/ @hashicorp/web-presence @hashicorp/terraform-devex +/website/data/ +/website/public/ +/website/content/ + +# education and engineering get notified of, and can approve changes to web content. + +/website/data/ @hashicorp/team-docs-packer-and-terraform @hashicorp/terraform-devex +/website/public/ @hashicorp/team-docs-packer-and-terraform @hashicorp/terraform-devex +/website/content/ @hashicorp/team-docs-packer-and-terraform @hashicorp/terraform-devex +/website/docs/ @hashicorp/team-docs-packer-and-terraform @hashicorp/terraform-devex +/website/img/ @hashicorp/team-docs-packer-and-terraform @hashicorp/terraform-devex +/website/README.md @hashicorp/team-docs-packer-and-terraform @hashicorp/terraform-devex \ No newline at end of file diff --git a/.github/workflows/ci-github-actions.yml b/.github/workflows/ci-github-actions.yml index 9d7e22dc9..8451dde35 100644 --- a/.github/workflows/ci-github-actions.yml +++ b/.github/workflows/ci-github-actions.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 + - uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0 with: go-version-file: 'go.mod' - run: go install github.com/rhysd/actionlint/cmd/actionlint@latest diff --git a/.github/workflows/ci-go.yml b/.github/workflows/ci-go.yml index 05b8918d8..61a7e6260 100644 --- a/.github/workflows/ci-go.yml +++ b/.github/workflows/ci-go.yml @@ -17,21 +17,21 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 + - uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0 with: go-version-file: 'go.mod' - run: go mod download - - uses: golangci/golangci-lint-action@971e284b6050e8a5849b72094c50ab08da042db8 # v6.1.1 + - uses: golangci/golangci-lint-action@2226d7cb06a077cd73e56eedd38eecad18e5d837 # v6.5.0 test: name: test (Go ${{ matrix.go-version }} / TF ${{ matrix.terraform }}) runs-on: ubuntu-latest strategy: matrix: - go-version: [ '1.23', '1.22' ] + go-version: [ '1.24', '1.23' ] terraform: ${{ fromJSON(vars.TF_VERSIONS_PROTOCOL_V5) }} steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 + - uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0 with: go-version: ${{ matrix.go-version }} - uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2 @@ -49,7 +49,7 @@ jobs: wildcard=".*" echo "version=${orginal_version%"$wildcard"}" >> "$GITHUB_OUTPUT" - run: go tool cover -html=coverage.out -o coverage.html - - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + - uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1 with: name: go-${{ matrix.go-version }}-terraform-${{ steps.tf_version.outputs.version }}-coverage path: coverage.html diff --git a/.github/workflows/ci-goreleaser.yml b/.github/workflows/ci-goreleaser.yml index 2c0ae1af4..76735ffb5 100644 --- a/.github/workflows/ci-goreleaser.yml +++ b/.github/workflows/ci-goreleaser.yml @@ -15,9 +15,9 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 + - uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0 with: go-version-file: 'go.mod' - - uses: goreleaser/goreleaser-action@9ed2f89a662bf1735a48bc8557fd212fa902bebf # v6.1.0 + - uses: goreleaser/goreleaser-action@90a3faa9d0182683851fbfa97ca1a2cb983bfca3 # v6.2.1 with: args: check diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4899981c4..eb7bc6abf 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -84,7 +84,7 @@ jobs: ref: ${{ inputs.versionNumber }} fetch-depth: 0 - - uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 + - uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0 with: go-version-file: 'go.mod' @@ -93,7 +93,7 @@ jobs: cd .changes sed -e "1{/# /d;}" -e "2{/^$/d;}" ${{ needs.changelog-version.outputs.version }}.md > /tmp/release-notes.txt - - uses: goreleaser/goreleaser-action@9ed2f89a662bf1735a48bc8557fd212fa902bebf # v6.1.0 + - uses: goreleaser/goreleaser-action@90a3faa9d0182683851fbfa97ca1a2cb983bfca3 # v6.2.1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: diff --git a/.golangci.yml b/.golangci.yml index 78387e63c..8b0f17d94 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,13 +1,13 @@ issues: - max-per-linter: 0 + max-issues-per-linter: 0 max-same-issues: 0 linters: disable-all: true enable: + - copyloopvar - durationcheck - errcheck - - exportloopref - forcetypeassert - gofmt - gosimple @@ -18,12 +18,12 @@ linters: - paralleltest - predeclared - staticcheck - - tenv - unconvert - unparam - unused + - usetesting - govet run: # Prevent false positive timeouts in CI - timeout: 5m \ No newline at end of file + timeout: 5m diff --git a/CHANGELOG.md b/CHANGELOG.md index 96b3b8c20..9af99a795 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,22 @@ +## 1.12.0 (March 18, 2025) + +NOTES: + +* all: This Go module has been updated to Go 1.23 per the [Go support policy](https://go.dev/doc/devel/release#policy). It is recommended to review the [Go 1.23 release notes](https://go.dev/doc/go1.23) before upgrading. Any consumers building on earlier Go versions may experience errors. ([#454](https://github.com/hashicorp/terraform-plugin-testing/issues/454)) + +FEATURES: + +* knownvalue: added function checks for custom validation of resource attribute or output values. ([#412](https://github.com/hashicorp/terraform-plugin-testing/issues/412)) + +ENHANCEMENTS: + +* knownvalue: Updated the `ObjectExact` error message to report extra/missing attributes from the actual object. ([#451](https://github.com/hashicorp/terraform-plugin-testing/issues/451)) +* plancheck: Improved the unknown value plan check error messages to include a known value if one exists. ([#450](https://github.com/hashicorp/terraform-plugin-testing/issues/450)) + +BUG FIXES: + +* plancheck: Fixed bug with all unknown value plan checks where a valid path would return a "path not found" error. ([#450](https://github.com/hashicorp/terraform-plugin-testing/issues/450)) + ## 1.11.0 (November 19, 2024) NOTES: diff --git a/README.md b/README.md index 4f12b82e9..f14d5e49b 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ When run from the root of a Terraform Provider codebase, Terraform’s testing f This project follows the [support policy](https://golang.org/doc/devel/release.html#policy) of Go as its support policy. The two latest major releases of Go are supported by the project. -Currently, that means Go **1.22** or later must be used when including this project as a dependency. +Currently, that means Go **1.23** or later must be used when including this project as a dependency. ## Contributing diff --git a/compare/values_differ_test.go b/compare/values_differ_test.go index 35653f339..6a6988721 100644 --- a/compare/values_differ_test.go +++ b/compare/values_differ_test.go @@ -47,8 +47,6 @@ func TestValuesDiffer_CompareValues(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/compare/values_same_test.go b/compare/values_same_test.go index dde2ee6ea..e868ab0ea 100644 --- a/compare/values_same_test.go +++ b/compare/values_same_test.go @@ -49,8 +49,6 @@ func TestValuesSame_CompareValues(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/config/directory_test.go b/config/directory_test.go index 22225cc75..2418c40f4 100644 --- a/config/directory_test.go +++ b/config/directory_test.go @@ -39,8 +39,6 @@ func TestTestStepConfigFunc_Exec_Directory(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/config/file_test.go b/config/file_test.go index c5cd49ac3..db60cba6a 100644 --- a/config/file_test.go +++ b/config/file_test.go @@ -39,8 +39,6 @@ func TestTestStepConfigFunc_Exec_File(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/config/variable_test.go b/config/variable_test.go index cdec9b7f1..8cea766cc 100644 --- a/config/variable_test.go +++ b/config/variable_test.go @@ -273,8 +273,6 @@ func TestMarshalJSON(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() @@ -321,8 +319,6 @@ func TestVariablesWrite(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/go.mod b/go.mod index 3b3681e58..0c532d06f 100644 --- a/go.mod +++ b/go.mod @@ -1,30 +1,30 @@ module github.com/hashicorp/terraform-plugin-testing -go 1.22.0 +go 1.23.0 -toolchain go1.22.7 +toolchain go1.23.7 require ( - github.com/google/go-cmp v0.6.0 - github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 + github.com/google/go-cmp v0.7.0 + github.com/hashicorp/go-cty v1.5.0 github.com/hashicorp/go-hclog v1.6.3 github.com/hashicorp/go-uuid v1.0.3 github.com/hashicorp/go-version v1.7.0 - github.com/hashicorp/hc-install v0.9.0 + github.com/hashicorp/hc-install v0.9.1 github.com/hashicorp/hcl/v2 v2.23.0 github.com/hashicorp/logutils v1.0.0 - github.com/hashicorp/terraform-exec v0.21.0 - github.com/hashicorp/terraform-json v0.23.0 - github.com/hashicorp/terraform-plugin-go v0.25.0 + github.com/hashicorp/terraform-exec v0.22.0 + github.com/hashicorp/terraform-json v0.24.0 + github.com/hashicorp/terraform-plugin-go v0.26.0 github.com/hashicorp/terraform-plugin-log v0.9.0 - github.com/hashicorp/terraform-plugin-sdk/v2 v2.35.0 + github.com/hashicorp/terraform-plugin-sdk/v2 v2.36.1 github.com/mitchellh/go-testing-interface v1.14.1 - github.com/zclconf/go-cty v1.15.0 - golang.org/x/crypto v0.29.0 + github.com/zclconf/go-cty v1.16.2 + golang.org/x/crypto v0.36.0 ) require ( - github.com/ProtonMail/go-crypto v1.1.0-alpha.2 // indirect + github.com/ProtonMail/go-crypto v1.1.3 // indirect github.com/agext/levenshtein v1.2.2 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/cloudflare/circl v1.3.7 // indirect @@ -36,7 +36,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-plugin v1.6.2 // indirect github.com/hashicorp/go-retryablehttp v0.7.7 // indirect - github.com/hashicorp/terraform-registry-address v0.2.3 // indirect + github.com/hashicorp/terraform-registry-address v0.2.4 // indirect github.com/hashicorp/terraform-svchost v0.1.1 // indirect github.com/hashicorp/yamux v0.1.1 // indirect github.com/mattn/go-colorable v0.1.13 // indirect @@ -49,14 +49,14 @@ require ( github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect - golang.org/x/mod v0.21.0 // indirect - golang.org/x/net v0.28.0 // indirect - golang.org/x/sync v0.9.0 // indirect - golang.org/x/sys v0.27.0 // indirect - golang.org/x/text v0.20.0 // indirect + golang.org/x/mod v0.22.0 // indirect + golang.org/x/net v0.37.0 // indirect + golang.org/x/sync v0.12.0 // indirect + golang.org/x/sys v0.31.0 // indirect + golang.org/x/text v0.23.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect - google.golang.org/grpc v1.67.1 // indirect - google.golang.org/protobuf v1.35.1 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 // indirect + google.golang.org/grpc v1.69.4 // indirect + google.golang.org/protobuf v1.36.3 // indirect ) diff --git a/go.sum b/go.sum index 8ed2849a4..f56d072f5 100644 --- a/go.sum +++ b/go.sum @@ -2,8 +2,8 @@ dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= -github.com/ProtonMail/go-crypto v1.1.0-alpha.2 h1:bkyFVUP+ROOARdgCiJzNQo2V2kiB97LyUpzH9P6Hrlg= -github.com/ProtonMail/go-crypto v1.1.0-alpha.2/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= +github.com/ProtonMail/go-crypto v1.1.3 h1:nRBOetoydLeUb4nHajyO2bKqMLfWQ/ZPwkXqXxPxCFk= +github.com/ProtonMail/go-crypto v1.1.3/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= github.com/agext/levenshtein v1.2.2 h1:0S/Yg6LYmFJ5stwQeRp6EeOcCbj7xiqQSdNelsXvaqE= github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec= @@ -13,8 +13,8 @@ github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZ github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= -github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= -github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= +github.com/cyphar/filepath-securejoin v0.2.5 h1:6iR5tXJ/e6tJZzzdMc1km3Sa7RRIVBKAK32O2s7AYfo= +github.com/cyphar/filepath-securejoin v0.2.5/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -25,10 +25,14 @@ github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= -github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= -github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= -github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys= -github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY= +github.com/go-git/go-billy/v5 v5.6.0 h1:w2hPNtoehvJIxR00Vb4xX94qHQi/ApZfX+nBE2Cjio8= +github.com/go-git/go-billy/v5 v5.6.0/go.mod h1:sFDq7xD3fn3E0GOwUSZqHo9lrkmx8xJhA0ZrfvjBRGM= +github.com/go-git/go-git/v5 v5.13.0 h1:vLn5wlGIh/X78El6r3Jr+30W16Blk0CTcxTYcYPWi5E= +github.com/go-git/go-git/v5 v5.13.0/go.mod h1:Wjo7/JyVKtQgUNdXYXIepzWfJQkUEIGvkvVkiXRR/zw= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= @@ -40,8 +44,10 @@ github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-checkpoint v0.5.0 h1:MFYpPZCnQqQTE18jFwSII6eUQrD/oxMFp3mlgcqk5mU= @@ -49,8 +55,8 @@ github.com/hashicorp/go-checkpoint v0.5.0/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuD github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 h1:1/D3zfFHttUKaCaGKZ/dR2roBXv0vKbSCnssIldfQdI= -github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320/go.mod h1:EiZBMaudVLy8fmjf9Npq1dq9RalhveqZG5w/yz3mHWs= +github.com/hashicorp/go-cty v1.5.0 h1:EkQ/v+dDNUqnuVpmS5fPqyY71NXVgT5gf32+57xY8g0= +github.com/hashicorp/go-cty v1.5.0/go.mod h1:lFUCG5kd8exDobgSfyj4ONE/dc822kiYMguVKdHGMLM= github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= @@ -64,24 +70,24 @@ github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/C github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/hc-install v0.9.0 h1:2dIk8LcvANwtv3QZLckxcjyF5w8KVtiMxu6G6eLhghE= -github.com/hashicorp/hc-install v0.9.0/go.mod h1:+6vOP+mf3tuGgMApVYtmsnDoKWMDcFXeTxCACYZ8SFg= +github.com/hashicorp/hc-install v0.9.1 h1:gkqTfE3vVbafGQo6VZXcy2v5yoz2bE0+nhZXruCuODQ= +github.com/hashicorp/hc-install v0.9.1/go.mod h1:pWWvN/IrfeBK4XPeXXYkL6EjMufHkCK5DvwxeLKuBf0= github.com/hashicorp/hcl/v2 v2.23.0 h1:Fphj1/gCylPxHutVSEOf2fBOh1VE4AuLV7+kbJf3qos= github.com/hashicorp/hcl/v2 v2.23.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA= github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/terraform-exec v0.21.0 h1:uNkLAe95ey5Uux6KJdua6+cv8asgILFVWkd/RG0D2XQ= -github.com/hashicorp/terraform-exec v0.21.0/go.mod h1:1PPeMYou+KDUSSeRE9szMZ/oHf4fYUmB923Wzbq1ICg= -github.com/hashicorp/terraform-json v0.23.0 h1:sniCkExU4iKtTADReHzACkk8fnpQXrdD2xoR+lppBkI= -github.com/hashicorp/terraform-json v0.23.0/go.mod h1:MHdXbBAbSg0GvzuWazEGKAn/cyNfIB7mN6y7KJN6y2c= -github.com/hashicorp/terraform-plugin-go v0.25.0 h1:oi13cx7xXA6QciMcpcFi/rwA974rdTxjqEhXJjbAyks= -github.com/hashicorp/terraform-plugin-go v0.25.0/go.mod h1:+SYagMYadJP86Kvn+TGeV+ofr/R3g4/If0O5sO96MVw= +github.com/hashicorp/terraform-exec v0.22.0 h1:G5+4Sz6jYZfRYUCg6eQgDsqTzkNXV+fP8l+uRmZHj64= +github.com/hashicorp/terraform-exec v0.22.0/go.mod h1:bjVbsncaeh8jVdhttWYZuBGj21FcYw6Ia/XfHcNO7lQ= +github.com/hashicorp/terraform-json v0.24.0 h1:rUiyF+x1kYawXeRth6fKFm/MdfBS6+lW4NbeATsYz8Q= +github.com/hashicorp/terraform-json v0.24.0/go.mod h1:Nfj5ubo9xbu9uiAoZVBsNOjvNKB66Oyrvtit74kC7ow= +github.com/hashicorp/terraform-plugin-go v0.26.0 h1:cuIzCv4qwigug3OS7iKhpGAbZTiypAfFQmw8aE65O2M= +github.com/hashicorp/terraform-plugin-go v0.26.0/go.mod h1:+CXjuLDiFgqR+GcrM5a2E2Kal5t5q2jb0E3D57tTdNY= github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0= github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow= -github.com/hashicorp/terraform-plugin-sdk/v2 v2.35.0 h1:wyKCCtn6pBBL46c1uIIBNUOWlNfYXfXpVo16iDyLp8Y= -github.com/hashicorp/terraform-plugin-sdk/v2 v2.35.0/go.mod h1:B0Al8NyYVr8Mp/KLwssKXG1RqnTk7FySqSn4fRuLNgw= -github.com/hashicorp/terraform-registry-address v0.2.3 h1:2TAiKJ1A3MAkZlH1YI/aTVcLZRu7JseiXNRHbOAyoTI= -github.com/hashicorp/terraform-registry-address v0.2.3/go.mod h1:lFHA76T8jfQteVfT7caREqguFrW3c4MFSPhZB7HHgUM= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.36.1 h1:WNMsTLkZf/3ydlgsuXePa3jvZFwAJhruxTxP/c1Viuw= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.36.1/go.mod h1:P6o64QS97plG44iFzSM6rAn6VJIC/Sy9a9IkEtl79K4= +github.com/hashicorp/terraform-registry-address v0.2.4 h1:JXu/zHB2Ymg/TGVCRu10XqNa4Sh2bWcqCNyKWjnCPJA= +github.com/hashicorp/terraform-registry-address v0.2.4/go.mod h1:tUNYTVyCtU4OIGXXMDp7WNcJ+0W1B4nmstVDgHMjfAU= github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ= github.com/hashicorp/terraform-svchost v0.1.1/go.mod h1:mNsjQfZyf/Jhz35v6/0LWcv26+X7JPS+buii2c9/ctc= github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= @@ -124,8 +130,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= -github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A= -github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= +github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY= +github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5LvTDjFK7M= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= @@ -140,28 +146,38 @@ github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/zclconf/go-cty v1.15.0 h1:tTCRWxsexYUmtt/wVxgDClUe+uQusuI443uL6e+5sXQ= -github.com/zclconf/go-cty v1.15.0/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= +github.com/zclconf/go-cty v1.16.2 h1:LAJSwc3v81IRBZyUVQDUdZ7hs3SYs9jv0eZJDWHD/70= +github.com/zclconf/go-cty v1.16.2/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940 h1:4r45xpDWB6ZMSMNJFMOjqrGHynW3DIBuR2H9j0ug+Mo= github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940/go.mod h1:CmBdvvj3nqzfzJ6nTCIwDTPZ56aVGvDrmztiO5g3qrM= +go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY= +go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE= +go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE= +go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY= +go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk= +go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0= +go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4JjxTeYusH7zMc= +go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8= +go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys= +go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= -golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= +golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= +golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= -golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= +golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c= +golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= -golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= +golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -174,19 +190,18 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= -golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU= -golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E= +golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y= +golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= -golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= +golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= +golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= @@ -197,14 +212,14 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= -google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 h1:X58yt85/IXCx0Y3ZwN6sEIKZzQtDEYaBWrDvErdXrRE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= +google.golang.org/grpc v1.69.4 h1:MF5TftSMkd8GLw/m0KM6V8CMOCY6NZ1NQDPGFgbTt4A= +google.golang.org/grpc v1.69.4/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= -google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.3 h1:82DV7MYdb8anAVi3qge1wSnMDrnKK7ebr+I0hHRN1BU= +google.golang.org/protobuf v1.36.3/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/helper/acctest/random_test.go b/helper/acctest/random_test.go index 85064780f..ebeab89e3 100644 --- a/helper/acctest/random_test.go +++ b/helper/acctest/random_test.go @@ -96,8 +96,6 @@ func TestRandSSHKeyPair(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() @@ -198,7 +196,6 @@ func TestInverseMask(t *testing.T) { } for tName, tCase := range testCases { - tName, tCase := tName, tCase t.Run(tName, func(t *testing.T) { t.Parallel() diff --git a/helper/resource/plugin_test.go b/helper/resource/plugin_test.go index ac8244185..e3b159963 100644 --- a/helper/resource/plugin_test.go +++ b/helper/resource/plugin_test.go @@ -79,8 +79,6 @@ func TestProtoV5ProviderFactoriesMerge(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() @@ -154,8 +152,6 @@ func TestProtoV6ProviderFactoriesMerge(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() @@ -229,8 +225,6 @@ func TestSdkProviderFactoriesMerge(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/helper/resource/testcase_providers_test.go b/helper/resource/testcase_providers_test.go index 45af1c784..4b54d725d 100644 --- a/helper/resource/testcase_providers_test.go +++ b/helper/resource/testcase_providers_test.go @@ -231,8 +231,6 @@ provider "test" {}`, } for name, test := range tests { - name, test := name, test - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/helper/resource/testcase_validate_test.go b/helper/resource/testcase_validate_test.go index a3aa09b59..7e79492be 100644 --- a/helper/resource/testcase_validate_test.go +++ b/helper/resource/testcase_validate_test.go @@ -36,8 +36,6 @@ func TestTestCaseHasExternalProviders(t *testing.T) { } for name, test := range tests { - name, test := name, test - t.Run(name, func(t *testing.T) { t.Parallel() @@ -104,8 +102,6 @@ func TestTestCaseHasProviders(t *testing.T) { } for name, test := range tests { - name, test := name, test - t.Run(name, func(t *testing.T) { t.Parallel() @@ -184,8 +180,6 @@ func TestTestCaseValidate(t *testing.T) { } for name, test := range tests { - name, test := name, test - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/helper/resource/testing_new_test.go b/helper/resource/testing_new_test.go index c285c1b13..22f726261 100644 --- a/helper/resource/testing_new_test.go +++ b/helper/resource/testing_new_test.go @@ -1125,8 +1125,6 @@ func TestShimState(t *testing.T) { } for i, tc := range testCases { - i, tc := i, tc - t.Run(fmt.Sprintf("%d-%s", i, tc.Name), func(t *testing.T) { t.Parallel() diff --git a/helper/resource/testing_sets_test.go b/helper/resource/testing_sets_test.go index 0805a90b5..4d50e7ecc 100644 --- a/helper/resource/testing_sets_test.go +++ b/helper/resource/testing_sets_test.go @@ -402,7 +402,6 @@ func TestTestCheckTypeSetElemAttr(t *testing.T) { } for _, testCase := range testCases { - testCase := testCase t.Run(testCase.Description, func(t *testing.T) { t.Parallel() @@ -1010,7 +1009,6 @@ func TestTestCheckTypeSetElemAttrPair(t *testing.T) { } for _, testCase := range testCases { - testCase := testCase t.Run(testCase.Description, func(t *testing.T) { t.Parallel() @@ -1754,7 +1752,6 @@ func TestTestMatchTypeSetElemNestedAttrs(t *testing.T) { } for _, testCase := range testCases { - testCase := testCase t.Run(testCase.Description, func(t *testing.T) { t.Parallel() @@ -2593,7 +2590,6 @@ func TestTestCheckTypeSetElemNestedAttrs(t *testing.T) { } for _, testCase := range testCases { - testCase := testCase t.Run(testCase.Description, func(t *testing.T) { t.Parallel() diff --git a/helper/resource/testing_test.go b/helper/resource/testing_test.go index 00137efc9..cfd8afcff 100644 --- a/helper/resource/testing_test.go +++ b/helper/resource/testing_test.go @@ -177,7 +177,7 @@ func TestTest_Main(t *testing.T) { for _, tc := range cases { // reset sweepers sweeperFuncs = map[string]*Sweeper{} - tc := tc + t.Run(tc.Name, func(t *testing.T) { t.Parallel() @@ -389,7 +389,6 @@ func TestFilterSweepers(t *testing.T) { for _, tc := range cases { // reset sweepers sweeperFuncs = map[string]*Sweeper{} - tc := tc t.Run(tc.Name, func(t *testing.T) { t.Parallel() @@ -634,7 +633,6 @@ func TestFilterSweeperWithDependencies(t *testing.T) { for _, tc := range cases { // reset sweepers sweeperFuncs = map[string]*Sweeper{} - tc := tc t.Run(tc.Name, func(t *testing.T) { t.Parallel() @@ -813,7 +811,6 @@ func TestRunSweepers(t *testing.T) { for _, tc := range cases { // reset sweepers sweeperFuncs = map[string]*Sweeper{} - tc := tc t.Run(tc.Name, func(t *testing.T) { t.Parallel() @@ -1363,8 +1360,6 @@ func TestTestCheckResourceAttr(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() @@ -1778,8 +1773,6 @@ func TestTestCheckResourceAttrWith(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() @@ -2000,8 +1993,6 @@ func TestTestCheckNoResourceAttr(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() @@ -2295,8 +2286,6 @@ func TestTestCheckResourceAttrPair(t *testing.T) { } for name, test := range tests { - name, test := name, test - t.Run(name, func(t *testing.T) { t.Parallel() @@ -2431,8 +2420,6 @@ func TestTestCheckResourceAttrSet(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/helper/resource/teststep_providers_test.go b/helper/resource/teststep_providers_test.go index e4d1fd7fb..68a5c4621 100644 --- a/helper/resource/teststep_providers_test.go +++ b/helper/resource/teststep_providers_test.go @@ -657,8 +657,6 @@ resource "test_test" "test" {} } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() @@ -1382,8 +1380,6 @@ resource "test_test" "test" {} } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() @@ -1601,8 +1597,6 @@ provider "test" {} } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() @@ -1856,8 +1850,6 @@ terraform { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/helper/resource/teststep_validate_test.go b/helper/resource/teststep_validate_test.go index a4e955b39..e040726d5 100644 --- a/helper/resource/teststep_validate_test.go +++ b/helper/resource/teststep_validate_test.go @@ -43,8 +43,6 @@ func TestTestStepHasExternalProviders(t *testing.T) { } for name, test := range tests { - name, test := name, test - t.Run(name, func(t *testing.T) { t.Parallel() @@ -105,8 +103,6 @@ func TestTestStepHasProviders(t *testing.T) { var stepIndex int for name, test := range tests { - name, test := name, test - t.Run(name, func(t *testing.T) { t.Parallel() @@ -510,8 +506,6 @@ func TestTestStepValidate(t *testing.T) { } for name, test := range tests { - name, test := name, test - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/helper/resource/tfversion_checks_test.go b/helper/resource/tfversion_checks_test.go index 0bc2238f4..6410bc732 100644 --- a/helper/resource/tfversion_checks_test.go +++ b/helper/resource/tfversion_checks_test.go @@ -48,8 +48,6 @@ func TestRunTFVersionChecks(t *testing.T) { } for name, test := range tests { - name, test := name, test - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/internal/configs/configschema/coerce_value_test.go b/internal/configs/configschema/coerce_value_test.go index 9363e7075..30ea60e04 100644 --- a/internal/configs/configschema/coerce_value_test.go +++ b/internal/configs/configschema/coerce_value_test.go @@ -546,8 +546,6 @@ func TestCoerceValue(t *testing.T) { } for name, test := range tests { - name, test := name, test - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/internal/configs/configschema/empty_value_test.go b/internal/configs/configschema/empty_value_test.go index 6b7d758da..cd7642568 100644 --- a/internal/configs/configschema/empty_value_test.go +++ b/internal/configs/configschema/empty_value_test.go @@ -163,7 +163,6 @@ func TestBlockEmptyValue(t *testing.T) { } for _, test := range tests { - test := test t.Run(fmt.Sprintf("%#v", test.Schema), func(t *testing.T) { t.Parallel() diff --git a/internal/configs/configschema/implied_type_test.go b/internal/configs/configschema/implied_type_test.go index 5da233a91..1faf25252 100644 --- a/internal/configs/configschema/implied_type_test.go +++ b/internal/configs/configschema/implied_type_test.go @@ -119,8 +119,6 @@ func TestBlockImpliedType(t *testing.T) { } for name, test := range tests { - name, test := name, test - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/internal/configs/hcl2shim/flatmap_test.go b/internal/configs/hcl2shim/flatmap_test.go index 410887fa2..3eb5fead2 100644 --- a/internal/configs/hcl2shim/flatmap_test.go +++ b/internal/configs/hcl2shim/flatmap_test.go @@ -243,7 +243,6 @@ func TestFlatmapValueFromHCL2(t *testing.T) { } for _, test := range tests { - test := test t.Run(test.Value.GoString(), func(t *testing.T) { t.Parallel() @@ -312,7 +311,6 @@ func TestFlatmapValueFromHCL2FromFlatmap(t *testing.T) { } for _, test := range tests { - test := test t.Run(test.Name, func(t *testing.T) { t.Parallel() @@ -740,8 +738,6 @@ func TestHCL2ValueFromFlatmap(t *testing.T) { } for i, test := range tests { - i, test := i, test - t.Run(fmt.Sprintf("%d %#v as %#v", i, test.Flatmap, test.Type), func(t *testing.T) { t.Parallel() diff --git a/internal/configs/hcl2shim/paths_test.go b/internal/configs/hcl2shim/paths_test.go index 82ce4b68f..1b5c38373 100644 --- a/internal/configs/hcl2shim/paths_test.go +++ b/internal/configs/hcl2shim/paths_test.go @@ -211,7 +211,6 @@ func TestPathFromFlatmap(t *testing.T) { } for _, test := range tests { - test := test t.Run(fmt.Sprintf("%s as %#v", test.Flatmap, test.Type), func(t *testing.T) { t.Parallel() @@ -364,7 +363,6 @@ func TestRequiresReplace(t *testing.T) { }, }, } { - tc := tc t.Run(tc.name, func(t *testing.T) { t.Parallel() @@ -413,8 +411,6 @@ func TestFlatmapKeyFromPath(t *testing.T) { attr: "attr.key.obj_attr.0.force_new", }, } { - i, tc := i, tc - t.Run(strconv.Itoa(i), func(t *testing.T) { t.Parallel() diff --git a/internal/configs/hcl2shim/values_equiv_test.go b/internal/configs/hcl2shim/values_equiv_test.go index bfbb41ec1..35b40fe45 100644 --- a/internal/configs/hcl2shim/values_equiv_test.go +++ b/internal/configs/hcl2shim/values_equiv_test.go @@ -419,7 +419,6 @@ func TestValuesSDKEquivalent(t *testing.T) { } for _, test := range tests { - test := test t.Run(fmt.Sprintf("%#v ≈ %#v", test.A, test.B), func(t *testing.T) { t.Parallel() diff --git a/internal/configs/hcl2shim/values_test.go b/internal/configs/hcl2shim/values_test.go index e063bbed9..f14d76882 100644 --- a/internal/configs/hcl2shim/values_test.go +++ b/internal/configs/hcl2shim/values_test.go @@ -241,7 +241,6 @@ func TestConfigValueFromHCL2Block(t *testing.T) { } for _, test := range tests { - test := test t.Run(fmt.Sprintf("%#v", test.Input), func(t *testing.T) { t.Parallel() @@ -334,7 +333,6 @@ func TestConfigValueFromHCL2(t *testing.T) { } for _, test := range tests { - test := test t.Run(fmt.Sprintf("%#v", test.Input), func(t *testing.T) { t.Parallel() @@ -423,7 +421,6 @@ func TestHCL2ValueFromConfigValue(t *testing.T) { } for _, test := range tests { - test := test t.Run(fmt.Sprintf("%#v", test.Input), func(t *testing.T) { t.Parallel() diff --git a/internal/teststep/config_test.go b/internal/teststep/config_test.go index 5a5415cb7..7f7061b72 100644 --- a/internal/teststep/config_test.go +++ b/internal/teststep/config_test.go @@ -136,8 +136,6 @@ func TestPrepareConfigurationRequest_Exec(t *testing.T) { }) for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() @@ -198,8 +196,6 @@ func TestConfigurationRequest_Validate(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() @@ -262,8 +258,6 @@ func TestConfiguration(t *testing.T) { ) for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/internal/teststep/directory_test.go b/internal/teststep/directory_test.go index dfea5c663..0118b91d5 100644 --- a/internal/teststep/directory_test.go +++ b/internal/teststep/directory_test.go @@ -102,8 +102,6 @@ func TestConfigurationDirectory_HasProviderBlock(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() @@ -219,8 +217,6 @@ func TestConfigurationDirectory_HasProviderBlock_AbsolutePath(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() @@ -308,8 +304,6 @@ func TestConfigurationDirectory_HasTerraformBlock(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() @@ -389,8 +383,6 @@ func TestConfigurationDirectory_HasTerraformBlock_AbsolutePath(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() @@ -456,8 +448,6 @@ func TestConfigurationDirectory_Write(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() @@ -549,8 +539,6 @@ func TestConfigurationDirectory_Write_AbsolutePath(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/internal/teststep/file_test.go b/internal/teststep/file_test.go index 4854c2be9..5d0ebb73f 100644 --- a/internal/teststep/file_test.go +++ b/internal/teststep/file_test.go @@ -102,8 +102,6 @@ func TestConfigurationFile_HasProviderBlock(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() @@ -219,8 +217,6 @@ func TestConfigurationFile_HasProviderBlock_AbsolutePath(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() @@ -308,8 +304,6 @@ func TestConfigurationFile_HasTerraformBlock(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() @@ -389,8 +383,6 @@ func TestConfigurationFile_HasTerraformBlock_AbsolutePath(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() @@ -446,8 +438,6 @@ func TestConfigurationFile_Write(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() @@ -511,8 +501,6 @@ func TestConfigurationFile_Write_AbsolutePath(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/internal/teststep/string_test.go b/internal/teststep/string_test.go index cb9fdecdd..a55501efc 100644 --- a/internal/teststep/string_test.go +++ b/internal/teststep/string_test.go @@ -149,8 +149,6 @@ resource "test_test" "test" {} } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() @@ -240,8 +238,6 @@ resource "test_test" "test" {} } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() @@ -278,8 +274,6 @@ resource "test_test" "test" {} } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/knownvalue/bool_func.go b/knownvalue/bool_func.go new file mode 100644 index 000000000..15135c10f --- /dev/null +++ b/knownvalue/bool_func.go @@ -0,0 +1,39 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package knownvalue + +import "fmt" + +var _ Check = boolFunc{} + +type boolFunc struct { + checkFunc func(v bool) error +} + +// CheckValue determines whether the passed value is of type bool, and +// returns no error from the provided check function +func (v boolFunc) CheckValue(other any) error { + val, ok := other.(bool) + + if !ok { + return fmt.Errorf("expected bool value for BoolFunc check, got: %T", other) + } + + return v.checkFunc(val) +} + +// String returns the bool representation of the value. +func (v boolFunc) String() string { + // Validation is up the the implementer of the function, so there are no + // bool literal or regex comparers to print here + return "BoolFunc" +} + +// BoolFunc returns a Check for passing the bool value in state +// to the provided check function +func BoolFunc(fn func(v bool) error) boolFunc { + return boolFunc{ + checkFunc: fn, + } +} diff --git a/knownvalue/bool_func_test.go b/knownvalue/bool_func_test.go new file mode 100644 index 000000000..9d2b362b1 --- /dev/null +++ b/knownvalue/bool_func_test.go @@ -0,0 +1,75 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package knownvalue_test + +import ( + "encoding/json" + "fmt" + "testing" + + "github.com/google/go-cmp/cmp" + + "github.com/hashicorp/terraform-plugin-testing/knownvalue" +) + +func TestBoolFunc_CheckValue(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + self knownvalue.Check + other any + expectedError error + }{ + "nil": { + self: knownvalue.BoolFunc(func(bool) error { return nil }), + expectedError: fmt.Errorf("expected bool value for BoolFunc check, got: "), + }, + "wrong-type": { + self: knownvalue.BoolFunc(func(bool) error { return nil }), + other: json.Number("1.234"), + expectedError: fmt.Errorf("expected bool value for BoolFunc check, got: json.Number"), + }, + "failure": { + self: knownvalue.BoolFunc(func(b bool) error { + if b != true { + return fmt.Errorf("%t was not true", b) + } + return nil + }), + other: false, + expectedError: fmt.Errorf("%t was not true", false), + }, + "success": { + self: knownvalue.BoolFunc(func(b bool) error { + if b != true { + return fmt.Errorf("%t was not foo", b) + } + return nil + }), + other: true, + }, + } + + for name, testCase := range testCases { + 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 TestBoolFunc_String(t *testing.T) { + t.Parallel() + + got := knownvalue.BoolFunc(func(bool) error { return nil }).String() + + if diff := cmp.Diff(got, "BoolFunc"); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } +} diff --git a/knownvalue/bool_test.go b/knownvalue/bool_test.go index 35ba1d40e..aa962fec8 100644 --- a/knownvalue/bool_test.go +++ b/knownvalue/bool_test.go @@ -49,8 +49,6 @@ func TestBoolValue_CheckValue(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/knownvalue/float32_func.go b/knownvalue/float32_func.go new file mode 100644 index 000000000..5d3b55fcd --- /dev/null +++ b/knownvalue/float32_func.go @@ -0,0 +1,48 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package knownvalue + +import ( + "encoding/json" + "fmt" + "strconv" +) + +var _ Check = float32Func{} + +type float32Func struct { + checkFunc func(v float32) error +} + +// CheckValue determines whether the passed value is of type float32, and +// returns no error from the provided check function +func (v float32Func) CheckValue(other any) error { + jsonNum, ok := other.(json.Number) + + if !ok { + return fmt.Errorf("expected json.Number value for Float32Func check, got: %T", other) + } + + otherVal, err := strconv.ParseFloat(string(jsonNum), 32) + if err != nil { + return fmt.Errorf("expected json.Number to be parseable as float32 value for Float32Func check: %s", err) + } + + return v.checkFunc(float32(otherVal)) +} + +// String returns the float32 representation of the value. +func (v float32Func) String() string { + // Validation is up the the implementer of the function, so there are no + // float32 literal or regex comparers to print here + return "Float32Func" +} + +// Float32Func returns a Check for passing the float32 value in state +// to the provided check function +func Float32Func(fn func(v float32) error) float32Func { + return float32Func{ + checkFunc: fn, + } +} diff --git a/knownvalue/float32_func_test.go b/knownvalue/float32_func_test.go new file mode 100644 index 000000000..01b928e31 --- /dev/null +++ b/knownvalue/float32_func_test.go @@ -0,0 +1,80 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package knownvalue_test + +import ( + "encoding/json" + "fmt" + "testing" + + "github.com/google/go-cmp/cmp" + + "github.com/hashicorp/terraform-plugin-testing/knownvalue" +) + +func TestFloat32Func_CheckValue(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + self knownvalue.Check + other any + expectedError error + }{ + "nil": { + self: knownvalue.Float32Func(func(float32) error { return nil }), + expectedError: fmt.Errorf("expected json.Number value for Float32Func check, got: "), + }, + "wrong-type": { + self: knownvalue.Float32Func(func(float32) error { return nil }), + other: "wrongtype", + expectedError: fmt.Errorf("expected json.Number value for Float32Func check, got: string"), + }, + "no-digits": { + self: knownvalue.Float32Func(func(float32) error { return nil }), + other: json.Number("str"), + expectedError: fmt.Errorf("expected json.Number to be parseable as float32 value for Float32Func check: strconv.ParseFloat: parsing \"str\": invalid syntax"), + }, + "failure": { + self: knownvalue.Float32Func(func(f float32) error { + if f != 1.1 { + return fmt.Errorf("%f was not 1.1", f) + } + return nil + }), + other: json.Number("1.2"), + expectedError: fmt.Errorf("%f was not 1.1", 1.2), + }, + "success": { + self: knownvalue.Float32Func(func(f float32) error { + if f != 1.1 { + return fmt.Errorf("%f was not 1.1", f) + } + return nil + }), + other: json.Number("1.1"), + }, + } + + for name, testCase := range testCases { + 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 TestFloat32Func_String(t *testing.T) { + t.Parallel() + + got := knownvalue.Float32Func(func(float32) error { return nil }).String() + + if diff := cmp.Diff(got, "Float32Func"); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } +} diff --git a/knownvalue/float32_test.go b/knownvalue/float32_test.go index 4b2ef14c4..ecab29c0d 100644 --- a/knownvalue/float32_test.go +++ b/knownvalue/float32_test.go @@ -50,8 +50,6 @@ func TestFloat32Value_CheckValue(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/knownvalue/float64_func.go b/knownvalue/float64_func.go new file mode 100644 index 000000000..56f17e0c1 --- /dev/null +++ b/knownvalue/float64_func.go @@ -0,0 +1,48 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package knownvalue + +import ( + "encoding/json" + "fmt" + "strconv" +) + +var _ Check = float64Func{} + +type float64Func struct { + checkFunc func(v float64) error +} + +// CheckValue determines whether the passed value is of type float64, and +// returns no error from the provided check function +func (v float64Func) CheckValue(other any) error { + jsonNum, ok := other.(json.Number) + + if !ok { + return fmt.Errorf("expected json.Number value for Float64Func check, got: %T", other) + } + + otherVal, err := strconv.ParseFloat(string(jsonNum), 64) + if err != nil { + return fmt.Errorf("expected json.Number to be parseable as float64 value for Float64Func check: %s", err) + } + + return v.checkFunc(otherVal) +} + +// String returns the float64 representation of the value. +func (v float64Func) String() string { + // Validation is up the the implementer of the function, so there are no + // float64 literal or regex comparers to print here + return "Float64Func" +} + +// Float64Func returns a Check for passing the float64 value in state +// to the provided check function +func Float64Func(fn func(v float64) error) float64Func { + return float64Func{ + checkFunc: fn, + } +} diff --git a/knownvalue/float64_func_test.go b/knownvalue/float64_func_test.go new file mode 100644 index 000000000..8bc3884fe --- /dev/null +++ b/knownvalue/float64_func_test.go @@ -0,0 +1,80 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package knownvalue_test + +import ( + "encoding/json" + "fmt" + "testing" + + "github.com/google/go-cmp/cmp" + + "github.com/hashicorp/terraform-plugin-testing/knownvalue" +) + +func TestFloat64Func_CheckValue(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + self knownvalue.Check + other any + expectedError error + }{ + "nil": { + self: knownvalue.Float64Func(func(float64) error { return nil }), + expectedError: fmt.Errorf("expected json.Number value for Float64Func check, got: "), + }, + "wrong-type": { + self: knownvalue.Float64Func(func(float64) error { return nil }), + other: "wrongtype", + expectedError: fmt.Errorf("expected json.Number value for Float64Func check, got: string"), + }, + "no-digits": { + self: knownvalue.Float64Func(func(float64) error { return nil }), + other: json.Number("str"), + expectedError: fmt.Errorf("expected json.Number to be parseable as float64 value for Float64Func check: strconv.ParseFloat: parsing \"str\": invalid syntax"), + }, + "failure": { + self: knownvalue.Float64Func(func(f float64) error { + if f != 1.1 { + return fmt.Errorf("%f was not 1.1", f) + } + return nil + }), + other: json.Number("1.2"), + expectedError: fmt.Errorf("%f was not 1.1", 1.2), + }, + "success": { + self: knownvalue.Float64Func(func(f float64) error { + if f != 1.1 { + return fmt.Errorf("%f was not 1.1", f) + } + return nil + }), + other: json.Number("1.1"), + }, + } + + for name, testCase := range testCases { + 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 TestFloat64Func_String(t *testing.T) { + t.Parallel() + + got := knownvalue.Float64Func(func(float64) error { return nil }).String() + + if diff := cmp.Diff(got, "Float64Func"); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } +} diff --git a/knownvalue/float64_test.go b/knownvalue/float64_test.go index 2a051f8b2..26b2cf309 100644 --- a/knownvalue/float64_test.go +++ b/knownvalue/float64_test.go @@ -50,8 +50,6 @@ func TestFloat64Value_CheckValue(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/knownvalue/int32_func.go b/knownvalue/int32_func.go new file mode 100644 index 000000000..587f7aae6 --- /dev/null +++ b/knownvalue/int32_func.go @@ -0,0 +1,48 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package knownvalue + +import ( + "encoding/json" + "fmt" + "strconv" +) + +var _ Check = int32Func{} + +type int32Func struct { + checkFunc func(v int32) error +} + +// CheckValue determines whether the passed value is of type int32, and +// returns no error from the provided check function +func (v int32Func) CheckValue(other any) error { + jsonNum, ok := other.(json.Number) + + if !ok { + return fmt.Errorf("expected json.Number value for Int32Func check, got: %T", other) + } + + otherVal, err := strconv.ParseInt(string(jsonNum), 10, 32) + if err != nil { + return fmt.Errorf("expected json.Number to be parseable as int32 value for Int32Func check: %s", err) + } + + return v.checkFunc(int32(otherVal)) +} + +// String returns the int32 representation of the value. +func (v int32Func) String() string { + // Validation is up the the implementer of the function, so there are no + // int32 literal or regex comparers to print here + return "Int32Func" +} + +// Int32Func returns a Check for passing the int32 value in state +// to the provided check function +func Int32Func(fn func(v int32) error) int32Func { + return int32Func{ + checkFunc: fn, + } +} diff --git a/knownvalue/int32_func_test.go b/knownvalue/int32_func_test.go new file mode 100644 index 000000000..41776732d --- /dev/null +++ b/knownvalue/int32_func_test.go @@ -0,0 +1,80 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package knownvalue_test + +import ( + "encoding/json" + "fmt" + "testing" + + "github.com/google/go-cmp/cmp" + + "github.com/hashicorp/terraform-plugin-testing/knownvalue" +) + +func TestInt32Func_CheckValue(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + self knownvalue.Check + other any + expectedError error + }{ + "nil": { + self: knownvalue.Int32Func(func(int32) error { return nil }), + expectedError: fmt.Errorf("expected json.Number value for Int32Func check, got: "), + }, + "wrong-type": { + self: knownvalue.Int32Func(func(int32) error { return nil }), + other: "wrongtype", + expectedError: fmt.Errorf("expected json.Number value for Int32Func check, got: string"), + }, + "no-digits": { + self: knownvalue.Int32Func(func(int32) error { return nil }), + other: json.Number("str"), + expectedError: fmt.Errorf("expected json.Number to be parseable as int32 value for Int32Func check: strconv.ParseInt: parsing \"str\": invalid syntax"), + }, + "failure": { + self: knownvalue.Int32Func(func(i int32) error { + if i != 1 { + return fmt.Errorf("%d was not 1", i) + } + return nil + }), + other: json.Number("2"), + expectedError: fmt.Errorf("%d was not 1", 2), + }, + "success": { + self: knownvalue.Int32Func(func(i int32) error { + if i != 1 { + return fmt.Errorf("%d was not 1", i) + } + return nil + }), + other: json.Number("1"), + }, + } + + for name, testCase := range testCases { + 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 TestInt32Func_String(t *testing.T) { + t.Parallel() + + got := knownvalue.Int32Func(func(int32) error { return nil }).String() + + if diff := cmp.Diff(got, "Int32Func"); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } +} diff --git a/knownvalue/int32_test.go b/knownvalue/int32_test.go index b153dee29..158724ca0 100644 --- a/knownvalue/int32_test.go +++ b/knownvalue/int32_test.go @@ -50,8 +50,6 @@ func TestInt32Value_CheckValue(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/knownvalue/int64_func.go b/knownvalue/int64_func.go new file mode 100644 index 000000000..1269355c4 --- /dev/null +++ b/knownvalue/int64_func.go @@ -0,0 +1,48 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package knownvalue + +import ( + "encoding/json" + "fmt" + "strconv" +) + +var _ Check = int64Func{} + +type int64Func struct { + checkFunc func(v int64) error +} + +// CheckValue determines whether the passed value is of type int64, and +// returns no error from the provided check function +func (v int64Func) CheckValue(other any) error { + jsonNum, ok := other.(json.Number) + + if !ok { + return fmt.Errorf("expected json.Number value for Int64Func check, got: %T", other) + } + + otherVal, err := strconv.ParseInt(string(jsonNum), 10, 64) + if err != nil { + return fmt.Errorf("expected json.Number to be parseable as int64 value for Int64Func check: %s", err) + } + + return v.checkFunc(otherVal) +} + +// String returns the int64 representation of the value. +func (v int64Func) String() string { + // Validation is up the the implementer of the function, so there are no + // int64 literal or regex comparers to print here + return "Int64Func" +} + +// Int64Func returns a Check for passing the int64 value in state +// to the provided check function +func Int64Func(fn func(v int64) error) int64Func { + return int64Func{ + checkFunc: fn, + } +} diff --git a/knownvalue/int64_func_test.go b/knownvalue/int64_func_test.go new file mode 100644 index 000000000..56613f70c --- /dev/null +++ b/knownvalue/int64_func_test.go @@ -0,0 +1,80 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package knownvalue_test + +import ( + "encoding/json" + "fmt" + "testing" + + "github.com/google/go-cmp/cmp" + + "github.com/hashicorp/terraform-plugin-testing/knownvalue" +) + +func TestInt64Func_CheckValue(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + self knownvalue.Check + other any + expectedError error + }{ + "nil": { + self: knownvalue.Int64Func(func(int64) error { return nil }), + expectedError: fmt.Errorf("expected json.Number value for Int64Func check, got: "), + }, + "wrong-type": { + self: knownvalue.Int64Func(func(int64) error { return nil }), + other: "wrongtype", + expectedError: fmt.Errorf("expected json.Number value for Int64Func check, got: string"), + }, + "no-digits": { + self: knownvalue.Int64Func(func(int64) error { return nil }), + other: json.Number("str"), + expectedError: fmt.Errorf("expected json.Number to be parseable as int64 value for Int64Func check: strconv.ParseInt: parsing \"str\": invalid syntax"), + }, + "failure": { + self: knownvalue.Int64Func(func(i int64) error { + if i != 1 { + return fmt.Errorf("%d was not 1", i) + } + return nil + }), + other: json.Number("2"), + expectedError: fmt.Errorf("%d was not 1", 2), + }, + "success": { + self: knownvalue.Int64Func(func(i int64) error { + if i != 1 { + return fmt.Errorf("%d was not 1", i) + } + return nil + }), + other: json.Number("1"), + }, + } + + for name, testCase := range testCases { + 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 TestInt64Func_String(t *testing.T) { + t.Parallel() + + got := knownvalue.Int64Func(func(int64) error { return nil }).String() + + if diff := cmp.Diff(got, "Int64Func"); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } +} diff --git a/knownvalue/int64_test.go b/knownvalue/int64_test.go index f367f33a0..2f7cd7c50 100644 --- a/knownvalue/int64_test.go +++ b/knownvalue/int64_test.go @@ -50,8 +50,6 @@ func TestInt64Value_CheckValue(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/knownvalue/list_partial_test.go b/knownvalue/list_partial_test.go index 31cb6163c..eafb8d2e1 100644 --- a/knownvalue/list_partial_test.go +++ b/knownvalue/list_partial_test.go @@ -111,8 +111,6 @@ func TestListValuePartial_CheckValue(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/knownvalue/list_size_test.go b/knownvalue/list_size_test.go index 1ca2fd547..89e97d9d4 100644 --- a/knownvalue/list_size_test.go +++ b/knownvalue/list_size_test.go @@ -61,8 +61,6 @@ func TestListElements_CheckValue(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/knownvalue/list_test.go b/knownvalue/list_test.go index 8b11f1c96..6b6b700d2 100644 --- a/knownvalue/list_test.go +++ b/knownvalue/list_test.go @@ -108,8 +108,6 @@ func TestListValue_CheckValue(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/knownvalue/map_partial_test.go b/knownvalue/map_partial_test.go index 30bceae11..1cc3c2897 100644 --- a/knownvalue/map_partial_test.go +++ b/knownvalue/map_partial_test.go @@ -114,8 +114,6 @@ func TestMapValuePartial_CheckValue(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/knownvalue/map_size_test.go b/knownvalue/map_size_test.go index 9cf171738..d90814017 100644 --- a/knownvalue/map_size_test.go +++ b/knownvalue/map_size_test.go @@ -61,8 +61,6 @@ func TestMapElements_CheckValue(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/knownvalue/map_test.go b/knownvalue/map_test.go index 09e6736b5..59ff34458 100644 --- a/knownvalue/map_test.go +++ b/knownvalue/map_test.go @@ -121,8 +121,6 @@ func TestMapValue_CheckValue(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/knownvalue/not_null_test.go b/knownvalue/not_null_test.go index 908c4b769..4ed3e44d5 100644 --- a/knownvalue/not_null_test.go +++ b/knownvalue/not_null_test.go @@ -36,8 +36,6 @@ func TestNotNullValue_CheckValue(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/knownvalue/null_test.go b/knownvalue/null_test.go index a9cc33d97..d6cb27a2d 100644 --- a/knownvalue/null_test.go +++ b/knownvalue/null_test.go @@ -35,8 +35,6 @@ func TestNullValue_CheckValue(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/knownvalue/number_func.go b/knownvalue/number_func.go new file mode 100644 index 000000000..75cce4938 --- /dev/null +++ b/knownvalue/number_func.go @@ -0,0 +1,48 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package knownvalue + +import ( + "encoding/json" + "fmt" + "math/big" +) + +var _ Check = numberFunc{} + +type numberFunc struct { + checkFunc func(v *big.Float) error +} + +// CheckValue determines whether the passed value is of type int64, and +// returns no error from the provided check function +func (v numberFunc) CheckValue(other any) error { + jsonNum, ok := other.(json.Number) + + if !ok { + return fmt.Errorf("expected json.Number value for NumberFunc check, got: %T", other) + } + + otherVal, _, err := big.ParseFloat(jsonNum.String(), 10, 512, big.ToNearestEven) + if err != nil { + return fmt.Errorf("expected json.Number to be parseable as big.Float value for NumberFunc check: %s", err) + } + + return v.checkFunc(otherVal) +} + +// String returns the int64 representation of the value. +func (v numberFunc) String() string { + // Validation is up the the implementer of the function, so there are no + // int64 literal or regex comparers to print here + return "NumberFunc" +} + +// NumberFunc returns a Check for passing the int64 value in state +// to the provided check function +func NumberFunc(fn func(v *big.Float) error) numberFunc { + return numberFunc{ + checkFunc: fn, + } +} diff --git a/knownvalue/number_func_test.go b/knownvalue/number_func_test.go new file mode 100644 index 000000000..e9075c6e5 --- /dev/null +++ b/knownvalue/number_func_test.go @@ -0,0 +1,95 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package knownvalue_test + +import ( + "encoding/json" + "fmt" + "math/big" + "testing" + + "github.com/google/go-cmp/cmp" + + "github.com/hashicorp/terraform-plugin-testing/knownvalue" +) + +func TestNumberFunc_CheckValue(t *testing.T) { + t.Parallel() + + expected, _, err := big.ParseFloat("1.797693134862315797693134862315797693134862315", 10, 512, big.ToNearestEven) + if err != nil { + t.Errorf("%s", err) + } + + testCases := map[string]struct { + self knownvalue.Check + other any + expectedError error + }{ + "nil": { + self: knownvalue.NumberFunc(func(*big.Float) error { return nil }), + expectedError: fmt.Errorf("expected json.Number value for NumberFunc check, got: "), + }, + "wrong-type": { + self: knownvalue.NumberFunc(func(*big.Float) error { return nil }), + other: "wrongtype", + expectedError: fmt.Errorf("expected json.Number value for NumberFunc check, got: string"), + }, + "no-digits": { + self: knownvalue.NumberFunc(func(*big.Float) error { return nil }), + other: json.Number("str"), + expectedError: fmt.Errorf("expected json.Number to be parseable as big.Float value for NumberFunc check: number has no digits"), + }, + "failure": { + self: knownvalue.NumberFunc(func(i *big.Float) error { + if i.Cmp(expected) != 0 { + return fmt.Errorf("%s was not %s", i.Text('f', -1), expected.Text('f', -1)) + } + return nil + }), + other: json.Number("1.667114241575161769818551140818851511176942075"), + expectedError: fmt.Errorf("1.667114241575161769818551140818851511176942075 was not 1.797693134862315797693134862315797693134862315"), + }, + "success-precise-number": { + self: knownvalue.NumberFunc(func(i *big.Float) error { + if i.Cmp(expected) != 0 { + return fmt.Errorf("%s was not %s", i.Text('f', -1), expected.Text('f', -1)) + } + return nil + }), + other: json.Number("1.797693134862315797693134862315797693134862315"), + }, + "success-whole-number": { + self: knownvalue.NumberFunc(func(i *big.Float) error { + if i.Cmp(big.NewFloat(1)) != 0 { + return fmt.Errorf("%s was not %s", i.Text('f', -1), big.NewFloat(1).Text('f', -1)) + } + return nil + }), + other: json.Number("1"), + }, + } + + for name, testCase := range testCases { + 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 TestNumberFunc_String(t *testing.T) { + t.Parallel() + + got := knownvalue.NumberFunc(func(*big.Float) error { return nil }).String() + + if diff := cmp.Diff(got, "NumberFunc"); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } +} diff --git a/knownvalue/number_test.go b/knownvalue/number_test.go index 50f6e12d5..26446f50e 100644 --- a/knownvalue/number_test.go +++ b/knownvalue/number_test.go @@ -58,8 +58,6 @@ func TestNumberValue_Equal(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/knownvalue/object.go b/knownvalue/object.go index 87eabfb63..e15c03928 100644 --- a/knownvalue/object.go +++ b/knownvalue/object.go @@ -5,6 +5,8 @@ package knownvalue import ( "fmt" + "maps" + "slices" "sort" ) @@ -24,18 +26,14 @@ func (v objectExact) CheckValue(other any) error { } if len(otherVal) != len(v.value) { - expectedAttributes := "attributes" - actualAttributes := "attributes" - - if len(v.value) == 1 { - expectedAttributes = "attribute" - } - - if len(otherVal) == 1 { - actualAttributes = "attribute" + deltaMsg := "" + if len(otherVal) > len(v.value) { + deltaMsg = createDeltaString(otherVal, v.value, "actual value has extra attribute(s): ") + } else { + deltaMsg = createDeltaString(v.value, otherVal, "actual value is missing attribute(s): ") } - return fmt.Errorf("expected %d %s for ObjectExact check, got %d %s", len(v.value), expectedAttributes, len(otherVal), actualAttributes) + return fmt.Errorf("expected %d attribute(s) for ObjectExact check, got %d attribute(s): %s", len(v.value), len(otherVal), deltaMsg) } var keys []string @@ -92,3 +90,27 @@ func ObjectExact(value map[string]Check) objectExact { value: value, } } + +// createDeltaString prints the map keys that are present in mapA and not present in mapB +func createDeltaString[T any, V any](mapA map[string]T, mapB map[string]V, msgPrefix string) string { + deltaMsg := "" + + deltaMap := make(map[string]T, len(mapA)) + maps.Copy(deltaMap, mapA) + for key := range mapB { + delete(deltaMap, key) + } + + deltaKeys := slices.Sorted(maps.Keys(deltaMap)) + + for i, k := range deltaKeys { + if i == 0 { + deltaMsg += msgPrefix + } else if i != 0 { + deltaMsg += ", " + } + deltaMsg += fmt.Sprintf("%q", k) + } + + return deltaMsg +} diff --git a/knownvalue/object_partial_test.go b/knownvalue/object_partial_test.go index 20884d0e4..7fae38086 100644 --- a/knownvalue/object_partial_test.go +++ b/knownvalue/object_partial_test.go @@ -114,8 +114,6 @@ func TestObjectValuePartial_CheckValue(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/knownvalue/object_test.go b/knownvalue/object_test.go index 07693fbff..173aba0ae 100644 --- a/knownvalue/object_test.go +++ b/knownvalue/object_test.go @@ -53,9 +53,9 @@ func TestObjectValue_CheckValue(t *testing.T) { "three": knownvalue.Float64Exact(7.89), }), other: map[string]any{}, - expectedError: fmt.Errorf("expected 3 attributes for ObjectExact check, got 0 attributes"), + expectedError: fmt.Errorf("expected 3 attribute(s) for ObjectExact check, got 0 attribute(s): actual value is missing attribute(s): \"one\", \"three\", \"two\""), }, - "wrong-length": { + "missing-one-attribute": { self: knownvalue.ObjectExact(map[string]knownvalue.Check{ "one": knownvalue.Float64Exact(1.23), "two": knownvalue.Float64Exact(4.56), @@ -65,7 +65,47 @@ func TestObjectValue_CheckValue(t *testing.T) { "one": json.Number("1.23"), "two": json.Number("4.56"), }, - expectedError: fmt.Errorf("expected 3 attributes for ObjectExact check, got 2 attributes"), + expectedError: fmt.Errorf("expected 3 attribute(s) for ObjectExact check, got 2 attribute(s): actual value is missing attribute(s): \"three\""), + }, + "missing-multiple-attributes": { + self: knownvalue.ObjectExact(map[string]knownvalue.Check{ + "one": knownvalue.Float64Exact(1.23), + "two": knownvalue.Float64Exact(4.56), + "three": knownvalue.Float64Exact(7.89), + "four": knownvalue.Float64Exact(0.12), + "five": knownvalue.Float64Exact(3.45), + }), + other: map[string]any{ + "one": json.Number("1.23"), + "two": json.Number("4.56"), + }, + expectedError: fmt.Errorf("expected 5 attribute(s) for ObjectExact check, got 2 attribute(s): actual value is missing attribute(s): \"five\", \"four\", \"three\""), + }, + "extra-one-attribute": { + self: knownvalue.ObjectExact(map[string]knownvalue.Check{ + "one": knownvalue.Float64Exact(1.23), + "two": knownvalue.Float64Exact(4.56), + }), + other: map[string]any{ + "one": json.Number("1.23"), + "two": json.Number("4.56"), + "three": json.Number("7.89"), + }, + expectedError: fmt.Errorf("expected 2 attribute(s) for ObjectExact check, got 3 attribute(s): actual value has extra attribute(s): \"three\""), + }, + "extra-multiple-attributes": { + self: knownvalue.ObjectExact(map[string]knownvalue.Check{ + "one": knownvalue.Float64Exact(1.23), + "two": knownvalue.Float64Exact(4.56), + }), + other: map[string]any{ + "one": json.Number("1.23"), + "two": json.Number("4.56"), + "three": json.Number("7.89"), + "four": json.Number("0.12"), + "five": json.Number("3.45"), + }, + expectedError: fmt.Errorf("expected 2 attribute(s) for ObjectExact check, got 5 attribute(s): actual value has extra attribute(s): \"five\", \"four\", \"three\""), }, "not-equal": { self: knownvalue.ObjectExact(map[string]knownvalue.Check{ @@ -121,8 +161,6 @@ func TestObjectValue_CheckValue(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/knownvalue/set_partial_test.go b/knownvalue/set_partial_test.go index b58baff50..b936c4c97 100644 --- a/knownvalue/set_partial_test.go +++ b/knownvalue/set_partial_test.go @@ -98,8 +98,6 @@ func TestSetValuePartial_CheckValue(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/knownvalue/set_size_test.go b/knownvalue/set_size_test.go index aed263be6..b45dcdf32 100644 --- a/knownvalue/set_size_test.go +++ b/knownvalue/set_size_test.go @@ -61,8 +61,6 @@ func TestSetElements_CheckValue(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/knownvalue/set_test.go b/knownvalue/set_test.go index dad5cd849..125cd19cf 100644 --- a/knownvalue/set_test.go +++ b/knownvalue/set_test.go @@ -107,8 +107,6 @@ func TestSetValue_CheckValue(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/knownvalue/string_func.go b/knownvalue/string_func.go new file mode 100644 index 000000000..e1dc3f0b9 --- /dev/null +++ b/knownvalue/string_func.go @@ -0,0 +1,39 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package knownvalue + +import "fmt" + +var _ Check = stringFunc{} + +type stringFunc struct { + checkFunc func(v string) error +} + +// CheckValue determines whether the passed value is of type string, and +// returns no error from the provided check function +func (v stringFunc) CheckValue(value any) error { + val, ok := value.(string) + + if !ok { + return fmt.Errorf("expected string value for StringFunc check, got: %T", value) + } + + return v.checkFunc(val) +} + +// String returns the string representation of the value. +func (v stringFunc) String() string { + // Validation is up the the implementer of the function, so there are no + // string literal or regex comparers to print here + return "StringFunc" +} + +// StringFunc returns a Check for passing the string value in state +// to the provided check function +func StringFunc(fn func(v string) error) stringFunc { + return stringFunc{ + checkFunc: fn, + } +} diff --git a/knownvalue/string_func_test.go b/knownvalue/string_func_test.go new file mode 100644 index 000000000..7e83fdc94 --- /dev/null +++ b/knownvalue/string_func_test.go @@ -0,0 +1,74 @@ +// 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 TestStringFunc_CheckValue(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + self knownvalue.Check + other any + expectedError error + }{ + "nil": { + self: knownvalue.StringFunc(func(string) error { return nil }), + expectedError: fmt.Errorf("expected string value for StringFunc check, got: "), + }, + "wrong-type": { + self: knownvalue.StringFunc(func(string) error { return nil }), + other: 1.234, + expectedError: fmt.Errorf("expected string value for StringFunc check, got: float64"), + }, + "failure": { + self: knownvalue.StringFunc(func(s string) error { + if s != "foo" { + return fmt.Errorf("%s was not foo", s) + } + return nil + }), + other: "bar", + expectedError: fmt.Errorf("bar was not foo"), + }, + "success": { + self: knownvalue.StringFunc(func(s string) error { + if s != "foo" { + return fmt.Errorf("%s was not foo", s) + } + return nil + }), + other: "foo", + }, + } + + for name, testCase := range testCases { + 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 TestStringFunc_String(t *testing.T) { + t.Parallel() + + got := knownvalue.StringFunc(func(string) error { return nil }).String() + + if diff := cmp.Diff(got, "StringFunc"); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } +} diff --git a/knownvalue/string_regexp_test.go b/knownvalue/string_regexp_test.go index 172a72286..86d5d4834 100644 --- a/knownvalue/string_regexp_test.go +++ b/knownvalue/string_regexp_test.go @@ -50,8 +50,6 @@ func TestStringRegexp_CheckValue(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/knownvalue/string_test.go b/knownvalue/string_test.go index 7d7a8da3a..2bab25739 100644 --- a/knownvalue/string_test.go +++ b/knownvalue/string_test.go @@ -49,8 +49,6 @@ func TestStringValue_CheckValue(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/knownvalue/tuple_partial_test.go b/knownvalue/tuple_partial_test.go index 4935c9f3e..56eb34e19 100644 --- a/knownvalue/tuple_partial_test.go +++ b/knownvalue/tuple_partial_test.go @@ -109,8 +109,6 @@ func TestTuplePartial_CheckValue(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/knownvalue/tuple_size_test.go b/knownvalue/tuple_size_test.go index 7e8388bd2..bd5954f2f 100644 --- a/knownvalue/tuple_size_test.go +++ b/knownvalue/tuple_size_test.go @@ -62,8 +62,6 @@ func TestTupleSizeExact_CheckValue(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/knownvalue/tuple_test.go b/knownvalue/tuple_test.go index f1dfdd605..f5a82d76c 100644 --- a/knownvalue/tuple_test.go +++ b/knownvalue/tuple_test.go @@ -108,8 +108,6 @@ func TestTupleExact_CheckValue(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/plancheck/expect_known_output_value_at_path_test.go b/plancheck/expect_known_output_value_at_path_test.go index a6eca3356..0d61e57dd 100644 --- a/plancheck/expect_known_output_value_at_path_test.go +++ b/plancheck/expect_known_output_value_at_path_test.go @@ -1947,8 +1947,6 @@ func TestExpectKnownOutputValueAtPath_CheckPlan_UnknownAttributeType(t *testing. } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/plancheck/expect_known_output_value_test.go b/plancheck/expect_known_output_value_test.go index 504c30c8f..2065e20ba 100644 --- a/plancheck/expect_known_output_value_test.go +++ b/plancheck/expect_known_output_value_test.go @@ -1647,8 +1647,6 @@ func TestExpectKnownOutputValue_CheckPlan_UnknownAttributeType(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/plancheck/expect_known_value_test.go b/plancheck/expect_known_value_test.go index 63a68d7e9..5256892a9 100644 --- a/plancheck/expect_known_value_test.go +++ b/plancheck/expect_known_value_test.go @@ -1498,8 +1498,6 @@ func TestExpectKnownValue_CheckPlan_UnknownAttributeType(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/plancheck/expect_unknown_output_value.go b/plancheck/expect_unknown_output_value.go index f3af398c9..a104b4887 100644 --- a/plancheck/expect_unknown_output_value.go +++ b/plancheck/expect_unknown_output_value.go @@ -37,10 +37,15 @@ func (e expectUnknownOutputValue) CheckPlan(ctx context.Context, req CheckPlanRe } result, err := tfjsonpath.Traverse(change.AfterUnknown, tfjsonpath.Path{}) - if err != nil { - resp.Error = err + // If we find the output in the known values, return a more explicit message + knownVal, knownErr := tfjsonpath.Traverse(change.After, tfjsonpath.Path{}) + if knownErr == nil { + resp.Error = fmt.Errorf("Expected unknown value at output %q, but found known value: \"%v\"", e.outputAddress, knownVal) + return + } + resp.Error = err return } @@ -53,7 +58,13 @@ func (e expectUnknownOutputValue) CheckPlan(ctx context.Context, req CheckPlanRe } if !isUnknown { - resp.Error = fmt.Errorf("attribute at path is known") + // The output should have a known value, look first to return a more explicit message + knownVal, knownErr := tfjsonpath.Traverse(change.After, tfjsonpath.Path{}) + if knownErr == nil { + resp.Error = fmt.Errorf("Expected unknown value at output %q, but found known value: \"%v\"", e.outputAddress, knownVal) + return + } + resp.Error = fmt.Errorf("Expected unknown value at output %q, but found known value", e.outputAddress) return } diff --git a/plancheck/expect_unknown_output_value_at_path.go b/plancheck/expect_unknown_output_value_at_path.go index 74f694e2f..9c54e09b8 100644 --- a/plancheck/expect_unknown_output_value_at_path.go +++ b/plancheck/expect_unknown_output_value_at_path.go @@ -38,8 +38,14 @@ func (e expectUnknownOutputValueAtPath) CheckPlan(ctx context.Context, req Check } result, err := tfjsonpath.Traverse(change.AfterUnknown, e.valuePath) - if err != nil { + // If we find the output in the known values, return a more explicit message + knownVal, knownErr := tfjsonpath.Traverse(change.After, e.valuePath) + if knownErr == nil { + resp.Error = fmt.Errorf("Expected unknown value at output %q path %q, but found known value: \"%v\"", e.outputAddress, e.valuePath.String(), knownVal) + return + } + resp.Error = err return @@ -54,7 +60,13 @@ func (e expectUnknownOutputValueAtPath) CheckPlan(ctx context.Context, req Check } if !isUnknown { - resp.Error = fmt.Errorf("attribute at path is known") + // The output should have a known value, look first to return a more explicit message + knownVal, knownErr := tfjsonpath.Traverse(change.After, e.valuePath) + if knownErr == nil { + resp.Error = fmt.Errorf("Expected unknown value at output %q path %q, but found known value: \"%v\"", e.outputAddress, e.valuePath.String(), knownVal) + return + } + resp.Error = fmt.Errorf("Expected unknown value at output %q path %q, but found known value", e.outputAddress, e.valuePath.String()) return } diff --git a/plancheck/expect_unknown_output_value_at_path_test.go b/plancheck/expect_unknown_output_value_at_path_test.go index a766bb39a..b2b9c0c49 100644 --- a/plancheck/expect_unknown_output_value_at_path_test.go +++ b/plancheck/expect_unknown_output_value_at_path_test.go @@ -361,7 +361,7 @@ func Test_ExpectUnknownOutputValueAtPath_SetNestedBlock_Object(t *testing.T) { }) } -func Test_ExpectUnknownOutputValueAtPath_ExpectError_KnownValue(t *testing.T) { +func Test_ExpectUnknownOutputValueAtPath_ExpectError_KnownValue_PathNotFound(t *testing.T) { t.Parallel() r.UnitTest(t, r.TestCase{ @@ -381,7 +381,201 @@ func Test_ExpectUnknownOutputValueAtPath_ExpectError_KnownValue(t *testing.T) { { Config: ` resource "test_resource" "one" { - set_attribute = ["value1"] + list_nested_block { + list_nested_block_attribute = "value 1" + } + } + + output "resource" { + value = test_resource.one + } + `, + ConfigPlanChecks: r.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectUnknownOutputValueAtPath("resource", tfjsonpath.New("list_nested_block").AtSliceIndex(0).AtMapKey("not_correct_attr")), + }, + }, + ExpectError: regexp.MustCompile(`path not found: specified key not_correct_attr not found in map at list_nested_block.0.not_correct_attr`), + }, + }, + }) +} + +func Test_ExpectUnknownOutputValueAtPath_ExpectError_KnownValue_ListAttribute(t *testing.T) { + t.Parallel() + + r.UnitTest(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 planned 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"] + } + + output "resource" { + value = test_resource.one + } + `, + ConfigPlanChecks: r.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectUnknownOutputValueAtPath("resource", tfjsonpath.New("list_attribute").AtSliceIndex(0)), + }, + }, + ExpectError: regexp.MustCompile(`Expected unknown value at output "resource" path "list_attribute.0", but found known value: "value1"`), + }, + }, + }) +} + +func Test_ExpectUnknownOutputValueAtPath_ExpectError_KnownValue_StringAttribute(t *testing.T) { + t.Parallel() + + r.UnitTest(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 planned 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 = "hello world!" + } + + output "resource" { + value = test_resource.one + } + `, + ConfigPlanChecks: r.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectUnknownOutputValueAtPath("resource", tfjsonpath.New("string_attribute")), + }, + }, + ExpectError: regexp.MustCompile(`Expected unknown value at output "resource" path "string_attribute", but found known value: "hello world!"`), + }, + }, + }) +} + +func Test_ExpectUnknownOutputValueAtPath_ExpectError_KnownValue_BoolAttribute(t *testing.T) { + t.Parallel() + + r.UnitTest(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 planned 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 "resource" { + value = test_resource.one + } + `, + ConfigPlanChecks: r.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectUnknownOutputValueAtPath("resource", tfjsonpath.New("bool_attribute")), + }, + }, + ExpectError: regexp.MustCompile(`Expected unknown value at output "resource" path "bool_attribute", but found known value: "true"`), + }, + }, + }) +} + +func Test_ExpectUnknownOutputValueAtPath_ExpectError_KnownValue_FloatAttribute(t *testing.T) { + t.Parallel() + + r.UnitTest(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 planned 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.234 + } + + output "resource" { + value = test_resource.one + } + `, + ConfigPlanChecks: r.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectUnknownOutputValueAtPath("resource", tfjsonpath.New("float_attribute")), + }, + }, + ExpectError: regexp.MustCompile(`Expected unknown value at output "resource" path "float_attribute", but found known value: "1.234"`), + }, + }, + }) +} + +func Test_ExpectUnknownOutputValueAtPath_ExpectError_KnownValue_ListNestedBlock(t *testing.T) { + t.Parallel() + + r.UnitTest(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 planned 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 = "value 1" + } } output "resource" { @@ -390,10 +584,10 @@ func Test_ExpectUnknownOutputValueAtPath_ExpectError_KnownValue(t *testing.T) { `, ConfigPlanChecks: r.ConfigPlanChecks{ PreApply: []plancheck.PlanCheck{ - plancheck.ExpectUnknownOutputValueAtPath("resource", tfjsonpath.New("set_attribute").AtSliceIndex(0)), + plancheck.ExpectUnknownOutputValueAtPath("resource", tfjsonpath.New("list_nested_block").AtSliceIndex(0).AtMapKey("list_nested_block_attribute")), }, }, - ExpectError: regexp.MustCompile(`attribute at path is known`), + ExpectError: regexp.MustCompile(`Expected unknown value at output "resource" path "list_nested_block.0.list_nested_block_attribute", but found known value: "value 1"`), }, }, }) diff --git a/plancheck/expect_unknown_output_value_test.go b/plancheck/expect_unknown_output_value_test.go index 376303514..1e0c15770 100644 --- a/plancheck/expect_unknown_output_value_test.go +++ b/plancheck/expect_unknown_output_value_test.go @@ -226,7 +226,7 @@ func Test_ExpectUnknownOutputValue_ListNestedBlock(t *testing.T) { }) } -func Test_ExpectUnknownOutputValue_ExpectError_KnownValue(t *testing.T) { +func Test_ExpectUnknownOutputValue_ExpectError_KnownValue_ListAttribute(t *testing.T) { t.Parallel() r.UnitTest(t, r.TestCase{ @@ -239,19 +239,145 @@ func Test_ExpectUnknownOutputValue_ExpectError_KnownValue(t *testing.T) { { Config: ` resource "test_resource" "one" { - set_attribute = ["value1"] + list_attribute = ["value1"] } - output "set_attribute" { - value = test_resource.one.set_attribute + output "list_attribute" { + value = test_resource.one.list_attribute } `, ConfigPlanChecks: r.ConfigPlanChecks{ PreApply: []plancheck.PlanCheck{ - plancheck.ExpectUnknownOutputValue("set_attribute"), + plancheck.ExpectUnknownOutputValue("list_attribute"), + }, + }, + ExpectError: regexp.MustCompile(`Expected unknown value at output "list_attribute", but found known value: "\[value1\]"`), + }, + }, + }) +} + +func Test_ExpectUnknownOutputValue_ExpectError_KnownValue_StringAttribute(t *testing.T) { + t.Parallel() + + r.UnitTest(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 = "hello world!" + } + + output "string_attribute" { + value = test_resource.one.string_attribute + } + `, + ConfigPlanChecks: r.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectUnknownOutputValue("string_attribute"), + }, + }, + ExpectError: regexp.MustCompile(`Expected unknown value at output "string_attribute", but found known value: "hello world!"`), + }, + }, + }) +} + +func Test_ExpectUnknownOutputValue_ExpectError_KnownValue_BoolAttribute(t *testing.T) { + t.Parallel() + + r.UnitTest(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_attribute" { + value = test_resource.one.bool_attribute + } + `, + ConfigPlanChecks: r.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectUnknownOutputValue("bool_attribute"), + }, + }, + ExpectError: regexp.MustCompile(`Expected unknown value at output "bool_attribute", but found known value: "true"`), + }, + }, + }) +} + +func Test_ExpectUnknownOutputValue_ExpectError_KnownValue_FloatAttribute(t *testing.T) { + t.Parallel() + + r.UnitTest(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.234 + } + + output "float_attribute" { + value = test_resource.one.float_attribute + } + `, + ConfigPlanChecks: r.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectUnknownOutputValue("float_attribute"), + }, + }, + ExpectError: regexp.MustCompile(`Expected unknown value at output "float_attribute", but found known value: "1.234"`), + }, + }, + }) +} + +func Test_ExpectUnknownOutputValue_ExpectError_KnownValue_ListNestedBlock(t *testing.T) { + t.Parallel() + + r.UnitTest(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 = "value 1" + } + } + + output "list_nested_block" { + value = test_resource.one.list_nested_block + } + `, + ConfigPlanChecks: r.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectUnknownOutputValue("list_nested_block"), }, }, - ExpectError: regexp.MustCompile(`attribute at path is known`), + ExpectError: regexp.MustCompile(`Expected unknown value at output "list_nested_block", but found known value: "\[map\[list_nested_block_attribute:value 1\]\]"`), }, }, }) diff --git a/plancheck/expect_unknown_value.go b/plancheck/expect_unknown_value.go index 1569397c2..91ec3beb2 100644 --- a/plancheck/expect_unknown_value.go +++ b/plancheck/expect_unknown_value.go @@ -27,6 +27,13 @@ func (e expectUnknownValue) CheckPlan(ctx context.Context, req CheckPlanRequest, result, err := tfjsonpath.Traverse(rc.Change.AfterUnknown, e.attributePath) if err != nil { + // If we find the attribute in the known values, return a more explicit message + knownVal, knownErr := tfjsonpath.Traverse(rc.Change.After, e.attributePath) + if knownErr == nil { + resp.Error = fmt.Errorf("Expected unknown value at %q, but found known value: \"%v\"", e.attributePath.String(), knownVal) + return + } + resp.Error = err return } @@ -38,7 +45,14 @@ func (e expectUnknownValue) CheckPlan(ctx context.Context, req CheckPlanRequest, } if !isUnknown { - resp.Error = fmt.Errorf("attribute at path is known") + // The attribute should have a known value, look first to return a more explicit message + knownVal, knownErr := tfjsonpath.Traverse(rc.Change.After, e.attributePath) + if knownErr == nil { + resp.Error = fmt.Errorf("Expected unknown value at %q, but found known value: \"%v\"", e.attributePath.String(), knownVal) + return + } + + resp.Error = fmt.Errorf("Expected unknown value at %q, but found known value", e.attributePath.String()) return } diff --git a/plancheck/expect_unknown_value_test.go b/plancheck/expect_unknown_value_test.go index 4a46387d2..fd2b1c789 100644 --- a/plancheck/expect_unknown_value_test.go +++ b/plancheck/expect_unknown_value_test.go @@ -217,7 +217,91 @@ func Test_ExpectUnknownValue_SetNestedBlock(t *testing.T) { }) } -func Test_ExpectUnknownValue_ExpectError_KnownValue(t *testing.T) { +func Test_ExpectUnknownValue_ExpectError_KnownValue_PathNotFound(t *testing.T) { + t.Parallel() + + r.UnitTest(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" "two" { + list_nested_block { + list_nested_block_attribute = "value 1" + } + } + `, + ConfigPlanChecks: r.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectUnknownValue("test_resource.two", + tfjsonpath.New("list_nested_block").AtSliceIndex(0).AtMapKey("not_correct_attr")), + }, + }, + ExpectError: regexp.MustCompile(`path not found: specified key not_correct_attr not found in map at list_nested_block.0.not_correct_attr`), + }, + }, + }) +} + +func Test_ExpectUnknownValue_ExpectError_KnownValue_ListAttribute(t *testing.T) { + t.Parallel() + + r.UnitTest(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"] + } + `, + ConfigPlanChecks: r.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectUnknownValue("test_resource.one", tfjsonpath.New("list_attribute").AtSliceIndex(0)), + }, + }, + ExpectError: regexp.MustCompile(`Expected unknown value at "list_attribute.0", but found known value: "value1"`), + }, + }, + }) +} + +func Test_ExpectUnknownValue_ExpectError_KnownValue_StringAttribute(t *testing.T) { + t.Parallel() + + r.UnitTest(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 = "hello world!" + } + `, + ConfigPlanChecks: r.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectUnknownValue("test_resource.one", tfjsonpath.New("string_attribute")), + }, + }, + ExpectError: regexp.MustCompile(`Expected unknown value at "string_attribute", but found known value: "hello world!"`), + }, + }, + }) +} + +func Test_ExpectUnknownValue_ExpectError_KnownValue_BoolAttribute(t *testing.T) { t.Parallel() r.UnitTest(t, r.TestCase{ @@ -230,15 +314,72 @@ func Test_ExpectUnknownValue_ExpectError_KnownValue(t *testing.T) { { Config: ` resource "test_resource" "one" { - set_attribute = ["value1"] + bool_attribute = true } `, ConfigPlanChecks: r.ConfigPlanChecks{ PreApply: []plancheck.PlanCheck{ - plancheck.ExpectUnknownValue("test_resource.one", tfjsonpath.New("set_attribute").AtSliceIndex(0)), + plancheck.ExpectUnknownValue("test_resource.one", tfjsonpath.New("bool_attribute")), + }, + }, + ExpectError: regexp.MustCompile(`Expected unknown value at "bool_attribute", but found known value: "true"`), + }, + }, + }) +} + +func Test_ExpectUnknownValue_ExpectError_KnownValue_FloatAttribute(t *testing.T) { + t.Parallel() + + r.UnitTest(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.234 + } + `, + ConfigPlanChecks: r.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectUnknownValue("test_resource.one", tfjsonpath.New("float_attribute")), + }, + }, + ExpectError: regexp.MustCompile(`Expected unknown value at "float_attribute", but found known value: "1.234"`), + }, + }, + }) +} + +func Test_ExpectUnknownValue_ExpectError_KnownValue_ListNestedBlock(t *testing.T) { + t.Parallel() + + r.UnitTest(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" "two" { + list_nested_block { + list_nested_block_attribute = "value 1" + } + } + `, + ConfigPlanChecks: r.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectUnknownValue("test_resource.two", + tfjsonpath.New("list_nested_block").AtSliceIndex(0).AtMapKey("list_nested_block_attribute")), }, }, - ExpectError: regexp.MustCompile(`attribute at path is known`), + ExpectError: regexp.MustCompile(`Expected unknown value at "list_nested_block.0.list_nested_block_attribute", but found known value: "value 1"`), }, }, }) diff --git a/statecheck/expect_known_output_value_at_path_test.go b/statecheck/expect_known_output_value_at_path_test.go index 0b6013bcd..34e0bfe0b 100644 --- a/statecheck/expect_known_output_value_at_path_test.go +++ b/statecheck/expect_known_output_value_at_path_test.go @@ -1611,8 +1611,6 @@ func TestExpectKnownOutputValueAtPath_CheckState_UnknownAttributeType(t *testing } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/statecheck/expect_known_output_value_test.go b/statecheck/expect_known_output_value_test.go index 62d9067fe..69c63dc1d 100644 --- a/statecheck/expect_known_output_value_test.go +++ b/statecheck/expect_known_output_value_test.go @@ -1545,8 +1545,6 @@ func TestExpectKnownOutputValue_CheckState_UnknownAttributeType(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/statecheck/expect_known_value_test.go b/statecheck/expect_known_value_test.go index 2eb56d4e4..18cc07901 100644 --- a/statecheck/expect_known_value_test.go +++ b/statecheck/expect_known_value_test.go @@ -1515,8 +1515,6 @@ func TestExpectKnownValue_CheckState_UnknownAttributeType(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/terraform/diff_test.go b/terraform/diff_test.go index df75bedc2..325b208f6 100644 --- a/terraform/diff_test.go +++ b/terraform/diff_test.go @@ -820,8 +820,6 @@ func TestInstanceDiffSame(t *testing.T) { } for i, tc := range cases { - i, tc := i, tc - t.Run(fmt.Sprintf("%d", i), func(t *testing.T) { t.Parallel() @@ -867,8 +865,6 @@ func TestCountFlatmapContainerValues(t *testing.T) { count: "2", }, } { - i, tc := i, tc - t.Run(strconv.Itoa(i), func(t *testing.T) { t.Parallel() diff --git a/terraform/resource_address_test.go b/terraform/resource_address_test.go index 6cbacc257..285c2fb33 100644 --- a/terraform/resource_address_test.go +++ b/terraform/resource_address_test.go @@ -189,8 +189,6 @@ func TestParseResourceAddress(t *testing.T) { } for tn, tc := range cases { - tn, tc := tn, tc - t.Run(tn, func(t *testing.T) { t.Parallel() @@ -288,7 +286,6 @@ func TestResourceAddressLess(t *testing.T) { } for _, test := range tests { - test := test t.Run(fmt.Sprintf("%s < %s", test.A, test.B), func(t *testing.T) { t.Parallel() diff --git a/terraform/resource_test.go b/terraform/resource_test.go index 9f871351a..baccc4254 100644 --- a/terraform/resource_test.go +++ b/terraform/resource_test.go @@ -185,8 +185,6 @@ func TestResourceConfigGet(t *testing.T) { } for i, tc := range cases { - i, tc := i, tc - rc := NewResourceConfigShimmed(tc.Config, tc.Schema) // Test getting a key @@ -636,7 +634,6 @@ func TestNewResourceConfigShimmed(t *testing.T) { }, }, } { - tc := tc t.Run(tc.Name, func(t *testing.T) { t.Parallel() diff --git a/terraform/state_test.go b/terraform/state_test.go index a7a233cc9..41c536856 100644 --- a/terraform/state_test.go +++ b/terraform/state_test.go @@ -183,8 +183,6 @@ func TestStateDeepCopy(t *testing.T) { } for i, tc := range cases { - i, tc := i, tc - t.Run(fmt.Sprintf("copy-%d", i), func(t *testing.T) { t.Parallel() @@ -389,8 +387,6 @@ func TestStateEqual(t *testing.T) { } for i, tc := range cases { - i, tc := i, tc - t.Run(fmt.Sprintf("%d-%s", i, tc.Name), func(t *testing.T) { t.Parallel() diff --git a/terraform/unknown_value_walk_test.go b/terraform/unknown_value_walk_test.go index 581849ea4..775c76b48 100644 --- a/terraform/unknown_value_walk_test.go +++ b/terraform/unknown_value_walk_test.go @@ -56,8 +56,6 @@ func TestUnknownValueWalk(t *testing.T) { } for name, testCase := range testCases { - name, testCase := name, testCase - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/terraform/util_test.go b/terraform/util_test.go index 0c68f9e67..461cea234 100644 --- a/terraform/util_test.go +++ b/terraform/util_test.go @@ -43,8 +43,6 @@ func TestUniqueStrings(t *testing.T) { } for i, tc := range cases { - i, tc := i, tc - t.Run(fmt.Sprintf("unique-%d", i), func(t *testing.T) { t.Parallel() diff --git a/tfjsonpath/path_test.go b/tfjsonpath/path_test.go index 83c13061c..878def1fa 100644 --- a/tfjsonpath/path_test.go +++ b/tfjsonpath/path_test.go @@ -472,8 +472,6 @@ func Test_Traverse_Array_ExpectError(t *testing.T) { } for name, tc := range testCases { - name, tc := name, tc - t.Run(name, func(t *testing.T) { t.Parallel() @@ -516,8 +514,6 @@ func TestPath_String(t *testing.T) { } for name, tc := range testCases { - name, tc := name, tc - t.Run(name, func(t *testing.T) { t.Parallel() diff --git a/tfversion/versions.go b/tfversion/versions.go index 3db43e02e..ac734e598 100644 --- a/tfversion/versions.go +++ b/tfversion/versions.go @@ -37,4 +37,5 @@ var ( Version1_8_0 *version.Version = version.Must(version.NewVersion("1.8.0")) Version1_9_0 *version.Version = version.Must(version.NewVersion("1.9.0")) Version1_10_0 *version.Version = version.Must(version.NewVersion("1.10.0")) + Version1_11_0 *version.Version = version.Must(version.NewVersion("1.11.0")) ) diff --git a/tools/go.mod b/tools/go.mod index 738e2a3d3..938dd04b7 100644 --- a/tools/go.mod +++ b/tools/go.mod @@ -1,18 +1,17 @@ module tools -go 1.22.7 +go 1.23.7 -require github.com/hashicorp/copywrite v0.19.0 +require github.com/hashicorp/copywrite v0.21.0 require ( - github.com/AlecAivazis/survey/v2 v2.3.6 // indirect + github.com/AlecAivazis/survey/v2 v2.3.7 // indirect github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 // indirect github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef // indirect github.com/bmatcuk/doublestar/v4 v4.6.0 // indirect github.com/bradleyfalzon/ghinstallation/v2 v2.5.0 // indirect - github.com/cli/go-gh v1.2.1 // indirect + github.com/cli/go-gh/v2 v2.11.2 // indirect github.com/cli/safeexec v1.0.0 // indirect - github.com/cli/shurcooL-graphql v0.0.2 // indirect github.com/cloudflare/circl v1.3.7 // indirect github.com/fatih/color v1.13.0 // indirect github.com/fsnotify/fsnotify v1.5.4 // indirect @@ -25,41 +24,37 @@ require ( github.com/google/go-querystring v1.1.0 // indirect github.com/hashicorp/go-hclog v1.5.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect - github.com/henvic/httpretty v0.0.6 // indirect github.com/inconshreveable/mousetrap v1.0.1 // indirect github.com/jedib0t/go-pretty v4.3.0+incompatible // indirect github.com/jedib0t/go-pretty/v6 v6.4.6 // indirect github.com/joho/godotenv v1.3.0 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/knadh/koanf v1.5.0 // indirect - github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect - github.com/mattn/go-runewidth v0.0.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect github.com/mergestat/timediff v0.0.3 // indirect github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect - github.com/muesli/termenv v0.12.0 // indirect github.com/oklog/ulid v1.3.1 // indirect - github.com/rivo/uniseg v0.2.0 // indirect + github.com/rivo/uniseg v0.4.7 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect github.com/samber/lo v1.37.0 // indirect github.com/spf13/cobra v1.6.1 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/thanhpk/randstr v1.0.4 // indirect - github.com/thlib/go-timezone-local v0.0.0-20210907160436-ef149e42d28e // indirect go.mongodb.org/mongo-driver v1.10.0 // indirect - golang.org/x/crypto v0.21.0 // indirect + golang.org/x/crypto v0.36.0 // indirect golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect - golang.org/x/net v0.23.0 // indirect + golang.org/x/net v0.37.0 // indirect golang.org/x/oauth2 v0.8.0 // indirect - golang.org/x/sync v0.1.0 // indirect - golang.org/x/sys v0.18.0 // indirect - golang.org/x/term v0.18.0 // indirect - golang.org/x/text v0.14.0 // indirect + golang.org/x/sync v0.12.0 // indirect + golang.org/x/sys v0.31.0 // indirect + golang.org/x/term v0.30.0 // indirect + golang.org/x/text v0.23.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.33.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/tools/go.sum b/tools/go.sum index cfc168fa2..abe7c9dc7 100644 --- a/tools/go.sum +++ b/tools/go.sum @@ -1,8 +1,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= -github.com/AlecAivazis/survey/v2 v2.3.6 h1:NvTuVHISgTHEHeBFqt6BHOe4Ny/NwGZr7w+F8S9ziyw= -github.com/AlecAivazis/survey/v2 v2.3.6/go.mod h1:4AuI9b7RjAR+G7v9+C4YSlX/YL3K3cWNXgWXOhllqvI= +github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ= +github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= @@ -44,12 +44,10 @@ github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7N github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cli/go-gh v1.2.1 h1:xFrjejSsgPiwXFP6VYynKWwxLQcNJy3Twbu82ZDlR/o= -github.com/cli/go-gh v1.2.1/go.mod h1:Jxk8X+TCO4Ui/GarwY9tByWm/8zp4jJktzVZNlTW5VM= +github.com/cli/go-gh/v2 v2.11.2 h1:oad1+sESTPNTiTvh3I3t8UmxuovNDxhwLzeMHk45Q9w= +github.com/cli/go-gh/v2 v2.11.2/go.mod h1:vVFhi3TfjseIW26ED9itAR8gQK0aVThTm8sYrsZ5QTI= github.com/cli/safeexec v1.0.0 h1:0VngyaIyqACHdcMNWfo6+KdUYnqEr2Sg+bSP1pdF+dI= github.com/cli/safeexec v1.0.0/go.mod h1:Z/D4tTN8Vs5gXYHDCbaM1S/anmEDnJb1iW0+EJ5zx3Q= -github.com/cli/shurcooL-graphql v0.0.2 h1:rwP5/qQQ2fM0TzkUTwtt6E2LbIYf6R+39cUXTa04NYk= -github.com/cli/shurcooL-graphql v0.0.2/go.mod h1:tlrLmw/n5Q/+4qSvosT+9/W5zc8ZMjnJeYBxSdb4nWA= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I= github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= @@ -144,12 +142,10 @@ github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw= -github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= github.com/hashicorp/consul/api v1.13.0/go.mod h1:ZlVrynguJKcYr54zGaDbaL3fOvKC9m72FhPvA8T35KQ= github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= -github.com/hashicorp/copywrite v0.19.0 h1:f9LVxTDBfFYeQmdBpOsZ+HWknXonI8ZwubbO/RwyuCo= -github.com/hashicorp/copywrite v0.19.0/go.mod h1:6wvQH+ICDoD2bpjO1RJ6fi+h3aY5NeLEM12oTkEtFoc= +github.com/hashicorp/copywrite v0.21.0 h1:IE8uByQdos8s0uAyHF4O8RHV5cJEhmIc+Awk+wkKXKI= +github.com/hashicorp/copywrite v0.21.0/go.mod h1:mu6DAyUI6m6vq8weoJn9a0HDuUUrV+0GQdRp4mD50yU= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= @@ -184,8 +180,6 @@ github.com/hashicorp/vault/api v1.0.4/go.mod h1:gDcqh3WGcR1cpF5AJz/B1UFheUEneMoI github.com/hashicorp/vault/sdk v0.1.13/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvhkWnjtSYCaS2M= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= -github.com/henvic/httpretty v0.0.6 h1:JdzGzKZBajBfnvlMALXXMVQWxWMF/ofTy8C3/OSUTxs= -github.com/henvic/httpretty v0.0.6/go.mod h1:X38wLjWXHkXT7r2+uK8LjCMne9rsuNaBLJ+5cU2/Pmo= github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog= github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68= github.com/hjson/hjson-go/v4 v4.0.0 h1:wlm6IYYqHjOdXH1gHev4VoXCaW20HdQAGCxdOEEg2cs= @@ -224,8 +218,6 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= -github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= @@ -241,10 +233,11 @@ github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOA github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mergestat/timediff v0.0.3 h1:ucCNh4/ZrTPjFZ081PccNbhx9spymCJkFxSzgVuPU+Y= github.com/mergestat/timediff v0.0.3/go.mod h1:yvMUaRu2oetc+9IbPLYBJviz6sA7xz8OXMDfhBl7YSI= @@ -276,10 +269,6 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= -github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= -github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= -github.com/muesli/termenv v0.12.0 h1:KuQRUE3PgxRFWhq4gHvZtPSLCGDqM5q/cYr1pZ39ytc= -github.com/muesli/termenv v0.12.0/go.mod h1:WCCv32tusQ/EEZ5S8oUIIrC/nIuBcxCVqlN4Xfkv+7A= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= @@ -317,8 +306,9 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/rhnvrm/simples3 v0.6.1/go.mod h1:Y+3vYm2V7Y4VijFoJHHTrja6OgPrJ2cBti8dPGkC3sA= -github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= @@ -355,8 +345,6 @@ github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/thanhpk/randstr v1.0.4 h1:IN78qu/bR+My+gHCvMEXhR/i5oriVHcTB/BJJIRTsNo= github.com/thanhpk/randstr v1.0.4/go.mod h1:M/H2P1eNLZzlDwAzpkkkUvoyNNMbzRGhESZuEQk3r0U= -github.com/thlib/go-timezone-local v0.0.0-20210907160436-ef149e42d28e h1:BuzhfgfWQbX0dWzYzT1zsORLnHRv3bcRcsaUk0VmXA8= -github.com/thlib/go-timezone-local v0.0.0-20210907160436-ef149e42d28e/go.mod h1:/Tnicc6m/lsJE0irFMA0LfIwTBo4QP7A8IfyIv4zZKI= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= @@ -384,8 +372,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= +golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 h1:3MTrJm4PyNL9NBqvYDSj3DHl46qQakyfqfWo4jgfaEM= golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= @@ -419,13 +407,12 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220923203811-8be639271d50/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c= +golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -441,8 +428,9 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= +golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -476,16 +464,12 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -493,17 +477,16 @@ golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210503060354-a79de5458b56/go.mod h1:tfny5GFUkzUvx4ps4ajbZsCe5lw1metzhBm9T3x7oIY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y= +golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= @@ -515,8 +498,8 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= +golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -575,8 +558,6 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/h2non/gock.v1 v1.1.2 h1:jBbHXgGBK/AoPVfJh5x4r/WxIrElvbLel8TCZkkZJoY= -gopkg.in/h2non/gock.v1 v1.1.2/go.mod h1:n7UGz/ckNChHiK05rDoiC4MYSunEC/lyaUm2WWaDva0= gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/website/README.md b/website/README.md index 21976cb0a..4b67a363f 100644 --- a/website/README.md +++ b/website/README.md @@ -1,5 +1,8 @@ # Terraform Documentation +> [!IMPORTANT] +> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com. + This directory contains the portions of [the Terraform website][terraform.io] that pertain to the Terraform Plugin Testing. The files in this directory are intended to be used in conjunction with diff --git a/website/docs/plugin/testing/acceptance-tests/configuration.mdx b/website/docs/plugin/testing/acceptance-tests/configuration.mdx index f18c2a940..c0e821908 100644 --- a/website/docs/plugin/testing/acceptance-tests/configuration.mdx +++ b/website/docs/plugin/testing/acceptance-tests/configuration.mdx @@ -5,6 +5,9 @@ description: >- in conjunction with Terraform configuration. --- +> [!IMPORTANT] +> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com. + # Terraform Configuration The configuration used during the execution of an acceptance test can be specified at the [TestStep](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/helper/resource#TestStep) level by populating one of the following mutually exclusive fields: diff --git a/website/docs/plugin/testing/acceptance-tests/ephemeral-resources.mdx b/website/docs/plugin/testing/acceptance-tests/ephemeral-resources.mdx index 36c6fea29..db5d04bd4 100644 --- a/website/docs/plugin/testing/acceptance-tests/ephemeral-resources.mdx +++ b/website/docs/plugin/testing/acceptance-tests/ephemeral-resources.mdx @@ -4,6 +4,9 @@ description: >- Guidance on how to test ephemeral resources and data. --- +> [!IMPORTANT] +> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com. + Ephemeral resource support is in technical preview and offered without compatibility promises until Terraform 1.10 is generally available. diff --git a/website/docs/plugin/testing/acceptance-tests/index.mdx b/website/docs/plugin/testing/acceptance-tests/index.mdx index 4703a1f51..ebc038120 100644 --- a/website/docs/plugin/testing/acceptance-tests/index.mdx +++ b/website/docs/plugin/testing/acceptance-tests/index.mdx @@ -5,6 +5,9 @@ description: |- imitate applying one or more configuration files. --- +> [!IMPORTANT] +> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com. + # Acceptance Tests In order to deliver on our promise to be safe and predictable, we need to be 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 a3f8be559..d5e91e113 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 @@ -1,14 +1,18 @@ --- page_title: 'Plugin Development - Acceptance Testing: Known Values' description: >- - Bool Value Checks for use with Plan Checks. + Bool Value Checks for use with Plan and State Checks. --- +> [!IMPORTANT] +> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com. + # Bool Known Value Checks The known value checks that are available for bool values are: * [Bool](/terraform/plugin/testing/acceptance-tests/known-value-checks/bool#bool-check) +* [BoolFunc](/terraform/plugin/testing/acceptance-tests/known-value-checks/bool#boolfunc-check) ## `Bool` Check @@ -40,3 +44,37 @@ func TestExpectKnownValue_CheckPlan_Bool(t *testing.T) { }) } ``` + +## `BoolFunc` Check + +The [BoolFunc](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#BoolFunc) check allows defining a custom function to validate whether the bool value of a resource attribute or output satisfies specific conditions. + +Example usage of [BoolFunc](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#BoolFunc) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/state-checks/resource) state check. + +```go +func TestExpectKnownValue_CheckState_BoolFunc(t *testing.T) { + t.Parallel() + + resource.Test(t, resource.TestCase{ + // Provider definition omitted. + Steps: []resource.TestStep{ + { + // Example resource containing a boolean attribute named "configurable_attribute" + Config: `resource "test_resource" "one" {}`, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("configurable_attribute"), + knownvalue.BoolFunc(func(v bool) error { + if !v { + return fmt.Errorf("expected true, got %t", v) + } + return nil + }), + ), + }, + }, + }, + }) +} +``` \ No newline at end of file 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 ef92d4e80..b0423ccd2 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 @@ -4,6 +4,9 @@ description: >- Custom Value Checks for use with Plan Checks. --- +> [!IMPORTANT] +> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com. + # Custom Known Value Checks Custom known value checks can be created by implementing the [knownvalue.Check](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#Check) interface. diff --git a/website/docs/plugin/testing/acceptance-tests/known-value-checks/float32.mdx b/website/docs/plugin/testing/acceptance-tests/known-value-checks/float32.mdx index 26f5a77fc..31b58fda3 100644 --- a/website/docs/plugin/testing/acceptance-tests/known-value-checks/float32.mdx +++ b/website/docs/plugin/testing/acceptance-tests/known-value-checks/float32.mdx @@ -1,14 +1,18 @@ --- page_title: 'Plugin Development - Acceptance Testing: Known Values' description: >- - Float32 Value Checks for use with Plan Checks. + Float32 Value Checks for use with Plan and State Checks. --- +> [!IMPORTANT] +> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com. + # Float32 Known Value Checks The known value checks that are available for float32 values are: * [Float32Exact](/terraform/plugin/testing/acceptance-tests/known-value-checks/float32#float32exact-check) +* [Float32Func](/terraform/plugin/testing/acceptance-tests/known-value-checks/float32#float32func-check) ## `Float32Exact` Check @@ -40,3 +44,37 @@ func TestExpectKnownValue_CheckPlan_Float32(t *testing.T) { }) } ``` + +## `Float32Func` Check + +The [Float32Func](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#Float32Func) check allows defining a custom function to validate whether the float32 value of a resource attribute or output satisfies specific conditions. + +Example usage of [Float32Func](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#Float32Func) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/state-checks/resource) state check. + +```go +func TestExpectKnownValue_CheckState_Float32Func(t *testing.T) { + t.Parallel() + + resource.Test(t, resource.TestCase{ + // Provider definition omitted. + Steps: []resource.TestStep{ + { + // Example resource containing a float32 attribute named "configurable_attribute" + Config: `resource "test_resource" "one" {}`, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("configurable_attribute"), + knownvalue.Float32Func(func(v float32) error { + if v > 1.0 && v < 5.0 { + return fmt.Errorf("value must be between 1.0 and 5.0") + } + return nil + }), + ), + }, + }, + }, + }) +} +``` \ No newline at end of file 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 af7de4d29..378eccc27 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 @@ -4,11 +4,15 @@ description: >- Float64 Value Checks for use with Plan Checks. --- +> [!IMPORTANT] +> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com. + # Float64 Known Value Checks The known value checks that are available for float64 values are: * [Float64Exact](/terraform/plugin/testing/acceptance-tests/known-value-checks/float64#float64exact-check) +* [Float64Func](/terraform/plugin/testing/acceptance-tests/known-value-checks/float64#float64func-check) ## `Float64Exact` Check @@ -40,3 +44,37 @@ func TestExpectKnownValue_CheckPlan_Float64(t *testing.T) { }) } ``` + +## `Float64Func` Check + +The [Float64Func](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#Float64Func) check allows defining a custom function to validate whether the float64 value of a resource attribute or output satisfies specific conditions. + +Example usage of [Float64Func](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#Float64Func) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/state-checks/resource) state check. + +```go +func TestExpectKnownValue_CheckState_Float64Func(t *testing.T) { + t.Parallel() + + resource.Test(t, resource.TestCase{ + // Provider definition omitted. + Steps: []resource.TestStep{ + { + // Example resource containing a float64 attribute named "configurable_attribute" + Config: `resource "test_resource" "one" {}`, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("configurable_attribute"), + knownvalue.Float64Func(func(v float64) error { + if v > 1.0 && v < 5.0 { + return fmt.Errorf("value must be between 1.0 and 5.0") + } + return nil + }), + ), + }, + }, + }, + }) +} +``` \ No newline at end of file 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 569f6b5b6..a150822c0 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 @@ -5,6 +5,9 @@ description: >- Known values define an expected type, and value for a resource attribute, or output value in a Terraform plan or state for use in Plan Checks or State Checks. --- +> [!IMPORTANT] +> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com. + # Known Value Checks Known Value Checks are for use in conjunction with [Plan Checks](/terraform/plugin/testing/acceptance-tests/plan-checks), and [State Checks](/terraform/plugin/testing/acceptance-tests/state-checks) which leverage the [terraform-json](https://pkg.go.dev/github.com/hashicorp/terraform-json) representation of a Terraform plan. diff --git a/website/docs/plugin/testing/acceptance-tests/known-value-checks/int32.mdx b/website/docs/plugin/testing/acceptance-tests/known-value-checks/int32.mdx index 69f1bd7ab..fed9c31f3 100644 --- a/website/docs/plugin/testing/acceptance-tests/known-value-checks/int32.mdx +++ b/website/docs/plugin/testing/acceptance-tests/known-value-checks/int32.mdx @@ -1,14 +1,18 @@ --- page_title: 'Plugin Development - Acceptance Testing: Known Values' description: >- - Int32 Value Checks for use with Plan Checks. + Int32 Value Checks for use with Plan and State Checks. --- +> [!IMPORTANT] +> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com. + # Int32 Known Value Checks The known value checks that are available for int32 values are: * [Int32Exact](/terraform/plugin/testing/acceptance-tests/known-value-checks/int32#int32exact-check) +* [Int32Func](/terraform/plugin/testing/acceptance-tests/known-value-checks/int32#int32func-check) ## `Int32Exact` Check @@ -40,3 +44,37 @@ func TestExpectKnownValue_CheckPlan_Int32(t *testing.T) { }) } ``` + +## `Int32Func` Check + +The [Int32Func](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#Int32Func) check allows defining a custom function to validate whether the int32 value of a resource attribute or output satisfies specific conditions. + +Example usage of [Int32Func](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#Int32Func) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/state-checks/resource) state check. + +```go +func TestExpectKnownValue_CheckState_Int32Func(t *testing.T) { + t.Parallel() + + resource.Test(t, resource.TestCase{ + // Provider definition omitted. + Steps: []resource.TestStep{ + { + // Example resource containing an int32 attribute named "configurable_attribute" + Config: `resource "test_resource" "one" {}`, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("configurable_attribute"), + knownvalue.Int32Func(func(v int32) error { + if v > 1 && v < 12 { + return fmt.Errorf("value must be between 1 and 12") + } + return nil + }), + ), + }, + }, + }, + }) +} +``` \ No newline at end of file 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 55cc46192..6f6516637 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 @@ -1,14 +1,18 @@ --- page_title: 'Plugin Development - Acceptance Testing: Known Values' description: >- - Int64 Value Checks for use with Plan Checks. + Int64 Value Checks for use with Plan and State Checks. --- +> [!IMPORTANT] +> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com. + # Int64 Known Value Checks The known value checks that are available for int64 values are: * [Int64Exact](/terraform/plugin/testing/acceptance-tests/known-value-checks/int64#int64exact-check) +* [Int64Func](/terraform/plugin/testing/acceptance-tests/known-value-checks/int64#int64func-check) ## `Int64Exact` Check @@ -40,3 +44,37 @@ func TestExpectKnownValue_CheckPlan_Int64(t *testing.T) { }) } ``` + +## `Int64Func` Check + +The [Int64Func](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#Int64Func) check allows defining a custom function to validate whether the int64 value of a resource attribute or output satisfies specific conditions. + +Example usage of [Int64Func](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#Int64Func) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/state-checks/resource) state check. + +```go +func TestExpectKnownValue_CheckState_Int64Func(t *testing.T) { + t.Parallel() + + resource.Test(t, resource.TestCase{ + // Provider definition omitted. + Steps: []resource.TestStep{ + { + // Example resource containing an int64 attribute named "configurable_attribute" + Config: `resource "test_resource" "one" {}`, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("configurable_attribute"), + knownvalue.Int64Func(func(v int64) error { + if v > 1 && v < 12 { + return fmt.Errorf("value must be between 1 and 12") + } + return nil + }), + ), + }, + }, + }, + }) +} +``` \ No newline at end of file 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 92963b91e..ce252c16d 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 @@ -4,6 +4,9 @@ description: >- List Value Checks for use with Plan Checks. --- +> [!IMPORTANT] +> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com. + # List Known Value Checks The known value checks that are available for list values are: 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 9685249c4..5a4820ab3 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 @@ -4,6 +4,9 @@ description: >- Map Value Checks for use with Plan Checks. --- +> [!IMPORTANT] +> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com. + # Map Known Value Checks The known value checks that are available for map values are: diff --git a/website/docs/plugin/testing/acceptance-tests/known-value-checks/not-null.mdx b/website/docs/plugin/testing/acceptance-tests/known-value-checks/not-null.mdx index b6e39030f..25c60cde0 100644 --- a/website/docs/plugin/testing/acceptance-tests/known-value-checks/not-null.mdx +++ b/website/docs/plugin/testing/acceptance-tests/known-value-checks/not-null.mdx @@ -4,6 +4,9 @@ description: >- NotNull Value Checks for use with Plan Checks or State Checks. --- +> [!IMPORTANT] +> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com. + # NotNull Known Value Checks The known value checks that are available for values that are not null are: 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 8cd4bee00..0504034aa 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 @@ -4,6 +4,9 @@ description: >- Null Value Checks for use with Plan Checks or State Checks. --- +> [!IMPORTANT] +> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com. + # Null Known Value Checks The known value checks that are available for null values are: 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 fa4b6dcbb..fee58d9cb 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 @@ -4,6 +4,9 @@ description: >- Number Value Checks for use with Plan Checks. --- +> [!IMPORTANT] +> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com. + # Number Known Value Checks The known value checks that are available for number values are: @@ -46,3 +49,36 @@ func TestExpectKnownValue_CheckPlan_Number(t *testing.T) { }) } ``` + +## `NumberFunc` Check + +The [NumberFunc](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#NumberFunc) check allows defining a custom function to validate whether the number value of a resource attribute or output satisfies specific conditions. + +Example usage of [NumberFunc](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#NumberFunc) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/state-checks/resource) state check. + +```go +func TestExpectKnownValue_CheckState_NumberFunc(t *testing.T) { + t.Parallel() + + resource.Test(t, resource.TestCase{ + // Provider definition omitted. + Steps: []resource.TestStep{ + { + // Example resource containing a number attribute named "configurable_attribute" + Config: `resource "test_resource" "one" {}`, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("configurable_attribute"), + knownvalue.NumberFunc(func(v *big.Float) error { + if err := testConfigurableAttribute(v); err != nil { + return fmt.Errorf("attribute validation failed: %w", err) + } + return nil + }), + ), + }, + }, + }, + }) +} \ No newline at end of file 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 68569dcde..11cc0934a 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 @@ -4,6 +4,9 @@ description: >- Object Value Checks for use with Plan Checks. --- +> [!IMPORTANT] +> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com. + # Object Known Value Checks The known value checks that are available for object values are: 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 48d906926..55f1919d0 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 @@ -4,6 +4,9 @@ description: >- Set Value Checks for use with Plan Checks. --- +> [!IMPORTANT] +> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com. + # Set Known Value Checks The known value checks that are available for set values are: 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 ce92df3cd..2f6e1039f 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 @@ -4,12 +4,16 @@ description: >- String Value Checks for use with Plan Checks. --- +> [!IMPORTANT] +> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com. + # String Known Value Checks The known value checks that are available for string values are: * [StringExact](/terraform/plugin/testing/acceptance-tests/known-value-checks/string#stringexact-check) * [StringRegexp](/terraform/plugin/testing/acceptance-tests/known-value-checks/string#stringregexp-check) +* [StringFunc](/terraform/plugin/testing/acceptance-tests/known-value-checks/string#stringfunc-check) ## `StringExact` Check @@ -70,3 +74,37 @@ func TestExpectKnownValue_CheckPlan_StringRegexp(t *testing.T) { }) } ``` + +## `StringFunc` Check + +The [StringFunc](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#StringFunc) check allows defining a custom function to validate whether the string value of a resource attribute or output satisfies specific conditions. + +Example usage of [StringFunc](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/knownvalue#StringFunc) in an [ExpectKnownValue](/terraform/plugin/testing/acceptance-tests/state-checks/resource) state check. + +```go +func TestExpectKnownValue_CheckState_StringFunc(t *testing.T) { + t.Parallel() + + resource.Test(t, resource.TestCase{ + // Provider definition omitted. + Steps: []resource.TestStep{ + { + // Example resource containing a string attribute named "configurable_attribute" + Config: `resource "test_resource" "one" {}`, + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue( + "test_resource.one", + tfjsonpath.New("configurable_attribute"), + knownvalue.StringFunc(func(v string) error { + if !strings.HasPrefix(v, "str") { + return fmt.Errorf("value must start with 'str'") + } + return nil + }), + ), + }, + }, + }, + }) +} +``` \ No newline at end of file diff --git a/website/docs/plugin/testing/acceptance-tests/known-value-checks/tuple.mdx b/website/docs/plugin/testing/acceptance-tests/known-value-checks/tuple.mdx index 95129a23a..b353bcc0f 100644 --- a/website/docs/plugin/testing/acceptance-tests/known-value-checks/tuple.mdx +++ b/website/docs/plugin/testing/acceptance-tests/known-value-checks/tuple.mdx @@ -4,6 +4,9 @@ description: >- Tuple Value Checks for use with Plan Checks. --- +> [!IMPORTANT] +> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com. + # Tuple Known Value Checks diff --git a/website/docs/plugin/testing/acceptance-tests/plan-checks/custom.mdx b/website/docs/plugin/testing/acceptance-tests/plan-checks/custom.mdx index 5e3672a51..a4e6a889d 100644 --- a/website/docs/plugin/testing/acceptance-tests/plan-checks/custom.mdx +++ b/website/docs/plugin/testing/acceptance-tests/plan-checks/custom.mdx @@ -4,6 +4,9 @@ description: >- Plan Checks are test assertions that can inspect a plan at different phases in a TestStep. Custom Plan Checks can be implemented. --- +> [!IMPORTANT] +> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com. + # Custom Plan Checks The package [`plancheck`](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/plancheck) also provides the [`PlanCheck`](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/plancheck#PlanCheck) interface, which can be implemented for a custom plan check. diff --git a/website/docs/plugin/testing/acceptance-tests/plan-checks/index.mdx b/website/docs/plugin/testing/acceptance-tests/plan-checks/index.mdx index 9c1960b54..cff623441 100644 --- a/website/docs/plugin/testing/acceptance-tests/plan-checks/index.mdx +++ b/website/docs/plugin/testing/acceptance-tests/plan-checks/index.mdx @@ -5,6 +5,9 @@ description: >- provides built-in Plan Checks for common use-cases, and custom Plan Checks can also be implemented. --- +> [!IMPORTANT] +> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com. + # Plan Checks During the **Lifecycle (config)** and **Refresh** [modes](/terraform/plugin/testing/acceptance-tests/teststep#test-modes) of a `TestStep`, the testing framework will run `terraform plan` before and after certain operations. For example, the **Lifecycle (config)** mode will run a plan before the `terraform apply` phase, as well as a plan before and after the `terraform refresh` phase. 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 3f0b97bf7..e390b5d85 100644 --- a/website/docs/plugin/testing/acceptance-tests/plan-checks/output.mdx +++ b/website/docs/plugin/testing/acceptance-tests/plan-checks/output.mdx @@ -5,6 +5,9 @@ description: >- provides built-in Output Value Plan Checks for common use-cases. --- +> [!IMPORTANT] +> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com. + # Output Plan Checks The `terraform-plugin-testing` module provides a package [`plancheck`](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/plancheck) with built-in output value plan checks for common use-cases: 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 b96ae68bb..1172ce855 100644 --- a/website/docs/plugin/testing/acceptance-tests/plan-checks/resource.mdx +++ b/website/docs/plugin/testing/acceptance-tests/plan-checks/resource.mdx @@ -5,6 +5,9 @@ description: >- provides built-in Managed Resource and Data Source Plan Checks for common use-cases. --- +> [!IMPORTANT] +> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com. + # Resource Plan Checks The `terraform-plugin-testing` module provides a package [`plancheck`](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/plancheck) with built-in managed resource, and data source plan checks for common use-cases: 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 46cd3877e..7c0751c46 100644 --- a/website/docs/plugin/testing/acceptance-tests/state-checks/custom.mdx +++ b/website/docs/plugin/testing/acceptance-tests/state-checks/custom.mdx @@ -4,6 +4,9 @@ description: >- State Checks are test assertions that can inspect state during a TestStep. Custom State Checks can be implemented. --- +> [!IMPORTANT] +> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com. + # 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. diff --git a/website/docs/plugin/testing/acceptance-tests/state-checks/index.mdx b/website/docs/plugin/testing/acceptance-tests/state-checks/index.mdx index 36304e388..d8efb3d6a 100644 --- a/website/docs/plugin/testing/acceptance-tests/state-checks/index.mdx +++ b/website/docs/plugin/testing/acceptance-tests/state-checks/index.mdx @@ -5,6 +5,9 @@ description: >- provides built-in State Checks for common use-cases, and custom State Checks can also be implemented. --- +> [!IMPORTANT] +> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com. + # 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`. 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 434e7486b..b27149373 100644 --- a/website/docs/plugin/testing/acceptance-tests/state-checks/output.mdx +++ b/website/docs/plugin/testing/acceptance-tests/state-checks/output.mdx @@ -5,6 +5,9 @@ description: >- provides built-in Output Value State Checks for common use-cases. --- +> [!IMPORTANT] +> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com. + # 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: 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 d11db8f63..5d88681c0 100644 --- a/website/docs/plugin/testing/acceptance-tests/state-checks/resource.mdx +++ b/website/docs/plugin/testing/acceptance-tests/state-checks/resource.mdx @@ -5,6 +5,9 @@ description: >- provides built-in Managed Resource and Data Source State Checks for common use-cases. --- +> [!IMPORTANT] +> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com. + # 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: diff --git a/website/docs/plugin/testing/acceptance-tests/sweepers.mdx b/website/docs/plugin/testing/acceptance-tests/sweepers.mdx index 2fff9834f..ef0953cf5 100644 --- a/website/docs/plugin/testing/acceptance-tests/sweepers.mdx +++ b/website/docs/plugin/testing/acceptance-tests/sweepers.mdx @@ -5,6 +5,9 @@ description: >- testing framework. Sweepers clean up leftover infrastructure. --- +> [!IMPORTANT] +> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com. + # Sweepers Acceptance tests in Terraform provision and verify real infrastructure using [Terraform's testing framework](/terraform/plugin/testing/acceptance-tests). Ideally all infrastructure created is then destroyed within the lifecycle of a test, however the reality is that there are several situations that can arise where resources created during a test are “leaked”. Leaked test resources are resources created by Terraform during a test, but Terraform either failed to destroy them as part of the test, or the test falsely reported all resources were destroyed after completing the test. Common causes are intermittent errors or failures in vendor APIs, or developer error in the resource code or test. diff --git a/website/docs/plugin/testing/acceptance-tests/testcase.mdx b/website/docs/plugin/testing/acceptance-tests/testcase.mdx index 77ba53078..9e90849cd 100644 --- a/website/docs/plugin/testing/acceptance-tests/testcase.mdx +++ b/website/docs/plugin/testing/acceptance-tests/testcase.mdx @@ -5,6 +5,9 @@ description: |- creates a set of resources then verifies the new infrastructure. --- +> [!IMPORTANT] +> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com. + # Acceptance Tests: TestCases Acceptance tests are expressed in terms of **Test Cases**, each using one or diff --git a/website/docs/plugin/testing/acceptance-tests/teststep.mdx b/website/docs/plugin/testing/acceptance-tests/teststep.mdx index 01e791999..3d08b81c4 100644 --- a/website/docs/plugin/testing/acceptance-tests/teststep.mdx +++ b/website/docs/plugin/testing/acceptance-tests/teststep.mdx @@ -5,6 +5,9 @@ description: |- file to a given state. --- +> [!IMPORTANT] +> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com. + # Acceptance Tests: TestSteps `TestStep`s represent the application of an actual Terraform configuration file diff --git a/website/docs/plugin/testing/acceptance-tests/tfjson-paths.mdx b/website/docs/plugin/testing/acceptance-tests/tfjson-paths.mdx index a40e90f52..92302e040 100644 --- a/website/docs/plugin/testing/acceptance-tests/tfjson-paths.mdx +++ b/website/docs/plugin/testing/acceptance-tests/tfjson-paths.mdx @@ -5,6 +5,9 @@ description: >- Attribute paths represent the location of an attribute within Terraform JSON data. --- +> [!IMPORTANT] +> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com. + # Terraform JSON Paths An exact location within Terraform JSON data is referred to as a Terraform JSON or tfjson path. diff --git a/website/docs/plugin/testing/acceptance-tests/tfversion-checks.mdx b/website/docs/plugin/testing/acceptance-tests/tfversion-checks.mdx index 3c8efd4f0..7fda56cf4 100644 --- a/website/docs/plugin/testing/acceptance-tests/tfversion-checks.mdx +++ b/website/docs/plugin/testing/acceptance-tests/tfversion-checks.mdx @@ -5,6 +5,9 @@ description: >- provides built-in Version Checks for common use-cases, but custom Version Checks can also be implemented. --- +> [!IMPORTANT] +> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com. + # Terraform Version Checks **Terraform Version Checks** are generic checks defined at the TestCase level that check logic against the Terraform CLI version. The checks are executed at the beginning of the TestCase before any TestStep is executed. diff --git a/website/docs/plugin/testing/acceptance-tests/value-comparers/index.mdx b/website/docs/plugin/testing/acceptance-tests/value-comparers/index.mdx index 3ef5e19d6..99d640927 100644 --- a/website/docs/plugin/testing/acceptance-tests/value-comparers/index.mdx +++ b/website/docs/plugin/testing/acceptance-tests/value-comparers/index.mdx @@ -5,6 +5,9 @@ description: >- Value comparers define a comparison for a resource attribute, or output value for use in State Checks. --- +> [!IMPORTANT] +> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com. + # Value Comparers diff --git a/website/docs/plugin/testing/index.mdx b/website/docs/plugin/testing/index.mdx index d994c3ad7..6e6a86383 100644 --- a/website/docs/plugin/testing/index.mdx +++ b/website/docs/plugin/testing/index.mdx @@ -5,6 +5,9 @@ description: |- plugins. --- +> [!IMPORTANT] +> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com. + # Testing Terraform Plugins Here we cover information needed to write successful tests for Terraform diff --git a/website/docs/plugin/testing/migrating.mdx b/website/docs/plugin/testing/migrating.mdx index 51de60610..f4a9c75e5 100644 --- a/website/docs/plugin/testing/migrating.mdx +++ b/website/docs/plugin/testing/migrating.mdx @@ -4,6 +4,9 @@ description: >- Migrate your provider's acceptance testing dependencies from SDKv2 to the testing module. --- +> [!IMPORTANT] +> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com. + # Overview This guide helps you migrate a Terraform provider's acceptance testing dependencies from SDKv2 to the plugin testing module. We recommend migrating to terraform-plugin-testing to take advantage of new features of the testing module and to avoid importing the SDKv2 for providers that are built on the plugin Framework. diff --git a/website/docs/plugin/testing/testing-patterns.mdx b/website/docs/plugin/testing/testing-patterns.mdx index 662e51d4c..93c80c11b 100644 --- a/website/docs/plugin/testing/testing-patterns.mdx +++ b/website/docs/plugin/testing/testing-patterns.mdx @@ -5,6 +5,9 @@ description: |- Terraform resources. --- +> [!IMPORTANT] +> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com. + # Testing Patterns In [Testing Terraform Plugins][1] we introduce Terraform's Testing Framework, diff --git a/website/docs/plugin/testing/unit-testing.mdx b/website/docs/plugin/testing/unit-testing.mdx index c8b8690c1..a85130071 100644 --- a/website/docs/plugin/testing/unit-testing.mdx +++ b/website/docs/plugin/testing/unit-testing.mdx @@ -5,6 +5,9 @@ description: |- flatten API responses into data structures that Terraform stores as state. --- +> [!IMPORTANT] +> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com. + # Unit Testing Testing plugin code in small, isolated units is distinct from Acceptance Tests,