yao/agent/robot/executor/standard/executor_test.go
Max add933d34c Refactor Job System Integration to Execution Storage
- 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.
2026-01-22 18:24:50 +08:00

155 lines
4.8 KiB
Go

package standard_test
import (
"context"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/yaoapp/yao/agent/robot/executor/standard"
"github.com/yaoapp/yao/agent/robot/executor/types"
"github.com/yaoapp/yao/agent/robot/store"
robottypes "github.com/yaoapp/yao/agent/robot/types"
"github.com/yaoapp/yao/agent/testutils"
oauthTypes "github.com/yaoapp/yao/openapi/oauth/types"
)
// ============================================================================
// Executor Persistence Integration Tests
// ============================================================================
func TestExecutorPersistence(t *testing.T) {
if testing.Short() {
t.Skip("Skipping integration test")
}
testutils.Prepare(t)
defer testutils.Clean(t)
t.Run("persists_execution_record_on_start", func(t *testing.T) {
ctx := robottypes.NewContext(context.Background(), &oauthTypes.AuthorizedInfo{
UserID: "user_persist_001",
TeamID: "team_persist_001",
})
robot := createPersistenceTestRobot("member_persist_001", "team_persist_001")
// Create executor with persistence enabled
e := standard.NewWithConfig(types.Config{
SkipPersistence: false,
})
// Execute with simulated failure to ensure we get a result
exec, err := e.Execute(ctx, robot, robottypes.TriggerHuman, "simulate_failure")
require.NoError(t, err)
require.NotNil(t, exec)
// Verify execution record was persisted
s := store.NewExecutionStore()
record, err := s.Get(context.Background(), exec.ID)
require.NoError(t, err)
require.NotNil(t, record)
assert.Equal(t, exec.ID, record.ExecutionID)
assert.Equal(t, "member_persist_001", record.MemberID)
assert.Equal(t, "team_persist_001", record.TeamID)
assert.Equal(t, robottypes.TriggerHuman, record.TriggerType)
assert.Equal(t, robottypes.ExecFailed, record.Status)
assert.Equal(t, "simulated failure", record.Error)
// Cleanup
_ = s.Delete(context.Background(), exec.ID)
})
t.Run("persists_failed_status_with_error", func(t *testing.T) {
ctx := robottypes.NewContext(context.Background(), &oauthTypes.AuthorizedInfo{
UserID: "user_persist_002",
TeamID: "team_persist_002",
})
robot := createPersistenceTestRobot("member_persist_002", "team_persist_002")
e := standard.NewWithConfig(types.Config{
SkipPersistence: false,
})
// Execute with simulated failure
exec, err := e.Execute(ctx, robot, robottypes.TriggerHuman, "simulate_failure")
require.NoError(t, err)
require.NotNil(t, exec)
// Verify the record has failed status with error message
s := store.NewExecutionStore()
record, err := s.Get(context.Background(), exec.ID)
require.NoError(t, err)
require.NotNil(t, record)
assert.Equal(t, robottypes.ExecFailed, record.Status)
assert.Equal(t, "simulated failure", record.Error)
assert.NotNil(t, record.StartTime)
// Cleanup
_ = s.Delete(context.Background(), exec.ID)
})
t.Run("skips_persistence_when_disabled", func(t *testing.T) {
ctx := robottypes.NewContext(context.Background(), &oauthTypes.AuthorizedInfo{
UserID: "user_persist_003",
TeamID: "team_persist_003",
})
robot := createPersistenceTestRobot("member_persist_003", "team_persist_003")
// Create executor with persistence disabled
e := standard.NewWithConfig(types.Config{
SkipPersistence: true,
})
exec, err := e.Execute(ctx, robot, robottypes.TriggerHuman, "simulate_failure")
require.NoError(t, err)
require.NotNil(t, exec)
// Verify no record was created
s := store.NewExecutionStore()
record, err := s.Get(context.Background(), exec.ID)
require.NoError(t, err)
assert.Nil(t, record) // Should not exist
})
}
// ============================================================================
// Helper Functions
// ============================================================================
func createPersistenceTestRobot(memberID, teamID string) *robottypes.Robot {
return &robottypes.Robot{
MemberID: memberID,
TeamID: teamID,
DisplayName: "Persistence Test Robot",
Status: robottypes.RobotIdle,
AutonomousMode: true,
Config: &robottypes.Config{
Identity: &robottypes.Identity{
Role: "Test Robot",
Duties: []string{"Testing persistence"},
},
Quota: &robottypes.Quota{
Max: 5,
Queue: 10,
},
Triggers: &robottypes.Triggers{
Intervene: &robottypes.TriggerSwitch{Enabled: true},
},
Resources: &robottypes.Resources{
Phases: map[robottypes.Phase]string{
robottypes.PhaseInspiration: "robot.inspiration",
robottypes.PhaseGoals: "robot.goals",
robottypes.PhaseTasks: "robot.tasks",
robottypes.PhaseRun: "robot.validation",
"validation": "robot.validation",
},
Agents: []string{"experts.text-writer", "experts.data-analyst"},
},
},
}
}