This is an automated email from the ASF dual-hosted git repository.

sruehl pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit 99a0299d6ab2674f25271a1cc92972f6c7d5db22
Author: Sebastian Rühl <[email protected]>
AuthorDate: Mon Jul 20 13:28:43 2026 +0200

    test(plc4go): fix three -race flakes in spi test hygiene
    
    - spi/default: Test_defaultCodec_Connect built the codec by hand without
      ctx/ctxCancel - the expire/receive workers panic on the nil-ctx select,
      and teardown joined wg instead of activeWorker, so the recover path
      logged through the finished test's logger (log-after-test panic, then
      SIGSEGV of the test binary). Give the codec a real ctx and join both
      worker groups in t.Cleanup.
    - spi/transactions: Test_requestTransaction_AwaitCompletion appended to
      runningRequests under workLogMutex.RLock - wrong mutex, and a read
      lock for a write. Use runningRequestMutex.Lock like production code.
    - spi/utils: TestStopWarn's logHook mutated its slices concurrently from
      the StopWarn ticker goroutine and the test goroutine's deferred stop
      (which logs before joining). Guard Run with a mutex.
    
    All three reproduced reliably with go test -race -count>=20 and are green
    for 50-500 iterations after the fix.
---
 plc4go/spi/default/DefaultCodec_test.go            | 12 ++++++++++--
 plc4go/spi/transactions/RequestTransaction_test.go |  4 ++--
 plc4go/spi/utils/StopWarn_test.go                  |  5 +++++
 3 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/plc4go/spi/default/DefaultCodec_test.go 
b/plc4go/spi/default/DefaultCodec_test.go
index 82a71691bf..d5906085c4 100644
--- a/plc4go/spi/default/DefaultCodec_test.go
+++ b/plc4go/spi/default/DefaultCodec_test.go
@@ -423,9 +423,17 @@ func Test_defaultCodec_Connect(t *testing.T) {
                                customMessageHandling:         
tt.fields.customMessageHandling,
                                log:                           
testutils.ProduceTestingLogger(t),
                        }
+                       // Connect starts the expire/receive workers, which 
select on m.ctx and
+                       // log through m.log on panic — so ctx must be non-nil 
and the workers
+                       // (tracked by activeWorker, not wg) must be joined 
before the test ends.
+                       m.ctx, m.ctxCancel = context.WithCancel(t.Context())
+                       t.Cleanup(func() {
+                               m.running.Store(false)
+                               m.ctxCancel()
+                               m.activeWorker.Wait()
+                               m.wg.Wait()
+                       })
                        tt.wantErr(t, m.Connect(tt.args.ctx), 
fmt.Sprintf("Connect(%v)", tt.args.ctx))
-                       m.running.Store(false)
-                       m.wg.Wait()
                })
        }
 }
diff --git a/plc4go/spi/transactions/RequestTransaction_test.go 
b/plc4go/spi/transactions/RequestTransaction_test.go
index 49208e5483..46280524d8 100644
--- a/plc4go/spi/transactions/RequestTransaction_test.go
+++ b/plc4go/spi/transactions/RequestTransaction_test.go
@@ -324,8 +324,8 @@ func Test_requestTransaction_AwaitCompletion(t1 *testing.T) 
{
                                wg.Go(func() {
                                        time.Sleep(100 * time.Millisecond)
                                        r := transaction.parent
-                                       r.workLogMutex.RLock()
-                                       defer r.workLogMutex.RUnlock()
+                                       r.runningRequestMutex.Lock()
+                                       defer r.runningRequestMutex.Unlock()
                                        r.runningRequests = 
append(r.runningRequests, &requestTransaction{transactionId: 1})
                                })
                        },
diff --git a/plc4go/spi/utils/StopWarn_test.go 
b/plc4go/spi/utils/StopWarn_test.go
index 2d737734de..4a331667a0 100644
--- a/plc4go/spi/utils/StopWarn_test.go
+++ b/plc4go/spi/utils/StopWarn_test.go
@@ -131,12 +131,17 @@ func TestStopWarn(t *testing.T) {
 }
 
 type logHook struct {
+       // Run is invoked concurrently: the StopWarn ticker goroutine logs its
+       // warnings while the stop func logs "done" from the test goroutine.
+       mu        sync.Mutex
        logEvents []zerolog.Event
        level     []zerolog.Level
        messages  []string
 }
 
 func (logHook *logHook) Run(logEvent *zerolog.Event, level zerolog.Level, 
message string) {
+       logHook.mu.Lock()
+       defer logHook.mu.Unlock()
        logHook.logEvents = append(logHook.logEvents, *logEvent)
        logHook.level = append(logHook.level, level)
        logHook.messages = append(logHook.messages, message)

Reply via email to