fix: resolve plugin lifecycle dependencies deterministically
This commit is contained in:
@@ -33,10 +33,18 @@ func (r *Registry) Register(pluginID string, capabilities []string) error {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
|
||||
pending := make(map[string]struct{}, len(capabilities))
|
||||
for _, name := range capabilities {
|
||||
if existing, ok := r.capabilities[name]; ok {
|
||||
return fmt.Errorf("capability %q already registered by plugin %q", name, existing.PluginID)
|
||||
}
|
||||
if _, ok := pending[name]; ok {
|
||||
return fmt.Errorf("capability %q is registered more than once by plugin %q", name, pluginID)
|
||||
}
|
||||
pending[name] = struct{}{}
|
||||
}
|
||||
|
||||
for _, name := range capabilities {
|
||||
r.capabilities[name] = &Entry{
|
||||
Name: name,
|
||||
PluginID: pluginID,
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package capability
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestRegisterDoesNotPartiallyRegisterCapabilitiesOnConflict(t *testing.T) {
|
||||
registry := NewRegistry()
|
||||
if err := registry.Register("existing.plugin", []string{"shared.capability"}); err != nil {
|
||||
t.Fatalf("register existing capability: %v", err)
|
||||
}
|
||||
|
||||
if err := registry.Register("failed.plugin", []string{"new.capability", "shared.capability"}); err == nil {
|
||||
t.Fatal("Register returned nil for a duplicate capability")
|
||||
}
|
||||
if registry.Has("new.capability") {
|
||||
t.Fatal("Register leaked a capability from the failed registration")
|
||||
}
|
||||
entry := registry.Get("shared.capability")
|
||||
if entry == nil || entry.PluginID != "existing.plugin" {
|
||||
t.Fatalf("shared capability entry = %#v, want existing.plugin", entry)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user