- add finalize-task-routing skill with policy and test scripts - add execution target selection scripts and tests for orchestrate-agent-task-loop - add quota probe adapter and CLI status for node app - update plan, finalize-task-routing, and orchestration skill files - add agent-task archive for runtime target selector - update stream-evidence-gate-core milestone
123 lines
4.4 KiB
Go
123 lines
4.4 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"strings"
|
|
"testing"
|
|
|
|
"iop/apps/node/internal/adapters/cli/status"
|
|
"iop/packages/go/config"
|
|
)
|
|
|
|
func TestQuotaProbeCommandEmitsSelectorCompatibleSnapshot(t *testing.T) {
|
|
original := quotaCheckUsage
|
|
t.Cleanup(func() { quotaCheckUsage = original })
|
|
quotaCheckUsage = func(_ context.Context, target string, profile config.CLIProfileConf) (*status.UsageStatus, error) {
|
|
if target != "Gemini 3.6 Flash Medium" || profile.Command != "agy" {
|
|
t.Fatalf("checker input = target=%q command=%q", target, profile.Command)
|
|
}
|
|
return &status.UsageStatus{DailyLimit: "25%", RawOutput: "secret provider output"}, nil
|
|
}
|
|
|
|
root := rootCmd()
|
|
var out bytes.Buffer
|
|
root.SetOut(&out)
|
|
root.SetErr(&out)
|
|
root.SetArgs([]string{"quota-probe", "--target", "Gemini 3.6 Flash Medium", "--command", "agy", "--required-cap", "overall", "--checked-at", "2026-07-25T08:00:00Z"})
|
|
if err := root.Execute(); err != nil {
|
|
t.Fatalf("execute: %v\n%s", err, out.String())
|
|
}
|
|
var snapshot status.QuotaSnapshot
|
|
if err := json.Unmarshal(out.Bytes(), &snapshot); err != nil {
|
|
t.Fatalf("decode JSON: %v\n%s", err, out.String())
|
|
}
|
|
if got := snapshot.Targets; len(got) != 1 || got[0].Adapter != "agy" || got[0].Target != "Gemini 3.6 Flash Medium" || got[0].Status != "available" {
|
|
t.Fatalf("selector target entry = %#v", got)
|
|
}
|
|
if strings.Contains(out.String(), "secret provider output") {
|
|
t.Fatalf("raw checker output leaked: %s", out.String())
|
|
}
|
|
}
|
|
|
|
func TestQuotaProbeCommandReturnsUnknownForCheckerError(t *testing.T) {
|
|
original := quotaCheckUsage
|
|
t.Cleanup(func() { quotaCheckUsage = original })
|
|
quotaCheckUsage = func(context.Context, string, config.CLIProfileConf) (*status.UsageStatus, error) {
|
|
return nil, errors.New("provider stderr must not leak")
|
|
}
|
|
root := rootCmd()
|
|
var out bytes.Buffer
|
|
root.SetOut(&out)
|
|
root.SetErr(&out)
|
|
root.SetArgs([]string{"quota-probe", "--target", "sonnet", "--command", "claude", "--required-cap", "overall", "--checked-at", "2026-07-25T08:00:00Z"})
|
|
if err := root.Execute(); err != nil {
|
|
t.Fatalf("execute: %v\n%s", err, out.String())
|
|
}
|
|
if strings.Contains(out.String(), "provider stderr") {
|
|
t.Fatalf("checker error leaked: %s", out.String())
|
|
}
|
|
var snapshot status.QuotaSnapshot
|
|
if err := json.Unmarshal(out.Bytes(), &snapshot); err != nil {
|
|
t.Fatalf("decode JSON: %v", err)
|
|
}
|
|
if snapshot.Targets[0].Status != "unknown" || len(snapshot.ReasonCodes) != 1 || snapshot.ReasonCodes[0] != "checker_error" {
|
|
t.Fatalf("snapshot = %#v", snapshot)
|
|
}
|
|
}
|
|
|
|
func TestQuotaProbeCommandRejectsInvalidCaps(t *testing.T) {
|
|
root := rootCmd()
|
|
var out bytes.Buffer
|
|
root.SetOut(&out)
|
|
root.SetErr(&out)
|
|
root.SetArgs([]string{"quota-probe", "--target", "sonnet", "--command", "claude", "--required-cap", "weekly"})
|
|
if err := root.Execute(); err == nil || !strings.Contains(err.Error(), "invalid required cap") {
|
|
t.Fatalf("error = %v, output=%s", err, out.String())
|
|
}
|
|
}
|
|
|
|
func TestQuotaProbeCommandRejectsEmptyTargetAndCommand(t *testing.T) {
|
|
original := quotaCheckUsage
|
|
t.Cleanup(func() { quotaCheckUsage = original })
|
|
checkerCalled := false
|
|
quotaCheckUsage = func(context.Context, string, config.CLIProfileConf) (*status.UsageStatus, error) {
|
|
checkerCalled = true
|
|
return nil, nil
|
|
}
|
|
|
|
for name, args := range map[string][]string{
|
|
"empty_target": {"quota-probe", "--target=", "--command", "claude", "--required-cap", "overall"},
|
|
"whitespace_target": {"quota-probe", "--target", " \t ", "--command", "claude", "--required-cap", "overall"},
|
|
"empty_command": {"quota-probe", "--target", "sonnet", "--command=", "--required-cap", "overall"},
|
|
"whitespace_command": {"quota-probe", "--target", "sonnet", "--command", " \t ", "--required-cap", "overall"},
|
|
} {
|
|
t.Run(name, func(t *testing.T) {
|
|
checkerCalled = false
|
|
root := rootCmd()
|
|
var out bytes.Buffer
|
|
root.SetOut(&out)
|
|
root.SetErr(&out)
|
|
root.SetArgs(args)
|
|
if err := root.Execute(); err == nil || !strings.Contains(err.Error(), "must be non-empty") {
|
|
t.Fatalf("error = %v, output=%s", err, out.String())
|
|
}
|
|
if checkerCalled {
|
|
t.Fatal("checker must not run for empty identity input")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestQuotaProbeCommandIsHidden(t *testing.T) {
|
|
root := rootCmd()
|
|
probe, _, err := root.Find([]string{"quota-probe"})
|
|
if err != nil {
|
|
t.Fatalf("find quota-probe: %v", err)
|
|
}
|
|
if !probe.Hidden {
|
|
t.Fatal("quota-probe must be hidden")
|
|
}
|
|
}
|