Accept CLI option for the number of parallel ops in a test run's plan/apply (#36323)

This commit is contained in:
Samsondeen 2025-02-05 09:48:05 +01:00 committed by GitHub
parent 8f1b79aefb
commit 16a34fe47f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 229 additions and 63 deletions

View file

@ -0,0 +1,5 @@
kind: ENHANCEMENTS
body: Terraform Test command now accepts a -parallelism=n option, which sets the number of parallel operations in a test run's plan/apply operation.
time: 2025-01-23T10:18:38.979866+01:00
custom:
Issue: "34237"

6
go.mod
View file

@ -28,12 +28,12 @@ require (
github.com/hashicorp/go-plugin v1.6.0
github.com/hashicorp/go-retryablehttp v0.7.7
github.com/hashicorp/go-slug v0.16.3
github.com/hashicorp/go-tfe v1.70.0
github.com/hashicorp/go-tfe v1.74.1
github.com/hashicorp/go-uuid v1.0.3
github.com/hashicorp/go-version v1.7.0
github.com/hashicorp/hcl v1.0.0
github.com/hashicorp/hcl/v2 v2.23.1-0.20250203194505-ba0759438da2
github.com/hashicorp/jsonapi v1.3.1
github.com/hashicorp/jsonapi v1.3.2
github.com/hashicorp/terraform-registry-address v0.2.3
github.com/hashicorp/terraform-svchost v0.1.1
github.com/hashicorp/terraform/internal/backend/remote-state/azure v0.0.0-00010101000000-000000000000
@ -256,7 +256,7 @@ require (
go.opentelemetry.io/proto/otlp v1.0.0 // indirect
golang.org/x/exp/typeparams v0.0.0-20231108232855-2478ac86f678 // indirect
golang.org/x/sync v0.10.0 // indirect
golang.org/x/time v0.7.0 // indirect
golang.org/x/time v0.9.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/api v0.126.0 // indirect
google.golang.org/appengine v1.6.8 // indirect

16
go.sum
View file

@ -1123,8 +1123,8 @@ github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerX
github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc=
github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A=
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
github.com/hashicorp/go-tfe v1.70.0 h1:R5a9Z+jdVz6eRWtSLsl1nw+5Qe/swunZcJgeKK5NQtQ=
github.com/hashicorp/go-tfe v1.70.0/go.mod h1:2rOcdTxXwbWm0W7dCKjC3Ec8KQ+HhW165GiurXNshc4=
github.com/hashicorp/go-tfe v1.74.1 h1:I/8fOwSYox17IZV7SULIQH0ZRPNL2g/biW6hHWnOTVY=
github.com/hashicorp/go-tfe v1.74.1/go.mod h1:kGHWMZ3HHjitgqON8nBZ4kPVJ3cLbzM4JMgmNVMs9aQ=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
@ -1141,8 +1141,8 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/hcl/v2 v2.23.1-0.20250203194505-ba0759438da2 h1:JP8y98OtHTujECs4s/HxlKc5yql/RlC99Dt1Iz4R+lM=
github.com/hashicorp/hcl/v2 v2.23.1-0.20250203194505-ba0759438da2/go.mod h1:k+HgkLpoWu9OS81sy4j1XKDXaWm/rLysG33v5ibdDnc=
github.com/hashicorp/jsonapi v1.3.1 h1:GtPvnmcWgYwCuDGvYT5VZBHcUyFdq9lSyCzDjn1DdPo=
github.com/hashicorp/jsonapi v1.3.1/go.mod h1:kWfdn49yCjQvbpnvY1dxxAuAFzISwrrMDQOcu6NsFoM=
github.com/hashicorp/jsonapi v1.3.2 h1:gP3fX2ZT7qXi+PbwieptzkspIohO2kCSiBUvUTBAbMs=
github.com/hashicorp/jsonapi v1.3.2/go.mod h1:kWfdn49yCjQvbpnvY1dxxAuAFzISwrrMDQOcu6NsFoM=
github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y=
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc=
@ -1460,8 +1460,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.563/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.588 h1:DYtBXB7sVc3EOW5horg8j55cLZynhsLYhHrvQ/jXKKM=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.588/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y=
@ -1917,8 +1917,8 @@ golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxb
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ=
golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY=
golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

View file

@ -64,7 +64,7 @@ require (
golang.org/x/sys v0.29.0 // indirect
golang.org/x/term v0.28.0 // indirect
golang.org/x/text v0.21.0 // indirect
golang.org/x/time v0.7.0 // indirect
golang.org/x/time v0.9.0 // indirect
golang.org/x/tools v0.25.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect

View file

@ -492,8 +492,8 @@ golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ=
golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY=
golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=

View file

@ -82,6 +82,10 @@ type TestSuiteRunner struct {
// Verbose tells the runner to print out plan files during each test run.
Verbose bool
// OperationParallelism is the limit Terraform places on total parallel operations
// during the plan or apply command within a single test run.
OperationParallelism int
// Filters restricts which test files will be executed.
Filters []string
@ -204,6 +208,7 @@ func (runner *TestSuiteRunner) Test() (moduletest.Status, tfdiags.Diagnostics) {
Filters: runner.Filters,
TestDirectory: tfe.String(runner.TestingDirectory),
Verbose: tfe.Bool(runner.Verbose),
Parallelism: tfe.Int(runner.OperationParallelism),
Variables: func() []*tfe.RunVariable {
runVariables := make([]*tfe.RunVariable, 0, len(variables))
for name, value := range variables {

View file

@ -103,6 +103,81 @@ Success! 2 passed, 0 failed.
}
}
func TestTest_Parallelism(t *testing.T) {
streams, _ := terminal.StreamsForTesting(t)
view := views.NewTest(arguments.ViewHuman, views.NewView(streams))
colorize := mockColorize()
colorize.Disable = true
mock := NewMockClient()
client := &tfe.Client{
ConfigurationVersions: mock.ConfigurationVersions,
Organizations: mock.Organizations,
RegistryModules: mock.RegistryModules,
TestRuns: mock.TestRuns,
}
if _, err := client.Organizations.Create(context.Background(), tfe.OrganizationCreateOptions{
Name: tfe.String("organisation"),
}); err != nil {
t.Fatalf("failed to create organisation: %v", err)
}
if _, err := client.RegistryModules.Create(context.Background(), "organisation", tfe.RegistryModuleCreateOptions{
Name: tfe.String("name"),
Provider: tfe.String("provider"),
RegistryName: "app.terraform.io",
Namespace: "organisation",
}); err != nil {
t.Fatalf("failed to create registry module: %v", err)
}
runner := TestSuiteRunner{
// Configuration data.
ConfigDirectory: "testdata/test",
TestingDirectory: "tests",
Config: nil, // We don't need this for this test.
Source: "app.terraform.io/organisation/name/provider",
// Cancellation controls, we won't be doing any cancellations in this
// test.
Stopped: false,
Cancelled: false,
StoppedCtx: context.Background(),
CancelledCtx: context.Background(),
// Test Options, empty for this test.
GlobalVariables: nil,
Verbose: false,
OperationParallelism: 4,
Filters: nil,
// Outputs
Renderer: &jsonformat.Renderer{
Streams: streams,
Colorize: colorize,
RunningInAutomation: false,
},
View: view,
Streams: streams,
// Networking
Services: nil, // Don't need this when the client is overridden.
clientOverride: client,
}
_, diags := runner.Test()
if len(diags) > 0 {
t.Errorf("found diags and expected none: %s", diags.ErrWithWarnings())
}
if mock.TestRuns.parallelism != 4 {
t.Errorf("expected parallelism to be 4 but was %d", mock.TestRuns.parallelism)
}
}
func TestTest_JSON(t *testing.T) {
streams, done := terminal.StreamsForTesting(t)

View file

@ -1673,9 +1673,10 @@ type MockTestRuns struct {
client *MockClient
// TestRuns and modules keep track of our tfe.TestRun objects.
TestRuns map[string]*tfe.TestRun
modules map[string][]*tfe.TestRun
logs map[string]string
TestRuns map[string]*tfe.TestRun
modules map[string][]*tfe.TestRun
logs map[string]string
parallelism int
// delayedCancel allows a mock test run to cancel an operation instead of
// completing an operation. It's used
@ -1767,6 +1768,9 @@ func (m *MockTestRuns) Create(ctx context.Context, options tfe.TestRunCreateOpti
"test.log",
)
m.modules[tr.RegistryModule.ID] = append(m.modules[tr.RegistryModule.ID], tr)
if options.Parallelism != nil {
m.parallelism = *options.Parallelism
}
return tr, nil
}
@ -2170,6 +2174,30 @@ func (m *MockWorkspaces) UpdateByID(ctx context.Context, workspaceID string, opt
return w, nil
}
func (m *MockWorkspaces) ListEffectiveTagBindings(ctx context.Context, workspaceID string) ([]*tfe.EffectiveTagBinding, error) {
w, ok := m.workspaceIDs[workspaceID]
if !ok {
return nil, tfe.ErrResourceNotFound
}
var effectiveTagBindings []*tfe.EffectiveTagBinding
for _, tb := range w.TagBindings {
effectiveTagBindings = append(effectiveTagBindings, &tfe.EffectiveTagBinding{
Key: tb.Key,
Value: tb.Value,
})
}
return effectiveTagBindings, nil
}
func (m *MockWorkspaces) DeleteAllTagBindings(ctx context.Context, workspaceID string) error {
w, ok := m.workspaceIDs[workspaceID]
if !ok {
return tfe.ErrResourceNotFound
}
w.TagBindings = nil
return nil
}
func updateMockWorkspaceAttributes(w *tfe.Workspace, options tfe.WorkspaceUpdateOptions) error {
// for TestCloud_setUnavailableTerraformVersion
if w.Name == "unavailable-terraform-version" && options.TerraformVersion != nil {

View file

@ -18,6 +18,10 @@ type Test struct {
// will be executed.
Filter []string
// OperationParallelism is the limit Terraform places on total parallel operations
// during the plan or apply command within a single test run.
OperationParallelism int
// TestDirectory allows the user to override the directory that the test
// command will use to discover test files, defaults to "tests". Regardless
// of the value here, test files within the configuration directory will
@ -55,6 +59,7 @@ func ParseTest(args []string) (*Test, tfdiags.Diagnostics) {
cmdFlags.BoolVar(&jsonOutput, "json", false, "json")
cmdFlags.StringVar(&test.JUnitXMLFile, "junit-xml", "", "junit-xml")
cmdFlags.BoolVar(&test.Verbose, "verbose", false, "verbose")
cmdFlags.IntVar(&test.OperationParallelism, "parallelism", DefaultParallelism, "parallelism")
// TODO: Finalise the name of this flag.
cmdFlags.StringVar(&test.CloudRunSource, "cloud-run", "", "cloud-run")
@ -73,6 +78,10 @@ func ParseTest(args []string) (*Test, tfdiags.Diagnostics) {
"The -junit-xml option is currently not compatible with remote test execution via the -cloud-run flag. If you are interested in JUnit XML output for remotely-executed tests please open an issue in GitHub."))
}
if test.OperationParallelism < 1 {
test.OperationParallelism = DefaultParallelism
}
switch {
case jsonOutput:
test.ViewType = ViewJSON

View file

@ -72,60 +72,88 @@ func TestParseTest(t *testing.T) {
"defaults": {
args: nil,
want: &Test{
Filter: nil,
TestDirectory: "tests",
ViewType: ViewHuman,
Vars: &Vars{},
Filter: nil,
TestDirectory: "tests",
ViewType: ViewHuman,
Vars: &Vars{},
OperationParallelism: 10,
},
wantDiags: nil,
},
"with-filters": {
args: []string{"-filter=one.tftest.hcl", "-filter=two.tftest.hcl"},
want: &Test{
Filter: []string{"one.tftest.hcl", "two.tftest.hcl"},
TestDirectory: "tests",
ViewType: ViewHuman,
Vars: &Vars{},
Filter: []string{"one.tftest.hcl", "two.tftest.hcl"},
TestDirectory: "tests",
ViewType: ViewHuman,
Vars: &Vars{},
OperationParallelism: 10,
},
wantDiags: nil,
},
"json": {
args: []string{"-json"},
want: &Test{
Filter: nil,
TestDirectory: "tests",
ViewType: ViewJSON,
Vars: &Vars{},
Filter: nil,
TestDirectory: "tests",
ViewType: ViewJSON,
Vars: &Vars{},
OperationParallelism: 10,
},
wantDiags: nil,
},
"test-directory": {
args: []string{"-test-directory=other"},
want: &Test{
Filter: nil,
TestDirectory: "other",
ViewType: ViewHuman,
Vars: &Vars{},
Filter: nil,
TestDirectory: "other",
ViewType: ViewHuman,
Vars: &Vars{},
OperationParallelism: 10,
},
wantDiags: nil,
},
"verbose": {
args: []string{"-verbose"},
want: &Test{
Filter: nil,
TestDirectory: "tests",
ViewType: ViewHuman,
Verbose: true,
Vars: &Vars{},
Filter: nil,
TestDirectory: "tests",
ViewType: ViewHuman,
Verbose: true,
Vars: &Vars{},
OperationParallelism: 10,
},
},
"with-parallelism-set": {
args: []string{"-parallelism=5"},
want: &Test{
Filter: nil,
TestDirectory: "tests",
ViewType: ViewHuman,
Vars: &Vars{},
OperationParallelism: 5,
},
wantDiags: nil,
},
"with-parallelism-0": {
args: []string{"-parallelism=0"},
want: &Test{
Filter: nil,
TestDirectory: "tests",
ViewType: ViewHuman,
Vars: &Vars{},
OperationParallelism: 10,
},
wantDiags: nil,
},
"unknown flag": {
args: []string{"-boop"},
want: &Test{
Filter: nil,
TestDirectory: "tests",
ViewType: ViewHuman,
Vars: &Vars{},
Filter: nil,
TestDirectory: "tests",
ViewType: ViewHuman,
Vars: &Vars{},
OperationParallelism: 10,
},
wantDiags: tfdiags.Diagnostics{
tfdiags.Sourceless(
@ -138,12 +166,13 @@ func TestParseTest(t *testing.T) {
"incompatible flags: -junit-xml and -cloud-run": {
args: []string{"-junit-xml=./output.xml", "-cloud-run=foobar"},
want: &Test{
CloudRunSource: "foobar",
JUnitXMLFile: "./output.xml",
Filter: nil,
TestDirectory: "tests",
ViewType: ViewHuman,
Vars: &Vars{},
CloudRunSource: "foobar",
JUnitXMLFile: "./output.xml",
Filter: nil,
TestDirectory: "tests",
ViewType: ViewHuman,
Vars: &Vars{},
OperationParallelism: 10,
},
wantDiags: tfdiags.Diagnostics{
tfdiags.Sourceless(

View file

@ -59,6 +59,9 @@ Options:
-no-color If specified, output won't contain any color.
-parallelism=n Limit the number of concurrent operations within the
plan/apply operation of a test run. Defaults to 10.
-test-directory=path Set the Terraform test directory, defaults to "tests".
-var 'foo=bar' Set a value for one of the input variables in the root
@ -99,6 +102,7 @@ func (c *TestCommand) Run(rawArgs []string) int {
c.View.HelpPrompt("test")
return 1
}
c.Meta.parallelism = args.OperationParallelism
view := views.NewTest(args.ViewType, c.View)
@ -183,21 +187,22 @@ func (c *TestCommand) Run(rawArgs []string) int {
}
runner = &cloud.TestSuiteRunner{
ConfigDirectory: ".", // Always loading from the current directory.
TestingDirectory: args.TestDirectory,
Config: config,
Services: c.Services,
Source: args.CloudRunSource,
GlobalVariables: variables,
Stopped: false,
Cancelled: false,
StoppedCtx: stopCtx,
CancelledCtx: cancelCtx,
Verbose: args.Verbose,
Filters: args.Filter,
Renderer: renderer,
View: view,
Streams: c.Streams,
ConfigDirectory: ".", // Always loading from the current directory.
TestingDirectory: args.TestDirectory,
Config: config,
Services: c.Services,
Source: args.CloudRunSource,
GlobalVariables: variables,
Stopped: false,
Cancelled: false,
StoppedCtx: stopCtx,
CancelledCtx: cancelCtx,
Verbose: args.Verbose,
OperationParallelism: args.OperationParallelism,
Filters: args.Filter,
Renderer: renderer,
View: view,
Streams: c.Streams,
}
} else {
localRunner := &local.TestSuiteRunner{

View file

@ -35,6 +35,7 @@ func TestTest_Runs(t *testing.T) {
code int
initCode int
skip bool
desc string
}{
"simple_pass": {
expectedOut: []string{"1 passed, 0 failed."},
@ -54,6 +55,13 @@ func TestTest_Runs(t *testing.T) {
expectedOut: []string{"1 passed, 0 failed."},
code: 0,
},
"simple_pass_cmd_parallel": {
override: "simple_pass",
args: []string{"-parallelism", "1"},
expectedOut: []string{"1 passed, 0 failed."},
code: 0,
desc: "simple_pass with parallelism set to 1",
},
"simple_pass_very_nested_alternate": {
override: "simple_pass_very_nested",
args: []string{"-test-directory", "./tests/subdir"},

View file

@ -38,6 +38,8 @@ The following options apply to the Terraform `terraform test` command:
* `-verbose` - Prints out the plan or state for each `run` block within a test file, based on the `command` attribute of each `run` block.
* `-parallelism=<n>` - Specifies the number of plan/apply operations to execute in parallel within a single test run. The default is 10.
## State Management
Each Terraform test file will maintain all Terraform state it requires within memory as it executes, starting empty. This state is entirely separate from any existing state for the configuration under test, so you can safely execute Terraform test commands without affecting any live infrastructure.