Skip to content

Commit

Permalink
Add initial version of a plugin-framework provider config test, move …
Browse files Browse the repository at this point in the history
…code between packages to allow tests (#8797) (#6180)

* Add initial version of plugin framework provider config test affected by inaccessible functions

* Move `ReplaceVarsForFrameworkTest` to `fwresource` package

This mirrors how old, ReplaceVars* functions are in the `tpgresource` package

* Move functions for changing ENVs in tests to `acctest` package, update usage

* Move `GenerateFakeCredentialsJson` function to `acctest` package, update usage

* Refactor provider config tests to use plugin-framework types

* Add all test cases to match equivalent SDK provider config tests

Some test cases currently fail due to different handling of empty values by the SDK and plugin framework

* Add test case about handling of Unknown values for `project`

* Update tests to check values in BOTH the data model and provider config struct after `LoadAndValidateFramework` runs

Signed-off-by: Modular Magician <[email protected]>
  • Loading branch information
modular-magician authored Aug 30, 2023
1 parent d005f34 commit ac37ec7
Show file tree
Hide file tree
Showing 8 changed files with 152 additions and 148 deletions.
3 changes: 3 additions & 0 deletions .changelog/8797.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:none

```
51 changes: 0 additions & 51 deletions google-beta/acctest/framework_test_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,12 @@ import (
"context"
"fmt"
"log"
"reflect"
"regexp"
"strings"
"testing"

"github.com/hashicorp/terraform-plugin-framework/diag"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"

"github.com/hashicorp/terraform-provider-google-beta/google-beta/fwtransport"
"github.com/hashicorp/terraform-provider-google-beta/google-beta/tpgresource"
)

func GetFwTestProvider(t *testing.T) *frameworkTestProvider {
Expand Down Expand Up @@ -81,48 +75,3 @@ func testStringValue(sPtr *string) string {

return *sPtr
}

// This function isn't a test of transport.go; instead, it is used as an alternative
// to ReplaceVars inside tests.
func ReplaceVarsForFrameworkTest(prov *fwtransport.FrameworkProviderConfig, rs *terraform.ResourceState, linkTmpl string) (string, error) {
re := regexp.MustCompile("{{([[:word:]]+)}}")
var project, region, zone string

if strings.Contains(linkTmpl, "{{project}}") {
project = rs.Primary.Attributes["project"]
}

if strings.Contains(linkTmpl, "{{region}}") {
region = tpgresource.GetResourceNameFromSelfLink(rs.Primary.Attributes["region"])
}

if strings.Contains(linkTmpl, "{{zone}}") {
zone = tpgresource.GetResourceNameFromSelfLink(rs.Primary.Attributes["zone"])
}

replaceFunc := func(s string) string {
m := re.FindStringSubmatch(s)[1]
if m == "project" {
return project
}
if m == "region" {
return region
}
if m == "zone" {
return zone
}

if v, ok := rs.Primary.Attributes[m]; ok {
return v
}

// Attempt to draw values from the provider
if f := reflect.Indirect(reflect.ValueOf(prov)).FieldByName(m); f.IsValid() {
return f.String()
}

return ""
}

return re.ReplaceAllStringFunc(linkTmpl, replaceFunc), nil
}
54 changes: 54 additions & 0 deletions google-beta/acctest/test_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/hashicorp/terraform-plugin-mux/tf5muxserver"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"github.com/hashicorp/terraform-provider-google-beta/google-beta/envvar"
)

func CheckDataSourceStateMatchesResourceState(dataSourceName, resourceName string) func(*terraform.State) error {
Expand Down Expand Up @@ -202,3 +203,56 @@ func CreateZIPArchiveForCloudFunctionSource(t *testing.T, sourcePath string) str
}
return tmpfile.Name()
}

// providerConfigEnvNames returns a list of all the environment variables that could be set by a user to configure the provider
func providerConfigEnvNames() []string {

envs := []string{}

// Use existing collections of ENV names
envVarsSets := [][]string{
envvar.CredsEnvVars, // credentials field
envvar.ProjectEnvVars, // project field
envvar.RegionEnvVars, //region field
envvar.ZoneEnvVars, // zone field
}
for _, set := range envVarsSets {
envs = append(envs, set...)
}

// Add remaining ENVs
envs = append(envs, "GOOGLE_OAUTH_ACCESS_TOKEN") // access_token field
envs = append(envs, "GOOGLE_BILLING_PROJECT") // billing_project field
envs = append(envs, "GOOGLE_IMPERSONATE_SERVICE_ACCOUNT") // impersonate_service_account field
envs = append(envs, "USER_PROJECT_OVERRIDE") // user_project_override field
envs = append(envs, "CLOUDSDK_CORE_REQUEST_REASON") // request_reason field

return envs
}

// UnsetProviderConfigEnvs unsets any ENVs in the test environment that
// configure the provider.
// The testing package will restore the original values after the test
func UnsetTestProviderConfigEnvs(t *testing.T) {
envs := providerConfigEnvNames()
if len(envs) > 0 {
for _, k := range envs {
t.Setenv(k, "")
}
}
}

func SetupTestEnvs(t *testing.T, envValues map[string]string) {
// Set ENVs
if len(envValues) > 0 {
for k, v := range envValues {
t.Setenv(k, v)
}
}
}

// Returns a fake credentials JSON string with the client_email set to a test-specific value
func GenerateFakeCredentialsJson(testId string) string {
json := fmt.Sprintf(`{"private_key_id": "foo","private_key": "bar","client_email": "%[email protected]","client_id": "[email protected]","type": "service_account"}`, testId)
return json
}
3 changes: 2 additions & 1 deletion google-beta/fwprovider/framework_provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"

"github.com/hashicorp/terraform-provider-google-beta/google-beta/acctest"
"github.com/hashicorp/terraform-provider-google-beta/google-beta/fwresource"
"github.com/hashicorp/terraform-provider-google-beta/google-beta/fwtransport"
"github.com/hashicorp/terraform-provider-google-beta/google-beta/tpgresource"
transport_tpg "github.com/hashicorp/terraform-provider-google-beta/google-beta/transport"
Expand Down Expand Up @@ -223,7 +224,7 @@ func testAccCheckDNSManagedZoneDestroyProducerFramework(t *testing.T) func(s *te

p := acctest.GetFwTestProvider(t)

url, err := acctest.ReplaceVarsForFrameworkTest(&p.FrameworkProvider.FrameworkProviderConfig, rs, "{{DNSBasePath}}projects/{{project}}/managedZones/{{name}}")
url, err := fwresource.ReplaceVarsForFrameworkTest(&p.FrameworkProvider.FrameworkProviderConfig, rs, "{{DNSBasePath}}projects/{{project}}/managedZones/{{name}}")
if err != nil {
return err
}
Expand Down
49 changes: 49 additions & 0 deletions google-beta/fwresource/field_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@ package fwresource

import (
"fmt"
"reflect"
"regexp"
"strings"

"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"github.com/hashicorp/terraform-provider-google-beta/google-beta/fwtransport"
"github.com/hashicorp/terraform-provider-google-beta/google-beta/tpgresource"
)

Expand Down Expand Up @@ -64,3 +68,48 @@ func ParseProjectFieldValueFramework(resourceType, fieldValue, projectSchemaFiel
ResourceType: resourceType,
}
}

// This function isn't a test of transport.go; instead, it is used as an alternative
// to ReplaceVars inside tests.
func ReplaceVarsForFrameworkTest(prov *fwtransport.FrameworkProviderConfig, rs *terraform.ResourceState, linkTmpl string) (string, error) {
re := regexp.MustCompile("{{([[:word:]]+)}}")
var project, region, zone string

if strings.Contains(linkTmpl, "{{project}}") {
project = rs.Primary.Attributes["project"]
}

if strings.Contains(linkTmpl, "{{region}}") {
region = tpgresource.GetResourceNameFromSelfLink(rs.Primary.Attributes["region"])
}

if strings.Contains(linkTmpl, "{{zone}}") {
zone = tpgresource.GetResourceNameFromSelfLink(rs.Primary.Attributes["zone"])
}

replaceFunc := func(s string) string {
m := re.FindStringSubmatch(s)[1]
if m == "project" {
return project
}
if m == "region" {
return region
}
if m == "zone" {
return zone
}

if v, ok := rs.Primary.Attributes[m]; ok {
return v
}

// Attempt to draw values from the provider
if f := reflect.Indirect(reflect.ValueOf(prov)).FieldByName(m); f.IsValid() {
return f.String()
}

return ""
}

return re.ReplaceAllStringFunc(linkTmpl, replaceFunc), nil
}
Loading

0 comments on commit ac37ec7

Please sign in to comment.