terraform/backend/testing.go

141 lines
3.2 KiB
Go

package backend
import (
"reflect"
"sort"
"testing"
"github.com/hashicorp/terraform/config"
"github.com/hashicorp/terraform/terraform"
)
// TestBackendConfig validates and configures the backend with the
// given configuration.
func TestBackendConfig(t *testing.T, b Backend, c map[string]interface{}) Backend {
// Get the proper config structure
rc, err := config.NewRawConfig(c)
if err != nil {
t.Fatalf("bad: %s", err)
}
conf := terraform.NewResourceConfig(rc)
// Validate
warns, errs := b.Validate(conf)
if len(warns) > 0 {
t.Fatalf("warnings: %s", warns)
}
if len(errs) > 0 {
t.Fatalf("errors: %s", errs)
}
// Configure
if err := b.Configure(conf); err != nil {
t.Fatalf("err: %s", err)
}
return b
}
// TestBackend will test the functionality of a Backend. The backend is
// assumed to already be configured. This will test state functionality.
// If the backend reports it doesn't support multi-state by returning the
// error ErrNamedStatesNotSupported, then it will not test that.
func TestBackend(t *testing.T, b Backend) {
testBackendStates(t, b)
}
func testBackendStates(t *testing.T, b Backend) {
states, err := b.States()
if err == ErrNamedStatesNotSupported {
t.Logf("TestBackend: named states not supported in %T, skipping", b)
return
}
// Test it starts with only the default
if len(states) != 1 || states[0] != DefaultStateName {
t.Fatalf("should only have default to start: %#v", states)
}
// Create a couple states
fooState, err := b.State("foo")
if err != nil {
t.Fatalf("error: %s", err)
}
if err := fooState.RefreshState(); err != nil {
t.Fatalf("bad: %s", err)
}
if v := fooState.State(); v.HasResources() {
t.Fatalf("should be empty: %s", v)
}
barState, err := b.State("bar")
if err != nil {
t.Fatalf("error: %s", err)
}
if err := barState.RefreshState(); err != nil {
t.Fatalf("bad: %s", err)
}
if v := barState.State(); v.HasResources() {
t.Fatalf("should be empty: %s", v)
}
// Verify they are distinct states
{
s := barState.State()
s.Lineage = "bar"
if err := barState.WriteState(s); err != nil {
t.Fatalf("bad: %s", err)
}
if err := barState.PersistState(); err != nil {
t.Fatalf("bad: %s", err)
}
if err := fooState.RefreshState(); err != nil {
t.Fatalf("bad: %s", err)
}
if v := fooState.State(); v.Lineage == "bar" {
t.Fatalf("bad: %#v", v)
}
}
// Verify we can now list them
{
states, err := b.States()
if err == ErrNamedStatesNotSupported {
t.Logf("TestBackend: named states not supported in %T, skipping", b)
return
}
sort.Strings(states)
expected := []string{"bar", "default", "foo"}
if !reflect.DeepEqual(states, expected) {
t.Fatalf("bad: %#v", states)
}
}
// Delete some states
if err := b.DeleteState("foo"); err != nil {
t.Fatalf("err: %s", err)
}
// Verify the default state can't be deleted
if err := b.DeleteState(DefaultStateName); err == nil {
t.Fatal("expected error")
}
// Verify deletion
{
states, err := b.States()
if err == ErrNamedStatesNotSupported {
t.Logf("TestBackend: named states not supported in %T, skipping", b)
return
}
sort.Strings(states)
expected := []string{"bar", "default"}
if !reflect.DeepEqual(states, expected) {
t.Fatalf("bad: %#v", states)
}
}
}