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 }