Skip to content

Commit

Permalink
Improve set detailed diffs (#2451)
Browse files Browse the repository at this point in the history
This change adds improved TF set handling to the detailed diff v2. The
main challenge here is that pulumi does not have native sets, so set
types are represented as lists.

### Diffing sets using the hash ###

To correctly find the diff of two sets we calculate the hash of each
element ourselves and do the diffs based on that. What makes this
somewhat non-trivial is that due to MaxItemsOne flattening we can't just
hash the pulumi `PropertyValue`s given to us by the engine. Instead we
use `makeSingleTerraformInput` to transform the values using the schema.
We then use the hashes of the elements in the set to calculate the
diffs. This allows us to correctly account for shuffling and duplicates,
matching the terraform behaviour of sets.

When returning the element indices back to the engine, we need to return
them in terms of oldState and newInputs because the engine does not have
access to the plannedState (see
#2281). To do
that we keep the newInputs and match plannedState elements to their
newInputs index by the set hash. Note that this is not possible if the
set element contains any computed properties - these can change during
the planning process, so we do not attempt to match and print a warning
about possibly inaccurate diff results instead.


### Unknowns in sets ###
Note that the terraform planning process does not allow a set to contain
any unknowns, because that breaks the hashing. Because of that plan
should always return an unknown for a set which contains any unknowns.
This accounts for cases where resolving the unknown can result in
duplicate elements.

Unknown elements in sets - the whole set becomes unknown in the plan, so
the algorithm no longer works. Currently we return an update for the
whole set to the engine and it does the diff on its side.

### Testing ###
This PR also includes tests for the set behaviour, both unit tests for
the detailed diff algorithm and integration tests using pulumi programs
for:
- Single element additions, updates and removals
- Shuffling, also with additions, updates and removals
- Multi-element additions, updates and removals
- Unknowns

### Issues ###

Builds on #2405

Stacked on #2515,
#2516,
#2496 and
#2497

fixes #2200
fixes #2300
fixes #1904
fixes #186
  • Loading branch information
VenelinMartinov authored Oct 30, 2024
1 parent ef94e28 commit 7b500d2
Show file tree
Hide file tree
Showing 9 changed files with 3,739 additions and 804 deletions.
2 changes: 1 addition & 1 deletion pkg/internal/tests/cross-tests/diff_cross_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1042,7 +1042,7 @@ func findKeyInPulumiDetailedDiff(detailedDiff map[string]interface{}, key string
}

func TestNilVsEmptyNestedCollections(t *testing.T) {
// TODO: remove once accurate bridge previews are rolled out
// TODO[pulumi/pulumi-terraform-bridge#2517]: remove once accurate bridge previews are rolled out
t.Setenv("PULUMI_TF_BRIDGE_ACCURATE_BRIDGE_PREVIEW", "true")
for _, MaxItems := range []int{0, 1} {
t.Run(fmt.Sprintf("MaxItems=%d", MaxItems), func(t *testing.T) {
Expand Down
Loading

0 comments on commit 7b500d2

Please sign in to comment.