Major changes: - Add internal/logging package with field constants, context propagation, sensitive data auto-redaction, and per-component log levels - Add worker timeout constants (TimeoutQuickOp, TimeoutHealthCheck, etc.) - Extend SDLC with callback handlers, generate endpoints, and executor - Add new cookbook trees for aeries and slackpath progression - Add skeleton templates for queue, realtime, and microservices - Add worker component template with async job processing - Refactor services and handlers to use new logging infrastructure - Split component.go into component_infra.go and component_listing.go Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
158 lines
3.9 KiB
Go
158 lines
3.9 KiB
Go
package worker
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/orchard9/rdev/internal/domain"
|
|
)
|
|
|
|
func TestSDLCTaskExecutor_ParseSpec(t *testing.T) {
|
|
exec := NewSDLCTaskExecutor(SDLCTaskExecutorConfig{
|
|
Namespace: "rdev",
|
|
})
|
|
|
|
t.Run("valid spec", func(t *testing.T) {
|
|
spec, err := exec.parseSpec(map[string]any{
|
|
"command": "feature-create",
|
|
"args": []any{"auth-flow", "--title", "Authentication Flow"},
|
|
"git_clone_url": "https://git.example.com/owner/repo.git",
|
|
"auto_commit": true,
|
|
"auto_push": true,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("parseSpec() error = %v", err)
|
|
}
|
|
if spec.Command != "feature-create" {
|
|
t.Errorf("got command %q, want %q", spec.Command, "feature-create")
|
|
}
|
|
if len(spec.Args) != 3 {
|
|
t.Errorf("got %d args, want 3", len(spec.Args))
|
|
}
|
|
if spec.GitCloneURL != "https://git.example.com/owner/repo.git" {
|
|
t.Errorf("got git_clone_url %q", spec.GitCloneURL)
|
|
}
|
|
if !spec.AutoCommit {
|
|
t.Error("expected auto_commit = true")
|
|
}
|
|
if !spec.AutoPush {
|
|
t.Error("expected auto_push = true")
|
|
}
|
|
})
|
|
|
|
t.Run("missing command", func(t *testing.T) {
|
|
_, err := exec.parseSpec(map[string]any{
|
|
"git_clone_url": "https://git.example.com/owner/repo.git",
|
|
})
|
|
if err == nil {
|
|
t.Error("expected error for missing command")
|
|
}
|
|
})
|
|
|
|
t.Run("missing git_clone_url", func(t *testing.T) {
|
|
_, err := exec.parseSpec(map[string]any{
|
|
"command": "feature-create",
|
|
})
|
|
if err == nil {
|
|
t.Error("expected error for missing git_clone_url")
|
|
}
|
|
})
|
|
|
|
t.Run("args as string slice", func(t *testing.T) {
|
|
spec, err := exec.parseSpec(map[string]any{
|
|
"command": "feature-create",
|
|
"args": []string{"arg1", "arg2"},
|
|
"git_clone_url": "https://git.example.com/owner/repo.git",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("parseSpec() error = %v", err)
|
|
}
|
|
if len(spec.Args) != 2 {
|
|
t.Errorf("got %d args, want 2", len(spec.Args))
|
|
}
|
|
})
|
|
|
|
t.Run("empty args", func(t *testing.T) {
|
|
spec, err := exec.parseSpec(map[string]any{
|
|
"command": "state",
|
|
"git_clone_url": "https://git.example.com/owner/repo.git",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("parseSpec() error = %v", err)
|
|
}
|
|
if len(spec.Args) != 0 {
|
|
t.Errorf("got %d args, want 0", len(spec.Args))
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestSDLCTaskExecutor_Execute_NoPodGitOps(t *testing.T) {
|
|
exec := NewSDLCTaskExecutor(SDLCTaskExecutorConfig{
|
|
Namespace: "rdev",
|
|
PodGitOps: nil, // No git operations configured
|
|
})
|
|
|
|
task := &domain.WorkTask{
|
|
ID: "task-1",
|
|
ProjectID: "project-1",
|
|
Type: domain.WorkTaskTypeSDLC,
|
|
Spec: map[string]any{
|
|
"command": "feature-create",
|
|
"args": []any{"auth-flow"},
|
|
"git_clone_url": "https://git.example.com/owner/repo.git",
|
|
},
|
|
CreatedAt: time.Now(),
|
|
}
|
|
|
|
result := exec.Execute(context.Background(), task)
|
|
if result.Success {
|
|
t.Error("expected failure when pod git operations not configured")
|
|
}
|
|
if result.Error == "" {
|
|
t.Error("expected error message")
|
|
}
|
|
}
|
|
|
|
func TestSDLCTaskExecutor_Execute_InvalidSpec(t *testing.T) {
|
|
exec := NewSDLCTaskExecutor(SDLCTaskExecutorConfig{
|
|
Namespace: "rdev",
|
|
})
|
|
|
|
task := &domain.WorkTask{
|
|
ID: "task-1",
|
|
ProjectID: "project-1",
|
|
Type: domain.WorkTaskTypeSDLC,
|
|
Spec: map[string]any{
|
|
// Missing required fields
|
|
},
|
|
CreatedAt: time.Now(),
|
|
}
|
|
|
|
result := exec.Execute(context.Background(), task)
|
|
if result.Success {
|
|
t.Error("expected failure for invalid spec")
|
|
}
|
|
if result.Error == "" {
|
|
t.Error("expected error message for invalid spec")
|
|
}
|
|
}
|
|
|
|
func TestSDLCTaskSpec_Valid(t *testing.T) {
|
|
// Verify the domain type is valid
|
|
spec := domain.SDLCTaskSpec{
|
|
Command: "feature-create",
|
|
Args: []string{"auth-flow", "--title", "Auth Flow"},
|
|
GitCloneURL: "https://git.example.com/owner/repo.git",
|
|
AutoCommit: true,
|
|
AutoPush: true,
|
|
}
|
|
|
|
if spec.Command == "" {
|
|
t.Error("command should not be empty")
|
|
}
|
|
if len(spec.Args) != 3 {
|
|
t.Errorf("got %d args, want 3", len(spec.Args))
|
|
}
|
|
}
|