Skip to content

Commit fba59da

Browse files
committed
test: keep negative keepalive replies alive
1 parent 54d6671 commit fba59da

1 file changed

Lines changed: 28 additions & 13 deletions

File tree

‎server_test.go‎

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -373,12 +373,14 @@ func TestConnectionKeepAliveUsesChannelRequestWhenSessionOpen(t *testing.T) {
373373
}
374374
}
375375

376-
// TestConnectionKeepAliveNegativeGlobalReplyDoesNotReset verifies that a
377-
// protocol-level negative response is not counted as a successful keepalive.
378-
func TestConnectionKeepAliveNegativeGlobalReplyDoesNotReset(t *testing.T) {
376+
// TestConnectionKeepAliveNegativeGlobalReplyKeepsAlive verifies OpenSSH-style
377+
// keepalive semantics: a protocol-level failure reply still proves that the
378+
// peer received and processed the request, so it resets the liveness deadline.
379+
func TestConnectionKeepAliveNegativeGlobalReplyKeepsAlive(t *testing.T) {
379380
t.Parallel()
380381

381382
closingFired := make(chan struct{})
383+
var globalCount atomic.Int64
382384
srv := &Server{
383385
Handler: func(_ Session) {},
384386
ClientAliveInterval: 100 * time.Millisecond,
@@ -414,26 +416,34 @@ func TestConnectionKeepAliveNegativeGlobalReplyDoesNotReset(t *testing.T) {
414416
go func() {
415417
for req := range reqs {
416418
if req.Type == keepAliveRequestType {
419+
globalCount.Add(1)
417420
_ = req.Reply(false, nil)
418421
} else if req.WantReply {
419422
_ = req.Reply(true, nil)
420423
}
421424
}
422425
}()
423426

427+
// The configured timeout is 200ms. Negative replies must keep the
428+
// transport alive well beyond that window.
424429
select {
425430
case <-closingFired:
426-
case <-time.After(5 * time.Second):
427-
t.Fatal("negative global keepalive replies incorrectly reset the deadline")
431+
t.Fatal("negative global keepalive reply did not preserve liveness")
432+
case <-time.After(700 * time.Millisecond):
433+
}
434+
if got := globalCount.Load(); got < 2 {
435+
t.Fatalf("expected multiple negative global keepalive replies, got %d", got)
428436
}
429437
}
430438

431-
// TestConnectionKeepAliveNegativeChannelReplyDoesNotReset is the channel
432-
// request counterpart to TestConnectionKeepAliveNegativeGlobalReplyDoesNotReset.
433-
func TestConnectionKeepAliveNegativeChannelReplyDoesNotReset(t *testing.T) {
439+
// TestConnectionKeepAliveNegativeChannelReplyKeepsAlive is the channel
440+
// counterpart to TestConnectionKeepAliveNegativeGlobalReplyKeepsAlive. A
441+
// negative channel reply proves liveness and must not trigger global fallback.
442+
func TestConnectionKeepAliveNegativeChannelReplyKeepsAlive(t *testing.T) {
434443
t.Parallel()
435444

436445
closingFired := make(chan struct{})
446+
var globalCount, channelCount atomic.Int64
437447
srv := &Server{
438448
Handler: func(s Session) { <-s.Context().Done() },
439449
ClientAliveInterval: 100 * time.Millisecond,
@@ -466,7 +476,6 @@ func TestConnectionKeepAliveNegativeChannelReplyDoesNotReset(t *testing.T) {
466476
for range chans { //nolint:revive // intentional drain
467477
}
468478
}()
469-
var globalCount atomic.Int64
470479
go func() {
471480
for req := range reqs {
472481
if req.Type == keepAliveRequestType {
@@ -486,20 +495,26 @@ func TestConnectionKeepAliveNegativeChannelReplyDoesNotReset(t *testing.T) {
486495
go func() {
487496
for req := range chReqs {
488497
if req.Type == keepAliveRequestType {
498+
channelCount.Add(1)
489499
_ = req.Reply(false, nil)
490500
} else if req.WantReply {
491501
_ = req.Reply(true, nil)
492502
}
493503
}
494504
}()
495505

506+
// The configured timeout is 200ms. Repeated negative channel replies
507+
// must keep the connection alive and must not cause a global fallback.
496508
select {
497509
case <-closingFired:
498-
case <-time.After(5 * time.Second):
499-
t.Fatal("negative channel keepalive replies incorrectly reset the deadline")
510+
t.Fatal("negative channel keepalive reply did not preserve liveness")
511+
case <-time.After(700 * time.Millisecond):
500512
}
501-
if globalCount.Load() == 0 {
502-
t.Fatal("negative channel keepalive reply did not fall back to a global request")
513+
if got := channelCount.Load(); got < 2 {
514+
t.Fatalf("expected multiple negative channel keepalive replies, got %d", got)
515+
}
516+
if got := globalCount.Load(); got != 0 {
517+
t.Fatalf("negative channel replies unexpectedly triggered %d global keepalives", got)
503518
}
504519
}
505520

0 commit comments

Comments
 (0)