From b788cd3e393f7c44f541b43e9935aab3826b50fe Mon Sep 17 00:00:00 2001 From: Steven van der Vegt Date: Wed, 9 Sep 2026 15:04:43 +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 --- 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 a262da43b..01481f711 100644 --- a/network/network_integration_test.go +++ b/network/network_integration_test.go @@ -554,14 +554,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() - assert.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 @@ -575,8 +585,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) {