go-process/program_test.go
Codex d86f9abc29 fix(go-process): replace testify with stdlib testing patterns (AX-6)
Removes testify + davecgh/go-spew + pmezard/go-difflib from go.mod;
rewrites assert/require calls across 13 _test.go files
(buffer/daemon/errors/exec/global/health/pidfile/process/program/
registry/runner/service + pkg/api/provider) to stdlib t.Fatalf
patterns. go vet + go test all clean (GOWORK=off).

Closes tasks.lthn.sh/view.php?id=719

Co-authored-by: Codex <noreply@openai.com>
Via-codex-lane: Cyclops-719 dispatch (haiku forwarder, ~17min lane)
2026-04-24 18:03:24 +01:00

186 lines
4.2 KiB
Go

package process_test
import (
"context"
"errors"
"os/exec"
"path/filepath"
"testing"
"time"
process "dappco.re/go/core/process"
)
func testCtx(t *testing.T) context.Context {
t.Helper()
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
t.Cleanup(cancel)
return ctx
}
func TestProgram_Find_KnownBinary(t *testing.T) {
p := &process.Program{Name: "echo"}
if err := p.Find(); err != nil {
t.Fatalf("unexpected error: %v", err)
}
if p.Path == "" {
t.Fatal("expected non-empty path")
}
}
func TestProgram_Find_UnknownBinary(t *testing.T) {
p := &process.Program{Name: "no-such-binary-xyzzy-42"}
err := p.Find()
if err == nil {
t.Fatal("expected error, got nil")
}
if !errors.Is(err, process.ErrProgramNotFound) {
t.Fatalf("expected ErrProgramNotFound, got %v", err)
}
}
func TestProgram_Find_UsesExistingPath(t *testing.T) {
path, err := exec.LookPath("echo")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
p := &process.Program{Path: path}
if err := p.Find(); err != nil {
t.Fatalf("unexpected error: %v", err)
}
if p.Path != path {
t.Fatalf("want %v, got %v", path, p.Path)
}
}
func TestProgram_Find_PrefersExistingPathOverName(t *testing.T) {
path, err := exec.LookPath("echo")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
p := &process.Program{
Name: "no-such-binary-xyzzy-42",
Path: path,
}
if err := p.Find(); err != nil {
t.Fatalf("unexpected error: %v", err)
}
if p.Path != path {
t.Fatalf("want %v, got %v", path, p.Path)
}
}
func TestProgram_Find_EmptyName(t *testing.T) {
p := &process.Program{}
if err := p.Find(); err == nil {
t.Fatal("expected error, got nil")
}
}
func TestProgram_Run_ReturnsOutput(t *testing.T) {
p := &process.Program{Name: "echo"}
if err := p.Find(); err != nil {
t.Fatalf("unexpected error: %v", err)
}
out, err := p.Run(testCtx(t), "hello")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if out != "hello" {
t.Fatalf("want %q, got %q", "hello", out)
}
}
func TestProgram_Run_PreservesLeadingWhitespace(t *testing.T) {
p := &process.Program{Name: "sh"}
if err := p.Find(); err != nil {
t.Fatalf("unexpected error: %v", err)
}
out, err := p.Run(testCtx(t), "-c", "printf ' hello \n'")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if out != " hello" {
t.Fatalf("want %q, got %q", " hello", out)
}
}
func TestProgram_Run_WithoutFind_FallsBackToName(t *testing.T) {
// Path is empty; RunDir should fall back to Name for OS PATH resolution.
p := &process.Program{Name: "echo"}
out, err := p.Run(testCtx(t), "fallback")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if out != "fallback" {
t.Fatalf("want %q, got %q", "fallback", out)
}
}
func TestProgram_RunDir_UsesDirectory(t *testing.T) {
p := &process.Program{Name: "pwd"}
if err := p.Find(); err != nil {
t.Fatalf("unexpected error: %v", err)
}
dir := t.TempDir()
out, err := p.RunDir(testCtx(t), dir)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
// Resolve symlinks on both sides for portability (macOS uses /private/ prefix).
canonicalDir, err := filepath.EvalSymlinks(dir)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
canonicalOut, err := filepath.EvalSymlinks(out)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if canonicalDir != canonicalOut {
t.Fatalf("want %q, got %q", canonicalDir, canonicalOut)
}
}
func TestProgram_Run_FailingCommand(t *testing.T) {
p := &process.Program{Name: "false"}
if err := p.Find(); err != nil {
t.Fatalf("unexpected error: %v", err)
}
_, err := p.Run(testCtx(t))
if err == nil {
t.Fatal("expected error, got nil")
}
}
func TestProgram_Run_NilContextRejected(t *testing.T) {
p := &process.Program{Name: "echo"}
_, err := p.Run(nil, "test")
if err == nil {
t.Fatal("expected error, got nil")
}
if !errors.Is(err, process.ErrProgramContextRequired) {
t.Fatalf("expected ErrProgramContextRequired, got %v", err)
}
}
func TestProgram_RunDir_EmptyNameRejected(t *testing.T) {
p := &process.Program{}
_, err := p.RunDir(testCtx(t), "", "test")
if err == nil {
t.Fatal("expected error, got nil")
}
if !errors.Is(err, process.ErrProgramNameRequired) {
t.Fatalf("expected ErrProgramNameRequired, got %v", err)
}
}