Configuring a provider for acceptance test without environment vars?

I’m writing the testing framework for a new provider, but don’t want to pass required attributes with environment variables. Instead, I want to set them directly inside the test framework.

I’ve tried configuring the provider with a ResourceConfig, and I can verify that the provider’s ConfigureFunc is parsing the ResourceData as expected. For example:

func testAccPreCheck(t *testing.T) {
	testAccProviderConfigure.Do(func() {
		raw := map[string]interface{}{
			"broker_password": "pass",
			"broker_username": "user",
			"broker_url":      "http://localhost:1234/",
		}

		err := testAccProvider.Configure(context.Background(), terraform.NewResourceConfigRaw(raw))
		if err != nil {
			t.Fatal(err)
		}
	})
}

and

provider.ConfigureFunc = func(d *schema.ResourceData) (interface{}, error) {
    // broker_user prints as expected (without env vars)
    fmt.Println(d.Get("broker_user").(string))
}

Though I’m still getting “The argument FOO is required, but was not set” error when running the test. For example:

➜ TF_LOG=DEBUG TF_ACC=1 go test path/to/provider/tests -v

...

Error: Missing required argument

The argument "user" is required, but was not set.

I noticed it wasn’t the configuration that throws this error, and I’ve tentatively traced it back to github.com/hashicorp/hcl which makes me wonder:

  1. Is it even possible to configure a provider for acceptance test without providing required attributes via environment variables.
  2. What am I overlooking?

Hi @walker,

I’m not an expert on the current plugin SDK so I might not have all of the details exactly right here, but I believe that the test framework is designed to create a fresh configuration of your provider for each test, so that it’s less likely for the behavior of one test to inadvertently affect another.

Specifically, I think the test function in the test API is itself calling Configure on the provider based on what it found in the test configuration you provided.

Given that, I think the only way to get the result you were hoping for here would be to include a provider block in each of your test configurations which specifies this fixed configuration. To make that less repetitive, perhaps you could write a helper function which takes a configuration string and appends this hard-coded provider block to the end of it, and then use that function in each of your tests to make sure they all run with the expected configuration.

1 Like

That’s the detail I was overlooking! (that the testAPI itself configures the provider).

I’ve added the provider block to the test configuration, and everything is looking AOK.

Thanks for the quick response!

I’d love to see some code examples on how to do this exactly. I am having a lot of trouble set up tests on a provider that has a nested configuration structure, so that env vars can only be used for the inner vars. When initialising, the test framework complains the needed block(s) have not been specified.

For example below I can set the env var FOO_BAR, but the test framework will complain that “at least one” block named “foo” must be set.


provider "foobar" {
   foo {
      bar = "hello" //this can also be set with env var FOO_BAR
  }
}