interfaces: maintain Plug and Slot connection details #571

Merged
merged 10 commits into from Mar 4, 2016
View
@@ -306,6 +306,8 @@ func (r *Repository) Connect(plugSnapName, plugName, slotSnapName, slotName stri
}
r.slotPlugs[slot][plug] = true
r.plugSlots[plug][slot] = true
+ slot.Connections = append(slot.Connections, PlugRef{plug.Snap, plug.Name})
+ plug.Connections = append(plug.Connections, SlotRef{slot.Snap, slot.Name})
return nil
}
@@ -400,6 +402,26 @@ func (r *Repository) disconnect(plug *Plug, slot *Slot) {
if len(r.plugSlots[plug]) == 0 {
delete(r.plugSlots, plug)
}
+ for i, plugRef := range slot.Connections {
+ if plugRef.Snap == plug.Snap && plugRef.Name == plug.Name {
+ slot.Connections[i] = slot.Connections[len(slot.Connections)-1]
+ slot.Connections = slot.Connections[:len(slot.Connections)-1]
+ if len(slot.Connections) == 0 {
+ slot.Connections = nil
+ }
+ break
+ }
+ }
+ for i, slotRef := range plug.Connections {
+ if slotRef.Snap == slot.Snap && slotRef.Name == slot.Name {
+ plug.Connections[i] = plug.Connections[len(plug.Connections)-1]
+ plug.Connections = plug.Connections[:len(plug.Connections)-1]
+ if len(plug.Connections) == 0 {
+ plug.Connections = nil
+ }
+ break
+ }
+ }
}
// ConnectedSlots returns all the plugs connected to a given snap.
@@ -477,17 +499,11 @@ func (r *Repository) Interfaces() *Interfaces {
for _, plug := range plugs {
// Copy part of the data explicitly, leaving out attrs and apps.
p := &Plug{
- Name: plug.Name,
- Snap: plug.Snap,
- Interface: plug.Interface,
- Label: plug.Label,
- }
- // Add connection details
- for slot := range r.plugSlots[plug] {
- p.Connections = append(p.Connections, SlotRef{
- Name: slot.Name,
- Snap: slot.Snap,
- })
+ Name: plug.Name,
+ Snap: plug.Snap,
+ Interface: plug.Interface,
+ Label: plug.Label,
+ Connections: append([]SlotRef(nil), plug.Connections...),
}
sort.Sort(bySlotRef(p.Connections))
ifaces.Plugs = append(ifaces.Plugs, p)
@@ -497,17 +513,11 @@ func (r *Repository) Interfaces() *Interfaces {
for _, slot := range slots {
// Copy part of the data explicitly, leaving out attrs and apps.
s := &Slot{
- Name: slot.Name,
- Snap: slot.Snap,
- Interface: slot.Interface,
- Label: slot.Label,
- }
- // Add connection details
- for plug := range r.slotPlugs[slot] {
- s.Connections = append(s.Connections, PlugRef{
- Name: plug.Name,
- Snap: plug.Snap,
- })
+ Name: slot.Name,
+ Snap: slot.Snap,
+ Interface: slot.Interface,
+ Label: slot.Label,
+ Connections: append([]PlugRef(nil), slot.Connections...),
}
sort.Sort(byPlugRef(s.Connections))
ifaces.Slots = append(ifaces.Slots, s)
View
@@ -40,25 +40,25 @@ var _ = Suite(&RepositorySuite{
iface: &TestInterface{
InterfaceName: "interface",
},
- plug: &Plug{
+})
+
+func (s *RepositorySuite) SetUpTest(c *C) {
+ s.plug = &Plug{
Snap: "provider",
Name: "plug",
Interface: "interface",
Label: "label",
Attrs: map[string]interface{}{"attr": "value"},
Apps: []string{"meta/hooks/plug"},
- },
- slot: &Slot{
+ }
+ s.slot = &Slot{
Snap: "consumer",
Name: "slot",
Interface: "interface",
Label: "label",
Attrs: map[string]interface{}{"attr": "value"},
Apps: []string{"app"},
- },
-})
-
-func (s *RepositorySuite) SetUpTest(c *C) {
+ }
s.emptyRepo = NewRepository()
s.testRepo = NewRepository()
err := s.testRepo.AddInterface(s.iface)
@@ -732,7 +732,7 @@ func (s *RepositorySuite) TestConnectedSlotsReturnsCorrectData(c *C) {
c.Assert(s.testRepo.ConnectedSlots(s.slot.Snap), DeepEquals, map[*Slot][]*Plug{
s.slot: []*Plug{s.plug},
})
- // After revoking the result is empty again
+ // After disconnecting the result is empty again
err = s.testRepo.Disconnect(s.plug.Snap, s.plug.Name, s.slot.Snap, s.slot.Name)
c.Assert(err, IsNil)
c.Assert(s.testRepo.ConnectedSlots(s.slot.Snap), HasLen, 0)
@@ -762,7 +762,7 @@ func (s *RepositorySuite) TestConnectedPlugsReturnsCorrectData(c *C) {
c.Assert(connects, DeepEquals, map[*Plug][]*Slot{
s.plug: []*Slot{s.slot},
})
- // After revoking the result is empty again
+ // After disconnecting the result is empty again
err = s.testRepo.Disconnect(s.plug.Snap, s.plug.Name, s.slot.Snap, s.slot.Name)
c.Assert(err, IsNil)
c.Assert(s.testRepo.ConnectedPlugs(s.plug.Snap), HasLen, 0)
@@ -790,12 +790,59 @@ func (s *RepositorySuite) TestPlugConnectionsReturnsCorrectData(c *C) {
c.Assert(err, IsNil)
users := s.testRepo.PlugConnections(s.plug.Snap, s.plug.Name)
c.Assert(users, DeepEquals, []*Slot{s.slot})
- // After revoking the result is empty again
+ // After disconnecting the result is empty again
err = s.testRepo.Disconnect(s.plug.Snap, s.plug.Name, s.slot.Snap, s.slot.Name)
c.Assert(err, IsNil)
c.Assert(s.testRepo.PlugConnections(s.plug.Snap, s.plug.Name), HasLen, 0)
}
+// Tests for Repository.Interfaces()
+
+func (s *RepositorySuite) TestInterfacesSmokeTest(c *C) {
+ err := s.testRepo.AddPlug(s.plug)
+ c.Assert(err, IsNil)
+ err = s.testRepo.AddSlot(s.slot)
+ c.Assert(err, IsNil)
+ // After connecting the result is as expected
+ err = s.testRepo.Connect(s.plug.Snap, s.plug.Name, s.slot.Snap, s.slot.Name)
+ c.Assert(err, IsNil)
+ ifaces := s.testRepo.Interfaces()
+ c.Assert(ifaces, DeepEquals, &Interfaces{
+ Plugs: []*Plug{{
+ Name: s.plug.Name,
+ Snap: s.plug.Snap,
+ Interface: s.plug.Interface,
+ Label: s.plug.Label,
+ Connections: []SlotRef{{s.slot.Snap, s.slot.Name}},
+ }},
+ Slots: []*Slot{{
+ Snap: s.slot.Snap,
+ Name: s.slot.Name,
+ Interface: s.slot.Interface,
+ Label: s.slot.Label,
+ Connections: []PlugRef{{s.plug.Snap, s.plug.Name}},
+ }},
+ })
+ // After disconnecting the connections become empty
+ err = s.testRepo.Disconnect(s.plug.Snap, s.plug.Name, s.slot.Snap, s.slot.Name)
+ c.Assert(err, IsNil)
+ ifaces = s.testRepo.Interfaces()
+ c.Assert(ifaces, DeepEquals, &Interfaces{
+ Plugs: []*Plug{{
+ Name: s.plug.Name,
+ Snap: s.plug.Snap,
+ Interface: s.plug.Interface,
+ Label: s.plug.Label,
+ }},
+ Slots: []*Slot{{
+ Snap: s.slot.Snap,
+ Name: s.slot.Name,
+ Interface: s.slot.Interface,
+ Label: s.slot.Label,
+ }},
+ })
+}
+
// Tests for Repository.SecuritySnippetsForSnap()
func (s *RepositorySuite) TestSlotSnippetsForSnapSuccess(c *C) {