Skip to content

Commit f0b3283

Browse files
committed
test: Add E2E tests for state list and state show commands
1 parent 808713f commit f0b3283

File tree

6 files changed

+165
-0
lines changed

6 files changed

+165
-0
lines changed

internal/command/e2etest/pluggable_state_store_test.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@ import (
1111
"strings"
1212
"testing"
1313

14+
"github.com/google/go-cmp/cmp"
1415
"github.com/hashicorp/terraform/internal/e2e"
1516
"github.com/hashicorp/terraform/internal/getproviders"
1617
)
1718

19+
// Tests using `terraform workspace` commands in combination with pluggable state storage.
1820
func TestPrimary_stateStore_workspaceCmd(t *testing.T) {
1921
if !canRunGoBuild {
2022
// We're running in a separate-build-then-run context, so we can't
@@ -119,3 +121,79 @@ func TestPrimary_stateStore_workspaceCmd(t *testing.T) {
119121
t.Errorf("unexpected output, expected %q, but got:\n%s", expectedMsg, stdout)
120122
}
121123
}
124+
125+
// Tests using `terraform state` subcommands in combination with pluggable state storage:
126+
// > `terraform state show`
127+
// > `terraform state list`
128+
func TestPrimary_stateStore_stateCmds(t *testing.T) {
129+
130+
if !canRunGoBuild {
131+
// We're running in a separate-build-then-run context, so we can't
132+
// currently execute this test which depends on being able to build
133+
// new executable at runtime.
134+
//
135+
// (See the comment on canRunGoBuild's declaration for more information.)
136+
t.Skip("can't run without building a new provider executable")
137+
}
138+
139+
t.Setenv(e2e.TestExperimentFlag, "true")
140+
tfBin := e2e.GoBuild("github.com/hashicorp/terraform", "terraform")
141+
142+
fixturePath := filepath.Join("testdata", "initialized-directory-with-state-store-fs")
143+
tf := e2e.NewBinary(t, tfBin, fixturePath)
144+
145+
workspaceDirName := "states" // see test fixture value for workspace_dir
146+
147+
// In order to test integration with PSS we need a provider plugin implementing a state store.
148+
// Here will build the simple6 (built with protocol v6) provider, which implements PSS.
149+
simple6Provider := filepath.Join(tf.WorkDir(), "terraform-provider-simple6")
150+
simple6ProviderExe := e2e.GoBuild("github.com/hashicorp/terraform/internal/provider-simple-v6/main", simple6Provider)
151+
152+
// Move the provider binaries into the correct directory .terraform/providers/ directory
153+
// that will contain provider binaries in an initialized working directory.
154+
platform := getproviders.CurrentPlatform.String()
155+
if err := os.MkdirAll(tf.Path(".terraform/providers/registry.terraform.io/hashicorp/simple6/0.0.1/", platform), os.ModePerm); err != nil {
156+
t.Fatal(err)
157+
}
158+
if err := os.Rename(simple6ProviderExe, tf.Path(".terraform/providers/registry.terraform.io/hashicorp/simple6/0.0.1/", platform, "terraform-provider-simple6")); err != nil {
159+
t.Fatal(err)
160+
}
161+
162+
// Assert that the test starts with the default state present from test fixtures
163+
defaultStateId := "default"
164+
fi, err := os.Stat(path.Join(tf.WorkDir(), workspaceDirName, defaultStateId, "terraform.tfstate"))
165+
if err != nil {
166+
t.Fatalf("failed to open default workspace's state file: %s", err)
167+
}
168+
if fi.Size() == 0 {
169+
t.Fatal("default workspace's state file should not have size 0 bytes")
170+
}
171+
172+
//// List State: terraform state list
173+
expectedResourceAddr := "terraform_data.my-data"
174+
stdout, stderr, err := tf.Run("state", "list", "-no-color")
175+
if err != nil {
176+
t.Fatalf("unexpected error: %s\nstderr:\n%s", err, stderr)
177+
}
178+
expectedMsg := expectedResourceAddr + "\n" // This is the only resource instance in the test fixture state
179+
if stdout != expectedMsg {
180+
t.Errorf("unexpected output, expected %q, but got:\n%s", expectedMsg, stdout)
181+
}
182+
183+
//// Show State: terraform state show
184+
stdout, stderr, err = tf.Run("state", "show", expectedResourceAddr, "-no-color")
185+
if err != nil {
186+
t.Fatalf("unexpected error: %s\nstderr:\n%s", err, stderr)
187+
}
188+
// show displays the state for the specified resource
189+
expectedMsg = `# terraform_data.my-data:
190+
resource "terraform_data" "my-data" {
191+
id = "d71fb368-2ba1-fb4c-5bd9-6a2b7f05d60c"
192+
input = "hello world"
193+
output = "hello world"
194+
}
195+
`
196+
if diff := cmp.Diff(stdout, expectedMsg); diff != "" {
197+
t.Errorf("wrong result, diff:\n%s", diff)
198+
}
199+
}

internal/command/e2etest/testdata/initialized-directory-with-state-store-fs/.terraform.lock.hcl

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/command/e2etest/testdata/initialized-directory-with-state-store-fs/.terraform/providers/registry.terraform.io/hashicorp/simple6/0.0.1/.gitkeep

Whitespace-only changes.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"version": 3,
3+
"terraform_version": "1.15.0",
4+
"state_store": {
5+
"type": "simple6_fs",
6+
"provider": {
7+
"version": "0.0.1",
8+
"source": "registry.terraform.io/hashicorp/simple6",
9+
"config": {}
10+
},
11+
"config": {
12+
"workspace_dir": "states"
13+
},
14+
"hash": 3942813381
15+
}
16+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
terraform {
2+
required_providers {
3+
simple6 = {
4+
source = "registry.terraform.io/hashicorp/simple6"
5+
}
6+
}
7+
8+
state_store "simple6_fs" {
9+
provider "simple6" {}
10+
11+
workspace_dir = "states"
12+
}
13+
}
14+
15+
variable "name" {
16+
default = "world"
17+
}
18+
19+
resource "terraform_data" "my-data" {
20+
input = "hello ${var.name}"
21+
}
22+
23+
output "greeting" {
24+
value = resource.terraform_data.my-data.output
25+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{
2+
"version": 4,
3+
"terraform_version": "1.15.0",
4+
"serial": 1,
5+
"lineage": "9e13d881-e480-7a63-d47a-b4f5224e6743",
6+
"outputs": {
7+
"greeting": {
8+
"value": "hello world",
9+
"type": "string"
10+
}
11+
},
12+
"resources": [
13+
{
14+
"mode": "managed",
15+
"type": "terraform_data",
16+
"name": "my-data",
17+
"provider": "provider[\"terraform.io/builtin/terraform\"]",
18+
"instances": [
19+
{
20+
"schema_version": 0,
21+
"attributes": {
22+
"id": "d71fb368-2ba1-fb4c-5bd9-6a2b7f05d60c",
23+
"input": {
24+
"value": "hello world",
25+
"type": "string"
26+
},
27+
"output": {
28+
"value": "hello world",
29+
"type": "string"
30+
},
31+
"triggers_replace": null
32+
},
33+
"sensitive_attributes": [],
34+
"identity_schema_version": 0
35+
}
36+
]
37+
}
38+
],
39+
"check_results": null
40+
}

0 commit comments

Comments
 (0)