diff --git a/bitswap/network/connecteventmanager_test.go b/bitswap/network/connecteventmanager_test.go index e3904ee55..5ce4e690c 100644 --- a/bitswap/network/connecteventmanager_test.go +++ b/bitswap/network/connecteventmanager_test.go @@ -18,7 +18,8 @@ type mockConnEvent struct { type mockConnListener struct { sync.Mutex - events []mockConnEvent + events []mockConnEvent + peerConnectedCb func(p peer.ID) } func newMockConnListener() *mockConnListener { @@ -29,6 +30,9 @@ func (cl *mockConnListener) PeerConnected(p peer.ID) { cl.Lock() defer cl.Unlock() cl.events = append(cl.events, mockConnEvent{connected: true, peer: p}) + if cl.peerConnectedCb != nil { + cl.peerConnectedCb(p) + } } func (cl *mockConnListener) PeerDisconnected(p peer.ID) { @@ -173,3 +177,51 @@ func TestConnectEventManagerDisconnectAfterMarkUnresponsive(t *testing.T) { require.Empty(t, cem.peers) // all disconnected require.Equal(t, expectedEvents, connListener.events) } + +func TestConnectEventManagerConnectFlowSynchronous(t *testing.T) { + connListener := newMockConnListener() + actionsCh := make(chan string) + connListener.peerConnectedCb = func(p peer.ID) { + actionsCh <- "PeerConnected:" + p.String() + time.Sleep(time.Millisecond * 50) + } + + peers := testutil.GeneratePeers(2) + cem := newConnectEventManager(connListener) + cem.Start() + t.Cleanup(cem.Stop) + + go func() { + actionsCh <- "Connected:" + peers[0].String() + cem.Connected(peers[0]) + actionsCh <- "Done:" + peers[0].String() + actionsCh <- "Connected:" + peers[1].String() + cem.Connected(peers[1]) + actionsCh <- "Done:" + peers[1].String() + close(actionsCh) + }() + + // We expect Done to be sent _after_ PeerConnected, which demonstrates the + // call to Connected() blocks until PeerConnected() returns. + gotActions := make([]string, 0, 3) + for event := range actionsCh { + gotActions = append(gotActions, event) + } + expectedActions := []string{ + "Connected:" + peers[0].String(), + "PeerConnected:" + peers[0].String(), + "Done:" + peers[0].String(), + "Connected:" + peers[1].String(), + "PeerConnected:" + peers[1].String(), + "Done:" + peers[1].String(), + } + require.Equal(t, expectedActions, gotActions) + + // Flush the event queue. + wait(t, cem) + expectedEvents := []mockConnEvent{ + {peer: peers[0], connected: true}, + {peer: peers[1], connected: true}, + } + require.Equal(t, expectedEvents, connListener.events) +}