Terraform SDK 2.0 acceptance tests using provider binary

Hi,

I am in the process of updating the OpenAPI Terraform provider to Terraform SDK 2.0 and the integration tests are no longer working. The int tests are configured to use the OpenAPI provider source code (via setting the ProviderFactories field) as shown below; however the errors I am getting seem to suggest that the binary located at ~/.terraform.d/plugins is being used instead.

       p := openapi.ProviderOpenAPI{ProviderName: "openapi"}
	var testAccProviders = map[string]func() (*schema.Provider, error){
		providerName: func() (*schema.Provider, error) {
			return provider, nil
		},
	}
	resource.Test(t, resource.TestCase{
		ProviderFactories: testAccProviders,
                ....

Error returned when running the integration test:

    testing_new.go:79: init failed: 2020/10/04 10:10:16 [DEBUG] Using modified User-Agent: Terraform/0.12.29 HashiCorp-terraform-exec/0.10.0
        
        Provider "openapi" not available for installation.
        
        A provider named "openapi" could not be found in the Terraform Registry.
        
        This may result from mistyping the provider name, or the given provider may
        be a third-party provider that cannot be installed automatically.
        
        In the latter case, the plugin must be installed manually by locating and
        downloading a suitable distribution package and placing the plugin's executable
        file in the following directory:
            terraform.d/plugins/darwin_amd64
        
        Terraform detects necessary plugins by inspecting the configuration and state.
        To view the provider versions requested by each module, run
        "terraform providers".
        
        
        Error: no provider exists with the given name

Reading the Terraform testing docs How Acceptance Tests Work, I noticed the following:

Provider acceptance tests run real Terraform commands using a Terraform CLI binary, approximating as closely as possible the experience of using the provider under test with Terraform in production. We refer to this functionality as the "binary test driver".

However, I am not clear whether that means that the provider under test is also the real binary or the source code one. In previous versions of the SDK (before 2.0) the plugin under test was the one provided in the ProviderFactories or Providers fields in the resource.TestCase struct which also allowed me to set up breakpoints and debug any issues more easily.

Any help or pointers here would be much appreciated it!

Thanks,
Dani

Do you know what version / commit of SDKv2 you are using? There was a commit on master (unreleased) that caused reattaching to not work and the tests to attempt downloading.

What is the value for the providerName constant above? What does the test config look like?

For the factories, its probably not what is going wrong here, but its ideal for it to be a true factory, not just reusing a singleton value.

1 Like

Hi @paultyng,

I was using SDK 2.0 (github.com/hashicorp/terraform-plugin-sdk/v2 v2.0.0) and changing it to v2.0.3 made it work! Thanks for the pointers.

As far as the factory comment is concerned, do you have an example of that? For the integration tests, I was using the Providers fields but noticed is being deprecated so I am now looking at using the ProviderFactories field instead, however since the tests are only exercising the OpenAPI Terraform provider I figured having the factory only returning the openapi provider would be sufficient.

var testAccProviders = map[string]*schema.Provider{providerName: provider}
	resource.Test(t, resource.TestCase{
		Providers:  testAccProviders,
                ....
       }

Example using the factory:

	var testAccProviders = map[string]func() (*schema.Provider, error){
		"openapi": func() (*schema.Provider, error) {
			return provider, nil
		},
	}
	resource.Test(t, resource.TestCase{
		ProviderFactories: testAccProviders,
                ....
       }

Curious to learn though if there is a better way to do it.

Thanks!
Dani