terraform/backend/remote/backend_test.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_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 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_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)
}
}