Dev starts on pi-native and keeps pi-agent available for a failed turn. Latency tuning stays deferred.
64 lines
2.3 KiB
Go
64 lines
2.3 KiB
Go
package agent
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
type scriptBackend struct {
|
|
name string
|
|
res *Result
|
|
err error
|
|
calls int
|
|
}
|
|
|
|
func (s *scriptBackend) Name() string { return s.name }
|
|
|
|
func (s *scriptBackend) Execute(ctx context.Context, req Request) (*Result, error) {
|
|
s.calls++
|
|
return s.res, s.err
|
|
}
|
|
|
|
func TestFallbackKeepsNativeSuccess(t *testing.T) {
|
|
primary := &scriptBackend{name: "pi-native", res: &Result{Success: true, Logs: "native"}}
|
|
spare := &scriptBackend{name: "pi-agent", res: &Result{Success: true}}
|
|
got, err := (&fallbackBackend{primary: primary, fallback: spare}).Execute(context.Background(), Request{})
|
|
if err != nil || !got.Success || got.Logs != "native" || spare.calls != 0 {
|
|
t.Fatalf("got %#v err=%v spare=%d", got, err, spare.calls)
|
|
}
|
|
}
|
|
|
|
func TestFallbackUsesContainerAfterNativeFailure(t *testing.T) {
|
|
primary := &scriptBackend{name: "pi-native", res: &Result{Success: false, ErrorReason: "missing target deliverable"}}
|
|
spare := &scriptBackend{name: "pi-agent", res: &Result{Success: true, Logs: "container"}}
|
|
got, err := (&fallbackBackend{primary: primary, fallback: spare}).Execute(context.Background(), Request{})
|
|
if err != nil || !got.Success || spare.calls != 1 {
|
|
t.Fatalf("got %#v err=%v calls=%d", got, err, spare.calls)
|
|
}
|
|
if !strings.Contains(got.Logs, "served by pi-agent") || !strings.Contains(got.Logs, "missing target deliverable") {
|
|
t.Fatalf("logs %q", got.Logs)
|
|
}
|
|
}
|
|
|
|
func TestFallbackReturnsNativeWhenContainerAlsoFails(t *testing.T) {
|
|
primary := &scriptBackend{name: "pi-native", err: errors.New("native down")}
|
|
spare := &scriptBackend{name: "pi-agent", res: &Result{Success: false, ErrorReason: "runner down"}}
|
|
got, err := (&fallbackBackend{primary: primary, fallback: spare}).Execute(context.Background(), Request{})
|
|
if err == nil || err.Error() != "native down" || got != nil || spare.calls != 1 {
|
|
t.Fatalf("got %#v err=%v", got, err)
|
|
}
|
|
}
|
|
|
|
func TestFallbackStopsWhenContextCancelled(t *testing.T) {
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
cancel()
|
|
primary := &scriptBackend{name: "pi-native", err: context.Canceled}
|
|
spare := &scriptBackend{name: "pi-agent", res: &Result{Success: true}}
|
|
_, err := (&fallbackBackend{primary: primary, fallback: spare}).Execute(ctx, Request{})
|
|
if !errors.Is(err, context.Canceled) || spare.calls != 0 {
|
|
t.Fatalf("err=%v spare=%d", err, spare.calls)
|
|
}
|
|
}
|