Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement comparison state checks to replace TestCheckResourceAttrPtr, TestCheckResourceAttrPair and TestCheckTypeSetElemAttrPair #330

Merged
merged 66 commits into from
Aug 8, 2024

Conversation

bendbennett
Copy link
Contributor

@bendbennett bendbennett commented Apr 30, 2024

Closes: #295
References: #282
References: #187

Background

During the implementation of Consider Adding State Check Equivalents to Plan Checks, it was intended that the pre-built TestCheckFunc implementations would be deprecated. However, these deprecations were not included at that time partly because there was no satisfactory re-implementation of TestCheckResourceAttrPtr, which used the new style state checks which leverage tfjson.State, and neither TestCheckResourceAttrPair, nor TestCheckTypeSetElemAttrPair were re-implemented as it was unclear whether there was a need for such checks.

Comparison State Checks and the ValueComparer interface

The concepts from Consider Multiple Value Checking Interface have been used to implement comparison state checks to replace the built-in TestCheckFunc checks for TestCheckResourceAttrPtr, TestCheckResourceAttrPair, and TestCheckTypeSetElemAttrPair. All three implementations make use of the ValueComparer interface.

Replacement for TestCheckResourceAttrPtr - CompareValue

var _ StateCheck = &compareValue{}

type compareValue struct {
	resourceAddresses []string
	attributePaths    []tfjsonpath.Path
	stateValues       []any
	comparer          compare.ValueComparer
}

func (e *compareValue) AddStateValue(resourceAddress string, attributePath tfjsonpath.Path) StateCheck {
	e.resourceAddresses = append(e.resourceAddresses, resourceAddress)
	e.attributePaths = append(e.attributePaths, attributePath)

	return e
}

// CheckState implements the state check logic.
func (e *compareValue) CheckState(ctx context.Context, req CheckStateRequest, resp *CheckStateResponse) {
	/* ... */

	err = e.comparer.CompareValues(e.stateValues...)

	/* ... */
}

// CompareValue returns a state check that compares sequential values retrieved from state.
func CompareValue(comparer compare.ValueComparer) *compareValue {
	return &compareValue{
		comparer: comparer,
	}
}

Replacement for TestCheckResourceAttrPair - CompareValuePairs

var _ StateCheck = &compareValuePairs{}

type compareValuePairs struct {
	resourceAddressOne string
	attributePathOne   tfjsonpath.Path
	resourceAddressTwo string
	attributePathTwo   tfjsonpath.Path
	comparer           compare.ValueComparer
}

// CheckState implements the state check logic.
func (e *compareValuePairs) CheckState(ctx context.Context, req CheckStateRequest, resp *CheckStateResponse) {
	/* ... */

	err = e.comparer.CompareValues(resultOne, resultTwo)

	/* ... */
}

func CompareValuePairs(resourceAddressOne string, attributePathOne tfjsonpath.Path, resourceAddressTwo string, attributePathTwo tfjsonpath.Path, comparer compare.ValueComparer) StateCheck {
	return &compareValuePairs{
		resourceAddressOne: resourceAddressOne,
		attributePathOne:   attributePathOne,
		resourceAddressTwo: resourceAddressTwo,
		attributePathTwo:   attributePathTwo,
		comparer:           comparer,
	}
}

Replacement for TestCheckTypeSetElemAttrPair - CompareValueCollection

var _ StateCheck = &compareValueCollection{}

type compareValueCollection struct {
	resourceAddressOne string
	collectionPath     []tfjsonpath.Path
	resourceAddressTwo string
	attributePath      tfjsonpath.Path
	comparer           compare.ValueComparer
}

// CheckState implements the state check logic.
func (e *compareValueCollection) CheckState(ctx context.Context, req CheckStateRequest, resp *CheckStateResponse) {
	/* ... */

	for _, v := range results {
		switch resultTwo.(type) {
		case []any:
			errs = append(errs, e.comparer.CompareValues([]any{v}, resultTwo))
		default:
			errs = append(errs, e.comparer.CompareValues(v, resultTwo))
		}
	}

	/* ... */
}

// CompareValueCollection returns a state check that iterates over each element in a collection and compares the value of each element
// with the value of an attribute using the given value comparer.
func CompareValueCollection(resourceAddressOne string, collectionPath []tfjsonpath.Path, resourceAddressTwo string, attributePath tfjsonpath.Path, comparer compare.ValueComparer) StateCheck {
	return &compareValueCollection{
		resourceAddressOne: resourceAddressOne,
		collectionPath:     collectionPath,
		resourceAddressTwo: resourceAddressTwo,
		attributePath:      attributePath,
		comparer:           comparer,
	}
}

Implementations of the ValueComparer interface

