aboutsummaryrefslogtreecommitdiffhomepage
path: root/worker/swift/exec_test.go
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-02-16 22:49:07 +0900
committernsfisis <nsfisis@gmail.com>2026-02-16 22:49:07 +0900
commitefe05c1444963c046ab91bf54fa51a794bda58c0 (patch)
tree509b48f27d2e888740bea6bfd6f50895705c7472 /worker/swift/exec_test.go
parentdb87f85aa7055e597800481b8cc6d006c70bcc88 (diff)
downloadphperkaigi-2026-albatross-efe05c1444963c046ab91bf54fa51a794bda58c0.tar.gz
phperkaigi-2026-albatross-efe05c1444963c046ab91bf54fa51a794bda58c0.tar.zst
phperkaigi-2026-albatross-efe05c1444963c046ab91bf54fa51a794bda58c0.zip
test(worker): add unit tests for php and swift workers
Extract testable logic from exec.mjs into lib.mjs (preprocessCode, createIOCallbacks, buildResult) and add vitest tests. Add Go tests for models, exec helpers, and handlers in worker/swift. Update justfiles to include test tasks for local dev and CI. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'worker/swift/exec_test.go')
-rw-r--r--worker/swift/exec_test.go149
1 files changed, 149 insertions, 0 deletions
diff --git a/worker/swift/exec_test.go b/worker/swift/exec_test.go
new file mode 100644
index 0000000..ead2dc6
--- /dev/null
+++ b/worker/swift/exec_test.go
@@ -0,0 +1,149 @@
+package main
+
+import (
+ "context"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "testing"
+ "time"
+)
+
+func TestConvertCommandErrorToResultType(t *testing.T) {
+ tests := []struct {
+ name string
+ err error
+ defaultStatus string
+ want string
+ }{
+ {"nil error returns success", nil, resultRuntimeError, resultSuccess},
+ {"DeadlineExceeded returns timeout", context.DeadlineExceeded, resultRuntimeError, resultTimeout},
+ {"other error returns default status", os.ErrNotExist, resultCompileError, resultCompileError},
+ {"other error returns runtime_error default", os.ErrPermission, resultRuntimeError, resultRuntimeError},
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ got := convertCommandErrorToResultType(tt.err, tt.defaultStatus)
+ if got != tt.want {
+ t.Errorf("convertCommandErrorToResultType() = %q, want %q", got, tt.want)
+ }
+ })
+ }
+}
+
+func TestExecCommandWithTimeout_Success(t *testing.T) {
+ stdout, stderr, err := execCommandWithTimeout(
+ context.Background(),
+ t.TempDir(),
+ 5*time.Second,
+ func(ctx context.Context) *exec.Cmd {
+ return exec.CommandContext(ctx, "echo", "hello")
+ },
+ )
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ if stdout != "hello\n" {
+ t.Errorf("stdout = %q, want %q", stdout, "hello\n")
+ }
+ if stderr != "" {
+ t.Errorf("stderr = %q, want empty", stderr)
+ }
+}
+
+func TestExecCommandWithTimeout_Failure(t *testing.T) {
+ _, _, err := execCommandWithTimeout(
+ context.Background(),
+ t.TempDir(),
+ 5*time.Second,
+ func(ctx context.Context) *exec.Cmd {
+ return exec.CommandContext(ctx, "false")
+ },
+ )
+ if err == nil {
+ t.Fatal("expected error, got nil")
+ }
+}
+
+func TestExecCommandWithTimeout_Timeout(t *testing.T) {
+ _, _, err := execCommandWithTimeout(
+ context.Background(),
+ t.TempDir(),
+ 50*time.Millisecond,
+ func(ctx context.Context) *exec.Cmd {
+ return exec.CommandContext(ctx, "sleep", "10")
+ },
+ )
+ if err != context.DeadlineExceeded {
+ t.Errorf("expected DeadlineExceeded, got %v", err)
+ }
+}
+
+func TestExecCommandWithTimeout_Stderr(t *testing.T) {
+ _, stderr, _ := execCommandWithTimeout(
+ context.Background(),
+ t.TempDir(),
+ 5*time.Second,
+ func(ctx context.Context) *exec.Cmd {
+ return exec.CommandContext(ctx, "sh", "-c", "echo errmsg >&2")
+ },
+ )
+ if stderr != "errmsg\n" {
+ t.Errorf("stderr = %q, want %q", stderr, "errmsg\n")
+ }
+}
+
+func TestPrepareWorkingDir(t *testing.T) {
+ dir := filepath.Join(t.TempDir(), "subdir")
+ res := prepareWorkingDir(dir)
+ if res.Status != resultSuccess {
+ t.Fatalf("prepareWorkingDir() status = %q, want %q", res.Status, resultSuccess)
+ }
+ info, err := os.Stat(dir)
+ if err != nil {
+ t.Fatalf("directory not created: %v", err)
+ }
+ if !info.IsDir() {
+ t.Fatalf("expected directory, got file")
+ }
+}
+
+func TestPutSwiftSourceFile(t *testing.T) {
+ t.Run("writes file when Sources/ exists", func(t *testing.T) {
+ dir := t.TempDir()
+ sourcesDir := filepath.Join(dir, "Sources")
+ if err := os.MkdirAll(sourcesDir, 0755); err != nil {
+ t.Fatalf("failed to create Sources dir: %v", err)
+ }
+ res := putSwiftSourceFile(dir, "print(\"hello\")")
+ if res.Status != resultSuccess {
+ t.Fatalf("putSwiftSourceFile() status = %q, want %q", res.Status, resultSuccess)
+ }
+ content, err := os.ReadFile(filepath.Join(sourcesDir, "main.swift"))
+ if err != nil {
+ t.Fatalf("failed to read file: %v", err)
+ }
+ if string(content) != "print(\"hello\")" {
+ t.Errorf("file content = %q, want %q", string(content), "print(\"hello\")")
+ }
+ })
+
+ t.Run("returns error when Sources/ does not exist", func(t *testing.T) {
+ dir := t.TempDir()
+ res := putSwiftSourceFile(dir, "print(\"hello\")")
+ if res.Status == resultSuccess {
+ t.Fatal("expected error status, got success")
+ }
+ })
+}
+
+func TestRemoveWorkingDir(t *testing.T) {
+ dir := filepath.Join(t.TempDir(), "toremove")
+ if err := os.MkdirAll(dir, 0755); err != nil {
+ t.Fatalf("failed to create dir: %v", err)
+ }
+ removeWorkingDir(dir)
+ if _, err := os.Stat(dir); !os.IsNotExist(err) {
+ t.Errorf("directory still exists after removeWorkingDir")
+ }
+}