Skip to content

Commit 7d035ba

Browse files
authored
test: add integration tests for daemon server lifecycle (#5)
Add full-pipeline integration tests covering CLI client -> Unix socket -> server -> PTY -> storage -> read. These are the first tests that exercise the complete data flow end-to-end. - Add setupTestServer helper with temp socket dir and MemoryStorage - Add WithSocketDir server option and NewClientWithSocketPath for testability - TestLifecycle: create -> send -> read -> stop -> read -> kill - TestSearchBoundsValidation: negative before/after produces error (not panic) - TestConcurrentAccess: 5 parallel sessions with send/read - TestPerCursorReads: independent cursor position tracking - TestSessionErrorCases: invalid names, duplicates, nonexistent sessions - Fix data race: remove duplicate cmd.Wait()/proc.Wait() from handleStop and handleKill goroutines (captureOutput already handles process reaping)
1 parent 8813873 commit 7d035ba

File tree

3 files changed

+456
-8
lines changed

3 files changed

+456
-8
lines changed

internal/daemon/client.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,18 @@ import (
1111
"github.com/schovi/shelli/internal/wait"
1212
)
1313

14-
type Client struct{}
14+
type Client struct {
15+
customSocketPath string
16+
}
1517

1618
func NewClient() *Client {
1719
return &Client{}
1820
}
1921

22+
func NewClientWithSocketPath(path string) *Client {
23+
return &Client{customSocketPath: path}
24+
}
25+
2026
func (c *Client) EnsureDaemon() error {
2127
if c.Ping() {
2228
return nil
@@ -425,7 +431,11 @@ func (c *Client) Exec(name string, opts ExecOptions) (*ExecResult, error) {
425431
}
426432

427433
func (c *Client) send(req Request) (*Response, error) {
428-
conn, err := net.Dial("unix", SocketPath())
434+
sockPath := SocketPath()
435+
if c.customSocketPath != "" {
436+
sockPath = c.customSocketPath
437+
}
438+
conn, err := net.Dial("unix", sockPath)
429439
if err != nil {
430440
return nil, err
431441
}

internal/daemon/server.go

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,12 @@ func WithStoppedTTL(ttl time.Duration) ServerOption {
8484
}
8585
}
8686

87+
func WithSocketDir(dir string) ServerOption {
88+
return func(s *Server) {
89+
s.socketDir = dir
90+
}
91+
}
92+
8793
// Deprecated: use WithStorage instead
8894
func WithMaxOutputSize(size int) ServerOption {
8995
return func(s *Server) {
@@ -159,8 +165,12 @@ func SocketPath() string {
159165
return filepath.Join(homeDir, ".shelli", "shelli.sock")
160166
}
161167

168+
func (s *Server) socketPath() string {
169+
return filepath.Join(s.socketDir, "shelli.sock")
170+
}
171+
162172
func (s *Server) Start() error {
163-
sockPath := SocketPath()
173+
sockPath := s.socketPath()
164174
os.Remove(sockPath)
165175

166176
listener, err := net.Listen("unix", sockPath)
@@ -242,7 +252,7 @@ func (s *Server) Shutdown() {
242252
s.listener.Close()
243253
s.listener = nil
244254
}
245-
os.Remove(SocketPath())
255+
os.Remove(s.socketPath())
246256
}
247257

248258
type Request struct {
@@ -834,14 +844,12 @@ func (s *Server) handleStop(req Request) Response {
834844
}
835845

836846
if h.cmd != nil {
837-
cmd := h.cmd
838-
proc := cmd.Process
847+
proc := h.cmd.Process
839848
h.cmd = nil
840849
proc.Signal(syscall.SIGTERM)
841850
go func() {
842851
time.Sleep(KillGracePeriod)
843852
proc.Signal(syscall.SIGKILL)
844-
cmd.Wait()
845853
}()
846854
}
847855
h.frameDetector = nil
@@ -891,7 +899,6 @@ func (s *Server) handleKill(req Request) Response {
891899
proc.Signal(syscall.SIGTERM)
892900
time.Sleep(KillGracePeriod)
893901
proc.Signal(syscall.SIGKILL)
894-
proc.Wait()
895902
}()
896903
}
897904

0 commit comments

Comments
 (0)