type ValueComparer interface {
	CompareValues(values ...any) error
}
type ValuesSame struct{}

func (v ValuesSame) CompareValues(values ...any) error {
	for i := 1; i < len(values); i++ {
		if values[i-1] != values[i] {
			return fmt.Errorf("expected values to be the same, but they differ: %v != %v", values[i-1], values[i])
		}
	}

	return nil
}

There are implementations of the ValueComparer interface for:

  • ValuesSame
  • ValuesDiffer

These various implementations can be used in conjunction with CompareValue, CompareValueCollection, and CompareValuePairs.

@bendbennett bendbennett added the enhancement New feature or request label Apr 30, 2024
@bendbennett bendbennett added this to the v1.8.0 milestone Apr 30, 2024
Copy link
Member

@austinvalle austinvalle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes LGTM, will be interested to see the documentation as I can imagine we'll need to be prescriptive on "when" provider developers should use one of these state checks 👍🏻

compare/values_differ_any.go Outdated Show resolved Hide resolved
compare/values_differ_any.go Outdated Show resolved Hide resolved
@austinvalle austinvalle modified the milestones: v1.8.0, v1.9.0 May 17, 2024
@SBGoods SBGoods modified the milestones: v1.9.0, v1.10.0 Jul 9, 2024
dependabot bot and others added 10 commits July 10, 2024 17:30
Bumps [hashicorp/setup-terraform](https://github.com/hashicorp/setup-terraform) from 3.1.0 to 3.1.1.
- [Release notes](https://github.com/hashicorp/setup-terraform/releases)
- [Changelog](https://github.com/hashicorp/setup-terraform/blob/main/CHANGELOG.md)
- [Commits](hashicorp/setup-terraform@97f030c...651471c)

---
updated-dependencies:
- dependency-name: hashicorp/setup-terraform
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [hashicorp/setup-copywrite](https://github.com/hashicorp/setup-copywrite) from 1.1.2 to 1.1.3.
- [Release notes](https://github.com/hashicorp/setup-copywrite/releases)
- [Commits](hashicorp/setup-copywrite@867a1a2...32638da)

---
updated-dependencies:
- dependency-name: hashicorp/setup-copywrite
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: hashicorp-tsccr[bot] <hashicorp-tsccr[bot]@users.noreply.github.com>
Bumps [github.com/hashicorp/terraform-json](https://github.com/hashicorp/terraform-json) from 0.21.0 to 0.22.0.
- [Release notes](https://github.com/hashicorp/terraform-json/releases)
- [Commits](hashicorp/terraform-json@v0.21.0...v0.22.0)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/terraform-json
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [github.com/hashicorp/terraform-json](https://github.com/hashicorp/terraform-json) from 0.22.0 to 0.22.1.
- [Release notes](https://github.com/hashicorp/terraform-json/releases)
- [Commits](hashicorp/terraform-json@v0.22.0...v0.22.1)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/terraform-json
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [github.com/hashicorp/terraform-exec](https://github.com/hashicorp/terraform-exec) from 0.20.0 to 0.21.0.
- [Release notes](https://github.com/hashicorp/terraform-exec/releases)
- [Changelog](https://github.com/hashicorp/terraform-exec/blob/main/CHANGELOG.md)
- [Commits](hashicorp/terraform-exec@v0.20.0...v0.21.0)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/terraform-exec
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
… and CLI options) (#331)

* sloppy first commit!

* add version checks and tests

* add changelogs

* update terraform-plugin-go

* spelling fix

* update `terraform-json`

* switch to pointer bool value
SBGoods and others added 16 commits July 10, 2024 17:30
* Add `float32exact` and `int32exact` types

* Update website documentation

* Add changelog entries

* Update changelog wording
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.24.0 to 0.25.0.
- [Commits](golang/crypto@v0.24.0...v0.25.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
… and CLI options) (#331)

* sloppy first commit!

* add version checks and tests

* add changelogs

* update terraform-plugin-go

* spelling fix

* update `terraform-json`

* switch to pointer bool value
* Add `float32exact` and `int32exact` types

* Update website documentation

* Add changelog entries

* Update changelog wording
@austinvalle austinvalle marked this pull request as ready for review July 17, 2024 21:08
@austinvalle austinvalle requested a review from a team as a code owner July 17, 2024 21:08
@austinvalle austinvalle self-assigned this Jul 17, 2024
@austinvalle austinvalle requested a review from SBGoods July 17, 2024 21:11
Copy link
Contributor

@SBGoods SBGoods left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@austinvalle austinvalle merged commit 5d78aa4 into main Aug 8, 2024
35 checks passed
@austinvalle austinvalle deleted the bendbennett/issues-295 branch August 8, 2024 21:29
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 7, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Consider Multiple Value Checking Interface
4 participants