github.com/ethereum-optimism/optimism@v1.7.2/op-node/p2p/pings_test.go (about)

     1  package p2p
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/stretchr/testify/require"
    10  	"golang.org/x/exp/slog"
    11  
    12  	"github.com/libp2p/go-libp2p/core/peer"
    13  	"github.com/libp2p/go-libp2p/p2p/protocol/ping"
    14  
    15  	"github.com/ethereum-optimism/optimism/op-service/clock"
    16  	"github.com/ethereum-optimism/optimism/op-service/testlog"
    17  )
    18  
    19  func TestPingService(t *testing.T) {
    20  	peers := []peer.ID{"a", "b", "c"}
    21  	log, captLog := testlog.CaptureLogger(t, slog.LevelDebug)
    22  
    23  	pingCount := 0
    24  	pingFn := PingFn(func(ctx context.Context, peerID peer.ID) <-chan ping.Result {
    25  		out := make(chan ping.Result, 1)
    26  		switch pingCount % 3 {
    27  		case 0:
    28  			// success
    29  			out <- ping.Result{
    30  				RTT:   time.Millisecond * 10,
    31  				Error: nil,
    32  			}
    33  		case 1:
    34  			// fake timeout
    35  		case 2:
    36  			// error
    37  			out <- ping.Result{
    38  				RTT:   0,
    39  				Error: errors.New("fake error"),
    40  			}
    41  		}
    42  		close(out)
    43  		pingCount += 1
    44  		return out
    45  	})
    46  
    47  	fakeClock := clock.NewDeterministicClock(time.Now())
    48  	peersFn := PeersFn(func() []peer.ID {
    49  		return peers
    50  	})
    51  
    52  	srv := NewPingService(log, pingFn, peersFn, fakeClock)
    53  
    54  	trace := make(chan string)
    55  	srv.trace = func(work string) {
    56  		trace <- work
    57  	}
    58  
    59  	// wait for ping service to get online
    60  	require.Equal(t, "started", <-trace)
    61  	fakeClock.AdvanceTime(pingRound)
    62  	// wait for first round to start and complete
    63  	require.Equal(t, "pingPeers start", <-trace)
    64  	require.Equal(t, "pingPeers end", <-trace)
    65  	// see if client has hit all 3 cases we simulated on the server-side
    66  	require.Equal(t, 3, pingCount, "pinged 3 peers")
    67  	require.NotNil(t, captLog.FindLog(testlog.NewMessageContainsFilter("ping-pong")), "case 0")
    68  	require.NotNil(t, captLog.FindLog(testlog.NewMessageContainsFilter("failed to ping peer, context cancelled")), "case 1")
    69  	require.NotNil(t, captLog.FindLog(testlog.NewMessageContainsFilter("failed to ping peer, communication error")), "case 2")
    70  	captLog.Clear()
    71  
    72  	// advance clock again to proceed to second round, and wait for the round to start and complete
    73  	fakeClock.AdvanceTime(pingRound)
    74  	require.Equal(t, "pingPeers start", <-trace)
    75  	require.Equal(t, "pingPeers end", <-trace)
    76  	// see if client has hit all 3 cases we simulated on the server-side
    77  	require.Equal(t, 6, pingCount, "pinged 3 peers again")
    78  	require.NotNil(t, captLog.FindLog(testlog.NewMessageContainsFilter("ping-pong")), "case 0")
    79  	require.NotNil(t, captLog.FindLog(testlog.NewMessageContainsFilter("failed to ping peer, context cancelled")), "case 1")
    80  	require.NotNil(t, captLog.FindLog(testlog.NewMessageContainsFilter("failed to ping peer, communication error")), "case 2")
    81  	captLog.Clear()
    82  
    83  	srv.Close()
    84  }