Skip to content

FR and/or Doc: support for variadic parameters in unit testing and/or updates to corresponding documentation #1088

@mschuchard

Description

@mschuchard

Version: 1.11.0 <-- refers to terraform-plugin-testing

At the moment I have a simple function with a variadic parameter where the parameter value retrieval occurs according to documentation:

VariadicParameter: function.Int32Parameter{
	Name:        "number_of_characters",
	Description: "Optional: The number of terminating characters at the end of the string to return (default: 1). This must be fewer than the number of characters in the input string.",
},
...
var numCharsVar []int32

resp.Error = function.ConcatFuncErrors(resp.Error, req.Arguments.Get(ctx, &inputString, &numCharsVar))

During unit testing omitting the variadic parameter succeeds completely as expected:

"optional-param-absent": {
	request: function.RunRequest{
		Arguments: function.NewArgumentsData([]attr.Value{types.StringValue("hello"), types.Int32Null()}),
	},
	expected: function.RunResponse{
		Result: function.NewResultData(types.StringValue("o")),
	},
},

but specifying a value errors:

"three-terminating-chars": {
	request: function.RunRequest{
		Arguments: function.NewArgumentsData([]attr.Value{types.StringValue("hello"), types.Int32Value(3)}),
	},
	expected: function.RunResponse{
		Result: function.NewResultData(types.StringValue("llo")),
	},
},

actual value: Value Conversion Error: An unexpected error was encountered trying to convert tftypes.Value into []int32. This is always an error in the provider. Please report the following to the provider developer:
can't unmarshal tftypes.Number into *[]tftypes.Value expected []tftypes.Value

Ok so even though types.Int32Null() is valid in the function signature for the first unit test request, and it would also be a tuple tftype in the actual Terraform config, the expectation here in the unit testing framework is for the variadic parameters to be capable of marshalling to a slice?
Well the function.NewArgumentsData signature only accepts a single slice of attr.Value, and the second argument cannot be []types.Int32{types.Int32Value(3)} because the interface does not implement what is required for the attr.Value type, and so then is the variadic parameter argument supposed to be an enumerable tftype i.e. set or list?

So I am kind of at a coin flip between whether this is unsupported or undocumented.

Corollary: complex type return testing for e.g. tuples is supported although undocumented, and I did miraculously figure it out via:

"normal": {
	request: function.RunRequest{
		Arguments: function.NewArgumentsData([]attr.Value{types.StringValue("foobarbaz"), types.StringValue("bar")}),
	},
	expected: function.RunResponse{
		Result: function.NewResultData(types.TupleValueMust(
			[]attr.Type{types.StringType, types.StringType, types.BoolType},
			[]attr.Value{types.StringValue("foo"), types.StringValue("baz"), types.BoolValue(true)})),
	},
},

but this would also be benficial to add to documentation since e.g. currently in the AWS provider there is a function with an object tftype return and a "TODO: figure out how to do this" which implies both a documentation gap if they cannot figure it out, and also that probably some element of luck was involved with me actually figuring it out.

Thank you.

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentation

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions