mirror of
https://github.com/opentofu/opentofu.git
synced 2024-12-30 10:47:14 -06:00
ffe056bacb
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.
386 lines
7.7 KiB
Go
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)
|
|
}
|
|
}
|