From c2ad724e9a1d69abc594e9b1d28bca8caf4ac74d Mon Sep 17 00:00:00 2001 From: Patrick Ohly Date: Wed, 19 Feb 2025 19:52:48 +0100 Subject: [PATCH] ktesting: add Parallel It's useful for writing parallel unit tests. --- test/utils/ktesting/tcontext.go | 15 +++++++++++++++ test/utils/ktesting/tcontext_test.go | 17 +++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/test/utils/ktesting/tcontext.go b/test/utils/ktesting/tcontext.go index 18bc387e057..1d3de80e21c 100644 --- a/test/utils/ktesting/tcontext.go +++ b/test/utils/ktesting/tcontext.go @@ -75,6 +75,15 @@ type TContext interface { context.Context TB + // Parallel signals that this test is to be run in parallel with (and + // only with) other parallel tests. In other words, it needs to be + // called in each test which is meant to run in parallel. + // + // Only supported in Go unit tests. When such a test is run multiple + // times due to use of -test.count or -test.cpu, multiple instances of + // a single test never run in parallel with each other. + Parallel() + // Cancel can be invoked to cancel the context before the test is completed. // Tests which use the context to control goroutines and then wait for // termination of those goroutines must call Cancel to avoid a deadlock. @@ -381,6 +390,12 @@ type testingTB struct { TB } +func (tCtx tContext) Parallel() { + if tb, ok := tCtx.TB().(interface{ Parallel() }); ok { + tb.Parallel() + } +} + func (tCtx tContext) Cancel(cause string) { if tCtx.cancel != nil { tCtx.cancel(cause) diff --git a/test/utils/ktesting/tcontext_test.go b/test/utils/ktesting/tcontext_test.go index 116184d4e70..79605d8388b 100644 --- a/test/utils/ktesting/tcontext_test.go +++ b/test/utils/ktesting/tcontext_test.go @@ -86,6 +86,23 @@ func TestCancelCtx(t *testing.T) { tCtx.Cancel("test is complete") } +func TestParallel(t *testing.T) { + var wg sync.WaitGroup + wg.Add(3) + + tCtx := ktesting.Init(t) + + // Each sub-test runs in parallel to the others and waits for the other two. + test := func(tCtx ktesting.TContext) { + tCtx.Parallel() + wg.Done() + wg.Wait() + } + tCtx.Run("one", test) + tCtx.Run("two", test) + tCtx.Run("three", test) +} + func TestWithTB(t *testing.T) { tCtx := ktesting.Init(t)