- Removed the job system integration from the robot execution flow, transitioning to a dedicated ExecutionStore for managing execution records. - Updated the design documentation to reflect the new architecture, emphasizing the relationship between robots and concurrent executions. - Revised the API to return execution IDs instead of job IDs, ensuring clarity in execution tracking. - Enhanced logging mechanisms to utilize the kun/log package for better traceability of execution phases. - Updated tests and documentation to align with the removal of job-related structures and the introduction of execution management.
125 lines
3.7 KiB
Go
125 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
|
|
// Real integration tests are in manager_test.go
|
|
|
|
func TestExecutorSmoke(t *testing.T) {
|
|
exec := NewDryRunWithDelay(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 := NewDryRunWithDelay(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 := NewDryRunWithDelay(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 := NewDryRunWithDelay(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 := NewDryRunWithDelay(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 := NewDryRunWithDelay(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())
|
|
}
|