mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-08-15 07:30:53 +02:00
117 lines
3.2 KiB
Go
117 lines
3.2 KiB
Go
package multiagent
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"sync/atomic"
|
|
"testing"
|
|
|
|
"github.com/cloudwego/eino/adk"
|
|
)
|
|
|
|
type fakeRunnerControl struct {
|
|
runMessages []adk.Message
|
|
runOpts int
|
|
resumeID string
|
|
resumeOpts int
|
|
resumeErr error
|
|
}
|
|
|
|
func (f *fakeRunnerControl) Run(_ context.Context, messages []adk.Message, opts ...adk.AgentRunOption) *adk.AsyncIterator[*adk.AgentEvent] {
|
|
f.runMessages = messages
|
|
f.runOpts = len(opts)
|
|
iter, gen := adk.NewAsyncIteratorPair[*adk.AgentEvent]()
|
|
gen.Close()
|
|
return iter
|
|
}
|
|
|
|
func (f *fakeRunnerControl) Resume(_ context.Context, checkPointID string, opts ...adk.AgentRunOption) (*adk.AsyncIterator[*adk.AgentEvent], error) {
|
|
f.resumeID = checkPointID
|
|
f.resumeOpts = len(opts)
|
|
iter, gen := adk.NewAsyncIteratorPair[*adk.AgentEvent]()
|
|
gen.Close()
|
|
return iter, f.resumeErr
|
|
}
|
|
|
|
func TestEinoRunnerIteratorStarterStartAddsCancelAndCheckpoint(t *testing.T) {
|
|
runner := &fakeRunnerControl{}
|
|
var cancelPush func(error) bool
|
|
var nativeCancelCause atomic.Value
|
|
oldUnregistered := false
|
|
newUnregistered := false
|
|
unregister := func() { oldUnregistered = true }
|
|
|
|
iter := newEinoRunnerIteratorStarter(einoRunnerIteratorStarterConfig{
|
|
Context: context.Background(),
|
|
Runner: runner,
|
|
CheckPointID: "cp-1",
|
|
NativeCancelCause: &nativeCancelCause,
|
|
UnregisterAgentCancel: &unregister,
|
|
RuntimeCancelRegistrar: func(push func(error) bool) func() {
|
|
cancelPush = push
|
|
return func() { newUnregistered = true }
|
|
},
|
|
}).Start([]adk.Message{})
|
|
|
|
if iter == nil {
|
|
t.Fatal("iterator should be created")
|
|
}
|
|
if runner.runOpts != 2 {
|
|
t.Fatalf("run opts = %d, want cancel + checkpoint", runner.runOpts)
|
|
}
|
|
if !oldUnregistered {
|
|
t.Fatal("old unregister should be called before binding a new cancel hook")
|
|
}
|
|
if cancelPush == nil {
|
|
t.Fatal("cancel hook should be registered")
|
|
}
|
|
stopErr := errors.New("stop")
|
|
if cancelPush(stopErr) {
|
|
t.Fatal("unbound fake runner cancel should not report handled")
|
|
}
|
|
if got, _ := nativeCancelCause.Load().(error); !errors.Is(got, stopErr) {
|
|
t.Fatalf("native cancel cause = %v, want %v", got, stopErr)
|
|
}
|
|
unregister()
|
|
if !newUnregistered {
|
|
t.Fatal("new unregister should replace old unregister")
|
|
}
|
|
}
|
|
|
|
func TestEinoRunnerIteratorStarterResumeUsesCancelOnly(t *testing.T) {
|
|
runner := &fakeRunnerControl{}
|
|
|
|
iter, err := newEinoRunnerIteratorStarter(einoRunnerIteratorStarterConfig{
|
|
Context: context.Background(),
|
|
Runner: runner,
|
|
CheckPointID: "fresh-run-checkpoint",
|
|
}).Resume("resume-cp")
|
|
|
|
if err != nil {
|
|
t.Fatalf("resume err = %v", err)
|
|
}
|
|
if iter == nil {
|
|
t.Fatal("iterator should be created")
|
|
}
|
|
if runner.resumeID != "resume-cp" {
|
|
t.Fatalf("resume id = %q, want resume-cp", runner.resumeID)
|
|
}
|
|
if runner.resumeOpts != 1 {
|
|
t.Fatalf("resume opts = %d, want cancel only", runner.resumeOpts)
|
|
}
|
|
}
|
|
|
|
func TestEinoRunnerIteratorStarterResumePropagatesError(t *testing.T) {
|
|
resumeErr := errors.New("resume failed")
|
|
runner := &fakeRunnerControl{resumeErr: resumeErr}
|
|
|
|
_, err := newEinoRunnerIteratorStarter(einoRunnerIteratorStarterConfig{
|
|
Context: context.Background(),
|
|
Runner: runner,
|
|
}).Resume("resume-cp")
|
|
|
|
if !errors.Is(err, resumeErr) {
|
|
t.Fatalf("resume err = %v, want %v", err, resumeErr)
|
|
}
|
|
}
|