interfaces/builtin: ensure we don't register interfaces twice #3298

Merged
merged 2 commits into from May 11, 2017
Jump to file or symbol
Failed to load files and symbols.
+44 −8
Split
@@ -20,29 +20,35 @@
package builtin
import (
+ "fmt"
"sort"
"github.com/snapcore/snapd/interfaces"
)
var (
- allInterfaces []interfaces.Interface
- sorted bool
+ allInterfaces map[string]interfaces.Interface
)
// Interfaces returns all of the built-in interfaces.
func Interfaces() []interfaces.Interface {
- if !sorted {
- sort.Sort(byIfaceName(allInterfaces))
- sorted = true
+ ifaces := make([]interfaces.Interface, 0, len(allInterfaces))
+ for _, iface := range allInterfaces {
+ ifaces = append(ifaces, iface)
}
- return allInterfaces
+ sort.Sort(byIfaceName(ifaces))
+ return ifaces
}
// registerIface appends the given interface into the list of all known interfaces.
func registerIface(iface interfaces.Interface) {
- allInterfaces = append(allInterfaces, iface)
- sorted = false
+ if allInterfaces[iface.Name()] != nil {
+ panic(fmt.Errorf("cannot register duplicate interface %q", iface.Name()))
+ }
+ if allInterfaces == nil {
+ allInterfaces = make(map[string]interfaces.Interface)
+ }
+ allInterfaces[iface.Name()] = iface
}
type byIfaceName []interfaces.Interface
@@ -26,6 +26,7 @@ import (
"github.com/snapcore/snapd/interfaces/apparmor"
"github.com/snapcore/snapd/interfaces/builtin"
"github.com/snapcore/snapd/interfaces/dbus"
+ "github.com/snapcore/snapd/interfaces/ifacetest"
"github.com/snapcore/snapd/interfaces/kmod"
"github.com/snapcore/snapd/interfaces/mount"
"github.com/snapcore/snapd/interfaces/seccomp"
@@ -293,3 +294,16 @@ func (s *AllSuite) TestNoInterfaceImplementsOldBackendMethods(c *C) {
}
}
}
+
+func (s *AllSuite) TestRegisterIface(c *C) {
+ restore := builtin.MockInterfaces(nil)
+ defer restore()
+
+ // Registering an interface works correctly.
+ iface := &ifacetest.TestInterface{InterfaceName: "foo"}
+ builtin.RegisterIface(iface)
+ c.Assert(builtin.Interface("foo"), DeepEquals, iface)
+
+ // Duplicates are detected.
+ c.Assert(func() { builtin.RegisterIface(iface) }, PanicMatches, `cannot register duplicate interface "foo"`)
+}
@@ -19,8 +19,24 @@
package builtin
+import (
+ "github.com/snapcore/snapd/interfaces"
+)
+
func MprisGetName(iface *MprisInterface, attribs map[string]interface{}) (string, error) {
return iface.getName(attribs)
}
var ResolveSpecialVariable = resolveSpecialVariable
+
+func MockInterfaces(ifaces map[string]interfaces.Interface) (restore func()) {
+ old := allInterfaces
+ allInterfaces = ifaces
+ return func() { allInterfaces = old }
+}
+
+func Interface(name string) interfaces.Interface {
+ return allInterfaces[name]
+}
+
+var RegisterIface = registerIface