From 124be569eb08440eb2fa29425c42fb78f554e05e Mon Sep 17 00:00:00 2001 From: Su Shi <1684739+metacpp@users.noreply.github.com> Date: Thu, 30 Nov 2017 18:11:31 -0800 Subject: [PATCH 1/5] Support parallel testing in terraform testing framework: 1. Add Parallel() in the TestT interface so that testing.T.Parallel can be invoked in each test function. 2. Introduced the TF_PARA for user to enable it while running "go test". 3. Add unit test case. --- helper/resource/testing.go | 12 ++++++++++++ helper/resource/testing_test.go | 19 +++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/helper/resource/testing.go b/helper/resource/testing.go index 64f5c899b920..6051f2a98ce3 100644 --- a/helper/resource/testing.go +++ b/helper/resource/testing.go @@ -172,6 +172,9 @@ func runSweeperWithRegion(region string, s *Sweeper) error { const TestEnvVar = "TF_ACC" +// ParaTestEnvVar is used to enable parallelism in testing. +const ParaTestEnvVar = "TF_PARA" + // TestProvider can be implemented by any ResourceProvider to provide custom // reset functionality at the start of an acceptance test. // The helper/schema Provider implements this interface. @@ -415,6 +418,14 @@ func LogOutput(t TestT) (logOutput io.Writer, err error) { // long, we require the verbose flag so users are able to see progress // output. func Test(t TestT, c TestCase) { + // If "TF_PARA" is set to some non-empty value, all the parallel test cases + // will be run parallel. + // example usage: + // TF_PARA=1 go test [TEST] [TESTARGS] -parallel=n + if os.Getenv(ParaTestEnvVar) != "" { + t.Parallel() + } + // We only run acceptance tests if an env var is set because they're // slow and generally require some outside configuration. You can opt out // of this with OverrideEnvVar on individual TestCases. @@ -1002,6 +1013,7 @@ type TestT interface { Fatal(args ...interface{}) Skip(args ...interface{}) Name() string + Parallel() } // This is set to true by unit tests to alter some behavior diff --git a/helper/resource/testing_test.go b/helper/resource/testing_test.go index fcbde3ed9eb4..6a96844b579c 100644 --- a/helper/resource/testing_test.go +++ b/helper/resource/testing_test.go @@ -28,6 +28,10 @@ func init() { if err := os.Setenv(TestEnvVar, "1"); err != nil { panic(err) } + + if err := os.Setenv(ParaTestEnvVar, "1"); err != nil { + panic(err) + } } // wrap the mock provider to implement TestProvider @@ -376,6 +380,21 @@ func TestTest_noEnv(t *testing.T) { } } +func TestTest_noParaEnv(t *testing.T) { + // Unset the variable + if err := os.Setenv(ParaTestEnvVar, ""); err != nil { + t.Fatalf("err: %s", err) + } + defer os.Setenv(ParaTestEnvVar, "1") + + mt := new(mockT) + Test(mt, TestCase{}) + + if !mt.SkipCalled { + t.Fatal("skip not called") + } +} + func TestTest_preCheck(t *testing.T) { called := false From 9d3a6bfe03a2231d5bb24e9e8fb64c67d2ab84a9 Mon Sep 17 00:00:00 2001 From: Su Shi <1684739+metacpp@users.noreply.github.com> Date: Thu, 30 Nov 2017 18:52:16 -0800 Subject: [PATCH 2/5] add missed parallel method in mockT. --- helper/resource/testing_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/helper/resource/testing_test.go b/helper/resource/testing_test.go index 6a96844b579c..9cdfdd1895a3 100644 --- a/helper/resource/testing_test.go +++ b/helper/resource/testing_test.go @@ -650,6 +650,10 @@ func (t *mockT) Name() string { return "MockedName" } +func (t *mockT) Parallel() { + return +} + func (t *mockT) failed() bool { return t.f } From c159becfc7970c2c260ff5bdfad856b4f69b60e6 Mon Sep 17 00:00:00 2001 From: Su Shi <1684739+metacpp@users.noreply.github.com> Date: Thu, 30 Nov 2017 19:35:05 -0800 Subject: [PATCH 3/5] Update the unit test case for ParaTestEnv. --- helper/resource/testing_test.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/helper/resource/testing_test.go b/helper/resource/testing_test.go index 9cdfdd1895a3..3a67397866f8 100644 --- a/helper/resource/testing_test.go +++ b/helper/resource/testing_test.go @@ -380,18 +380,18 @@ func TestTest_noEnv(t *testing.T) { } } -func TestTest_noParaEnv(t *testing.T) { - // Unset the variable - if err := os.Setenv(ParaTestEnvVar, ""); err != nil { +func TestTest_withParaEnv(t *testing.T) { + // Set the variable + if err := os.Setenv(ParaTestEnvVar, "1"); err != nil { t.Fatalf("err: %s", err) } - defer os.Setenv(ParaTestEnvVar, "1") + defer os.Setenv(ParaTestEnvVar, "") mt := new(mockT) Test(mt, TestCase{}) - if !mt.SkipCalled { - t.Fatal("skip not called") + if !mt.Paralleled { + t.Fatal("parallel not called") } } @@ -624,6 +624,7 @@ type mockT struct { FatalArgs []interface{} SkipCalled bool SkipArgs []interface{} + Paralleled bool f bool } @@ -651,6 +652,7 @@ func (t *mockT) Name() string { } func (t *mockT) Parallel() { + t.Paralleled = true return } From 3dcda5a15d543236984ee692de89298dc611133c Mon Sep 17 00:00:00 2001 From: Su Shi <1684739+metacpp@users.noreply.github.com> Date: Thu, 30 Nov 2017 21:06:55 -0800 Subject: [PATCH 4/5] Fix the styling issue for mockT. --- helper/resource/testing_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helper/resource/testing_test.go b/helper/resource/testing_test.go index 3a67397866f8..19405e7321ef 100644 --- a/helper/resource/testing_test.go +++ b/helper/resource/testing_test.go @@ -624,7 +624,7 @@ type mockT struct { FatalArgs []interface{} SkipCalled bool SkipArgs []interface{} - Paralleled bool + Paralleled bool f bool } From 67f301d38a3e35bd7e6267fb16d5b5ca433423c9 Mon Sep 17 00:00:00 2001 From: Su Shi <1684739+metacpp@users.noreply.github.com> Date: Sun, 3 Dec 2017 21:13:52 -0800 Subject: [PATCH 5/5] Add IsParallel to enable case level parallelism. --- helper/resource/testing.go | 15 +++++++-------- helper/resource/testing_test.go | 14 ++------------ 2 files changed, 9 insertions(+), 20 deletions(-) diff --git a/helper/resource/testing.go b/helper/resource/testing.go index 6051f2a98ce3..f1c5491575cf 100644 --- a/helper/resource/testing.go +++ b/helper/resource/testing.go @@ -172,9 +172,6 @@ func runSweeperWithRegion(region string, s *Sweeper) error { const TestEnvVar = "TF_ACC" -// ParaTestEnvVar is used to enable parallelism in testing. -const ParaTestEnvVar = "TF_PARA" - // TestProvider can be implemented by any ResourceProvider to provide custom // reset functionality at the start of an acceptance test. // The helper/schema Provider implements this interface. @@ -201,6 +198,12 @@ type ImportStateIdFunc func(*terraform.State) (string, error) // When the destroy plan is executed, the config from the last TestStep // is used to plan it. type TestCase struct { + // IsParallel allows a test to run in parallel in Go tesing framework. + // Make sure the test case is independent without any shared resource. + // For subtests, if IsParallel is enabled while defining it, all the subtests + // within the same group will be run in paralllel. + IsParallel bool + // IsUnitTest allows a test to run regardless of the TF_ACC // environment variable. This should be used with care - only for // fast tests on local resources (e.g. remote state with a local @@ -418,11 +421,7 @@ func LogOutput(t TestT) (logOutput io.Writer, err error) { // long, we require the verbose flag so users are able to see progress // output. func Test(t TestT, c TestCase) { - // If "TF_PARA" is set to some non-empty value, all the parallel test cases - // will be run parallel. - // example usage: - // TF_PARA=1 go test [TEST] [TESTARGS] -parallel=n - if os.Getenv(ParaTestEnvVar) != "" { + if c.IsParallel { t.Parallel() } diff --git a/helper/resource/testing_test.go b/helper/resource/testing_test.go index 19405e7321ef..5d0d53292af9 100644 --- a/helper/resource/testing_test.go +++ b/helper/resource/testing_test.go @@ -28,10 +28,6 @@ func init() { if err := os.Setenv(TestEnvVar, "1"); err != nil { panic(err) } - - if err := os.Setenv(ParaTestEnvVar, "1"); err != nil { - panic(err) - } } // wrap the mock provider to implement TestProvider @@ -380,15 +376,9 @@ func TestTest_noEnv(t *testing.T) { } } -func TestTest_withParaEnv(t *testing.T) { - // Set the variable - if err := os.Setenv(ParaTestEnvVar, "1"); err != nil { - t.Fatalf("err: %s", err) - } - defer os.Setenv(ParaTestEnvVar, "") - +func TestTest_withParallelCase(t *testing.T) { mt := new(mockT) - Test(mt, TestCase{}) + Test(mt, TestCase{IsParallel: true}) if !mt.Paralleled { t.Fatal("parallel not called")