| package cliconfig |
| |
| import ( |
| "os" |
| "path/filepath" |
| "reflect" |
| "testing" |
| |
| "github.com/davecgh/go-spew/spew" |
| "github.com/google/go-cmp/cmp" |
| ) |
| |
| // This is the directory where our test fixtures are. |
| const fixtureDir = "./testdata" |
| |
| func TestLoadConfig(t *testing.T) { |
| c, err := loadConfigFile(filepath.Join(fixtureDir, "config")) |
| if err != nil { |
| t.Fatalf("err: %s", err) |
| } |
| |
| expected := &Config{ |
| Providers: map[string]string{ |
| "aws": "foo", |
| "do": "bar", |
| }, |
| } |
| |
| if !reflect.DeepEqual(c, expected) { |
| t.Fatalf("bad: %#v", c) |
| } |
| } |
| |
| func TestLoadConfig_env(t *testing.T) { |
| defer os.Unsetenv("TFTEST") |
| os.Setenv("TFTEST", "hello") |
| |
| c, err := loadConfigFile(filepath.Join(fixtureDir, "config-env")) |
| if err != nil { |
| t.Fatalf("err: %s", err) |
| } |
| |
| expected := &Config{ |
| Providers: map[string]string{ |
| "aws": "hello", |
| "google": "bar", |
| }, |
| Provisioners: map[string]string{ |
| "local": "hello", |
| }, |
| } |
| |
| if !reflect.DeepEqual(c, expected) { |
| t.Fatalf("bad: %#v", c) |
| } |
| } |
| |
| func TestLoadConfig_hosts(t *testing.T) { |
| got, diags := loadConfigFile(filepath.Join(fixtureDir, "hosts")) |
| if len(diags) != 0 { |
| t.Fatalf("%s", diags.Err()) |
| } |
| |
| want := &Config{ |
| Hosts: map[string]*ConfigHost{ |
| "example.com": { |
| Services: map[string]interface{}{ |
| "modules.v1": "https://example.com/", |
| }, |
| }, |
| }, |
| } |
| |
| if !reflect.DeepEqual(got, want) { |
| t.Errorf("wrong result\ngot: %swant: %s", spew.Sdump(got), spew.Sdump(want)) |
| } |
| } |
| |
| func TestLoadConfig_credentials(t *testing.T) { |
| got, err := loadConfigFile(filepath.Join(fixtureDir, "credentials")) |
| if err != nil { |
| t.Fatal(err) |
| } |
| |
| want := &Config{ |
| Credentials: map[string]map[string]interface{}{ |
| "example.com": map[string]interface{}{ |
| "token": "foo the bar baz", |
| }, |
| "example.net": map[string]interface{}{ |
| "username": "foo", |
| "password": "baz", |
| }, |
| }, |
| CredentialsHelpers: map[string]*ConfigCredentialsHelper{ |
| "foo": &ConfigCredentialsHelper{ |
| Args: []string{"bar", "baz"}, |
| }, |
| }, |
| } |
| |
| if !reflect.DeepEqual(got, want) { |
| t.Errorf("wrong result\ngot: %swant: %s", spew.Sdump(got), spew.Sdump(want)) |
| } |
| } |
| |
| func TestConfigValidate(t *testing.T) { |
| tests := map[string]struct { |
| Config *Config |
| DiagCount int |
| }{ |
| "nil": { |
| nil, |
| 0, |
| }, |
| "empty": { |
| &Config{}, |
| 0, |
| }, |
| "host good": { |
| &Config{ |
| Hosts: map[string]*ConfigHost{ |
| "example.com": {}, |
| }, |
| }, |
| 0, |
| }, |
| "host with bad hostname": { |
| &Config{ |
| Hosts: map[string]*ConfigHost{ |
| "example..com": {}, |
| }, |
| }, |
| 1, // host block has invalid hostname |
| }, |
| "credentials good": { |
| &Config{ |
| Credentials: map[string]map[string]interface{}{ |
| "example.com": map[string]interface{}{ |
| "token": "foo", |
| }, |
| }, |
| }, |
| 0, |
| }, |
| "credentials with bad hostname": { |
| &Config{ |
| Credentials: map[string]map[string]interface{}{ |
| "example..com": map[string]interface{}{ |
| "token": "foo", |
| }, |
| }, |
| }, |
| 1, // credentials block has invalid hostname |
| }, |
| "credentials helper good": { |
| &Config{ |
| CredentialsHelpers: map[string]*ConfigCredentialsHelper{ |
| "foo": {}, |
| }, |
| }, |
| 0, |
| }, |
| "credentials helper too many": { |
| &Config{ |
| CredentialsHelpers: map[string]*ConfigCredentialsHelper{ |
| "foo": {}, |
| "bar": {}, |
| }, |
| }, |
| 1, // no more than one credentials_helper block allowed |
| }, |
| "provider_installation good none": { |
| &Config{ |
| ProviderInstallation: nil, |
| }, |
| 0, |
| }, |
| "provider_installation good one": { |
| &Config{ |
| ProviderInstallation: []*ProviderInstallation{ |
| {}, |
| }, |
| }, |
| 0, |
| }, |
| "provider_installation too many": { |
| &Config{ |
| ProviderInstallation: []*ProviderInstallation{ |
| {}, |
| {}, |
| }, |
| }, |
| 1, // no more than one provider_installation block allowed |
| }, |
| "plugin_cache_dir does not exist": { |
| &Config{ |
| PluginCacheDir: "fake", |
| }, |
| 1, // The specified plugin cache dir %s cannot be opened |
| }, |
| } |
| |
| for name, test := range tests { |
| t.Run(name, func(t *testing.T) { |
| diags := test.Config.Validate() |
| if len(diags) != test.DiagCount { |
| t.Errorf("wrong number of diagnostics %d; want %d", len(diags), test.DiagCount) |
| for _, diag := range diags { |
| t.Logf("- %#v", diag.Description()) |
| } |
| } |
| }) |
| } |
| } |
| |
| func TestConfig_Merge(t *testing.T) { |
| c1 := &Config{ |
| Providers: map[string]string{ |
| "foo": "bar", |
| "bar": "blah", |
| }, |
| Provisioners: map[string]string{ |
| "local": "local", |
| "remote": "bad", |
| }, |
| Hosts: map[string]*ConfigHost{ |
| "example.com": { |
| Services: map[string]interface{}{ |
| "modules.v1": "http://example.com/", |
| }, |
| }, |
| }, |
| Credentials: map[string]map[string]interface{}{ |
| "foo": { |
| "bar": "baz", |
| }, |
| }, |
| CredentialsHelpers: map[string]*ConfigCredentialsHelper{ |
| "buz": {}, |
| }, |
| ProviderInstallation: []*ProviderInstallation{ |
| { |
| Methods: []*ProviderInstallationMethod{ |
| {Location: ProviderInstallationFilesystemMirror("a")}, |
| {Location: ProviderInstallationFilesystemMirror("b")}, |
| }, |
| }, |
| { |
| Methods: []*ProviderInstallationMethod{ |
| {Location: ProviderInstallationFilesystemMirror("c")}, |
| }, |
| }, |
| }, |
| } |
| |
| c2 := &Config{ |
| Providers: map[string]string{ |
| "bar": "baz", |
| "baz": "what", |
| }, |
| Provisioners: map[string]string{ |
| "remote": "remote", |
| }, |
| Hosts: map[string]*ConfigHost{ |
| "example.net": { |
| Services: map[string]interface{}{ |
| "modules.v1": "https://example.net/", |
| }, |
| }, |
| }, |
| Credentials: map[string]map[string]interface{}{ |
| "fee": { |
| "bur": "bez", |
| }, |
| }, |
| CredentialsHelpers: map[string]*ConfigCredentialsHelper{ |
| "biz": {}, |
| }, |
| ProviderInstallation: []*ProviderInstallation{ |
| { |
| Methods: []*ProviderInstallationMethod{ |
| {Location: ProviderInstallationFilesystemMirror("d")}, |
| }, |
| }, |
| }, |
| } |
| |
| expected := &Config{ |
| Providers: map[string]string{ |
| "foo": "bar", |
| "bar": "baz", |
| "baz": "what", |
| }, |
| Provisioners: map[string]string{ |
| "local": "local", |
| "remote": "remote", |
| }, |
| Hosts: map[string]*ConfigHost{ |
| "example.com": { |
| Services: map[string]interface{}{ |
| "modules.v1": "http://example.com/", |
| }, |
| }, |
| "example.net": { |
| Services: map[string]interface{}{ |
| "modules.v1": "https://example.net/", |
| }, |
| }, |
| }, |
| Credentials: map[string]map[string]interface{}{ |
| "foo": { |
| "bar": "baz", |
| }, |
| "fee": { |
| "bur": "bez", |
| }, |
| }, |
| CredentialsHelpers: map[string]*ConfigCredentialsHelper{ |
| "buz": {}, |
| "biz": {}, |
| }, |
| ProviderInstallation: []*ProviderInstallation{ |
| { |
| Methods: []*ProviderInstallationMethod{ |
| {Location: ProviderInstallationFilesystemMirror("a")}, |
| {Location: ProviderInstallationFilesystemMirror("b")}, |
| }, |
| }, |
| { |
| Methods: []*ProviderInstallationMethod{ |
| {Location: ProviderInstallationFilesystemMirror("c")}, |
| }, |
| }, |
| { |
| Methods: []*ProviderInstallationMethod{ |
| {Location: ProviderInstallationFilesystemMirror("d")}, |
| }, |
| }, |
| }, |
| } |
| |
| actual := c1.Merge(c2) |
| if diff := cmp.Diff(expected, actual); diff != "" { |
| t.Fatalf("wrong result\n%s", diff) |
| } |
| } |
| |
| func TestConfig_Merge_disableCheckpoint(t *testing.T) { |
| c1 := &Config{ |
| DisableCheckpoint: true, |
| } |
| |
| c2 := &Config{} |
| |
| expected := &Config{ |
| Providers: map[string]string{}, |
| Provisioners: map[string]string{}, |
| DisableCheckpoint: true, |
| } |
| |
| actual := c1.Merge(c2) |
| if !reflect.DeepEqual(actual, expected) { |
| t.Fatalf("bad: %#v", actual) |
| } |
| } |
| |
| func TestConfig_Merge_disableCheckpointSignature(t *testing.T) { |
| c1 := &Config{ |
| DisableCheckpointSignature: true, |
| } |
| |
| c2 := &Config{} |
| |
| expected := &Config{ |
| Providers: map[string]string{}, |
| Provisioners: map[string]string{}, |
| DisableCheckpointSignature: true, |
| } |
| |
| actual := c1.Merge(c2) |
| if !reflect.DeepEqual(actual, expected) { |
| t.Fatalf("bad: %#v", actual) |
| } |
| } |