Skip to content

Unable to mock data source attribute of list type using override_data, suspected due to missing type conversion #37939

@sanderginn

Description

@sanderginn

Terraform Version

1.14.0

Terraform Configuration Files

main.tf

terraform {
  required_providers {
    databricks = {
      source  = "databricks/databricks"
      version = "1.97.0"
    }
  }

  required_version = ">= 1.14.0"
}

data "databricks_external_location" "test" {
  name = "test"
}

test.tftest.hcl

mock_provider "databricks" {}

run "nothing_mocked_failure_shows_generated_id" {
  override_data {
    target = data.databricks_external_location.test
  }

  command = plan
  
  assert {
    condition = data.databricks_external_location.test.id == "expecting failure, not mocked"
    error_message = "See diff for generated ID"
  }
}

run "id_mocked_successfully" {
  override_data {
    target = data.databricks_external_location.test
    values = {
      id = "with-id-mocked"
    }
  }
  
  command = plan

  assert {
    condition = data.databricks_external_location.test.id == "with-id-mocked"
    error_message = "Expected the external location ID to be 'with-id-mocked'"
  }
}

run "external_location_url_mocked_unsuccessfully" {
  override_data {
    target = data.databricks_external_location.test
    values = {
      external_location_info = [{ url = "abfss://[email protected]/" }]
    }
  }

  command = plan

  assert {
    condition = data.databricks_external_location.test.external_location_info[0].url == "abfss://[email protected]/"
    error_message = "Expected the external location URL to be 'abfss://[email protected]/'"
  }
}

Debug Output

Output of TF_LOG=TRACE terraform test: gist

Expected Behavior

I would expect the test nothing_mocked_failure_shows_generated_id to fail, and the other tests to pass.

Actual Behavior

In addition to nothing_mocked_failure_shows_generated_id, external_location_url_mocked_unsuccessfully also fails:

  run "external_location_url_mocked_unsuccessfully"... fail
╷
│ Error: Invalid index
│ 
│   on variable_validation.tftest.hcl line 43, in run "external_location_url_mocked_unsuccessfully":
│   43:     condition = data.databricks_external_location.test.external_location_info[0].url == "abfss://[email protected]/"
│     ├────────────────
│     │ data.databricks_external_location.test.external_location_info is empty list of object
│ 
│ The given key does not identify an element in this collection value: the collection has no elements.
╵

Inspecting the data source value using an assertion which fails and printing the contents shows that external_location_url is not set:

╷
│ Error: Test assertion failed
│ 
│   on variable_validation.tftest.hcl line 43, in run "external_location_url_mocked_unsuccessfully":
│   43:     condition = length(data.databricks_external_location.test.external_location_info) > 0
│     ├────────────────
│ 
│ 
│ jsonencoded value of data:
│ {"external_location_info":[],"id":"c2rwnoaz","name":"test","provider_config":[]}

Steps to Reproduce

  1. terraform test

Additional Context

My strong suspicion is that the type conversion of tuple to list is not occurring properly in the override_data block, and instead of raising an error, the default value is used (an empty collection, as defined in the docs).

An argument against this suspicion is that types seem to be enforced when setting properties in override_data blocks. When I set the id attribute to ["with-id-mocked"] in the test id_mocked_successfully, it does raise an error:

  run "id_mocked_successfully"... fail
╷
│ Error: Failed to compute attribute
│ 
│   with data.databricks_external_location.test,
│   on main.tf line 12, in data "databricks_external_location" "test":
│   12: data "databricks_external_location" "test" {
│ 
│ Terraform could not compute a value for the target type string with the mocked data defined at variable_validation.tftest.hcl:17,3-16 with the attribute ".id": string required, but have tuple.

However, I'm not sure whether [] is considered valid input for an list attribute during type checking.

When I inspect the contents of a data source successfully fetched from a live environment using terraform console, I can see that the external_location_info is defined with tolist():

> data.databricks_external_location.schema_locations
{
  "<redacted>" = {
    "external_location_info" = tolist([
      {
        "browse_only" = false
        "comment" = "<redacted>"
        "created_at" = 1760513678249
        "created_by" = "<redacted>"
        "credential_id" = "<redacted>"
        "credential_name" = "<redacted>"
        "enable_file_events" = false
        "encryption_details" = tolist([])
        "fallback" = false
        "file_event_queue" = tolist([])
        "isolation_mode" = "ISOLATION_MODE_OPEN"
        "metastore_id" = "<redacted>"
        "name" = "<redacted>"
        "owner" = "<redacted>"
        "read_only" = false
        "updated_at" = 1760513678675
        "updated_by" = "<redacted>"
        "url" = "abfss://<redacted>@<redacted>.dfs.core.windows.net/"
      },
    ])
    "id" = "<redacted>"
    "name" = "<redacted>"
    "provider_config" = tolist(null) /* of object */
  }
}

Since functions in override_data blocks are not permitted, I don't know how I can verify whether my suspicion is correct.

References

No response

Generative AI / LLM assisted development?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugnewnew issue not yet triaged

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions