From 6d117d64a256234372f2bb177392b987aa1758af Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Sun, 6 Apr 2025 13:27:10 -0700 Subject: [PATCH] util/testenv: add func to report whether a testing.TB is in parallel mode For future in-memory network changes (#15558) to be able to be stricter and do automatic leak detection when it's safe to do so, in non-parallel tests. Updates tailscale/corp#27636 Change-Id: I50f03b16a3f92ce61a7ed88264b49d8c6628f638 Signed-off-by: Brad Fitzpatrick --- util/testenv/testenv.go | 39 ++++++++++++++++++++++++++++++++++++ util/testenv/testenv_test.go | 13 ++++++++++++ 2 files changed, 52 insertions(+) diff --git a/util/testenv/testenv.go b/util/testenv/testenv.go index 12ada9003..3e23baef4 100644 --- a/util/testenv/testenv.go +++ b/util/testenv/testenv.go @@ -6,6 +6,7 @@ package testenv import ( + "context" "flag" "tailscale.com/types/lazy" @@ -19,3 +20,41 @@ func InTest() bool { return flag.Lookup("test.v") != nil }) } + +// TB is testing.TB, to avoid importing "testing" in non-test code. +type TB interface { + Cleanup(func()) + Error(args ...any) + Errorf(format string, args ...any) + Fail() + FailNow() + Failed() bool + Fatal(args ...any) + Fatalf(format string, args ...any) + Helper() + Log(args ...any) + Logf(format string, args ...any) + Name() string + Setenv(key, value string) + Chdir(dir string) + Skip(args ...any) + SkipNow() + Skipf(format string, args ...any) + Skipped() bool + TempDir() string + Context() context.Context +} + +// InParallelTest reports whether t is running as a parallel test. +// +// Use of this function taints t such that its Parallel method (assuming t is an +// actual *testing.T) will panic if called after this function. +func InParallelTest(t TB) (isParallel bool) { + defer func() { + if r := recover(); r != nil { + isParallel = true + } + }() + t.Chdir(".") // panics in a t.Parallel test + return false +} diff --git a/util/testenv/testenv_test.go b/util/testenv/testenv_test.go index 43c332b26..c647d9aec 100644 --- a/util/testenv/testenv_test.go +++ b/util/testenv/testenv_test.go @@ -16,3 +16,16 @@ func TestDeps(t *testing.T) { }, }.Check(t) } + +func TestInParallelTestTrue(t *testing.T) { + t.Parallel() + if !InParallelTest(t) { + t.Fatal("InParallelTest should return true once t.Parallel has been called") + } +} + +func TestInParallelTestFalse(t *testing.T) { + if InParallelTest(t) { + t.Fatal("InParallelTest should return false before t.Parallel has been called") + } +}