From 7a97fa861d26d37bc3138910c4b1840002904c48 Mon Sep 17 00:00:00 2001 From: Sarah French Date: Wed, 12 Nov 2025 14:10:29 +0000 Subject: [PATCH 1/3] test: Add E2E test demonstrating `output` command used with PSS --- .../e2etest/pluggable_state_store_test.go | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/internal/command/e2etest/pluggable_state_store_test.go b/internal/command/e2etest/pluggable_state_store_test.go index 09f802ce8cca..9114da364ffc 100644 --- a/internal/command/e2etest/pluggable_state_store_test.go +++ b/internal/command/e2etest/pluggable_state_store_test.go @@ -197,3 +197,72 @@ resource "terraform_data" "my-data" { t.Errorf("wrong result, diff:\n%s", diff) } } + +// Tests using the `terraform output` command in combination with pluggable state storage: +// > `terraform output` +// > `terraform output ` +func TestPrimary_stateStore_outputCmd(t *testing.T) { + + if !canRunGoBuild { + // We're running in a separate-build-then-run context, so we can't + // currently execute this test which depends on being able to build + // new executable at runtime. + // + // (See the comment on canRunGoBuild's declaration for more information.) + t.Skip("can't run without building a new provider executable") + } + + t.Setenv(e2e.TestExperimentFlag, "true") + tfBin := e2e.GoBuild("github.com/hashicorp/terraform", "terraform") + + fixturePath := filepath.Join("testdata", "initialized-directory-with-state-store-fs") + tf := e2e.NewBinary(t, tfBin, fixturePath) + + workspaceDirName := "states" // see test fixture value for workspace_dir + + // In order to test integration with PSS we need a provider plugin implementing a state store. + // Here will build the simple6 (built with protocol v6) provider, which implements PSS. + simple6Provider := filepath.Join(tf.WorkDir(), "terraform-provider-simple6") + simple6ProviderExe := e2e.GoBuild("github.com/hashicorp/terraform/internal/provider-simple-v6/main", simple6Provider) + + // Move the provider binaries into the correct .terraform/providers/ directory + // that will contain provider binaries in an initialized working directory. + platform := getproviders.CurrentPlatform.String() + if err := os.MkdirAll(tf.Path(".terraform/providers/registry.terraform.io/hashicorp/simple6/0.0.1/", platform), os.ModePerm); err != nil { + t.Fatal(err) + } + if err := os.Rename(simple6ProviderExe, tf.Path(".terraform/providers/registry.terraform.io/hashicorp/simple6/0.0.1/", platform, "terraform-provider-simple6")); err != nil { + t.Fatal(err) + } + + // Assert that the test starts with the default state present from test fixtures + defaultStateId := "default" + fi, err := os.Stat(path.Join(tf.WorkDir(), workspaceDirName, defaultStateId, "terraform.tfstate")) + if err != nil { + t.Fatalf("failed to open default workspace's state file: %s", err) + } + if fi.Size() == 0 { + t.Fatal("default workspace's state file should not have size 0 bytes") + } + + //// List all outputs: terraform output + stdout, stderr, err := tf.Run("output", "-no-color") + if err != nil { + t.Fatalf("unexpected error: %s\nstderr:\n%s", err, stderr) + } + expectedMsg := "greeting = \"hello world\"\n" // See the test fixture files + if stdout != expectedMsg { + t.Errorf("unexpected output, expected %q, but got:\n%s", expectedMsg, stdout) + } + + //// View a specific output: terraform output + outputName := "greeting" + stdout, stderr, err = tf.Run("output", outputName, "-no-color") + if err != nil { + t.Fatalf("unexpected error: %s\nstderr:\n%s", err, stderr) + } + expectedMsg = "\"hello world\"\n" // Only the value is outputted, no name present + if stdout != expectedMsg { + t.Errorf("unexpected output, expected %q, but got:\n%s", expectedMsg, stdout) + } +} From fab00aae3af1a8e58b9a491b1b8fa4fcf14d1808 Mon Sep 17 00:00:00 2001 From: Sarah French Date: Wed, 12 Nov 2025 14:11:01 +0000 Subject: [PATCH 2/3] test: Add E2E test demonstrating `show` command used with PSS --- .../e2etest/pluggable_state_store_test.go | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/internal/command/e2etest/pluggable_state_store_test.go b/internal/command/e2etest/pluggable_state_store_test.go index 9114da364ffc..227f196c454f 100644 --- a/internal/command/e2etest/pluggable_state_store_test.go +++ b/internal/command/e2etest/pluggable_state_store_test.go @@ -266,3 +266,86 @@ func TestPrimary_stateStore_outputCmd(t *testing.T) { t.Errorf("unexpected output, expected %q, but got:\n%s", expectedMsg, stdout) } } + +// Tests using the `terraform show` command in combination with pluggable state storage +// > `terraform show` +// > `terraform show ` +// > `terraform show ` // TODO +func TestPrimary_stateStore_showCmd(t *testing.T) { + + if !canRunGoBuild { + // We're running in a separate-build-then-run context, so we can't + // currently execute this test which depends on being able to build + // new executable at runtime. + // + // (See the comment on canRunGoBuild's declaration for more information.) + t.Skip("can't run without building a new provider executable") + } + + t.Setenv(e2e.TestExperimentFlag, "true") + tfBin := e2e.GoBuild("github.com/hashicorp/terraform", "terraform") + + fixturePath := filepath.Join("testdata", "initialized-directory-with-state-store-fs") + tf := e2e.NewBinary(t, tfBin, fixturePath) + + workspaceDirName := "states" // see test fixture value for workspace_dir + + // In order to test integration with PSS we need a provider plugin implementing a state store. + // Here will build the simple6 (built with protocol v6) provider, which implements PSS. + simple6Provider := filepath.Join(tf.WorkDir(), "terraform-provider-simple6") + simple6ProviderExe := e2e.GoBuild("github.com/hashicorp/terraform/internal/provider-simple-v6/main", simple6Provider) + + // Move the provider binaries into the correct .terraform/providers/ directory + // that will contain provider binaries in an initialized working directory. + platform := getproviders.CurrentPlatform.String() + if err := os.MkdirAll(tf.Path(".terraform/providers/registry.terraform.io/hashicorp/simple6/0.0.1/", platform), os.ModePerm); err != nil { + t.Fatal(err) + } + if err := os.Rename(simple6ProviderExe, tf.Path(".terraform/providers/registry.terraform.io/hashicorp/simple6/0.0.1/", platform, "terraform-provider-simple6")); err != nil { + t.Fatal(err) + } + + // Assert that the test starts with the default state present from test fixtures + defaultStateId := "default" + fi, err := os.Stat(path.Join(tf.WorkDir(), workspaceDirName, defaultStateId, "terraform.tfstate")) + if err != nil { + t.Fatalf("failed to open default workspace's state file: %s", err) + } + if fi.Size() == 0 { + t.Fatal("default workspace's state file should not have size 0 bytes") + } + + //// Show state: terraform state + stdout, stderr, err := tf.Run("show", "-no-color") + if err != nil { + t.Fatalf("unexpected error: %s\nstderr:\n%s", err, stderr) + } + expectedMsg := `# terraform_data.my-data: +resource "terraform_data" "my-data" { + id = "d71fb368-2ba1-fb4c-5bd9-6a2b7f05d60c" + input = "hello world" + output = "hello world" +} + + +Outputs: + +greeting = "hello world" +` // See the test fixture folder's state file + + if diff := cmp.Diff(stdout, expectedMsg); diff != "" { + t.Errorf("wrong result, diff:\n%s", diff) + } + + //// Show state: terraform show + path := fmt.Sprintf("./%s/%s/terraform.tfstate", workspaceDirName, defaultStateId) + stdout, stderr, err = tf.Run("show", path, "-no-color") + if err != nil { + t.Fatalf("unexpected error: %s\nstderr:\n%s", err, stderr) + } + if diff := cmp.Diff(stdout, expectedMsg); diff != "" { + t.Errorf("wrong result, diff:\n%s", diff) + } + + // TODO: Show plan file: terraform show +} From e9ebdc8f320f7e3f3f6736c2271494ef14b0bf55 Mon Sep 17 00:00:00 2001 From: Sarah French Date: Wed, 12 Nov 2025 14:11:18 +0000 Subject: [PATCH 3/3] docs: Fix code comment --- internal/command/e2etest/pluggable_state_store_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/command/e2etest/pluggable_state_store_test.go b/internal/command/e2etest/pluggable_state_store_test.go index 227f196c454f..e014800ca9ab 100644 --- a/internal/command/e2etest/pluggable_state_store_test.go +++ b/internal/command/e2etest/pluggable_state_store_test.go @@ -149,7 +149,7 @@ func TestPrimary_stateStore_stateCmds(t *testing.T) { simple6Provider := filepath.Join(tf.WorkDir(), "terraform-provider-simple6") simple6ProviderExe := e2e.GoBuild("github.com/hashicorp/terraform/internal/provider-simple-v6/main", simple6Provider) - // Move the provider binaries into the correct directory .terraform/providers/ directory + // Move the provider binaries into the correct .terraform/providers/ directory // that will contain provider binaries in an initialized working directory. platform := getproviders.CurrentPlatform.String() if err := os.MkdirAll(tf.Path(".terraform/providers/registry.terraform.io/hashicorp/simple6/0.0.1/", platform), os.ModePerm); err != nil {