package kernel import ( "context" "sync" "testing" contractv1 "goaiapi/proto/contract/v1" ) func TestLoadBasePlugin(t *testing.T) { bin := pluginBin(t, "../../plugins/echo") reg := NewRegistry() brokerAddr := startTestBroker(t, reg) t.Cleanup(reg.Shutdown) info, err := reg.Load(context.Background(), bin, brokerAddr) if err != nil { t.Fatalf("Load: %v", err) } if info.Name != "echo-base" { t.Errorf("name = %q, want echo-base", info.Name) } if info.Tier != contractv1.PluginTier_TIER_BASE { t.Errorf("tier = %v, want BASE", info.Tier) } if !info.Healthy { t.Error("plugin not healthy") } } func TestLoadDuplicateRejected(t *testing.T) { bin := pluginBin(t, "../../plugins/echo") reg := NewRegistry() brokerAddr := startTestBroker(t, reg) t.Cleanup(reg.Shutdown) if _, err := reg.Load(context.Background(), bin, brokerAddr); err != nil { t.Fatalf("first Load: %v", err) } if _, err := reg.Load(context.Background(), bin, brokerAddr); err == nil { t.Fatal("期望重复加载报错,得到 nil") } } func TestUnloadBlockedByDependent(t *testing.T) { echoBin := pluginBin(t, "../../plugins/echo") transformBin := pluginBin(t, "../../plugins/transform") reg := NewRegistry() brokerAddr := startTestBroker(t, reg) t.Cleanup(reg.Shutdown) if _, err := reg.Load(context.Background(), echoBin, brokerAddr); err != nil { t.Fatalf("load echo: %v", err) } if _, err := reg.Load(context.Background(), transformBin, brokerAddr); err != nil { t.Fatalf("load transform: %v", err) } // echo-base 被 transform-mid 依赖,不能卸载。 if err := reg.Unload("echo-base"); err == nil { t.Fatal("期望卸载被依赖插件报错,得到 nil") } // 先卸 transform-mid,再卸 echo-base 应成功。 if err := reg.Unload("transform-mid"); err != nil { t.Fatalf("unload transform: %v", err) } if err := reg.Unload("echo-base"); err != nil { t.Fatalf("unload echo: %v", err) } } func TestConcurrentLoadList(t *testing.T) { echoBin := pluginBin(t, "../../plugins/echo") reg := NewRegistry() brokerAddr := startTestBroker(t, reg) t.Cleanup(reg.Shutdown) if _, err := reg.Load(context.Background(), echoBin, brokerAddr); err != nil { t.Fatalf("load: %v", err) } // 并发读 List/Get,配合 -race 检测数据竞争。 var wg sync.WaitGroup for i := 0; i < 20; i++ { wg.Add(1) go func() { defer wg.Done() _ = reg.List() _ = reg.Get("echo-base") }() } wg.Wait() }