test(muxterm): unit tests for protocol, token validation, and pool
This commit is contained in:
+25
-159
@@ -13,7 +13,7 @@ func TestNewPool(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetEmpty(t *testing.T) {
|
||||
func TestPool_Get_NoSession(t *testing.T) {
|
||||
p := NewPool()
|
||||
s := p.Get("nonexistent")
|
||||
if s != nil {
|
||||
@@ -21,35 +21,37 @@ func TestGetEmpty(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsAliveEmpty(t *testing.T) {
|
||||
func TestPool_IsAlive_NoSession(t *testing.T) {
|
||||
p := NewPool()
|
||||
if p.IsAlive("nonexistent") {
|
||||
t.Fatal("IsAlive on empty pool should return false")
|
||||
}
|
||||
}
|
||||
|
||||
// setupTmuxSession creates a tmux session for testing. Returns a cleanup function.
|
||||
func setupTmuxSession(t *testing.T, name string) func() {
|
||||
t.Helper()
|
||||
// Kill any leftover session with this name
|
||||
func TestPool_CloseAll_Empty(t *testing.T) {
|
||||
p := NewPool()
|
||||
p.CloseAll() // must not panic
|
||||
}
|
||||
|
||||
func TestPool_Attach_Real(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping integration test in short mode")
|
||||
}
|
||||
|
||||
name := "test-muxterm"
|
||||
|
||||
// Ensure the tmux session exists.
|
||||
exec.Command("tmux", "kill-session", "-t", name).Run()
|
||||
cmd := exec.Command("tmux", "new-session", "-d", "-s", name, "-x", "80", "-y", "24")
|
||||
if err := cmd.Run(); err != nil {
|
||||
t.Fatalf("failed to create tmux session %q: %v", name, err)
|
||||
}
|
||||
return func() {
|
||||
exec.Command("tmux", "kill-session", "-t", name).Run()
|
||||
}
|
||||
}
|
||||
|
||||
func TestAttachCreatesSession(t *testing.T) {
|
||||
name := "test-pool-attach"
|
||||
cleanup := setupTmuxSession(t, name)
|
||||
defer cleanup()
|
||||
defer exec.Command("tmux", "kill-session", "-t", name).Run()
|
||||
|
||||
p := NewPool()
|
||||
defer p.CloseAll()
|
||||
|
||||
// Attach
|
||||
sess, err := p.Attach(name, 80, 24)
|
||||
if err != nil {
|
||||
t.Fatalf("Attach failed: %v", err)
|
||||
@@ -60,165 +62,29 @@ func TestAttachCreatesSession(t *testing.T) {
|
||||
if sess.PTY == nil {
|
||||
t.Fatal("Session PTY is nil")
|
||||
}
|
||||
if sess.Cmd == nil {
|
||||
t.Fatal("Session Cmd is nil")
|
||||
}
|
||||
if sess.Cols != 80 {
|
||||
t.Errorf("Cols = %d, want 80", sess.Cols)
|
||||
}
|
||||
if sess.Rows != 24 {
|
||||
t.Errorf("Rows = %d, want 24", sess.Rows)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetReturnsSession(t *testing.T) {
|
||||
name := "test-pool-get"
|
||||
cleanup := setupTmuxSession(t, name)
|
||||
defer cleanup()
|
||||
|
||||
p := NewPool()
|
||||
defer p.CloseAll()
|
||||
|
||||
_, err := p.Attach(name, 80, 24)
|
||||
if err != nil {
|
||||
t.Fatalf("Attach failed: %v", err)
|
||||
}
|
||||
|
||||
sess := p.Get(name)
|
||||
if sess == nil {
|
||||
t.Fatal("Get returned nil after Attach")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsAliveAfterAttach(t *testing.T) {
|
||||
name := "test-pool-alive"
|
||||
cleanup := setupTmuxSession(t, name)
|
||||
defer cleanup()
|
||||
|
||||
p := NewPool()
|
||||
defer p.CloseAll()
|
||||
|
||||
_, err := p.Attach(name, 80, 24)
|
||||
if err != nil {
|
||||
t.Fatalf("Attach failed: %v", err)
|
||||
}
|
||||
|
||||
// IsAlive
|
||||
if !p.IsAlive(name) {
|
||||
t.Fatal("IsAlive should return true after Attach")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAttachReusesLiveSession(t *testing.T) {
|
||||
name := "test-pool-reuse"
|
||||
cleanup := setupTmuxSession(t, name)
|
||||
defer cleanup()
|
||||
|
||||
p := NewPool()
|
||||
defer p.CloseAll()
|
||||
|
||||
sess1, err := p.Attach(name, 80, 24)
|
||||
if err != nil {
|
||||
t.Fatalf("First Attach failed: %v", err)
|
||||
}
|
||||
|
||||
sess2, err := p.Attach(name, 80, 24)
|
||||
if err != nil {
|
||||
t.Fatalf("Second Attach failed: %v", err)
|
||||
}
|
||||
|
||||
if sess1 != sess2 {
|
||||
t.Fatal("Attach should reuse existing live session")
|
||||
}
|
||||
}
|
||||
|
||||
func TestResize(t *testing.T) {
|
||||
name := "test-pool-resize"
|
||||
cleanup := setupTmuxSession(t, name)
|
||||
defer cleanup()
|
||||
|
||||
p := NewPool()
|
||||
defer p.CloseAll()
|
||||
|
||||
_, err := p.Attach(name, 80, 24)
|
||||
if err != nil {
|
||||
t.Fatalf("Attach failed: %v", err)
|
||||
}
|
||||
|
||||
// Resize
|
||||
err = p.Resize(name, 120, 40)
|
||||
if err != nil {
|
||||
t.Fatalf("Resize failed: %v", err)
|
||||
}
|
||||
|
||||
sess := p.Get(name)
|
||||
if sess.Cols != 120 {
|
||||
t.Errorf("After resize Cols = %d, want 120", sess.Cols)
|
||||
resized := p.Get(name)
|
||||
if resized.Cols != 120 {
|
||||
t.Errorf("After resize Cols = %d, want 120", resized.Cols)
|
||||
}
|
||||
if sess.Rows != 40 {
|
||||
t.Errorf("After resize Rows = %d, want 40", sess.Rows)
|
||||
}
|
||||
}
|
||||
|
||||
func TestResizeNonexistent(t *testing.T) {
|
||||
p := NewPool()
|
||||
err := p.Resize("nonexistent", 80, 24)
|
||||
if err == nil {
|
||||
t.Fatal("Resize on nonexistent session should return error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCloseAll(t *testing.T) {
|
||||
name := "test-pool-closeall"
|
||||
cleanup := setupTmuxSession(t, name)
|
||||
defer cleanup()
|
||||
|
||||
p := NewPool()
|
||||
|
||||
_, err := p.Attach(name, 80, 24)
|
||||
if err != nil {
|
||||
t.Fatalf("Attach failed: %v", err)
|
||||
if resized.Rows != 40 {
|
||||
t.Errorf("After resize Rows = %d, want 40", resized.Rows)
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
p.CloseAll()
|
||||
|
||||
// Give the background goroutine time to clean up
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
if p.IsAlive(name) {
|
||||
t.Fatal("IsAlive should return false after CloseAll")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAttachCleansUpDeadSession(t *testing.T) {
|
||||
name := "test-pool-dead-cleanup"
|
||||
cleanup := setupTmuxSession(t, name)
|
||||
defer cleanup()
|
||||
|
||||
p := NewPool()
|
||||
defer p.CloseAll()
|
||||
|
||||
sess1, err := p.Attach(name, 80, 24)
|
||||
if err != nil {
|
||||
t.Fatalf("First Attach failed: %v", err)
|
||||
}
|
||||
|
||||
// Kill the process to simulate a dead session
|
||||
sess1.Cmd.Process.Kill()
|
||||
sess1.Cmd.Process.Wait()
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
// Re-create the tmux session since killing the attach killed our handle
|
||||
exec.Command("tmux", "kill-session", "-t", name).Run()
|
||||
setupCmd := exec.Command("tmux", "new-session", "-d", "-s", name, "-x", "80", "-y", "24")
|
||||
if err := setupCmd.Run(); err != nil {
|
||||
t.Fatalf("failed to recreate tmux session: %v", err)
|
||||
}
|
||||
|
||||
sess2, err := p.Attach(name, 80, 24)
|
||||
if err != nil {
|
||||
t.Fatalf("Second Attach after dead session failed: %v", err)
|
||||
}
|
||||
|
||||
if sess1 == sess2 {
|
||||
t.Fatal("Attach should create new session when old one is dead")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user