235 lines
6.6 KiB
Go
235 lines
6.6 KiB
Go
|
package remote
|
||
|
|
||
|
import (
|
||
|
"reflect"
|
||
|
"strings"
|
||
|
"testing"
|
||
|
|
||
|
"github.com/hashicorp/terraform/backend"
|
||
|
"github.com/zclconf/go-cty/cty"
|
||
|
)
|
||
|
|
||
|
func TestRemote(t *testing.T) {
|
||
|
var _ backend.Enhanced = New(nil)
|
||
|
var _ backend.CLI = New(nil)
|
||
|
}
|
||
|
|
||
|
func TestRemote_backendDefault(t *testing.T) {
|
||
|
b := testBackendDefault(t)
|
||
|
backend.TestBackendStates(t, b)
|
||
|
backend.TestBackendStateLocks(t, b, b)
|
||
|
backend.TestBackendStateForceUnlock(t, b, b)
|
||
|
}
|
||
|
|
||
|
func TestRemote_backendNoDefault(t *testing.T) {
|
||
|
b := testBackendNoDefault(t)
|
||
|
backend.TestBackendStates(t, b)
|
||
|
}
|
||
|
|
||
|
func TestRemote_config(t *testing.T) {
|
||
|
cases := map[string]struct {
|
||
|
config cty.Value
|
||
|
confErr string
|
||
|
valErr string
|
||
|
}{
|
||
|
"with_a_name": {
|
||
|
config: cty.ObjectVal(map[string]cty.Value{
|
||
|
"hostname": cty.NullVal(cty.String),
|
||
|
"organization": cty.StringVal("hashicorp"),
|
||
|
"token": cty.NullVal(cty.String),
|
||
|
"workspaces": cty.ObjectVal(map[string]cty.Value{
|
||
|
"name": cty.StringVal("prod"),
|
||
|
"prefix": cty.NullVal(cty.String),
|
||
|
}),
|
||
|
}),
|
||
|
},
|
||
|
"with_a_prefix": {
|
||
|
config: cty.ObjectVal(map[string]cty.Value{
|
||
|
"hostname": cty.NullVal(cty.String),
|
||
|
"organization": cty.StringVal("hashicorp"),
|
||
|
"token": cty.NullVal(cty.String),
|
||
|
"workspaces": cty.ObjectVal(map[string]cty.Value{
|
||
|
"name": cty.NullVal(cty.String),
|
||
|
"prefix": cty.StringVal("my-app-"),
|
||
|
}),
|
||
|
}),
|
||
|
},
|
||
|
"without_either_a_name_and_a_prefix": {
|
||
|
config: cty.ObjectVal(map[string]cty.Value{
|
||
|
"hostname": cty.NullVal(cty.String),
|
||
|
"organization": cty.StringVal("hashicorp"),
|
||
|
"token": cty.NullVal(cty.String),
|
||
|
"workspaces": cty.ObjectVal(map[string]cty.Value{
|
||
|
"name": cty.NullVal(cty.String),
|
||
|
"prefix": cty.NullVal(cty.String),
|
||
|
}),
|
||
|
}),
|
||
|
valErr: `Either workspace "name" or "prefix" is required`,
|
||
|
},
|
||
|
"with_both_a_name_and_a_prefix": {
|
||
|
config: cty.ObjectVal(map[string]cty.Value{
|
||
|
"hostname": cty.NullVal(cty.String),
|
||
|
"organization": cty.StringVal("hashicorp"),
|
||
|
"token": cty.NullVal(cty.String),
|
||
|
"workspaces": cty.ObjectVal(map[string]cty.Value{
|
||
|
"name": cty.StringVal("prod"),
|
||
|
"prefix": cty.StringVal("my-app-"),
|
||
|
}),
|
||
|
}),
|
||
|
valErr: `Only one of workspace "name" or "prefix" is allowed`,
|
||
|
},
|
||
|
"with_an_unknown_host": {
|
||
|
config: cty.ObjectVal(map[string]cty.Value{
|
||
|
"hostname": cty.StringVal("nonexisting.local"),
|
||
|
"organization": cty.StringVal("hashicorp"),
|
||
|
"token": cty.NullVal(cty.String),
|
||
|
"workspaces": cty.ObjectVal(map[string]cty.Value{
|
||
|
"name": cty.StringVal("prod"),
|
||
|
"prefix": cty.NullVal(cty.String),
|
||
|
}),
|
||
|
}),
|
||
|
confErr: "Host nonexisting.local does not provide a remote backend API",
|
||
|
},
|
||
|
}
|
||
|
|
||
|
for name, tc := range cases {
|
||
|
s := testServer(t)
|
||
|
b := New(testDisco(s))
|
||
|
|
||
|
// Validate
|
||
|
valDiags := b.ValidateConfig(tc.config)
|
||
|
if (valDiags.Err() == nil && tc.valErr != "") ||
|
||
|
(valDiags.Err() != nil && !strings.Contains(valDiags.Err().Error(), tc.valErr)) {
|
||
|
t.Fatalf("%s: unexpected validation result: %v", name, valDiags.Err())
|
||
|
}
|
||
|
|
||
|
// Configure
|
||
|
confDiags := b.Configure(tc.config)
|
||
|
if (confDiags.Err() == nil && tc.confErr != "") ||
|
||
|
(confDiags.Err() != nil && !strings.Contains(confDiags.Err().Error(), tc.confErr)) {
|
||
|
t.Fatalf("%s: unexpected configure result: %v", name, valDiags.Err())
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestRemote_nonexistingOrganization(t *testing.T) {
|
||
|
msg := "does not exist"
|
||
|
|
||
|
b := testBackendNoDefault(t)
|
||
|
b.organization = "nonexisting"
|
||
|
|
||
|
if _, err := b.StateMgr("prod"); err == nil || !strings.Contains(err.Error(), msg) {
|
||
|
t.Fatalf("expected %q error, got: %v", msg, err)
|
||
|
}
|
||
|
|
||
|
if err := b.DeleteWorkspace("prod"); err == nil || !strings.Contains(err.Error(), msg) {
|
||
|
t.Fatalf("expected %q error, got: %v", msg, err)
|
||
|
}
|
||
|
|
||
|
if _, err := b.Workspaces(); err == nil || !strings.Contains(err.Error(), msg) {
|
||
|
t.Fatalf("expected %q error, got: %v", msg, err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestRemote_addAndRemoveWorkspacesDefault(t *testing.T) {
|
||
|
b := testBackendDefault(t)
|
||
|
if _, err := b.Workspaces(); err != backend.ErrWorkspacesNotSupported {
|
||
|
t.Fatalf("expected error %v, got %v", backend.ErrWorkspacesNotSupported, err)
|
||
|
}
|
||
|
|
||
|
if _, err := b.StateMgr(backend.DefaultStateName); err != nil {
|
||
|
t.Fatalf("expected no error, got %v", err)
|
||
|
}
|
||
|
|
||
|
if _, err := b.StateMgr("prod"); err != backend.ErrWorkspacesNotSupported {
|
||
|
t.Fatalf("expected error %v, got %v", backend.ErrWorkspacesNotSupported, err)
|
||
|
}
|
||
|
|
||
|
if err := b.DeleteWorkspace(backend.DefaultStateName); err != nil {
|
||
|
t.Fatalf("expected no error, got %v", err)
|
||
|
}
|
||
|
|
||
|
if err := b.DeleteWorkspace("prod"); err != backend.ErrWorkspacesNotSupported {
|
||
|
t.Fatalf("expected error %v, got %v", backend.ErrWorkspacesNotSupported, err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestRemote_addAndRemoveWorkspacesNoDefault(t *testing.T) {
|
||
|
b := testBackendNoDefault(t)
|
||
|
states, err := b.Workspaces()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
expectedWorkspaces := []string(nil)
|
||
|
if !reflect.DeepEqual(states, expectedWorkspaces) {
|
||
|
t.Fatalf("expected states %#+v, got %#+v", expectedWorkspaces, states)
|
||
|
}
|
||
|
|
||
|
if _, err := b.StateMgr(backend.DefaultStateName); err != backend.ErrDefaultWorkspaceNotSupported {
|
||
|
t.Fatalf("expected error %v, got %v", backend.ErrDefaultWorkspaceNotSupported, err)
|
||
|
}
|
||
|
|
||
|
expectedA := "test_A"
|
||
|
if _, err := b.StateMgr(expectedA); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
states, err = b.Workspaces()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
expectedWorkspaces = append(expectedWorkspaces, expectedA)
|
||
|
if !reflect.DeepEqual(states, expectedWorkspaces) {
|
||
|
t.Fatalf("expected %#+v, got %#+v", expectedWorkspaces, states)
|
||
|
}
|
||
|
|
||
|
expectedB := "test_B"
|
||
|
if _, err := b.StateMgr(expectedB); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
states, err = b.Workspaces()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
expectedWorkspaces = append(expectedWorkspaces, expectedB)
|
||
|
if !reflect.DeepEqual(states, expectedWorkspaces) {
|
||
|
t.Fatalf("expected %#+v, got %#+v", expectedWorkspaces, states)
|
||
|
}
|
||
|
|
||
|
if err := b.DeleteWorkspace(backend.DefaultStateName); err != backend.ErrDefaultWorkspaceNotSupported {
|
||
|
t.Fatalf("expected error %v, got %v", backend.ErrDefaultWorkspaceNotSupported, err)
|
||
|
}
|
||
|
|
||
|
if err := b.DeleteWorkspace(expectedA); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
states, err = b.Workspaces()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
expectedWorkspaces = []string{expectedB}
|
||
|
if !reflect.DeepEqual(states, expectedWorkspaces) {
|
||
|
t.Fatalf("expected %#+v got %#+v", expectedWorkspaces, states)
|
||
|
}
|
||
|
|
||
|
if err := b.DeleteWorkspace(expectedB); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
states, err = b.Workspaces()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
expectedWorkspaces = []string(nil)
|
||
|
if !reflect.DeepEqual(states, expectedWorkspaces) {
|
||
|
t.Fatalf("expected %#+v, got %#+v", expectedWorkspaces, states)
|
||
|
}
|
||
|
}
|