helper/resource: Add ParallelTest() function to allow opt-in acceptance testing concurrency with t.Parallel()

While this initial implementation is a very simple wrapper function, implementing this in the helper/resource package provides some downstream benefits:
* Provides a standard interface for plugin developers to enable parallel acceptance testing
* Existing plugins can simply convert resource.Test to resource.ParallelTest references (as appropriate) to enable the functionality, rather than worrying about additional line(s) to each acceptance test function or TestCase
* Potential enhancements to ParallelTest (e.g. adding an environment variable to skip enabling the behavior) are consistently propagated
This commit is contained in:
Brian Flad 2018-08-15 14:03:13 -04:00
parent 4c08bf8b43
commit 798162125b
2 changed files with 35 additions and 6 deletions

View File

@ -418,6 +418,17 @@ func LogOutput(t TestT) (logOutput io.Writer, err error) {
return
}
// ParallelTest performs an acceptance test on a resource, allowing concurrency
// with other ParallelTest.
//
// Tests will fail if they do not properly handle conditions to allow multiple
// tests to occur against the same resource or service (e.g. random naming).
// All other requirements of the Test function also apply to this function.
func ParallelTest(t TestT, c TestCase) {
t.Parallel()
Test(t, c)
}
// Test performs an acceptance test on a resource.
//
// Tests are not run unless an environmental variable "TF_ACC" is
@ -1128,6 +1139,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

View File

@ -45,6 +45,15 @@ func (p *resetProvider) TestReset() error {
return p.TestResetError
}
func TestParallelTest(t *testing.T) {
mt := new(mockT)
ParallelTest(mt, TestCase{})
if !mt.ParallelCalled {
t.Fatal("Parallel() not called")
}
}
func TestTest(t *testing.T) {
mp := &resetProvider{
MockResourceProvider: testProvider(),
@ -112,6 +121,9 @@ func TestTest(t *testing.T) {
if mt.failed() {
t.Fatalf("test failed: %s", mt.failMessage())
}
if mt.ParallelCalled {
t.Fatal("Parallel() called")
}
if !checkStep {
t.Fatal("didn't call check for step")
}
@ -692,12 +704,13 @@ func TestComposeTestCheckFunc(t *testing.T) {
// mockT implements TestT for testing
type mockT struct {
ErrorCalled bool
ErrorArgs []interface{}
FatalCalled bool
FatalArgs []interface{}
SkipCalled bool
SkipArgs []interface{}
ErrorCalled bool
ErrorArgs []interface{}
FatalCalled bool
FatalArgs []interface{}
ParallelCalled bool
SkipCalled bool
SkipArgs []interface{}
f bool
}
@ -714,6 +727,10 @@ func (t *mockT) Fatal(args ...interface{}) {
t.f = true
}
func (t *mockT) Parallel() {
t.ParallelCalled = true
}
func (t *mockT) Skip(args ...interface{}) {
t.SkipCalled = true
t.SkipArgs = args