github.com/bugraaydogar/snapd@v0.0.0-20210315170335-8c70bb858939/interfaces/builtin/avahi_observe_test.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2016 Canonical Ltd 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 3 as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 package builtin_test 21 22 import ( 23 . "gopkg.in/check.v1" 24 25 "github.com/snapcore/snapd/interfaces" 26 "github.com/snapcore/snapd/interfaces/apparmor" 27 "github.com/snapcore/snapd/interfaces/builtin" 28 "github.com/snapcore/snapd/interfaces/dbus" 29 "github.com/snapcore/snapd/release" 30 "github.com/snapcore/snapd/snap" 31 "github.com/snapcore/snapd/testutil" 32 ) 33 34 type AvahiObserveInterfaceSuite struct { 35 iface interfaces.Interface 36 plug *interfaces.ConnectedPlug 37 plugInfo *snap.PlugInfo 38 appSlot *interfaces.ConnectedSlot 39 appSlotInfo *snap.SlotInfo 40 coreSlot *interfaces.ConnectedSlot 41 coreSlotInfo *snap.SlotInfo 42 snapdSlot *interfaces.ConnectedSlot 43 snapdSlotInfo *snap.SlotInfo 44 } 45 46 var _ = Suite(&AvahiObserveInterfaceSuite{ 47 iface: builtin.MustInterface("avahi-observe"), 48 }) 49 50 const avahiObserveConsumerYaml = `name: consumer 51 version: 0 52 apps: 53 app: 54 plugs: [avahi-observe] 55 ` 56 57 const avahiObserveProducerYaml = `name: producer 58 version: 0 59 apps: 60 app: 61 slots: [avahi-observe] 62 ` 63 64 const avahiObserveCoreYaml = `name: core 65 version: 0 66 type: os 67 slots: 68 avahi-observe: 69 ` 70 71 const avahiObserveSnapdYaml = `name: snapd 72 version: 0 73 type: snapd 74 slots: 75 avahi-observe: 76 ` 77 78 func (s *AvahiObserveInterfaceSuite) SetUpTest(c *C) { 79 s.plug, s.plugInfo = MockConnectedPlug(c, avahiObserveConsumerYaml, nil, "avahi-observe") 80 s.appSlot, s.appSlotInfo = MockConnectedSlot(c, avahiObserveProducerYaml, nil, "avahi-observe") 81 s.coreSlot, s.coreSlotInfo = MockConnectedSlot(c, avahiObserveCoreYaml, nil, "avahi-observe") 82 s.snapdSlot, s.snapdSlotInfo = MockConnectedSlot(c, avahiObserveSnapdYaml, nil, "avahi-observe") 83 } 84 85 func (s *AvahiObserveInterfaceSuite) TestName(c *C) { 86 c.Assert(s.iface.Name(), Equals, "avahi-observe") 87 } 88 89 func (s *AvahiObserveInterfaceSuite) TestSanitizeSlot(c *C) { 90 c.Assert(interfaces.BeforePrepareSlot(s.iface, s.coreSlotInfo), IsNil) 91 c.Assert(interfaces.BeforePrepareSlot(s.iface, s.appSlotInfo), IsNil) 92 // avahi-observe slot can now be used on snap other than core. 93 slot := &snap.SlotInfo{ 94 Snap: &snap.Info{SuggestedName: "some-snap"}, 95 Name: "avahi-observe", 96 Interface: "avahi-observe", 97 } 98 c.Assert(interfaces.BeforePrepareSlot(s.iface, slot), IsNil) 99 } 100 101 func (s *AvahiObserveInterfaceSuite) TestSanitizePlug(c *C) { 102 c.Assert(interfaces.BeforePreparePlug(s.iface, s.plugInfo), IsNil) 103 } 104 105 func (s *AvahiObserveInterfaceSuite) testAppArmorSpecWithProducer(c *C, 106 slot *interfaces.ConnectedSlot, slotInfo *snap.SlotInfo) { 107 // connected plug to app slot 108 spec := &apparmor.Specification{} 109 c.Assert(spec.AddConnectedPlug(s.iface, s.plug, slot), IsNil) 110 c.Assert(spec.SecurityTags(), DeepEquals, []string{"snap.consumer.app"}) 111 c.Assert(spec.SnippetForTag("snap.consumer.app"), testutil.Contains, "name=org.freedesktop.Avahi") 112 c.Assert(spec.SnippetForTag("snap.consumer.app"), testutil.Contains, `peer=(label="snap.producer.app"),`) 113 // make sure observe does have observe but not control capabilities 114 c.Assert(spec.SnippetForTag("snap.consumer.app"), testutil.Contains, `interface=org.freedesktop.Avahi.AddressResolver`) 115 c.Assert(spec.SnippetForTag("snap.consumer.app"), testutil.Contains, `interface=org.freedesktop.Avahi.HostNameResolver`) 116 c.Assert(spec.SnippetForTag("snap.consumer.app"), testutil.Contains, `interface=org.freedesktop.Avahi.ServiceResolver`) 117 c.Assert(spec.SnippetForTag("snap.consumer.app"), testutil.Contains, `interface=org.freedesktop.Avahi.RecordBrowser`) 118 // control capabilities 119 c.Assert(spec.SnippetForTag("snap.consumer.app"), Not(testutil.Contains), `member=Set*`) 120 c.Assert(spec.SnippetForTag("snap.consumer.app"), Not(testutil.Contains), `member=EntryGroupNew`) 121 c.Assert(spec.SnippetForTag("snap.consumer.app"), Not(testutil.Contains), `interface=org.freedesktop.Avahi.EntryGroup`) 122 123 // connected app slot to plug 124 spec = &apparmor.Specification{} 125 c.Assert(spec.AddConnectedSlot(s.iface, s.plug, slot), IsNil) 126 c.Assert(spec.SecurityTags(), DeepEquals, []string{"snap.producer.app"}) 127 c.Assert(spec.SnippetForTag("snap.producer.app"), testutil.Contains, `interface=org.freedesktop.Avahi`) 128 c.Assert(spec.SnippetForTag("snap.producer.app"), testutil.Contains, `peer=(label="snap.consumer.app"),`) 129 // make sure observe does have observe but not control capabilities 130 c.Assert(spec.SnippetForTag("snap.producer.app"), testutil.Contains, `interface=org.freedesktop.Avahi.AddressResolver`) 131 c.Assert(spec.SnippetForTag("snap.producer.app"), testutil.Contains, `interface=org.freedesktop.Avahi.HostNameResolver`) 132 c.Assert(spec.SnippetForTag("snap.producer.app"), testutil.Contains, `interface=org.freedesktop.Avahi.ServiceResolver`) 133 c.Assert(spec.SnippetForTag("snap.producer.app"), testutil.Contains, `interface=org.freedesktop.Avahi.RecordBrowser`) 134 // control capabilities 135 c.Assert(spec.SnippetForTag("snap.producer.app"), Not(testutil.Contains), `interface=org.freedesktop.Avahi.EntryGroup`) 136 137 // permanent app slot 138 spec = &apparmor.Specification{} 139 c.Assert(spec.AddPermanentSlot(s.iface, slotInfo), IsNil) 140 c.Assert(spec.SecurityTags(), DeepEquals, []string{"snap.producer.app"}) 141 c.Assert(spec.SnippetForTag("snap.producer.app"), testutil.Contains, `dbus (bind) 142 bus=system 143 name="org.freedesktop.Avahi",`) 144 } 145 146 func (s *AvahiObserveInterfaceSuite) testAppArmorSpecFromSystem(c *C, 147 slot *interfaces.ConnectedSlot, slotInfo *snap.SlotInfo) { 148 // connected plug to core slot 149 spec := &apparmor.Specification{} 150 c.Assert(spec.AddConnectedPlug(s.iface, s.plug, slot), IsNil) 151 c.Assert(spec.SecurityTags(), DeepEquals, []string{"snap.consumer.app"}) 152 c.Assert(spec.SnippetForTag("snap.consumer.app"), testutil.Contains, "name=org.freedesktop.Avahi") 153 c.Assert(spec.SnippetForTag("snap.consumer.app"), testutil.Contains, "peer=(label=\"{unconfined,/usr/sbin/avahi-daemon,avahi-daemon}\"),") 154 // make sure observe does have observe but not control capabilities 155 c.Assert(spec.SnippetForTag("snap.consumer.app"), testutil.Contains, `interface=org.freedesktop.Avahi.AddressResolver`) 156 c.Assert(spec.SnippetForTag("snap.consumer.app"), testutil.Contains, `interface=org.freedesktop.Avahi.HostNameResolver`) 157 c.Assert(spec.SnippetForTag("snap.consumer.app"), testutil.Contains, `interface=org.freedesktop.Avahi.ServiceResolver`) 158 // control capabilities 159 c.Assert(spec.SnippetForTag("snap.consumer.app"), Not(testutil.Contains), `member=Set*`) 160 c.Assert(spec.SnippetForTag("snap.consumer.app"), Not(testutil.Contains), `member=EntryGroupNew`) 161 c.Assert(spec.SnippetForTag("snap.consumer.app"), Not(testutil.Contains), `interface=org.freedesktop.Avahi.EntryGroup`) 162 163 // connected core slot to plug 164 spec = &apparmor.Specification{} 165 c.Assert(spec.AddConnectedSlot(s.iface, s.plug, slot), IsNil) 166 c.Assert(spec.SecurityTags(), HasLen, 0) 167 168 // permanent core slot 169 spec = &apparmor.Specification{} 170 c.Assert(spec.AddPermanentSlot(s.iface, slotInfo), IsNil) 171 c.Assert(spec.SecurityTags(), HasLen, 0) 172 } 173 174 func (s *AvahiObserveInterfaceSuite) TestAppArmorSpec(c *C) { 175 // on a core system with avahi slot coming from a regular app snap. 176 restore := release.MockOnClassic(false) 177 defer restore() 178 s.testAppArmorSpecWithProducer(c, s.appSlot, s.appSlotInfo) 179 180 // on a classic system with avahi slot coming from the system by core snap. 181 restore = release.MockOnClassic(true) 182 defer restore() 183 s.testAppArmorSpecWithProducer(c, s.appSlot, s.appSlotInfo) 184 185 // on a classic system with avahi slot coming from the system by core snap. 186 restore = release.MockOnClassic(true) 187 defer restore() 188 s.testAppArmorSpecFromSystem(c, s.coreSlot, s.coreSlotInfo) 189 190 // on a classic system with avahi slot coming from the system by snapd snap. 191 restore = release.MockOnClassic(true) 192 defer restore() 193 s.testAppArmorSpecFromSystem(c, s.snapdSlot, s.snapdSlotInfo) 194 } 195 196 func (s *AvahiObserveInterfaceSuite) testDBusSpecSlotByApp(c *C, classic bool) { 197 restore := release.MockOnClassic(classic) 198 defer restore() 199 200 spec := &dbus.Specification{} 201 c.Assert(spec.AddPermanentSlot(s.iface, s.appSlotInfo), IsNil) 202 c.Assert(spec.SecurityTags(), DeepEquals, []string{"snap.producer.app"}) 203 c.Assert(spec.SnippetForTag("snap.producer.app"), testutil.Contains, `<allow own="org.freedesktop.Avahi"/>`) 204 } 205 206 func (s *AvahiObserveInterfaceSuite) testDBusSpecSlotBySystem(c *C, slotInfo *snap.SlotInfo) { 207 restore := release.MockOnClassic(true) 208 defer restore() 209 210 spec := &dbus.Specification{} 211 c.Assert(spec.AddPermanentSlot(s.iface, slotInfo), IsNil) 212 c.Assert(spec.SecurityTags(), HasLen, 0) 213 } 214 215 func (s *AvahiObserveInterfaceSuite) TestDBusSpecSlot(c *C) { 216 // on a core system with avahi slot coming from a regular app snap. 217 s.testDBusSpecSlotByApp(c, false) 218 // on a classic system with avahi slot coming from a regular app snap. 219 s.testDBusSpecSlotByApp(c, true) 220 221 // on a classic system with avahi slot coming from the core snap. 222 s.testDBusSpecSlotBySystem(c, s.coreSlotInfo) 223 // on a classic system with avahi slot coming from the snapd snap. 224 s.testDBusSpecSlotBySystem(c, s.snapdSlotInfo) 225 } 226 227 func (s *AvahiObserveInterfaceSuite) TestStaticInfo(c *C) { 228 si := interfaces.StaticInfoOf(s.iface) 229 c.Assert(si.ImplicitOnCore, Equals, false) 230 c.Assert(si.ImplicitOnClassic, Equals, true) 231 c.Assert(si.Summary, Equals, `allows discovery on a local network via the mDNS/DNS-SD protocol suite`) 232 c.Assert(si.BaseDeclarationSlots, testutil.Contains, "avahi-observe") 233 } 234 235 func (s *AvahiObserveInterfaceSuite) TestAutoConnect(c *C) { 236 c.Assert(s.iface.AutoConnect(s.plugInfo, s.coreSlotInfo), Equals, true) 237 c.Assert(s.iface.AutoConnect(s.plugInfo, s.appSlotInfo), Equals, true) 238 } 239 240 func (s *AvahiObserveInterfaceSuite) TestInterfaces(c *C) { 241 c.Check(builtin.Interfaces(), testutil.DeepContains, s.iface) 242 }