github.com/onflow/flow-go@v0.33.17/network/p2p/distributor/gossipsub_inspector_test.go (about) 1 package distributor_test 2 3 import ( 4 "context" 5 "fmt" 6 "math/rand" 7 "sync" 8 "testing" 9 "time" 10 11 "github.com/libp2p/go-libp2p/core/peer" 12 "github.com/stretchr/testify/mock" 13 "github.com/stretchr/testify/require" 14 15 "github.com/onflow/flow-go/module/irrecoverable" 16 "github.com/onflow/flow-go/network/p2p" 17 "github.com/onflow/flow-go/network/p2p/distributor" 18 p2pmsg "github.com/onflow/flow-go/network/p2p/message" 19 mockp2p "github.com/onflow/flow-go/network/p2p/mock" 20 "github.com/onflow/flow-go/utils/unittest" 21 ) 22 23 // TestGossipSubInspectorNotification tests the GossipSub inspector notification by adding two consumers to the 24 // notification distributor component and sending a random set of notifications to the notification component. The test 25 // verifies that the consumers receive the notifications. 26 func TestGossipSubInspectorNotification(t *testing.T) { 27 g := distributor.DefaultGossipSubInspectorNotificationDistributor(unittest.Logger()) 28 29 c1 := mockp2p.NewGossipSubInvalidControlMessageNotificationConsumer(t) 30 c2 := mockp2p.NewGossipSubInvalidControlMessageNotificationConsumer(t) 31 32 g.AddConsumer(c1) 33 g.AddConsumer(c2) 34 35 tt := invalidControlMessageNotificationListFixture(t, 100) 36 37 c1Done := sync.WaitGroup{} 38 c1Done.Add(len(tt)) 39 c1Seen := unittest.NewProtectedMap[peer.ID, struct{}]() 40 c1.On("OnInvalidControlMessageNotification", mock.Anything).Run(func(args mock.Arguments) { 41 notification, ok := args.Get(0).(*p2p.InvCtrlMsgNotif) 42 require.True(t, ok) 43 44 require.Contains(t, tt, notification) 45 46 // ensure consumer see each peer once 47 require.False(t, c1Seen.Has(notification.PeerID)) 48 c1Seen.Add(notification.PeerID, struct{}{}) 49 50 c1Done.Done() 51 }).Return() 52 53 c2Done := sync.WaitGroup{} 54 c2Done.Add(len(tt)) 55 c2Seen := unittest.NewProtectedMap[peer.ID, struct{}]() 56 c2.On("OnInvalidControlMessageNotification", mock.Anything).Run(func(args mock.Arguments) { 57 notification, ok := args.Get(0).(*p2p.InvCtrlMsgNotif) 58 require.True(t, ok) 59 60 require.Contains(t, tt, notification) 61 // ensure consumer see each peer once 62 require.False(t, c2Seen.Has(notification.PeerID)) 63 c2Seen.Add(notification.PeerID, struct{}{}) 64 65 c2Done.Done() 66 }).Return() 67 68 cancelCtx, cancel := context.WithCancel(context.Background()) 69 defer cancel() 70 ctx, _ := irrecoverable.WithSignaler(cancelCtx) 71 g.Start(ctx) 72 73 unittest.RequireCloseBefore(t, g.Ready(), 100*time.Millisecond, "could not start distributor") 74 75 for i := 0; i < len(tt); i++ { 76 go func(i int) { 77 require.NoError(t, g.Distribute(tt[i])) 78 }(i) 79 } 80 81 unittest.RequireReturnsBefore(t, c1Done.Wait, 1*time.Second, "events are not received by consumer 1") 82 unittest.RequireReturnsBefore(t, c2Done.Wait, 1*time.Second, "events are not received by consumer 2") 83 cancel() 84 unittest.RequireCloseBefore(t, g.Done(), 100*time.Millisecond, "could not stop distributor") 85 } 86 87 func invalidControlMessageNotificationListFixture(t *testing.T, n int) []*p2p.InvCtrlMsgNotif { 88 list := make([]*p2p.InvCtrlMsgNotif, n) 89 for i := 0; i < n; i++ { 90 list[i] = invalidControlMessageNotificationFixture(t) 91 } 92 return list 93 } 94 95 func invalidControlMessageNotificationFixture(t *testing.T) *p2p.InvCtrlMsgNotif { 96 return &p2p.InvCtrlMsgNotif{ 97 PeerID: unittest.PeerIdFixture(t), 98 MsgType: []p2pmsg.ControlMessageType{p2pmsg.CtrlMsgGraft, p2pmsg.CtrlMsgPrune, p2pmsg.CtrlMsgIHave, p2pmsg.CtrlMsgIWant}[rand.Intn(4)], 99 Error: fmt.Errorf("this is an error"), 100 } 101 }