2017-09-08 16:11:41 +02:00
|
|
|
package gcs
|
2017-09-08 14:58:19 +02:00
|
|
|
|
|
|
|
import (
|
2017-09-26 09:20:43 +02:00
|
|
|
"fmt"
|
2017-09-11 15:39:48 +02:00
|
|
|
"os"
|
2017-09-26 09:20:43 +02:00
|
|
|
"strings"
|
2017-09-08 14:58:19 +02:00
|
|
|
"testing"
|
2017-09-11 15:39:48 +02:00
|
|
|
|
|
|
|
"github.com/hashicorp/terraform/backend"
|
|
|
|
"github.com/hashicorp/terraform/state/remote"
|
2017-09-08 14:58:19 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestStateFile(t *testing.T) {
|
2017-09-26 09:20:43 +02:00
|
|
|
t.Parallel()
|
|
|
|
|
2017-09-08 14:58:19 +02:00
|
|
|
cases := []struct {
|
2017-09-11 08:25:42 +02:00
|
|
|
prefix string
|
2017-09-08 14:58:19 +02:00
|
|
|
defaultStateFile string
|
|
|
|
name string
|
|
|
|
wantStateFile string
|
|
|
|
wantLockFile string
|
|
|
|
}{
|
|
|
|
{"state", "", "default", "state/default.tfstate", "state/default.tflock"},
|
|
|
|
{"state", "", "test", "state/test.tfstate", "state/test.tflock"},
|
|
|
|
{"state", "legacy.tfstate", "default", "legacy.tfstate", "legacy.tflock"},
|
|
|
|
{"state", "legacy.tfstate", "test", "state/test.tfstate", "state/test.tflock"},
|
|
|
|
{"state", "legacy.state", "default", "legacy.state", "legacy.state.tflock"},
|
|
|
|
{"state", "legacy.state", "test", "state/test.tfstate", "state/test.tflock"},
|
|
|
|
}
|
|
|
|
for _, c := range cases {
|
|
|
|
b := &gcsBackend{
|
2017-09-11 08:25:42 +02:00
|
|
|
prefix: c.prefix,
|
2017-09-08 14:58:19 +02:00
|
|
|
defaultStateFile: c.defaultStateFile,
|
|
|
|
}
|
|
|
|
|
|
|
|
if got := b.stateFile(c.name); got != c.wantStateFile {
|
|
|
|
t.Errorf("stateFile(%q) = %q, want %q", c.name, got, c.wantStateFile)
|
|
|
|
}
|
|
|
|
|
|
|
|
if got := b.lockFile(c.name); got != c.wantLockFile {
|
|
|
|
t.Errorf("lockFile(%q) = %q, want %q", c.name, got, c.wantLockFile)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-09-11 15:39:48 +02:00
|
|
|
|
2017-09-26 09:20:43 +02:00
|
|
|
func TestRemoteClient(t *testing.T) {
|
|
|
|
t.Parallel()
|
2017-09-11 15:39:48 +02:00
|
|
|
|
2017-09-26 09:20:43 +02:00
|
|
|
be := testBackend(t)
|
2017-09-11 15:39:48 +02:00
|
|
|
|
2017-09-26 09:20:43 +02:00
|
|
|
ss, err := be.State(backend.DefaultStateName)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("be.State(%q) = %v", backend.DefaultStateName, err)
|
2017-09-11 15:39:48 +02:00
|
|
|
}
|
|
|
|
|
2017-09-26 09:20:43 +02:00
|
|
|
rs, ok := ss.(*remote.State)
|
|
|
|
if !ok {
|
|
|
|
t.Fatalf("be.State(): got a %T, want a *remote.State", ss)
|
2017-09-11 15:39:48 +02:00
|
|
|
}
|
|
|
|
|
2017-09-26 09:20:43 +02:00
|
|
|
remote.TestClient(t, rs.Client)
|
2017-09-11 15:39:48 +02:00
|
|
|
|
2017-09-26 09:20:43 +02:00
|
|
|
cleanBackend(t, be)
|
|
|
|
}
|
2017-09-11 15:39:48 +02:00
|
|
|
|
2017-09-26 09:20:43 +02:00
|
|
|
func TestRemoteLocks(t *testing.T) {
|
|
|
|
t.Parallel()
|
2017-09-11 15:39:48 +02:00
|
|
|
|
2017-09-26 09:20:43 +02:00
|
|
|
be := testBackend(t)
|
2017-09-11 15:39:48 +02:00
|
|
|
|
2017-09-26 09:20:43 +02:00
|
|
|
remoteClient := func() (remote.Client, error) {
|
|
|
|
ss, err := be.State(backend.DefaultStateName)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2017-09-11 15:39:48 +02:00
|
|
|
}
|
|
|
|
|
2017-09-26 09:20:43 +02:00
|
|
|
rs, ok := ss.(*remote.State)
|
|
|
|
if !ok {
|
|
|
|
return nil, fmt.Errorf("be.State(): got a %T, want a *remote.State", ss)
|
|
|
|
}
|
|
|
|
|
|
|
|
return rs.Client, nil
|
2017-09-11 15:39:48 +02:00
|
|
|
}
|
|
|
|
|
2017-09-26 09:20:43 +02:00
|
|
|
c0, err := remoteClient()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("remoteClient(0) = %v", err)
|
|
|
|
}
|
|
|
|
c1, err := remoteClient()
|
2017-09-11 15:39:48 +02:00
|
|
|
if err != nil {
|
2017-09-26 09:20:43 +02:00
|
|
|
t.Fatalf("remoteClient(1) = %v", err)
|
2017-09-11 15:39:48 +02:00
|
|
|
}
|
|
|
|
|
2017-09-26 09:20:43 +02:00
|
|
|
remote.TestRemoteLocks(t, c0, c1)
|
|
|
|
|
|
|
|
cleanBackend(t, be)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestBackend(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
be0 := testBackend(t)
|
|
|
|
be1 := testBackend(t)
|
|
|
|
|
|
|
|
// clean up all states left behind by previous runs --
|
|
|
|
// backend.TestBackend() will complain about any non-default states.
|
|
|
|
cleanBackend(t, be0)
|
|
|
|
|
|
|
|
backend.TestBackend(t, be0, be1)
|
|
|
|
|
|
|
|
cleanBackend(t, be0)
|
|
|
|
}
|
|
|
|
|
|
|
|
// testBackend returns a new GCS backend.
|
|
|
|
func testBackend(t *testing.T) backend.Backend {
|
|
|
|
t.Helper()
|
|
|
|
|
|
|
|
projectID := os.Getenv("GOOGLE_PROJECT")
|
2017-10-04 08:50:58 +02:00
|
|
|
if projectID == "" || os.Getenv("TF_ACC") == "" {
|
|
|
|
t.Skip("This test creates a bucket in GCS and populates it. " +
|
|
|
|
"Since this may incur costs, it will only run if " +
|
|
|
|
"the TF_ACC and GOOGLE_PROJECT environment variables are set.")
|
2017-09-11 15:39:48 +02:00
|
|
|
}
|
2017-09-26 09:20:43 +02:00
|
|
|
|
|
|
|
config := map[string]interface{}{
|
|
|
|
"project": projectID,
|
|
|
|
"bucket": strings.ToLower(t.Name()),
|
|
|
|
"prefix": "",
|
2017-09-11 15:39:48 +02:00
|
|
|
}
|
|
|
|
|
2017-09-26 09:20:43 +02:00
|
|
|
if creds := os.Getenv("GOOGLE_CREDENTIALS"); creds != "" {
|
|
|
|
config["credentials"] = creds
|
|
|
|
t.Logf("using credentials from %q", creds)
|
|
|
|
} else {
|
|
|
|
t.Log("using default credentials; set GOOGLE_CREDENTIALS for custom credentials")
|
2017-09-11 15:39:48 +02:00
|
|
|
}
|
|
|
|
|
2017-09-26 09:20:43 +02:00
|
|
|
return backend.TestBackendConfig(t, New(), config)
|
|
|
|
}
|
|
|
|
|
|
|
|
// cleanBackend deletes all states from be except the default state.
|
|
|
|
func cleanBackend(t *testing.T, be backend.Backend) {
|
|
|
|
t.Helper()
|
|
|
|
|
|
|
|
states, err := be.States()
|
2017-09-11 15:39:48 +02:00
|
|
|
if err != nil {
|
2017-09-26 09:20:43 +02:00
|
|
|
t.Fatalf("be.States() = %v; manual clean-up may be required", err)
|
2017-09-11 15:39:48 +02:00
|
|
|
}
|
2017-09-26 09:20:43 +02:00
|
|
|
for _, st := range states {
|
|
|
|
if st == backend.DefaultStateName {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
if err := be.DeleteState(st); err != nil {
|
|
|
|
t.Fatalf("be.DeleteState(%q) = %v; manual clean-up may be required", st, err)
|
|
|
|
}
|
2017-09-11 15:39:48 +02:00
|
|
|
}
|
|
|
|
}
|