summaryrefslogtreecommitdiff
path: root/internal/executor/executor_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/executor/executor_test.go')
-rw-r--r--internal/executor/executor_test.go63
1 files changed, 53 insertions, 10 deletions
diff --git a/internal/executor/executor_test.go b/internal/executor/executor_test.go
index 0935545..9448816 100644
--- a/internal/executor/executor_test.go
+++ b/internal/executor/executor_test.go
@@ -116,6 +116,48 @@ func makeTask(id string) *task.Task {
}
}
+func TestPickAgent_PrefersLessActiveAgent(t *testing.T) {
+ status := SystemStatus{
+ ActiveTasks: map[string]int{"claude": 3, "gemini": 1},
+ RateLimited: map[string]bool{"claude": false, "gemini": false},
+ }
+ if got := pickAgent(status); got != "gemini" {
+ t.Errorf("expected gemini (fewer active tasks), got %s", got)
+ }
+}
+
+func TestPickAgent_SkipsRateLimitedAgent(t *testing.T) {
+ status := SystemStatus{
+ ActiveTasks: map[string]int{"claude": 0, "gemini": 5},
+ RateLimited: map[string]bool{"claude": true, "gemini": false},
+ }
+ if got := pickAgent(status); got != "gemini" {
+ t.Errorf("expected gemini (claude rate limited), got %s", got)
+ }
+}
+
+func TestPickAgent_FallsBackWhenAllRateLimited(t *testing.T) {
+ status := SystemStatus{
+ ActiveTasks: map[string]int{"claude": 2, "gemini": 5},
+ RateLimited: map[string]bool{"claude": true, "gemini": true},
+ }
+ // Falls back to least active regardless of rate limit.
+ if got := pickAgent(status); got != "claude" {
+ t.Errorf("expected claude (fewer active tasks among all), got %s", got)
+ }
+}
+
+func TestPickAgent_TieBreakPrefersFirstAlpha(t *testing.T) {
+ status := SystemStatus{
+ ActiveTasks: map[string]int{"claude": 2, "gemini": 2},
+ RateLimited: map[string]bool{"claude": false, "gemini": false},
+ }
+ got := pickAgent(status)
+ if got != "claude" && got != "gemini" {
+ t.Errorf("unexpected agent %q on tie", got)
+ }
+}
+
func TestPool_Submit_TopLevel_GoesToReady(t *testing.T) {
store := testStore(t)
runner := &mockRunner{}
@@ -995,13 +1037,17 @@ func TestHandleRunResult_SharedPath(t *testing.T) {
})
}
-func TestPool_UnsupportedAgent(t *testing.T) {
+// TestPool_LoadBalancing_OverridesAgentType verifies that load balancing picks
+// from registered runners, overriding any pre-set Agent.Type on the task.
+func TestPool_LoadBalancing_OverridesAgentType(t *testing.T) {
store := testStore(t)
- runners := map[string]Runner{"claude": &mockRunner{}}
+ runner := &mockRunner{}
+ runners := map[string]Runner{"claude": runner}
logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelError}))
pool := NewPool(2, runners, store, logger)
- tk := makeTask("bad-agent")
+ // Task has a non-existent agent type; load balancing should route to "claude".
+ tk := makeTask("lb-override")
tk.Agent.Type = "super-ai"
store.CreateTask(tk)
@@ -1010,13 +1056,10 @@ func TestPool_UnsupportedAgent(t *testing.T) {
}
result := <-pool.Results()
- if result.Err == nil {
- t.Fatal("expected error for unsupported agent")
- }
- if !strings.Contains(result.Err.Error(), "unsupported agent type") {
- t.Errorf("expected 'unsupported agent type' in error, got: %v", result.Err)
+ if result.Err != nil {
+ t.Fatalf("expected success (load balancing overrides agent type), got: %v", result.Err)
}
- if result.Execution.Status != "FAILED" {
- t.Errorf("status: want FAILED, got %q", result.Execution.Status)
+ if runner.callCount() != 1 {
+ t.Errorf("expected claude runner to be called once, got %d", runner.callCount())
}
}