@@ -373,9 +373,12 @@ func TestAgent_Session_TTY_FastCommandHasOutput(t *testing.T) {
373
373
374
374
var stdout bytes.Buffer
375
375
// NOTE(mafredri): Increase iterations to increase chance of failure,
376
- // assuming bug is present.
376
+ // assuming bug is present. Limiting GOMAXPROCS further
377
+ // increases the chance of failure.
377
378
// Using 1000 iterations is basically a guaranteed failure (but let's
378
379
// not increase test times needlessly).
380
+ // Limit GOMAXPROCS (e.g. `export GOMAXPROCS=1`) to further increase
381
+ // chance of failure. Also -race helps.
379
382
for i := 0 ; i < 5 ; i ++ {
380
383
func () {
381
384
stdout .Reset ()
@@ -399,6 +402,63 @@ func TestAgent_Session_TTY_FastCommandHasOutput(t *testing.T) {
399
402
}
400
403
}
401
404
405
+ func TestAgent_Session_TTY_HugeOutputIsNotLost (t * testing.T ) {
406
+ t .Parallel ()
407
+ if runtime .GOOS == "windows" {
408
+ // This might be our implementation, or ConPTY itself.
409
+ // It's difficult to find extensive tests for it, so
410
+ // it seems like it could be either.
411
+ t .Skip ("ConPTY appears to be inconsistent on Windows." )
412
+ }
413
+ t .Skip ("This test proves we have a bug where parts of large output on a PTY can be lost after the command exits, skipped to avoid test failures." )
414
+
415
+ // This test is here to prevent prove we have a bug where quickly executing
416
+ // commands (with TTY) don't flush their output to the SSH session. This is
417
+ // due to the pty being closed before all the output has been copied, but
418
+ // protecting against this requires a non-trivial rewrite of the output
419
+ // processing (or figuring out a way to put the pty in a mode where this
420
+ // does not happen).
421
+ ctx , cancel := context .WithTimeout (context .Background (), testutil .WaitLong )
422
+ defer cancel ()
423
+ //nolint:dogsled
424
+ conn , _ , _ , _ , _ := setupAgent (t , agentsdk.Metadata {}, 0 )
425
+ sshClient , err := conn .SSHClient (ctx )
426
+ require .NoError (t , err )
427
+ defer sshClient .Close ()
428
+
429
+ ptty := ptytest .New (t )
430
+
431
+ var stdout bytes.Buffer
432
+ // NOTE(mafredri): Increase iterations to increase chance of failure,
433
+ // assuming bug is present.
434
+ // Using 10 iterations is basically a guaranteed failure (but let's
435
+ // not increase test times needlessly). Run with -race and do not
436
+ // limit parallelism (`export GOMAXPROCS=10`) to increase the chance
437
+ // of failure.
438
+ for i := 0 ; i < 1 ; i ++ {
439
+ func () {
440
+ stdout .Reset ()
441
+
442
+ session , err := sshClient .NewSession ()
443
+ require .NoError (t , err )
444
+ defer session .Close ()
445
+ err = session .RequestPty ("xterm" , 128 , 128 , ssh.TerminalModes {})
446
+ require .NoError (t , err )
447
+
448
+ session .Stdout = & stdout
449
+ session .Stderr = ptty .Output ()
450
+ session .Stdin = ptty .Input ()
451
+ want := strings .Repeat ("wazzup" , 1024 + 1 ) // ~6KB, +1 because 1024 is a common buffer size.
452
+ err = session .Start ("echo " + want )
453
+ require .NoError (t , err )
454
+
455
+ err = session .Wait ()
456
+ require .NoError (t , err )
457
+ require .Contains (t , stdout .String (), want , "should output entire greeting" )
458
+ }()
459
+ }
460
+ }
461
+
402
462
//nolint:paralleltest // This test reserves a port.
403
463
func TestAgent_TCPLocalForwarding (t * testing.T ) {
404
464
random , err := net .Listen ("tcp" , "127.0.0.1:0" )
0 commit comments