diff --git a/backend/remote-state/gcs/backend_test.go b/backend/remote-state/gcs/backend_test.go index ddbdc6ae2..3ccb645f6 100644 --- a/backend/remote-state/gcs/backend_test.go +++ b/backend/remote-state/gcs/backend_test.go @@ -1,7 +1,11 @@ package gcs import ( + "os" "testing" + + "github.com/hashicorp/terraform/backend" + "github.com/hashicorp/terraform/state/remote" ) func TestStateFile(t *testing.T) { @@ -34,3 +38,89 @@ func TestStateFile(t *testing.T) { } } } + +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) + } +}