Acceptance testing: test a data source

Hi. I’m contributing to a plugin and I’d like to test a data source. I’ve already created some tests for resources, but now I’d like to test a data source. How can this be achieved?

Hi @juandspy :wave: Welcome to the HashiCorp Discuss community!

Acceptance testing a data source is very similar to a resource, but it may depend on what type of data source is being tested. If the source of the data is pre-existing (such as part of the API itself or in a pre-populated test environment), then the test can use a Terraform configuration with only the data source definition and checks in the testing framework can prepend “data.” to the first parameter to functions like resource.TestCheckResourceAttr(). For example:

func TestAccExampleDataSource(t *testing.T) {
	resource.Test(t, resource.TestCase{
		// ... other fields ...
		Steps: []resource.TestStep{
			// Read testing
			{
				Config: `data "examplecloud_thing" "test" {}`,
				Check: resource.ComposeAggregateTestCheckFunc(
					resource.TestCheckResourceAttr("data.examplecloud_thing.test", "id", "example-id"),
				),
			},
		},
	})
}

If the data source requires a resource to be created first, the Terraform configuration can be setup so the resource is created first and then the data source will be read:

resource "examplecloud_thing" "test" {}

data "examplecloud_thing" "test" {
  id = examplecloud_thing.test.id
}

The configuration reference between the resource and data source must be a computed (known after apply) value to ensure the proper ordering on the first apply. Attempting to use depends_on with data sources will always trigger plans that show the data source needing to be read during apply, which makes the testing less useful.

If you’re looking for more comprehensive code examples, you can find example data source testing in the terraform-plugin-scaffolding-framework GitHub repository or many large-scale providers such as the AWS provider.

The documentation for the acceptance testing framework itself can be found at: Plugin Development - Acceptance Testing | Terraform by HashiCorp

Hope this helps!

2 Likes

Hey @bflad , this is everything I needed :slight_smile:

I created a simple test like this for terraform-provider-rhoas:

// TestAccRHOASServiceAccount_DataSource checks the rhoas_service_accounts data source behavior
func TestAccRHOASServiceAccount_DataSource(t *testing.T) {
	var serviceAccount saclient.ServiceAccountData
	randomName := fmt.Sprintf("test-%s", randomString(10))
	config := fmt.Sprintf(`
resource "rhoas_service_account" "%[1]s" {
  name = "%[2]s"
}

data "rhoas_service_account" "test" {
	id = rhoas_service_account.%[1]s.id
}`, serviceAccountID, randomName)

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckServiceAccountDestroy,
		Steps: []resource.TestStep{
			{
				Config: config,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckServiceAccountExists(kafkaPath, &serviceAccount),
					resource.TestCheckResourceAttr(
						serviceAccountPath, "name", randomName),
					resource.TestCheckResourceAttr(
						"data.rhoas_service_account.test", "name", randomName),
				),
			},
		},
	})
}

However, it fails saying:

...
2022-09-30T12:49:00.469+0200 [WARN]  sdk.helper_schema: Previously configured provider being re-configured. This can cause issues in concurrent testing if the configurations are not equal.: tf_rpc=Configure tf_req_id=7b0fa233-5c35-8893-5234-365708badb11 tf_provider_addr=registry.terraform.io/hashicorp/rhoas
2022-09-30T12:49:00.520+0200 [WARN]  sdk.helper_schema: Previously configured provider being re-configured. This can cause issues in concurrent testing if the configurations are not equal.: tf_rpc=Configure tf_req_id=e7adee40-e1bc-c549-d88f-a1b7c568493d tf_provider_addr=registry.terraform.io/hashicorp/rhoas
...
2022-09-30T12:42:18.781+0200 [DEBUG] sdk.helper_resource: Creating sdkv2 provider instance: tf_provider_addr=registry.terraform.io/hashicorp/rhoas test_name=TestAccRHOASServiceAccount_DataSource test_step_number=1 test_terraform_path=/usr/bin/terraform test_working_directory=/tmp/plugintest125814261
2022-09-30T12:42:18.781+0200 [DEBUG] sdk.helper_resource: Created sdkv2 provider instance: test_terraform_path=/usr/bin/terraform tf_provider_addr=registry.terraform.io/hashicorp/rhoas test_working_directory=/tmp/plugintest125814261 test_name=TestAccRHOASServiceAccount_DataSource test_step_number=1
2022-09-30T12:42:18.781+0200 [DEBUG] sdk.helper_resource: Starting sdkv2 provider instance server: test_terraform_path=/usr/bin/terraform test_working_directory=/tmp/plugintest125814261 test_name=TestAccRHOASServiceAccount_DataSource test_step_number=1 tf_provider_addr=registry.terraform.io/hashicorp/rhoas
2022-09-30T12:42:18.781+0200 [DEBUG] sdk.helper_resource: Started sdkv2 provider instance server: test_step_number=1 test_terraform_path=/usr/bin/terraform test_working_directory=/tmp/plugintest125814261 test_name=TestAccRHOASServiceAccount_DataSource tf_provider_addr=registry.terraform.io/hashicorp/rhoas
    testing_new.go:62: no "id" found in attributes
...

Do you know what this error means? Also, I’m not sure if the warning is also problematic.

I’ve tried applying this exact configuration using terraform apply and it worked:

terraform {
  required_providers {
    rhoas = {
      source  = "registry.terraform.io/redhat-developer/rhoas"
      version = "0.1"
    }
  }
}

provider "rhoas" {}

resource "rhoas_service_account" "test" {
  name = "a-random-name"
}

data "rhoas_service_account" "test" {
  id = rhoas_service_account.test.id
}

So it looks like the “id” attribute should exist…

Thanks in advance!

Oh, I’ve just found this link from the docs asking for the “id” field to be computed. In my code it is a required attribute instead. Probably that’s generating the issue…

Yep, it was that :face_with_open_eyes_and_hand_over_mouth: . Thanks @bflad !

Ah, sorry for not also including the framework-specific acceptance testing page link that mentions the id attribute requirement! Hopefully we can find an easy way to remove that requirement. Glad you were able to get this sorted and best of luck with your provider and testing journey. :smile: Please reach out if you need anything else.

1 Like