ci / vet-and-test (pull_request) Successful in 42s
Why: The implementation commit left two files unformatted; keep the tree gofmt-clean. Evidence: gofmt -l now empty; targeted test still green. Impact: Formatting only. Refs: Follow-up to the wiring commit.
58 lines
1.9 KiB
Go
58 lines
1.9 KiB
Go
package app
|
||
|
||
import (
|
||
"context"
|
||
"path/filepath"
|
||
"testing"
|
||
|
||
"agent-system-backend/internal/rag"
|
||
"agent-system-backend/internal/settings"
|
||
"agent-system-backend/internal/store"
|
||
"agent-system-backend/pkg/extension"
|
||
)
|
||
|
||
// EXT-11 红测:注入前 NewScopedHost fail-closed;注入后重建句柄与分发期同构
|
||
// (owner 作用域、PluginID、KV 隔离、知识删除前缀强制)。
|
||
func TestScopedHostFactory(t *testing.T) {
|
||
// 注入前:fail-closed。
|
||
if _, err := extension.NewScopedHost("alice", "rdm"); err == nil {
|
||
t.Fatal("before wiring, NewScopedHost must fail closed(工厂未注入)")
|
||
}
|
||
|
||
st, err := store.OpenSQLite(filepath.Join(t.TempDir(), "t.db"))
|
||
if err != nil {
|
||
t.Fatal(err)
|
||
}
|
||
t.Cleanup(func() { st.Close() })
|
||
set := settings.NewService(st)
|
||
pipe := rag.NewPipeline(st, set, nil, nil)
|
||
caps := hostcaps{st: st, pipe: pipe, set: set}
|
||
|
||
// 组合根同款注入(app.Run 内以 wireScopedHostFactory 接线;此处直接调内部函数)。
|
||
wireScopedHostFactory(caps)
|
||
t.Cleanup(func() { extension.SetScopedHostFactory(nil) })
|
||
|
||
h, err := extension.NewScopedHost("alice", "rdm")
|
||
if err != nil {
|
||
t.Fatalf("NewScopedHost: %v", err)
|
||
}
|
||
if h.Owner() != "alice" || h.PluginID() != "rdm" {
|
||
t.Fatalf("Owner/PluginID = %s/%s, want alice/rdm", h.Owner(), h.PluginID())
|
||
}
|
||
// KV 往返落 owner 作用域。
|
||
if err := h.KVPut("k1", "v1"); err != nil {
|
||
t.Fatal(err)
|
||
}
|
||
if v, ok, err := h.KVGet("k1"); err != nil || !ok || v != "v1" {
|
||
t.Fatalf("KVGet = %q ok=%v err=%v", v, ok, err)
|
||
}
|
||
// 同构性:知识删除前缀强制(manual 不可及)。
|
||
if err := h.KnowledgeDelete(context.Background(), "manual"); err == nil {
|
||
t.Fatal("scoped host must keep the plugin:<id> prefix enforcement")
|
||
}
|
||
// 空 owner/pluginID:拒绝。
|
||
if _, err := extension.NewScopedHost("", "rdm"); err == nil {
|
||
t.Fatal("empty owner must be rejected")
|
||
}
|
||
}
|