Skip to content

Enhancements for comparing data structures in test results #37083

@wyardley

Description

@wyardley

Terraform Version

Terraform v1.12.0
on darwin_arm64

Use Cases

The changes in #36522 (for #34428) look great and are working really well.
One thought is that when comparing structures that are generated via jsonencode(), the escaping makes them pretty hard to read.
Maybe this is too niche a problem to solve, but would it be possible to diff the json directly in the case where we're comparing jsonencoded data on both sides?

In either case, with an error that the LHS and RHS are different types, would it be possible to display the internal type of each?

Attempted Solutions

  assert {
    # This messy jsonencode is necessary for now; see:
    # https://github.com/hashicorp/terraform/issues/34428
    condition = jsonencode(google_secret_manager_secret.this.labels) == jsonencode({
      "foo" = "asdfadsf", ## actually "bar"
      "baz" = "qux",
    })
    error_message = "Expected members not found."
  }

This behaves correctly, and is not a bug, however, when the structures being compared are json and the results don't match, the structures are compared with quoting and escaped double quotes, which makes them difficult to read.

│     │ --- actual
│     │ +++ expected
│     │ - "{\"baz\":\"qux\",\"foo\":\"bar\"}"
│     │ + "{\"baz\":\"qux\",\"foo\":\"asdfadsf\"}"
│ 
Image

(side note: not sure if +++ expected should also be green to match?)

Directly comparing the two without jsonencode() still doesn't work when the values are the expected values and in the expected order, though it does now produce a more useful error:

  assert {
    condition = google_secret_manager_secret.this.labels == {
      "baz" = "qux",
      "foo" = "bar",
    }
    error_message = "Expected members not found."
  }
│ Error: Test assertion failed
│ 
│   on tests/main.tftest.hcl line 88, in run "simple_example":
│   88:     condition = google_secret_manager_secret.this.labels == {
│   89:       "baz" = "qux",
│   90:       "foo" = "bar",
│   91:     }
│     ├────────────────
│     │ LHS:
│     │   {
│     │     "baz": "qux",
│     │     "foo": "bar"
│     │   }
│     │ RHS:
│     │   {
│     │     "baz": "qux",
│     │     "foo": "bar"
│     │   }
│     │ Warning: LHS and RHS values are of different types
│ 
│     │ google_secret_manager_secret.this.labels is {
│     │     "baz": "qux",
│     │     "foo": "bar"
│     │   }

In this case, it would be nice if we could list the type of the LHS and RHS explicitly, which I think it still does not do? (I can make a separate issue if requested). It's also interesting that the visual representation of each is both (though from the error, it seems like they're different types internally).

Presumably actually being able to compare these two directly would be a different / separate enhancement, and IIRC there may already even be an issue open about it.

Proposal

│   on tests/main.tftest.hcl line 90, in run "simple_example":
│   90:     condition = jsonencode(google_secret_manager_secret.this.labels) == jsonencode({
│   91:       "foo" = "asdfadsf",
│   92:       "baz" = "qux",
│   93:     })
│     ├────────────────
│     │ Diff:
│     │ --- actual
│     │ +++ expected
│     │ - {"baz": "qux", "foo": "bar"}
│     │ + {"baz": "qux", "foo": "asdfadsf"}

References

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions