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

default attribute values of object variables are ignored in tests #2018

Open
berahtlv opened this issue Sep 25, 2024 · 7 comments
Open

default attribute values of object variables are ignored in tests #2018

berahtlv opened this issue Sep 25, 2024 · 7 comments
Assignees
Labels
accepted This issue has been accepted for implementation. bug Something isn't working
Milestone

Comments

@berahtlv
Copy link

OpenTofu Version

OpenTofu v1.8.2

OpenTofu Configuration Files

main.tf

variable "root_disk" {
  type = object({
    type       = optional(string, "gp3")
    size       = optional(number, 40)
    iops       = optional(number)
    throughput = optional(number)
  })
}

tests.tftest.hcl

run "root_disk_var" {

  command = plan

  variables {
    root_disk = {
      size = 60
    }
  }

  assert {
    condition = var.root_disk == {
      size = 60
    }
    error_message = "Value is incorrect"
  }
}

Debug Output

terraform.tfvars

root_disk = {
  size = 60
}

tofu console

> var.root_disk
{
  "iops" = tonumber(null)
  "size" = 60
  "throughput" = tonumber(null)
  "type" = "gp3"
}

Expected Behavior

Test should fail since root_disk object has default value for type attribute.

Actual Behavior

Test is successful even though the attribute with a default value is missing.

Steps to Reproduce

tofu test

Additional Context

No response

References

No response

@berahtlv berahtlv added bug Something isn't working pending-decision This issue has not been accepted for implementation nor rejected. It's still open to discussion. labels Sep 25, 2024
@berahtlv berahtlv changed the title object variables with default attribute values are ignored in tests default attribute values of object variables are ignored in tests Sep 25, 2024
@ollevche
Copy link
Member

ollevche commented Sep 25, 2024

Hello @berahtlv and thank you for your issue!

I took a quick look and it works the same way for me. We handled variable defaults here, but didn't take into account variable type.

It looks like a bug indeed so let us get back to you after the core team discussion.

@apparentlymart
Copy link
Contributor

apparentlymart commented Oct 8, 2024

Looking at the example from the original issue, I'd note that as currently written that test ought to also fail for a different reason, because:

  • var.root_disk is declared as being of an object type with four attributes
  • the assert block's condition is comparing it to a value of type object({size = number}), without the other three attributes.
  • The == can only return true if the two operands have exactly the same type.

If the test harness were correctly setting var.root_disk to have the same value it would have when used inside the module -- which I assume is the intent -- then in order to pass this test would need to change to one of the two following forms:

run "root_disk_var" {
  command = plan

  variables {
    root_disk = {
      size = 60
    }
  }

  assert {
    # This variation would fail immediately if any new
    # attributes were added to the variable's type
    # constraint in future.
    condition = var.root_disk == {
      size       = 60
      type       = "gp3"
      iops       = tonumber(null)
      throughput = tonumber(null)
    }
    error_message = "Value is incorrect"
  }
}
run "root_disk_var" {
  command = plan

  variables {
    root_disk = {
      size = 60
    }
  }

  # This variation tolerates the addition of new attributes
  # without failing, by testing each attribute separately.
  assert {
    condition = (var.root_disk.size == 60)
    error_message = "Size is incorrect"
  }
  assert {
    condition = (var.root_disk.type == "gp3")
    error_message = "Type is incorrect"
  }
  assert {
    condition = (var.root_disk.iops == tonumber(null))
    error_message = "IOps is incorrect"
  }
  assert {
    condition = (var.root_disk.throughput == tonumber(null))
    error_message = "Throughput is incorrect"
  }
}

It seems like at the moment the bug reported by this issue is masking this problem. I'm mentioning it here only in the hope that it's helpful to someone working on this issue in future, since there is more than one way for the given example to fail and so it starting to fail does not necessarily mean that the bug is fixed.

@cam72cam cam72cam added this to the 1.9.0 milestone Oct 10, 2024
@cam72cam cam72cam added accepted This issue has been accepted for implementation. and removed pending-decision This issue has not been accepted for implementation nor rejected. It's still open to discussion. labels Oct 10, 2024
@AdosH1
Copy link
Contributor

AdosH1 commented Oct 28, 2024

Hey @cam72cam, may I take a look at this?

@ollevche
Copy link
Member

Hey @AdosH1 thank you for volunteering! Let me assign you, but before opening a PR, please describe your approach here so we can sync on the chosen implementation path.

@AdosH1
Copy link
Contributor

AdosH1 commented Nov 11, 2024

@ollevche In terms of the solution, I think the configVariables should contain a Default cty value of that object, and attempt to set each field that hasn't been set earlier. Would that be a reasonable start on this issue?

I don't have a strong opinion for ApparentlyMart's assertation methodology, but leaning towards the exact object matching given its for the test command (which we have full control over inputs)
I've been confused however, why the test command (with plan) behaves quite differently from the tests for plan command

@ollevche
Copy link
Member

Hey @AdosH1! Sorry for delay with reply from my side.

I think to resolve this particular issue (type defaults are not being applied to test variables), we need to extend parseAndApplyDefaultValues function to also handle TypeDefaults from config variables.

Object comparison is out of the scope of this particular bug in my opinion.

@AdosH1
Copy link
Contributor

AdosH1 commented Nov 30, 2024

Thanks ollevche, I will take a look in the coming week 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accepted This issue has been accepted for implementation. bug Something isn't working
Projects
None yet
Development

No branches or pull requests

5 participants