241 lines
5.8 KiB
Go
241 lines
5.8 KiB
Go
|
package remote
|
||
|
|
||
|
import (
|
||
|
"errors"
|
||
|
"reflect"
|
||
|
"strings"
|
||
|
"testing"
|
||
|
|
||
|
"github.com/hashicorp/terraform/backend"
|
||
|
"github.com/hashicorp/terraform/config"
|
||
|
"github.com/hashicorp/terraform/terraform"
|
||
|
)
|
||
|
|
||
|
func TestRemote(t *testing.T) {
|
||
|
var _ backend.Enhanced = New(nil)
|
||
|
var _ backend.CLI = New(nil)
|
||
|
}
|
||
|
|
||
|
func TestRemote_config(t *testing.T) {
|
||
|
cases := map[string]struct {
|
||
|
config map[string]interface{}
|
||
|
err error
|
||
|
}{
|
||
|
"with_a_name": {
|
||
|
config: map[string]interface{}{
|
||
|
"organization": "hashicorp",
|
||
|
"workspaces": []interface{}{
|
||
|
map[string]interface{}{
|
||
|
"name": "prod",
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
err: nil,
|
||
|
},
|
||
|
"with_a_prefix": {
|
||
|
config: map[string]interface{}{
|
||
|
"organization": "hashicorp",
|
||
|
"workspaces": []interface{}{
|
||
|
map[string]interface{}{
|
||
|
"prefix": "my-app-",
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
err: nil,
|
||
|
},
|
||
|
"without_either_a_name_and_a_prefix": {
|
||
|
config: map[string]interface{}{
|
||
|
"organization": "hashicorp",
|
||
|
"workspaces": []interface{}{
|
||
|
map[string]interface{}{},
|
||
|
},
|
||
|
},
|
||
|
err: errors.New("either workspace 'name' or 'prefix' is required"),
|
||
|
},
|
||
|
"with_both_a_name_and_a_prefix": {
|
||
|
config: map[string]interface{}{
|
||
|
"organization": "hashicorp",
|
||
|
"workspaces": []interface{}{
|
||
|
map[string]interface{}{
|
||
|
"name": "prod",
|
||
|
"prefix": "my-app-",
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
err: errors.New("only one of workspace 'name' or 'prefix' is allowed"),
|
||
|
},
|
||
|
"with_an_unknown_host": {
|
||
|
config: map[string]interface{}{
|
||
|
"hostname": "nonexisting.local",
|
||
|
"organization": "hashicorp",
|
||
|
"workspaces": []interface{}{
|
||
|
map[string]interface{}{
|
||
|
"name": "prod",
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
err: errors.New("host nonexisting.local does not provide a remote backend API"),
|
||
|
},
|
||
|
}
|
||
|
|
||
|
for name, tc := range cases {
|
||
|
s := testServer(t)
|
||
|
b := New(testDisco(s))
|
||
|
|
||
|
// Get the proper config structure
|
||
|
rc, err := config.NewRawConfig(tc.config)
|
||
|
if err != nil {
|
||
|
t.Fatalf("%s: error creating raw config: %v", name, err)
|
||
|
}
|
||
|
conf := terraform.NewResourceConfig(rc)
|
||
|
|
||
|
// Validate
|
||
|
warns, errs := b.Validate(conf)
|
||
|
if len(warns) > 0 {
|
||
|
t.Fatalf("%s: validation warnings: %v", name, warns)
|
||
|
}
|
||
|
if len(errs) > 0 {
|
||
|
t.Fatalf("%s: validation errors: %v", name, errs)
|
||
|
}
|
||
|
|
||
|
// Configure
|
||
|
err = b.Configure(conf)
|
||
|
if err != tc.err && err != nil && tc.err != nil && err.Error() != tc.err.Error() {
|
||
|
t.Fatalf("%s: expected error %q, got: %q", name, tc.err, err)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestRemote_nonexistingOrganization(t *testing.T) {
|
||
|
msg := "does not exist"
|
||
|
|
||
|
b := testBackendNoDefault(t)
|
||
|
b.organization = "nonexisting"
|
||
|
|
||
|
if _, err := b.State("prod"); err == nil || !strings.Contains(err.Error(), msg) {
|
||
|
t.Fatalf("expected %q error, got: %v", msg, err)
|
||
|
}
|
||
|
|
||
|
if err := b.DeleteState("prod"); err == nil || !strings.Contains(err.Error(), msg) {
|
||
|
t.Fatalf("expected %q error, got: %v", msg, err)
|
||
|
}
|
||
|
|
||
|
if _, err := b.States(); err == nil || !strings.Contains(err.Error(), msg) {
|
||
|
t.Fatalf("expected %q error, got: %v", msg, err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
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_addAndRemoveStatesDefault(t *testing.T) {
|
||
|
b := testBackendDefault(t)
|
||
|
if _, err := b.States(); err != backend.ErrNamedStatesNotSupported {
|
||
|
t.Fatalf("expected error %v, got %v", backend.ErrNamedStatesNotSupported, err)
|
||
|
}
|
||
|
|
||
|
if _, err := b.State(backend.DefaultStateName); err != nil {
|
||
|
t.Fatalf("expected no error, got %v", err)
|
||
|
}
|
||
|
|
||
|
if _, err := b.State("prod"); err != backend.ErrNamedStatesNotSupported {
|
||
|
t.Fatalf("expected error %v, got %v", backend.ErrNamedStatesNotSupported, err)
|
||
|
}
|
||
|
|
||
|
if err := b.DeleteState(backend.DefaultStateName); err != nil {
|
||
|
t.Fatalf("expected no error, got %v", err)
|
||
|
}
|
||
|
|
||
|
if err := b.DeleteState("prod"); err != backend.ErrNamedStatesNotSupported {
|
||
|
t.Fatalf("expected error %v, got %v", backend.ErrNamedStatesNotSupported, err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestRemote_addAndRemoveStatesNoDefault(t *testing.T) {
|
||
|
b := testBackendNoDefault(t)
|
||
|
states, err := b.States()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
expectedStates := []string(nil)
|
||
|
if !reflect.DeepEqual(states, expectedStates) {
|
||
|
t.Fatalf("expected states %#+v, got %#+v", expectedStates, states)
|
||
|
}
|
||
|
|
||
|
if _, err := b.State(backend.DefaultStateName); err != backend.ErrDefaultStateNotSupported {
|
||
|
t.Fatalf("expected error %v, got %v", backend.ErrDefaultStateNotSupported, err)
|
||
|
}
|
||
|
|
||
|
expectedA := "test_A"
|
||
|
if _, err := b.State(expectedA); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
states, err = b.States()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
expectedStates = append(expectedStates, expectedA)
|
||
|
if !reflect.DeepEqual(states, expectedStates) {
|
||
|
t.Fatalf("expected %#+v, got %#+v", expectedStates, states)
|
||
|
}
|
||
|
|
||
|
expectedB := "test_B"
|
||
|
if _, err := b.State(expectedB); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
states, err = b.States()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
expectedStates = append(expectedStates, expectedB)
|
||
|
if !reflect.DeepEqual(states, expectedStates) {
|
||
|
t.Fatalf("expected %#+v, got %#+v", expectedStates, states)
|
||
|
}
|
||
|
|
||
|
if err := b.DeleteState(backend.DefaultStateName); err != backend.ErrDefaultStateNotSupported {
|
||
|
t.Fatalf("expected error %v, got %v", backend.ErrDefaultStateNotSupported, err)
|
||
|
}
|
||
|
|
||
|
if err := b.DeleteState(expectedA); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
states, err = b.States()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
expectedStates = []string{expectedB}
|
||
|
if !reflect.DeepEqual(states, expectedStates) {
|
||
|
t.Fatalf("expected %#+v got %#+v", expectedStates, states)
|
||
|
}
|
||
|
|
||
|
if err := b.DeleteState(expectedB); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
states, err = b.States()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
expectedStates = []string(nil)
|
||
|
if !reflect.DeepEqual(states, expectedStates) {
|
||
|
t.Fatalf("expected %#+v, got %#+v", expectedStates, states)
|
||
|
}
|
||
|
}
|