diff --git a/integration/container/stop_linux_test.go b/integration/container/stop_linux_test.go index fa7338da81..6b2e5ed889 100644 --- a/integration/container/stop_linux_test.go +++ b/integration/container/stop_linux_test.go @@ -78,12 +78,12 @@ func TestStopContainerWithTimeout(t *testing.T) { // if the request is cancelled. // See issue https://github.com/moby/moby/issues/45731 func TestStopContainerWithTimeoutCancel(t *testing.T) { - t.Parallel() - ctx := setupTest(t) apiClient := testEnv.APIClient() t.Cleanup(func() { _ = apiClient.Close() }) + t.Parallel() + id := container.Run(ctx, t, apiClient, container.WithCmd("sh", "-c", "trap 'echo received TERM' TERM; while true; do usleep 10; done"), ) diff --git a/integration/volume/volume_test.go b/integration/volume/volume_test.go index da0b065178..90ae78abd0 100644 --- a/integration/volume/volume_test.go +++ b/integration/volume/volume_test.go @@ -111,9 +111,10 @@ func TestVolumesRemove(t *testing.T) { func TestVolumesRemoveSwarmEnabled(t *testing.T) { skip.If(t, testEnv.IsRemoteDaemon, "cannot run daemon when remote daemon") skip.If(t, testEnv.DaemonInfo.OSType == "windows", "TODO enable on windows") - t.Parallel() ctx := setupTest(t) + t.Parallel() + // Spin up a new daemon, so that we can run this test in parallel (it's a slow test) d := daemon.New(t) d.StartAndSwarmInit(ctx, t) diff --git a/testutil/environment/protect.go b/testutil/environment/protect.go index 34a5cc5805..14bb569928 100644 --- a/testutil/environment/protect.go +++ b/testutil/environment/protect.go @@ -10,6 +10,7 @@ import ( "github.com/docker/docker/api/types/image" "github.com/docker/docker/api/types/volume" "github.com/docker/docker/errdefs" + "github.com/docker/docker/testutil" "go.opentelemetry.io/otel" "gotest.tools/v3/assert" ) @@ -38,6 +39,8 @@ func newProtectedElements() protectedElements { // volumes, and, on Linux, plugins) from being cleaned up at the end of test // runs func ProtectAll(ctx context.Context, t testing.TB, testEnv *Execution) { + testutil.CheckNotParallel(t) + t.Helper() ctx, span := otel.Tracer("").Start(ctx, "ProtectAll") defer span.End() diff --git a/testutil/helpers.go b/testutil/helpers.go index 5c99e7bba4..dfc8c5d344 100644 --- a/testutil/helpers.go +++ b/testutil/helpers.go @@ -7,6 +7,7 @@ import ( "context" "io" "os" + "reflect" "strings" "sync" "testing" @@ -156,3 +157,21 @@ func SetContext(t TestingT, ctx context.Context) { func CleanupContext(t *testing.T) { testContexts.Delete(t) } + +// CheckNotParallel checks if t.Parallel() was not called on the current test. +// There's no public method to check this, so we use reflection to check the +// internal field set by t.Parallel() +// https://github.com/golang/go/blob/8e658eee9c7a67a8a79a8308695920ac9917566c/src/testing/testing.go#L1449 +// +// Since this is not a public API, it might change at any time. +func CheckNotParallel(t testing.TB) { + t.Helper() + field := reflect.ValueOf(t).Elem().FieldByName("isParallel") + if field.IsValid() { + if field.Bool() { + t.Fatal("t.Parallel() was called before") + } + } else { + t.Logf("FIXME: CheckParallel could not determine if test %s is parallel - did the t.Parallel() implementation change?", t.Name()) + } +}