Terraform
Custom Query Checks
The package querycheck also provides the QueryResultCheck interface, which can be implemented for a custom query check.
The querycheck.CheckQueryRequest contains the current query results, parsed by the terraform-json package.
Here is an example implementation of a query check that asserts that a specific query result resource object attribute has a known type and value:
package example_test
import (
"context"
"fmt"
tfjson "github.com/hashicorp/terraform-json"
"github.com/hashicorp/terraform-plugin-testing/knownvalue"
"github.com/hashicorp/terraform-plugin-testing/querycheck"
"github.com/hashicorp/terraform-plugin-testing/querycheck/queryfilter"
"github.com/hashicorp/terraform-plugin-testing/tfjsonpath"
)
var _ querycheck.QueryResultCheck = expectKnownValue{}
var _ querycheck.QueryResultCheckWithFilters = expectKnownValue{}
type expectKnownValue struct {
listResourceAddress string
filter queryfilter.QueryFilter
attributePath tfjsonpath.Path
knownValueCheck knownvalue.Check
}
func (e expectResourceKnownValues) QueryFilters(_ context.Context) []queryfilter.QueryFilter {
if e.filter == nil {
return []queryfilter.QueryFilter{}
}
return []queryfilter.QueryFilter{
e.filter,
}
}
func (e expectKnownValue) CheckQuery(_ context.Context, req querycheck.CheckQueryRequest, resp *querycheck.CheckQueryResponse) {
listRes := make([]tfjson.ListResourceFoundData, 0)
for _, res := range req.Query {
if e.listResourceAddress == strings.TrimPrefix(res.Address, "list.") {
listRes = append(listRes, res)
}
}
if len(listRes) == 0 {
resp.Error = fmt.Errorf("%s - no query results found after filtering", e.listResourceAddress)
return
}
if len(listRes) > 1 {
resp.Error = fmt.Errorf("%s - more than 1 query result found after filtering", e.listResourceAddress)
return
}
res := listRes[0]
if res.ResourceObject == nil {
resp.Error = fmt.Errorf("%s - no resource object was returned, ensure `include_resource` has been set to `true` in the list resource config`", e.listResourceAddress)
return
}
attribute, err := tfjsonpath.Traverse(res.ResourceObject, e.attributePath)
if err != nil {
resp.Error = err
return
}
if err := e.KnownValue.CheckValue(attribute); err != nil {
resp.Error = fmt.Errorf("error checking value for attribute at path: %s for resource with identity %s, err: %s", e.attributePath, e.filter, err)
return
}
}
func ExpectKnownValues(listResourceAddress string, filter queryfilter.QueryFilter, attributePath tfjsonpath.Path, knownValueCheck knownvalue.Check) QueryResultCheck {
return expectKnownValues{
listResourceAddress: listResourceAddress,
filter: filter,
attributePath: attributePath,
knownValueCheck: knownValueCheck,
}
}