package p2p_test import ( "context" "io" "testing" "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/p2p" ) func TestMemoryTransport(t *testing.T) { ctx := context.Background() network := p2p.NewMemoryNetwork(log.TestingLogger()) a := network.GenerateTransport() b := network.GenerateTransport() c := network.GenerateTransport() // Dialing a missing endpoint should fail. _, err := a.Dial(ctx, p2p.Endpoint{ Protocol: p2p.MemoryProtocol, PeerID: p2p.NodeID("foo"), Path: "foo", }) require.Error(t, err) // Dialing and accepting a→b and a→c should work. aToB, bToA, err := a.DialAccept(ctx, b) require.NoError(t, err) defer aToB.Close() defer bToA.Close() aToC, cToA, err := a.DialAccept(ctx, c) require.NoError(t, err) defer aToC.Close() defer cToA.Close() // Send and receive a message both ways a→b and b→a sent, err := aToB.SendMessage(1, []byte("hi!")) require.NoError(t, err) require.True(t, sent) ch, msg, err := bToA.ReceiveMessage() require.NoError(t, err) require.EqualValues(t, 1, ch) require.EqualValues(t, "hi!", msg) sent, err = bToA.SendMessage(1, []byte("hello")) require.NoError(t, err) require.True(t, sent) ch, msg, err = aToB.ReceiveMessage() require.NoError(t, err) require.EqualValues(t, 1, ch) require.EqualValues(t, "hello", msg) // Send and receive a message both ways a→c and c→a sent, err = aToC.SendMessage(1, []byte("foo")) require.NoError(t, err) require.True(t, sent) ch, msg, err = cToA.ReceiveMessage() require.NoError(t, err) require.EqualValues(t, 1, ch) require.EqualValues(t, "foo", msg) sent, err = cToA.SendMessage(1, []byte("bar")) require.NoError(t, err) require.True(t, sent) ch, msg, err = aToC.ReceiveMessage() require.NoError(t, err) require.EqualValues(t, 1, ch) require.EqualValues(t, "bar", msg) // If we close aToB, sending and receiving on either end will error. err = aToB.Close() require.NoError(t, err) _, err = aToB.SendMessage(1, []byte("foo")) require.Equal(t, io.EOF, err) _, _, err = aToB.ReceiveMessage() require.Equal(t, io.EOF, err) _, err = bToA.SendMessage(1, []byte("foo")) require.Equal(t, io.EOF, err) _, _, err = bToA.ReceiveMessage() require.Equal(t, io.EOF, err) // We can still send aToC. sent, err = aToC.SendMessage(1, []byte("foo")) require.NoError(t, err) require.True(t, sent) ch, msg, err = cToA.ReceiveMessage() require.NoError(t, err) require.EqualValues(t, 1, ch) require.EqualValues(t, "foo", msg) // If we close the c transport, it will no longer accept connections, // but we can still use the open connection. endpoint := c.Endpoints()[0] err = c.Close() require.NoError(t, err) require.Empty(t, c.Endpoints()) _, err = a.Dial(ctx, endpoint) require.Error(t, err) sent, err = aToC.SendMessage(1, []byte("bar")) require.NoError(t, err) require.True(t, sent) ch, msg, err = cToA.ReceiveMessage() require.NoError(t, err) require.EqualValues(t, 1, ch) require.EqualValues(t, "bar", msg) }