opentofu/internal/command/cliconfig/cliconfig_test.go
Martin Atkins ffe056bacb Move command/ to internal/command/
This is part of a general effort to move all of Terraform's non-library
package surface under internal in order to reinforce that these are for
internal use within Terraform only.

If you were previously importing packages under this prefix into an
external codebase, you could pin to an earlier release tag as an interim
solution until you've make a plan to achieve the same functionality some
other way.
2021-05-17 14:09:07 -07:00

386 lines
7.7 KiB
Go

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)
}
}