@@ -10,12 +10,13 @@ import (
10
10
11
11
"github.com/fortytw2/leaktest"
12
12
"github.com/jackc/pgx/v4/pgxpool"
13
+ "gopkg.in/check.v1"
14
+
13
15
"github.com/rstudio/platform-lib/pkg/rselection"
14
16
"github.com/rstudio/platform-lib/pkg/rselection/electiontypes"
15
17
"github.com/rstudio/platform-lib/pkg/rsnotify/broadcaster"
16
18
"github.com/rstudio/platform-lib/pkg/rsnotify/listener"
17
19
"github.com/rstudio/platform-lib/pkg/rsnotify/listeners/postgrespgx"
18
- "gopkg.in/check.v1"
19
20
)
20
21
21
22
type fakeTaskHandler struct {
@@ -363,6 +364,84 @@ func (s *LeaderSuite) TestPingNodes(c *check.C) {
363
364
c .Check (leader .unsuccessfulPing (), check .Equals , true )
364
365
}
365
366
367
+ func (s * LeaderSuite ) TestLeaderPingSelf (c * check.C ) {
368
+ defer leaktest .Check (c )
369
+
370
+ channel := c .TestName ()
371
+ // Use a real notifier to send the Ping Request notification.
372
+ realNotifier := & PgxPgNotifier {pool : s .pool }
373
+ // Use a fake notifier to record the Ping Response notification.
374
+ fakeNotifier := & dummyNotifier {}
375
+ matcher := listener .NewMatcher ("MessageType" )
376
+ matcher .Register (electiontypes .ClusterMessageTypePingResponse , & electiontypes.ClusterPingResponse {})
377
+ matcher .Register (electiontypes .ClusterMessageTypePing , & electiontypes.ClusterPingRequest {})
378
+ matcher .Register (electiontypes .ClusterMessageTypeNodes , & electiontypes.ClusterNodesNotification {})
379
+ plf := postgrespgx .NewPgxListener (postgrespgx.PgxListenerArgs {
380
+ Name : channel + "_leader" ,
381
+ Pool : s .pool ,
382
+ Matcher : matcher ,
383
+ IpReporter : & listener.TestIPReporter {Ip : "192.168.5.11" },
384
+ })
385
+ defer plf .Stop ()
386
+ awbStop := make (chan bool )
387
+ awb , err := broadcaster .NewNotificationBroadcaster (plf , awbStop )
388
+ c .Assert (err , check .IsNil )
389
+ defer func () {
390
+ awbStop <- true
391
+ }()
392
+ stop := make (chan bool )
393
+
394
+ pingCh := make (chan bool )
395
+ defer close (pingCh )
396
+
397
+ leader := & PgxLeader {
398
+ awb : awb ,
399
+ notify : fakeNotifier ,
400
+ chLeader : "leader" ,
401
+ chFollower : "follower" ,
402
+ address : "leader" ,
403
+ stop : stop ,
404
+ nodes : map [string ]* electiontypes.ClusterNode {},
405
+ pingResponseChTEST : pingCh ,
406
+ taskHandler : & fakeTaskHandler {},
407
+ debugLogger : & fakeLogger {},
408
+ traceLogger : & fakeLogger {},
409
+ }
410
+
411
+ // Notified when leader exits
412
+ done := make (chan struct {})
413
+ go func () {
414
+ defer close (done )
415
+ leader .lead (nil , nil , stop )
416
+ }()
417
+
418
+ // Receive notification from self
419
+ msgBytes , err := json .Marshal (& electiontypes.ClusterPingRequest {
420
+ ClusterNotification : electiontypes.ClusterNotification {
421
+ GuidVal : "65db0d7d-8db1-4fa8-bc2a-58fad248507f" ,
422
+ MessageType : electiontypes .ClusterMessageTypePing ,
423
+ SrcAddr : "leader" ,
424
+ },
425
+ })
426
+ c .Assert (err , check .IsNil )
427
+
428
+ now := time .Now ()
429
+ wait (pingCh , func () {
430
+ err = realNotifier .Notify (channel + "_leader" , msgBytes )
431
+ c .Assert (err , check .IsNil )
432
+ })
433
+ c .Assert (len (leader .nodes ), check .Equals , 1 )
434
+ node , ok := leader .nodes ["leader_192.168.5.11" ]
435
+ c .Assert (ok , check .Equals , true )
436
+ c .Assert (node .Ping .After (now ), check .Equals , true )
437
+
438
+ // Stop
439
+ close (stop )
440
+
441
+ // Wait for exit
442
+ <- done
443
+ }
444
+
366
445
func (s * LeaderSuite ) TestLeaderDemotion (c * check.C ) {
367
446
defer leaktest .Check (c )
368
447
0 commit comments