From 014bf49e377b5bb5739857f4987095bfd7adbe3a Mon Sep 17 00:00:00 2001 From: Steven van der Vegt Date: Wed, 9 Sep 2026 15:08:16 +0200 Subject: [PATCH] test(network): fix race in TestNetworkIntegration_PrivateTransaction/event_received node2 publishes a NATS event for every transaction it receives, so the subtest gets two messages: the bootstrap DID document and the private TX. The test waited for any message, returned on the first one and closed the connection, after which the second message's ack failed with "nats: connection closed" and asserted against a completed test. Wait for the private TX event specifically, record its ack error under the mutex and assert it on the test goroutine. Assisted-by: AI (cherry picked from commit b788cd3e393f7c44f541b43e9935aab3826b50fe) --- network/network_integration_test.go | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/network/network_integration_test.go b/network/network_integration_test.go index b3d5aff24..f20885857 100644 --- a/network/network_integration_test.go +++ b/network/network_integration_test.go @@ -560,14 +560,24 @@ func TestNetworkIntegration_PrivateTransaction(t *testing.T) { conn, _, err := node2.network.eventPublisher.Pool().Acquire(context.Background()) require.NoError(t, err) defer conn.Close() - var found []byte + // node2 emits an event for every transaction it receives: the bootstrap DID document and the private TX. + // Wait for the private TX specifically and record its ack result under the mutex, so the test does not + // return (closing conn) while a later message is still being acked on the callback goroutine. + // Do not assert inside the callback: it may run after the test has completed. + var found bool + var ackErr error foundMutex := sync.Mutex{} _ = stream.Subscribe(conn, "TEST", "TRANSACTIONS.tx", func(msg *nats.Msg) { foundMutex.Lock() defer foundMutex.Unlock() - found = msg.Data - err := msg.Ack() - require.NoError(t, err) + event := events.TransactionWithPayload{} + if err := json.Unmarshal(msg.Data, &event); err != nil || string(event.Payload) != "private TX" { + // not the transaction we are waiting for (e.g. the bootstrap DID document) + _ = msg.Ack() + return + } + ackErr = msg.Ack() + found = true }) node1DID := node1.network.nodeDID @@ -584,8 +594,11 @@ func TestNetworkIntegration_PrivateTransaction(t *testing.T) { test.WaitFor(t, func() (bool, error) { foundMutex.Lock() defer foundMutex.Unlock() - return len(found) > 0, nil - }, 100*time.Millisecond, "timeout waiting for message") + return found, nil + }, defaultTimeout, "timeout waiting for private TX event") + foundMutex.Lock() + defer foundMutex.Unlock() + assert.NoError(t, ackErr) }) t.Run("third node knows nothing", func(t *testing.T) {