@@ -406,6 +406,101 @@ func TestMultiNode_selectNode(t *testing.T) {
406406 })
407407}
408408
409+ func TestMultiNode_RandomRPC (t * testing.T ) {
410+ t .Parallel ()
411+ t .Run ("RandomRPC disables lease check" , func (t * testing.T ) {
412+ t .Parallel ()
413+ chainID := RandomID ()
414+ node := newHealthyNode (t , chainID )
415+ lggr , observedLogs := logger .TestObserved (t , zap .InfoLevel )
416+ mn := newTestMultiNode (t , multiNodeOpts {
417+ selectionMode : NodeSelectionModeRandomRPC ,
418+ chainID : chainID ,
419+ logger : lggr ,
420+ nodes : []Node [ID , multiNodeRPCClient ]{node },
421+ })
422+ servicetest .Run (t , mn )
423+ tests .RequireLogMessage (t , observedLogs , "Best node switching is disabled" )
424+ })
425+ t .Run ("RandomRPC is non-sticky, calls Select on every invocation" , func (t * testing.T ) {
426+ t .Parallel ()
427+ ctx := t .Context ()
428+ chainID := RandomID ()
429+ node1 := newMockNode [ID , multiNodeRPCClient ](t )
430+ node1 .On ("State" ).Return (nodeStateAlive ).Maybe ()
431+ node1 .On ("String" ).Return ("node1" ).Maybe ()
432+ node2 := newMockNode [ID , multiNodeRPCClient ](t )
433+ node2 .On ("State" ).Return (nodeStateAlive ).Maybe ()
434+ node2 .On ("String" ).Return ("node2" ).Maybe ()
435+ mn := newTestMultiNode (t , multiNodeOpts {
436+ selectionMode : NodeSelectionModeRandomRPC ,
437+ chainID : chainID ,
438+ nodes : []Node [ID , multiNodeRPCClient ]{node1 , node2 },
439+ })
440+ nodeSelector := newMockNodeSelector [ID , multiNodeRPCClient ](t )
441+ nodeSelector .On ("Select" ).Return (node1 ).Once ()
442+ nodeSelector .On ("Select" ).Return (node2 ).Once ()
443+ mn .nodeSelector = nodeSelector
444+
445+ first , err := mn .selectNode (ctx )
446+ require .NoError (t , err )
447+ assert .Same (t , node1 , first )
448+
449+ second , err := mn .selectNode (ctx )
450+ require .NoError (t , err )
451+ assert .Same (t , node2 , second )
452+ })
453+ t .Run ("RandomRPC does not unsubscribe previous node on selection" , func (t * testing.T ) {
454+ t .Parallel ()
455+ ctx := t .Context ()
456+ chainID := RandomID ()
457+ node1 := newMockNode [ID , multiNodeRPCClient ](t )
458+ node1 .On ("State" ).Return (nodeStateAlive ).Maybe ()
459+ node1 .On ("String" ).Return ("node1" ).Maybe ()
460+ node2 := newMockNode [ID , multiNodeRPCClient ](t )
461+ node2 .On ("State" ).Return (nodeStateAlive ).Maybe ()
462+ node2 .On ("String" ).Return ("node2" ).Maybe ()
463+ mn := newTestMultiNode (t , multiNodeOpts {
464+ selectionMode : NodeSelectionModeRandomRPC ,
465+ chainID : chainID ,
466+ nodes : []Node [ID , multiNodeRPCClient ]{node1 , node2 },
467+ })
468+ nodeSelector := newMockNodeSelector [ID , multiNodeRPCClient ](t )
469+ nodeSelector .On ("Select" ).Return (node1 ).Once ()
470+ nodeSelector .On ("Select" ).Return (node2 ).Once ()
471+ mn .nodeSelector = nodeSelector
472+
473+ _ , err := mn .selectNode (ctx )
474+ require .NoError (t , err )
475+ _ , err = mn .selectNode (ctx )
476+ require .NoError (t , err )
477+
478+ // UnsubscribeAllExceptAliveLoop must NOT have been called on either node.
479+ // mockNode would fail the test if an unexpected call was made.
480+ node1 .AssertNotCalled (t , "UnsubscribeAllExceptAliveLoop" )
481+ node2 .AssertNotCalled (t , "UnsubscribeAllExceptAliveLoop" )
482+ })
483+ t .Run ("RandomRPC reports error when no nodes available" , func (t * testing.T ) {
484+ t .Parallel ()
485+ ctx := t .Context ()
486+ chainID := RandomID ()
487+ lggr , observedLogs := logger .TestObserved (t , zap .InfoLevel )
488+ mn := newTestMultiNode (t , multiNodeOpts {
489+ selectionMode : NodeSelectionModeRandomRPC ,
490+ chainID : chainID ,
491+ logger : lggr ,
492+ })
493+ nodeSelector := newMockNodeSelector [ID , multiNodeRPCClient ](t )
494+ nodeSelector .On ("Select" ).Return (nil ).Once ()
495+ nodeSelector .On ("Name" ).Return ("MockedNodeSelector" ).Once ()
496+ mn .nodeSelector = nodeSelector
497+ node , err := mn .selectNode (ctx )
498+ require .EqualError (t , err , ErrNodeError .Error ())
499+ require .Nil (t , node )
500+ tests .RequireLogMessage (t , observedLogs , "No live RPC nodes available" )
501+ })
502+ }
503+
409504func TestMultiNode_ChainInfo (t * testing.T ) {
410505 t .Parallel ()
411506 type nodeParams struct {
0 commit comments