-
Notifications
You must be signed in to change notification settings - Fork 17
Description
terraform-plugin-testing version
v1.7.0
Use cases
When using knownvalue.NumberExact, it's possible to get confusing error messages in the situation where the provided *big.Float does not match the value parsed from a json.Number because of the mantissa using something like big.NewFloat.
Example
func TestNumberFunction_recreate(t *testing.T) {
resource.UnitTest(t, resource.TestCase{
ProtoV6ProviderFactories: map[string]func() (tfprotov6.ProviderServer, error){
"framework": providerserver.NewProtocol6WithError(New()),
},
Steps: []resource.TestStep{
{
Config: `output "test" {
value = 1.23
}`,
ConfigStateChecks: []statecheck.StateCheck{
statecheck.ExpectKnownOutputValue("test", knownvalue.NumberExact(big.NewFloat(1.23))),
},
},
},
})
}Test error
--- FAIL: TestNumberFunction_recreate (0.43s)
/Users/austin.valle/code/terraform-provider-corner/internal/framework6provider/number_function_test.go:80: Step 1/1 error: Post-apply refresh state check(s) failed:
error checking value for output at path: test, err: expected value 1.23 for NumberExact check, got: 1.23
FAIL
FAIL github.com/hashicorp/terraform-provider-corner/internal/framework6provider 0.896s
FAILWhat can make this more confusing is when it accidentally is correct and the test passes 😅 :
func TestNumberFunction_successful(t *testing.T) {
resource.UnitTest(t, resource.TestCase{
ProtoV6ProviderFactories: map[string]func() (tfprotov6.ProviderServer, error){
"framework": providerserver.NewProtocol6WithError(New()),
},
Steps: []resource.TestStep{
{
Config: `output "test" {
value = 1234.5
}`,
ConfigStateChecks: []statecheck.StateCheck{
// Success!
statecheck.ExpectKnownOutputValue("test", knownvalue.NumberExact(big.NewFloat(1234.5))),
},
},
},
})
}Workaround
You can workaround this by creating the *big.Float exactly how the internal state check logic/Terraform creates it. Fixing the initial example in this issue:
func TestNumberFunction_recreate(t *testing.T) {
matchingFloat, _, _ := big.ParseFloat("1.23", 10, 512, big.ToNearestEven)
resource.UnitTest(t, resource.TestCase{
ProtoV6ProviderFactories: map[string]func() (tfprotov6.ProviderServer, error){
"framework": providerserver.NewProtocol6WithError(New()),
},
Steps: []resource.TestStep{
{
Config: `output "test" {
value = 1.23
}`,
ConfigStateChecks: []statecheck.StateCheck{
// Success!
statecheck.ExpectKnownOutputValue("test", knownvalue.NumberExact(matchingFloat)),
},
},
},
})
}Proposal
Improve the error message to also include the precision/rounding/mantissa information to make it more apparent why two floating point numbers don't match. Perhaps we could also make a suggestion about how best to create the *big.Float value if a comparison doesn't match because of the mantissa.
References
- Found while writing dynamic tests in: Add dynamic resource and dynamic function parameter/return tests terraform-provider-corner#228