2017-09-08 16:11:41 +02:00
|
|
|
package gcs
|
2017-09-08 14:58:19 +02:00
|
|
|
|
|
|
|
import (
|
2017-09-11 15:39:48 +02:00
|
|
|
"os"
|
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) {
|
|
|
|
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
|
|
|
|
|
|
|
func TestGCSBackend(t *testing.T) {
|
|
|
|
// This test creates a bucket in GCS and populates it.
|
|
|
|
// It may incur costs, so it will only run if the GOOGLE_PROJECT
|
|
|
|
// environment variable is set.
|
|
|
|
|
|
|
|
projectID := os.Getenv("GOOGLE_PROJECT")
|
|
|
|
if projectID == "" {
|
|
|
|
t.Skipf("skipping; set GOOGLE_PROJECT to activate")
|
|
|
|
}
|
|
|
|
|
|
|
|
const bucketName = "terraform_remote-state_test"
|
|
|
|
t.Logf("using bucket %q in project %q", bucketName, projectID)
|
|
|
|
|
|
|
|
config := map[string]interface{}{
|
|
|
|
"bucket": bucketName,
|
|
|
|
"prefix": "",
|
|
|
|
}
|
|
|
|
|
|
|
|
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")
|
|
|
|
}
|
|
|
|
|
|
|
|
be := backend.TestBackendConfig(t, New(), config)
|
|
|
|
|
|
|
|
gcsBE, ok := be.(*gcsBackend)
|
|
|
|
if !ok {
|
|
|
|
t.Fatalf("backend: got %T, want *gcsBackend", be)
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx := gcsBE.storageContext
|
|
|
|
|
|
|
|
// create a new bucket and error out if we can't, e.g. because it already exists.
|
|
|
|
if err := gcsBE.storageClient.Bucket(bucketName).Create(ctx, projectID, nil); err != nil {
|
|
|
|
t.Fatalf("creating bucket failed: %v", err)
|
|
|
|
}
|
|
|
|
t.Log("bucket has been created")
|
|
|
|
|
|
|
|
defer func() {
|
|
|
|
if err := gcsBE.storageClient.Bucket(bucketName).Delete(ctx); err != nil {
|
|
|
|
t.Errorf("deleting bucket failed: %v", err)
|
|
|
|
} else {
|
|
|
|
t.Log("bucket has been deleted")
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
// this should create a new state file
|
|
|
|
_, err := be.State("TestGCSBackend")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("State(\"TestGCSBackend\"): %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
states, err := be.States()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("States(): %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
found := false
|
|
|
|
for _, st := range states {
|
|
|
|
if st == "TestGCSBackend" {
|
|
|
|
found = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if !found {
|
|
|
|
t.Errorf("be.States() = %#v, missing \"TestGCSBackend\"", states)
|
|
|
|
}
|
|
|
|
|
|
|
|
// ensure state file exists
|
|
|
|
if _, err := gcsBE.storageClient.Bucket(bucketName).Object("TestGCSBackend.tfstate").Attrs(ctx); err != nil {
|
|
|
|
t.Fatalf("Attrs(\"TestGCSBackend.tfstate\"): %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
c, err := gcsBE.client("TestGCSBackend_remote_TestClient")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
remote.TestClient(t, c)
|
|
|
|
|
|
|
|
if err := be.DeleteState("TestGCSBackend"); err != nil {
|
|
|
|
t.Errorf("DeleteState(\"TestGCSBackend\"): %v", err)
|
|
|
|
}
|
|
|
|
}
|