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

Acceptance testing custom function not finding function in provider #414

Open
JacobPotter opened this issue Jan 15, 2025 · 1 comment
Open
Labels
bug Something isn't working waiting-response Issues or pull requests waiting for an external response

Comments

@JacobPotter
Copy link

terraform-plugin-testing version

github.com/hashicorp/terraform-plugin-testing v1.11.0

Relevant provider source code

Custom provider function

package provider

import (
	"cmp"
	"context"
	"github.com/Dynatrace/terraform-provider-zendesk/internal/models"
	"github.com/hashicorp/terraform-plugin-framework/function"
	"github.com/hashicorp/terraform-plugin-framework/types"
	"slices"
)

var _ function.Function = &SortCustomFieldOptions{}

type SortCustomFieldOptions struct{}

func NewSortCustomFieldOptions() function.Function {
	return &SortCustomFieldOptions{}
}

func (s *SortCustomFieldOptions) Metadata(ctx context.Context, request function.MetadataRequest, response *function.MetadataResponse) {
	response.Name = "sort_custom_field_options"
}

func (s *SortCustomFieldOptions) Definition(ctx context.Context, request function.DefinitionRequest, response *function.DefinitionResponse) {
	response.Definition = function.Definition{
		Summary:     "Sort custom field options",
		Description: "Sort custom field options by display name",
		Parameters: []function.Parameter{
			function.ListParameter{
				Name:        "custom_field_options",
				Description: "Custom field options to sort",
				ElementType: types.ObjectType{AttrTypes: models.CustomFieldOptionResourceModel{}.AttributeTypes()},
			},
		},
		Return: function.ListReturn{ElementType: types.ObjectType{AttrTypes: models.CustomFieldOptionResourceModel{}.AttributeTypes()}},
	}
}

func (s *SortCustomFieldOptions) Run(ctx context.Context, request function.RunRequest, response *function.RunResponse) {
	var customFieldOptionsList types.List

	response.Error = function.ConcatFuncErrors(response.Error, request.Arguments.Get(ctx, &customFieldOptionsList))

	var customFieldOptions []models.CustomFieldOptionResourceModel

	diags := customFieldOptionsList.ElementsAs(ctx, &customFieldOptions, true)

	if diags.HasError() {
		response.Error = function.ConcatFuncErrors(response.Error, function.NewFuncError("Error converting list to custom field options"))
		return
	}

	slices.SortFunc(customFieldOptions, func(a, b models.CustomFieldOptionResourceModel) int {
		return cmp.Compare(a.Name.ValueString(), b.Name.ValueString())
	})

	customFieldOptionsList, diags = types.ListValueFrom(ctx, types.ObjectType{AttrTypes: models.CustomFieldOptionResourceModel{}.AttributeTypes()}, customFieldOptions)

	if diags.HasError() {
		response.Error = function.ConcatFuncErrors(response.Error, function.NewFuncError("Error converting custom field options to list"))
		return
	}

	response.Error = function.ConcatFuncErrors(response.Error, response.Result.Set(ctx, customFieldOptionsList))
}

Function in Provider def

func (p *ZendeskProvider) Functions(ctx context.Context) []func() function.Function {
	return []func() function.Function{
		NewSortCustomFieldOptions,
	}
}
func TestSortCustomFieldOptionsValid(t *testing.T) {
	t.Parallel()

	resource.UnitTest(t, resource.TestCase{
		ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
		Steps: []resource.TestStep{
			{
				ConfigFile: config.TestNameFile("main.tf"),
			},
		},
	})
}

Terraform Configuration Files

locals {
  cfos=[
	{name:"T",value:"T"},
	{name:"H",value:"H"},
	{name:"D",value:"D"},
	{name:"L",value:"L"}
  ]
}

output "test" {
  value = provider::zendesk::sort_custom_field_options(local.cfos)
}

Expected Behavior

Actual Behavior

Steps to Reproduce

References

@JacobPotter JacobPotter added the bug Something isn't working label Jan 15, 2025
@austinvalle
Copy link
Member

Hey there @JacobPotter 👋🏻 , thanks for reporting the issue and sorry you're running into trouble here.

I'm assuming the error you're seeing is something like:

        Error: Unknown provider function
        
          on main.tf line 11, in output "test":
          10:   value = provider::zendesk::sort_custom_field_options(local.cfos)
        
        There is no function named "provider::zendesk::sort_custom_field_options". Ensure that
        provider name "zendesk" is declared in this module's required_providers block,
        and that this provider offers a function named "sort_custom_field_options".

If so, I think all you need to do is add a required_providers block to your main.tf test file:

terraform {
  required_providers {
    zendesk = {
      # https://developer.hashicorp.com/terraform/language/providers/requirements#source-addresses
      source = "<source address>" 
    }
  }
}

locals {
  cfos=[
	{name:"T",value:"T"},
	{name:"H",value:"H"},
	{name:"D",value:"D"},
	{name:"L",value:"L"}
  ]
}

output "test" {
  value = provider::zendesk::sort_custom_field_options(local.cfos)
}

When using ConfigFile or ConfigDirectory, we treat them as "ready-to-run" configuration, which is different from the static string Config field, where we will attempt to inject the required_providers block if one is not provided.

For example, the time provider uses the Config field, so it doesn't include the required_providers block: https://github.com/hashicorp/terraform-provider-time/blob/e5a617df3d678be87d3ade238b65a9808336b4b7/internal/provider/function_rfc3339_parse_test.go#L24-L28

But if we wanted to run that same test with ConfigFile, we would need to create a .tf file with:

terraform {
  required_providers {
    time = {
      source = "hashicorp/time"
    }
  }
}

output "test" {
  value = provider::time::rfc3339_parse("2023-07-25T23:43:16Z")
}

Hopefully that helps!

@austinvalle austinvalle added the waiting-response Issues or pull requests waiting for an external response label Jan 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working waiting-response Issues or pull requests waiting for an external response
Projects
None yet
Development

No branches or pull requests

2 participants