internal/acceptance/check/that.go (146 lines of code) (raw):

package check import ( "encoding/json" "fmt" "regexp" "github.com/Azure/terraform-provider-azapi/internal/acceptance" "github.com/Azure/terraform-provider-azapi/internal/clients" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" ) type thatType struct { // resourceName being the full resource name e.g. azurerm_foo.bar resourceName string } // Key returns a type which can be used for more fluent assertions for a given Resource func That(resourceName string) thatType { return thatType{ resourceName: resourceName, } } // DoesNotExistInAzure validates that the specified resource does not exist within Azure func (t thatType) DoesNotExistInAzure(testResource acceptance.TestResource) resource.TestCheckFunc { return func(s *terraform.State) error { client, err := acceptance.BuildTestClient() if err != nil { return fmt.Errorf("building client: %+v", err) } return DoesNotExistInAzure(client, testResource, t.resourceName)(s) } } // ExistsInAzure validates that the specified resource exists within Azure func (t thatType) ExistsInAzure(testResource acceptance.TestResource) resource.TestCheckFunc { return func(s *terraform.State) error { client, err := acceptance.BuildTestClient() if err != nil { return fmt.Errorf("building client: %+v", err) } return ExistsInAzure(client, testResource, t.resourceName)(s) } } // Key returns a type which can be used for more fluent assertions for a given Resource & Key combination func (t thatType) Key(key string) thatWithKeyType { return thatWithKeyType{ resourceName: t.resourceName, key: key, } } type thatWithKeyType struct { // resourceName being the full resource name e.g. azurerm_foo.bar resourceName string // key being the specific field we're querying e.g. bar or a nested object ala foo.0.bar key string } // JsonAssertionFunc is a function which takes a deserialized JSON object and asserts on it type JsonAssertionFunc func(input []interface{}) (*bool, error) // ContainsKeyValue returns a TestCheckFunc which asserts upon a given JSON string set into // the State by deserializing it and then asserting on it via the JsonAssertionFunc func (t thatWithKeyType) ContainsJsonValue(assertion JsonAssertionFunc) resource.TestCheckFunc { return func(s *terraform.State) error { rs, exists := s.RootModule().Resources[t.resourceName] if !exists { return fmt.Errorf("%q was not found in the state", t.resourceName) } value, exists := rs.Primary.Attributes[t.key] if !exists { return fmt.Errorf("the value %q does not exist within %q", t.key, t.resourceName) } if value == "" { return fmt.Errorf("the value for %q was empty", t.key) } var out []interface{} if err := json.Unmarshal([]byte(value), &out); err != nil { return fmt.Errorf("deserializing the value for %q (%q) to json: %+v", t.key, value, err) } ok, err := assertion(out) if err != nil { return fmt.Errorf("asserting value for %q: %+v", t.key, err) } if ok == nil || !*ok { return fmt.Errorf("assertion failed for %q: %+v", t.key, err) } return nil } } func (t thatWithKeyType) IsJson() resource.TestCheckFunc { return func(s *terraform.State) error { rs, exists := s.RootModule().Resources[t.resourceName] if !exists { return fmt.Errorf("%q was not found in the state", t.resourceName) } value, exists := rs.Primary.Attributes[t.key] if !exists { return fmt.Errorf("the value %q does not exist within %q", t.key, t.resourceName) } if value == "" { return fmt.Errorf("the value for %q was empty", t.key) } var out interface{} if err := json.Unmarshal([]byte(value), &out); err != nil { return fmt.Errorf("deserializing the value for %q (%q) to json: %+v", t.key, value, err) } return nil } } // DoesNotExist returns a TestCheckFunc which validates that the specific key // does not exist on the resource func (t thatWithKeyType) DoesNotExist() resource.TestCheckFunc { return resource.TestCheckNoResourceAttr(t.resourceName, t.key) } // Exists returns a TestCheckFunc which validates that the specific key exists on the resource func (t thatWithKeyType) Exists() resource.TestCheckFunc { return resource.TestCheckResourceAttrSet(t.resourceName, t.key) } // IsEmpty returns a TestCheckFunc which validates that the specific key is empty on the resource func (t thatWithKeyType) IsEmpty() resource.TestCheckFunc { return resource.TestCheckResourceAttr(t.resourceName, t.key, "") } // IsSet returns a TestCheckFunc which validates that the specific key is set on the resource func (t thatWithKeyType) IsSet() resource.TestCheckFunc { return resource.TestCheckResourceAttrSet(t.resourceName, t.key) } // HasValue returns a TestCheckFunc which validates that the specific key has the // specified value on the resource func (t thatWithKeyType) HasValue(value string) resource.TestCheckFunc { return resource.TestCheckResourceAttr(t.resourceName, t.key, value) } // MatchesOtherKey returns a TestCheckFunc which validates that the key on this resource // matches another other key on another resource func (t thatWithKeyType) MatchesOtherKey(other thatWithKeyType) resource.TestCheckFunc { return resource.TestCheckResourceAttrPair(t.resourceName, t.key, other.resourceName, other.key) } // MatchesRegex returns a TestCheckFunc which validates that the key on this resource matches // the given regular expression func (t thatWithKeyType) MatchesRegex(r *regexp.Regexp) resource.TestCheckFunc { return resource.TestMatchResourceAttr(t.resourceName, t.key, r) } func DoesNotExistInAzure(client *clients.Client, testResource acceptance.TestResource, resourceName string) resource.TestCheckFunc { return existsFunc(false)(client, testResource, resourceName) } func ExistsInAzure(client *clients.Client, testResource acceptance.TestResource, resourceName string) resource.TestCheckFunc { return existsFunc(true)(client, testResource, resourceName) } func existsFunc(shouldExist bool) func(*clients.Client, acceptance.TestResource, string) resource.TestCheckFunc { return func(client *clients.Client, testResource acceptance.TestResource, resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { ctx := client.StopContext rs, ok := s.RootModule().Resources[resourceName] if !ok { return fmt.Errorf("%q was not found in the state", resourceName) } result, err := testResource.Exists(ctx, client, rs.Primary) if err != nil { return fmt.Errorf("running exists func for %q: %+v", resourceName, err) } if result == nil { return fmt.Errorf("received nil for exists for %q", resourceName) } if *result != shouldExist { if !shouldExist { return fmt.Errorf("%q still exists", resourceName) } return fmt.Errorf("%q did not exist", resourceName) } return nil } } }