Fix PTY workdir and process group teardown
This commit is contained in:
84
internal/pty/pty_test.go
Normal file
84
internal/pty/pty_test.go
Normal file
@@ -0,0 +1,84 @@
|
||||
package pty
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestStartUsesWorkDir(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
p, err := Start([]string{"sh", "-c", "pwd"}, nil, dir, 80, 24)
|
||||
if err != nil {
|
||||
t.Fatalf("Start: %v", err)
|
||||
}
|
||||
defer p.Close()
|
||||
|
||||
var out bytes.Buffer
|
||||
buf := make([]byte, 256)
|
||||
deadline := time.Now().Add(5 * time.Second)
|
||||
for time.Now().Before(deadline) {
|
||||
n, err := p.Read(buf)
|
||||
if n > 0 {
|
||||
out.Write(buf[:n])
|
||||
if strings.Contains(out.String(), dir) {
|
||||
break
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
_ = p.Wait()
|
||||
|
||||
if got := strings.TrimSpace(out.String()); got != dir {
|
||||
t.Fatalf("pwd output = %q, want %q", got, dir)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCloseKillsProcessGroup(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
pidFile := filepath.Join(dir, "sleep.pid")
|
||||
env := append(os.Environ(), "PIDFILE="+pidFile)
|
||||
p, err := Start([]string{"sh", "-c", "sleep 30 & echo $! > \"$PIDFILE\"; wait"}, env, "", 80, 24)
|
||||
if err != nil {
|
||||
t.Fatalf("Start: %v", err)
|
||||
}
|
||||
deadline := time.Now().Add(5 * time.Second)
|
||||
var childPID int
|
||||
for time.Now().Before(deadline) {
|
||||
b, err := os.ReadFile(pidFile)
|
||||
if err == nil {
|
||||
childPID, _ = strconv.Atoi(strings.TrimSpace(string(b)))
|
||||
if childPID > 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
time.Sleep(20 * time.Millisecond)
|
||||
}
|
||||
if childPID <= 0 {
|
||||
_ = p.Close()
|
||||
t.Fatalf("background child pid was not written")
|
||||
}
|
||||
|
||||
if err := p.Close(); err != nil {
|
||||
t.Fatalf("Close: %v", err)
|
||||
}
|
||||
_ = p.Wait()
|
||||
|
||||
deadline = time.Now().Add(5 * time.Second)
|
||||
for time.Now().Before(deadline) {
|
||||
err := syscall.Kill(childPID, 0)
|
||||
if errors.Is(err, syscall.ESRCH) {
|
||||
return
|
||||
}
|
||||
time.Sleep(20 * time.Millisecond)
|
||||
}
|
||||
t.Fatalf("background child pid %d still exists after PTY.Close", childPID)
|
||||
}
|
||||
Reference in New Issue
Block a user