From e2107e438378a0de5ca991b38e551d65392f4ed2 Mon Sep 17 00:00:00 2001 From: Dharsan Date: Thu, 9 May 2024 02:20:51 +0530 Subject: [PATCH] test(config): added config unit tests --- internal/provider/provider.go | 58 +++------------------------- internal/provider/utils.go | 68 +++++++++++++++++++++++++++++++-- internal/provider/utils_test.go | 52 +++++++++++++++++++++++++ 3 files changed, 123 insertions(+), 55 deletions(-) diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 4e2d0f3..f5a994b 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -3,7 +3,6 @@ package provider import ( "context" "crypto/tls" - "errors" "net/http" "os" @@ -13,7 +12,6 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/humanitec/humanitec-go-autogen" - "sigs.k8s.io/yaml" ) // Ensure HumanitecProvider satisfies various provider interfaces. @@ -94,59 +92,15 @@ func (p *HumanitecProvider) Configure(ctx context.Context, req provider.Configur return } - var c Config - - // Check for .humctl file generated by humctl command line tool - configFilePath := data.Config.ValueString() - if configFilePath == "" { - homeDir, err := os.UserHomeDir() - if err != nil { - resp.Diagnostics.AddWarning( - "Unable to determine home directory", - "While configuring the provider, terraform was unable "+ - "to determine user's home directory to read config file.", - ) - configFilePath = "" - } else { - configFilePath = homeDir + "/.humctl" - if _, err := os.Stat(configFilePath); errors.Is(err, os.ErrNotExist) { - configFilePath = "" - } - } - - } else if _, err := os.Stat(configFilePath); errors.Is(err, os.ErrNotExist) { - resp.Diagnostics.AddError( - "Unable to read config file", - "Terraform was unable to read config file mentioned "+ - "in the config attribute.", - ) + config, diags := readConfig(data) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { return } - if configFilePath != "" { - file, err := os.ReadFile(configFilePath) - if err != nil { - resp.Diagnostics.AddError( - "Unable to read config file", - "Terraform was unable to read the yaml config file "+ - "in "+configFilePath, - ) - return - } - - err = yaml.Unmarshal(file, &c) - if err != nil { - resp.Diagnostics.AddError( - "Unable to parse yaml from config file", - "Terraform was unable to parse yaml config "+ - "file in "+configFilePath, - ) - // Not returning early allows the logic to collect all errors. - } - } - apiPrefix := c.ApiPrefix - orgID := c.Org - token := c.Token + apiPrefix := config.ApiPrefix + orgID := config.Org + token := config.Token // Environment variables have precedence over config file, if found if hostOld := os.Getenv("HUMANITEC_HOST"); hostOld != "" { diff --git a/internal/provider/utils.go b/internal/provider/utils.go index e0eb7d2..1ee6c97 100644 --- a/internal/provider/utils.go +++ b/internal/provider/utils.go @@ -1,9 +1,17 @@ package provider +import ( + "errors" + "os" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "sigs.k8s.io/yaml" +) + type Config struct { - ApiPrefix string `json:"apiPrefix,omitempty"` - Org string `json:"org,omitempty"` - Token string `json:"token,omitempty"` + ApiPrefix string `yaml:"apiPrefix,omitempty"` + Org string `yaml:"org,omitempty"` + Token string `yaml:"token,omitempty"` } func valueAtPath[T any](input map[string]interface{}, path []string) (T, bool) { @@ -46,3 +54,57 @@ func findInSlicePtr[T any](in *[]T, f func(T) bool) (T, bool) { return element, found } + +func readConfig(data HumanitecProviderModel) (config Config, diags diag.Diagnostics) { + diags = diag.Diagnostics{} + // Check for .humctl file generated by humctl command line tool + configFilePath := data.Config.ValueString() + if configFilePath == "" { + homeDir, err := os.UserHomeDir() + if err != nil { + diags.AddWarning( + "Unable to determine home directory", + "While configuring the provider, terraform was unable "+ + "to determine user's home directory to read config file.", + ) + configFilePath = "" + } else { + configFilePath = homeDir + "/.humctl" + if _, err := os.Stat(configFilePath); errors.Is(err, os.ErrNotExist) { + configFilePath = "" + } + } + } else if _, err := os.Stat(configFilePath); errors.Is(err, os.ErrNotExist) { + diags.AddError( + "Unable to read config file", + "Terraform was unable to read config file mentioned "+ + "in the config attribute.", + ) + return + } + + if configFilePath == "" { + return + } + + file, err := os.ReadFile(configFilePath) + if err != nil { + diags.AddError( + "Unable to read config file", + "Terraform was unable to read the yaml config file "+ + "in "+configFilePath, + ) + return + } + + err = yaml.Unmarshal(file, &config) + if err != nil { + diags.AddError( + "Unable to parse yaml from config file", + "Terraform was unable to parse yaml config "+ + "file in "+configFilePath, + ) + return + } + return +} diff --git a/internal/provider/utils_test.go b/internal/provider/utils_test.go index 18e642a..3225872 100644 --- a/internal/provider/utils_test.go +++ b/internal/provider/utils_test.go @@ -1,9 +1,12 @@ package provider import ( + "os" "testing" + "github.com/hashicorp/terraform-plugin-framework/types" "github.com/stretchr/testify/assert" + "sigs.k8s.io/yaml" ) func TestValueAtPath(t *testing.T) { @@ -21,3 +24,52 @@ func TestValueAtPath(t *testing.T) { assert.True(ok) assert.Equal([]string{"a", "b"}, value) } + +func TestReadConfig(t *testing.T) { + assert := assert.New(t) + configData := Config{ + ApiPrefix: "https://test-api.humanitec.io/", + Org: "unittest-org", + Token: "unittest-token", + } + + configBytes, err := yaml.Marshal(configData) + if err != nil { + t.Fatal(err) + } + + configFile, err := os.CreateTemp(".", ".humctl") + if err != nil { + t.Fatal(err) + } + defer configFile.Close() + + _, err = configFile.Write(configBytes) + if err != nil { + t.Fatal(err) + } + + configPath := configFile.Name() + defer os.Remove(configPath) + + config, diags := readConfig(HumanitecProviderModel{ + Config: types.StringValue(configPath), + }) + assert.Len(diags, 0) + assert.Equal(config, configData) +} + +func TestReadConfigNonExistentFile(t *testing.T) { + assert := assert.New(t) + currentDirectory, err := os.Getwd() + if err != nil { + t.Fatal(err) + } + configPath := currentDirectory + ".humctl" + + _, diags := readConfig(HumanitecProviderModel{ + Config: types.StringValue(configPath), + }) + assert.Len(diags, 1) + assert.Equal("Unable to read config file", diags[0].Summary()) +}