alt/services/worker/internal/jobs/runner_test.go
toki f762d2abd9 feat: worker persistence layer and socket session updates
- Add worker storage layer with PostgreSQL/sqlc setup
- Add migration files for worker backbone schema
- Add job runner and built-in jobs implementation
- Add Redis key definitions for worker state management
- Archive socket-session-loop milestone (completed/renamed)
- Update roadmap current.md and foundation-alignment phase
- Add socket endpoint integration and runtime smoke tests
- Add infra-check, worker-storage-check, worker-storage-gen CLI tools
- Update API socket server and config
- Add pubspec dependencies and client socket endpoint changes
- Add config tests for API and worker services
2026-05-28 19:05:10 +09:00

110 lines
2.4 KiB
Go

package jobs
import (
"context"
"encoding/json"
"errors"
"testing"
)
func TestRunnerDispatchesRegisteredHandler(t *testing.T) {
runner := NewRunner()
called := false
var receivedPayload json.RawMessage
testKind := Kind("test_job")
runner.Register(testKind, func(ctx context.Context, payload json.RawMessage) error {
called = true
receivedPayload = payload
return nil
})
job := Job{
ID: "job-1",
Kind: testKind,
Payload: json.RawMessage(`{"key":"value"}`),
}
err := runner.Execute(context.Background(), job)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if !called {
t.Error("expected handler to be called, but it was not")
}
if string(receivedPayload) != `{"key":"value"}` {
t.Errorf("expected payload %q, got %q", `{"key":"value"}`, string(receivedPayload))
}
}
func TestRunnerRejectsUnknownKind(t *testing.T) {
runner := NewRunner()
job := Job{
ID: "job-2",
Kind: Kind("non_existent"),
}
err := runner.Execute(context.Background(), job)
if err == nil {
t.Fatal("expected error for unknown job kind, got nil")
}
}
func TestRunnerRespectsCanceledContext(t *testing.T) {
runner := NewRunner()
testKind := Kind("cancellation_test")
runner.Register(testKind, func(ctx context.Context, payload json.RawMessage) error {
return nil
})
ctx, cancel := context.WithCancel(context.Background())
cancel() // Cancel context immediately
job := Job{
ID: "job-3",
Kind: testKind,
}
err := runner.Execute(ctx, job)
if err == nil {
t.Fatal("expected error due to canceled context, got nil")
}
if !errors.Is(err, context.Canceled) {
t.Errorf("expected error %v, got %v", context.Canceled, err)
}
}
func TestRunnerHandlesPanic(t *testing.T) {
runner := NewRunner()
panicKind := Kind("panic_job")
runner.Register(panicKind, func(ctx context.Context, payload json.RawMessage) error {
panic("something went critically wrong")
})
job := Job{
ID: "job-4",
Kind: panicKind,
}
err := runner.Execute(context.Background(), job)
if err == nil {
t.Fatal("expected error from panic recovery, got nil")
}
if err.Error() != "job panicked: something went critically wrong" {
t.Errorf("unexpected error message: %v", err)
}
}
func TestRegisterBuiltins(t *testing.T) {
runner := NewRunner()
RegisterBuiltins(runner)
expectedCount := 3
if runner.Len() != expectedCount {
t.Errorf("expected %d registered built-in handlers, got %d", expectedCount, runner.Len())
}
}