yao/agent/robot/executor/executor_test.go
Max de4df27364 Enhance Executor Stub Implementation and Update TODO.md
- Marked the Executor Stub Enhancement section in TODO.md as complete, detailing the enhancements made to the executor's functionality.
- Improved the Executor to simulate full execution with Job integration, including phase transitions and logging.
- Introduced a Config struct for customizable executor behavior, allowing for testing with callbacks and job integration control.
- Implemented phase-specific methods for modular execution, preparing for future real phase implementations.
- Added comprehensive tests for the executor, including smoke tests and verification of phase progression and job logs.
- Updated progress tracking in TODO.md to reflect the current status of the executor and integration testing.
2026-01-15 16:46:58 +08:00

126 lines
3.7 KiB
Go

package executor
import (
"context"
"testing"
"github.com/stretchr/testify/assert"
"github.com/yaoapp/yao/agent/robot/types"
)
// Smoke tests to verify basic flow works
// These tests use SkipJobIntegration=true to avoid DB dependencies
// Real integration tests are in manager_test.go and job_test.go
func TestExecutorSmoke(t *testing.T) {
exec := NewWithDelay(0)
robot := &types.Robot{
MemberID: "test-smoke",
TeamID: "team-1",
Config: &types.Config{Quota: &types.Quota{Max: 1}},
}
ctx := types.NewContext(context.Background(), nil)
result, err := exec.Execute(ctx, robot, types.TriggerClock, nil)
assert.NoError(t, err)
assert.NotNil(t, result)
assert.Equal(t, types.ExecCompleted, result.Status)
assert.Equal(t, types.TriggerClock, result.TriggerType)
// Clock trigger executes all phases (P0-P5)
assert.NotNil(t, result.Inspiration, "P0 should be executed for clock trigger")
assert.NotNil(t, result.Goals, "P1 should be executed")
assert.NotEmpty(t, result.Tasks, "P2 should generate tasks")
assert.NotEmpty(t, result.Results, "P3 should generate results")
assert.NotNil(t, result.Delivery, "P4 should be executed")
assert.NotEmpty(t, result.Learning, "P5 should be executed")
}
func TestExecutorHumanTriggerSkipsP0(t *testing.T) {
exec := NewWithDelay(0)
robot := &types.Robot{
MemberID: "test-human",
TeamID: "team-1",
Config: &types.Config{Quota: &types.Quota{Max: 1}},
}
ctx := types.NewContext(context.Background(), nil)
result, err := exec.Execute(ctx, robot, types.TriggerHuman, nil)
assert.NoError(t, err)
assert.NotNil(t, result)
assert.Equal(t, types.ExecCompleted, result.Status)
// Human trigger skips P0 (Inspiration)
assert.Nil(t, result.Inspiration, "P0 should be skipped for human trigger")
assert.NotNil(t, result.Goals, "P1 should be executed")
}
func TestExecutorEventTriggerSkipsP0(t *testing.T) {
exec := NewWithDelay(0)
robot := &types.Robot{
MemberID: "test-event",
TeamID: "team-1",
Config: &types.Config{Quota: &types.Quota{Max: 1}},
}
ctx := types.NewContext(context.Background(), nil)
result, err := exec.Execute(ctx, robot, types.TriggerEvent, nil)
assert.NoError(t, err)
assert.Nil(t, result.Inspiration, "P0 should be skipped for event trigger")
assert.NotNil(t, result.Goals)
}
func TestExecutorNilRobot(t *testing.T) {
exec := NewWithDelay(0)
ctx := types.NewContext(context.Background(), nil)
result, err := exec.Execute(ctx, nil, types.TriggerClock, nil)
assert.Error(t, err)
assert.Nil(t, result)
assert.Contains(t, err.Error(), "robot cannot be nil")
}
func TestExecutorSimulatedFailure(t *testing.T) {
exec := NewWithDelay(0)
robot := &types.Robot{
MemberID: "test-fail",
TeamID: "team-1",
Config: &types.Config{Quota: &types.Quota{Max: 1}},
}
ctx := types.NewContext(context.Background(), nil)
// Pass "simulate_failure" to trigger simulated failure
result, err := exec.Execute(ctx, robot, types.TriggerClock, "simulate_failure")
assert.NoError(t, err) // Execute returns nil error, failure is in result
assert.NotNil(t, result)
assert.Equal(t, types.ExecFailed, result.Status)
assert.Equal(t, "simulated failure", result.Error)
}
func TestExecutorCounters(t *testing.T) {
exec := NewWithDelay(0)
robot := &types.Robot{
MemberID: "test-counter",
TeamID: "team-1",
Config: &types.Config{Quota: &types.Quota{Max: 10}},
}
ctx := types.NewContext(context.Background(), nil)
assert.Equal(t, 0, exec.ExecCount())
assert.Equal(t, 0, exec.CurrentCount())
_, _ = exec.Execute(ctx, robot, types.TriggerClock, nil)
assert.Equal(t, 1, exec.ExecCount())
assert.Equal(t, 0, exec.CurrentCount()) // Completed, so 0
_, _ = exec.Execute(ctx, robot, types.TriggerClock, nil)
assert.Equal(t, 2, exec.ExecCount())
exec.Reset()
assert.Equal(t, 0, exec.ExecCount())
}