mirror of
https://github.com/boshu2/agentops.git
synced 2026-09-14 15:08:13 +08:00
test(daemon): add factory local pilot rehearsal
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
@@ -495,6 +496,106 @@ func TestAgentOpsDaemonFakeExecutorPolicyClaimsFactoryAdmissionJob(t *testing.T)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAgentOpsDaemonFakeFactoryLocalPilotHandoffCompletesChildRPI(t *testing.T) {
|
||||
cwd := t.TempDir()
|
||||
headSHA := initDaemonFactoryGitRepo(t, cwd)
|
||||
now := time.Date(2026, 5, 5, 2, 30, 0, 0, time.UTC)
|
||||
store := daemonpkg.NewStore(cwd)
|
||||
queue := daemonpkg.NewQueue(store, daemonpkg.QueueOptions{LeaseDuration: time.Minute})
|
||||
work := daemonpkg.FactoryWorkOrder{
|
||||
SchemaVersion: daemonpkg.FactoryAdmissionJobSpecSchemaVersion,
|
||||
WorkOrderID: "factory-l3-rehearsal",
|
||||
GeneratedAt: now.Add(-10 * time.Minute).Format(time.RFC3339),
|
||||
ExpiresAt: now.Add(time.Hour).Format(time.RFC3339),
|
||||
BaseSHA: headSHA,
|
||||
Target: daemonpkg.FactoryTarget{
|
||||
Type: daemonpkg.FactoryTargetBead,
|
||||
ID: "soc-ff7b.7",
|
||||
Summary: "Exercise daemon factory local pilot handoff",
|
||||
},
|
||||
AllowedFiles: []string{
|
||||
"cli/internal/daemon/factory_admission_executor.go",
|
||||
},
|
||||
ValidationCommands: []string{
|
||||
"cd cli && go test ./internal/daemon -run FactoryAdmission",
|
||||
},
|
||||
LandingPolicy: daemonpkg.FactoryLandingPolicyManualPR,
|
||||
DigestPolicy: daemonpkg.FactoryDigestPolicyRequired,
|
||||
OpenPRBlockers: []daemonpkg.FactoryOpenPRBlocker{},
|
||||
UnknownEvidencePolicy: daemonpkg.FactoryUnknownEvidenceBlock,
|
||||
MainCIBaseline: daemonpkg.FactoryMainCIBaseline{
|
||||
Status: daemonpkg.FactoryCIStatusGreen,
|
||||
RunID: "25352104726",
|
||||
CheckedAt: now.Add(-15 * time.Minute).Format(time.RFC3339),
|
||||
FailedJobs: []string{},
|
||||
},
|
||||
}
|
||||
spec := daemonpkg.NewFactoryLocalPilotJobSpec("factory-l3-run", work)
|
||||
spec.Mode = daemonpkg.FactoryAdmissionModeRPIHandoff
|
||||
spec.Handoff = daemonpkg.FactoryHandoff{
|
||||
Kind: daemonpkg.FactoryHandoffRPI,
|
||||
ExecutionPacketPath: ".agents/rpi/runs/factory-l3-run/execution-packet.json",
|
||||
EpicID: "soc-ff7b.7",
|
||||
}
|
||||
jobSpec, err := spec.ToJobSpec("job-factory-l3")
|
||||
if err != nil {
|
||||
t.Fatalf("factory local pilot spec: %v", err)
|
||||
}
|
||||
if _, err := queue.SubmitJob(daemonpkg.SubmitJobInput{
|
||||
RequestID: "req-factory-l3",
|
||||
JobID: jobSpec.ID,
|
||||
JobType: jobSpec.Type,
|
||||
Payload: jobSpec.Payload,
|
||||
}, daemonpkg.QueueMutationOptions{}); err != nil {
|
||||
t.Fatalf("submit factory local pilot: %v", err)
|
||||
}
|
||||
|
||||
supervisor, err := buildAgentOpsDaemonSupervisor(cwd, agentopsDaemonRunOptions{
|
||||
ExecutorPolicy: "fake",
|
||||
Now: func() time.Time { return now },
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("build supervisor: %v", err)
|
||||
}
|
||||
admissionResult, err := supervisor.RunOnce(context.Background())
|
||||
if err != nil {
|
||||
t.Fatalf("run factory admission: %v", err)
|
||||
}
|
||||
if !admissionResult.Claimed || admissionResult.Job.Status != daemonpkg.JobStatusCompleted {
|
||||
t.Fatalf("admission result = %#v, want completed factory.local-pilot", admissionResult)
|
||||
}
|
||||
childJobID := admissionResult.Job.Artifacts["child_job_id"]
|
||||
if childJobID == "" {
|
||||
t.Fatalf("admission artifacts = %#v, want child_job_id", admissionResult.Job.Artifacts)
|
||||
}
|
||||
|
||||
childResult, err := supervisor.RunOnce(context.Background())
|
||||
if err != nil {
|
||||
t.Fatalf("run child rpi job: %v", err)
|
||||
}
|
||||
if !childResult.Claimed || childResult.Job.JobID != childJobID || childResult.Job.Status != daemonpkg.JobStatusCompleted {
|
||||
t.Fatalf("child result = %#v, want completed child rpi job %s", childResult, childJobID)
|
||||
}
|
||||
if got := childResult.Job.Artifacts["executor_policy"]; got != "fake" {
|
||||
t.Fatalf("child executor_policy = %q, want fake", got)
|
||||
}
|
||||
|
||||
projections, err := store.RebuildProjections(daemonpkg.ProjectionRebuildOptions{RebuiltAt: now})
|
||||
if err != nil {
|
||||
t.Fatalf("rebuild projections: %v", err)
|
||||
}
|
||||
if len(projections.Factory.Admissions) != 1 {
|
||||
t.Fatalf("admissions = %#v, want one admission", projections.Factory.Admissions)
|
||||
}
|
||||
admission := projections.Factory.Admissions[0]
|
||||
if !admission.Allowed || admission.ChildJobID != childJobID {
|
||||
t.Fatalf("admission projection = %#v, want allowed child handoff", admission)
|
||||
}
|
||||
if len(projections.Jobs) != 2 {
|
||||
t.Fatalf("queue projection jobs = %#v, want parent and child jobs", projections.Jobs)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAgentOpsDaemonFakeExecutorPolicyRoutesDreamRunJob(t *testing.T) {
|
||||
cwd := t.TempDir()
|
||||
queue := daemonpkg.NewQueue(daemonpkg.NewStore(cwd), daemonpkg.QueueOptions{LeaseDuration: time.Minute})
|
||||
@@ -670,6 +771,38 @@ func TestAgentOpsDaemonPlansProjectionExecutorRegistration(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func initDaemonFactoryGitRepo(t *testing.T, cwd string) string {
|
||||
t.Helper()
|
||||
runDaemonFactoryGit(t, cwd, "init", "-q")
|
||||
runDaemonFactoryGit(t, cwd, "config", "user.email", "test@example.com")
|
||||
runDaemonFactoryGit(t, cwd, "config", "user.name", "Test")
|
||||
if err := os.WriteFile(filepath.Join(cwd, "README.md"), []byte("factory rehearsal\n"), 0o644); err != nil {
|
||||
t.Fatalf("write README: %v", err)
|
||||
}
|
||||
if err := os.WriteFile(filepath.Join(cwd, ".gitignore"), []byte(".agents/\n"), 0o644); err != nil {
|
||||
t.Fatalf("write .gitignore: %v", err)
|
||||
}
|
||||
runDaemonFactoryGit(t, cwd, "add", "README.md", ".gitignore")
|
||||
runDaemonFactoryGit(t, cwd, "commit", "-q", "-m", "init")
|
||||
return strings.TrimSpace(runDaemonFactoryGitOutput(t, cwd, "rev-parse", "HEAD"))
|
||||
}
|
||||
|
||||
func runDaemonFactoryGit(t *testing.T, cwd string, args ...string) {
|
||||
t.Helper()
|
||||
_ = runDaemonFactoryGitOutput(t, cwd, args...)
|
||||
}
|
||||
|
||||
func runDaemonFactoryGitOutput(t *testing.T, cwd string, args ...string) string {
|
||||
t.Helper()
|
||||
cmd := exec.Command("git", args...)
|
||||
cmd.Dir = cwd
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
t.Fatalf("git %v: %v\n%s", args, err, out)
|
||||
}
|
||||
return string(out)
|
||||
}
|
||||
|
||||
func TestProviderOverrideWikiForgeWorkerForcesCLIFallback(t *testing.T) {
|
||||
inner := &recordingWikiForgeWorker{}
|
||||
worker := providerOverrideWikiForgeWorker{
|
||||
|
||||
@@ -86,6 +86,25 @@ Expected readback:
|
||||
- `projections.factory.admissions[]` contains the decision;
|
||||
- artifact paths point under `.agents/daemon/factory/runs/<run_id>/`.
|
||||
|
||||
## Fake L3 Rehearsal
|
||||
|
||||
The daemon-native no-merge rehearsal is covered by a local fake-policy test:
|
||||
|
||||
```bash
|
||||
cd cli && go test ./cmd/ao -run TestAgentOpsDaemonFakeFactoryLocalPilotHandoffCompletesChildRPI
|
||||
```
|
||||
|
||||
That test initializes a real git worktree, submits a `factory.local-pilot` job,
|
||||
runs the daemon supervisor twice, and verifies the sequence:
|
||||
|
||||
- admission allows the work order;
|
||||
- the parent job emits `child_job_id`;
|
||||
- the child `rpi.run` completes under the fake RPI executor;
|
||||
- the factory projection records the allowed admission and child handoff.
|
||||
|
||||
This is the current L3 gate before enabling recurring host scheduling for
|
||||
source-mutating factory work.
|
||||
|
||||
## Schedule Shape
|
||||
|
||||
Schedules can run the same path by materializing a `factory.local-pilot`
|
||||
|
||||
Reference in New Issue
Block a user