github.com/kubiko/snapd@v0.0.0-20201013125620-d4f3094d9ddf/interfaces/udev/spec_test.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2017 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 udev_test 21 22 import ( 23 . "gopkg.in/check.v1" 24 25 "github.com/snapcore/snapd/interfaces" 26 "github.com/snapcore/snapd/interfaces/ifacetest" 27 "github.com/snapcore/snapd/interfaces/udev" 28 "github.com/snapcore/snapd/snap" 29 "github.com/snapcore/snapd/snap/snaptest" 30 ) 31 32 type specSuite struct { 33 iface *ifacetest.TestInterface 34 spec *udev.Specification 35 plugInfo *snap.PlugInfo 36 plug *interfaces.ConnectedPlug 37 slotInfo *snap.SlotInfo 38 slot *interfaces.ConnectedSlot 39 } 40 41 var _ = Suite(&specSuite{ 42 iface: &ifacetest.TestInterface{ 43 InterfaceName: "test", 44 UDevConnectedPlugCallback: func(spec *udev.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { 45 spec.AddSnippet("connected-plug") 46 return nil 47 }, 48 UDevConnectedSlotCallback: func(spec *udev.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { 49 spec.AddSnippet("connected-slot") 50 return nil 51 }, 52 UDevPermanentPlugCallback: func(spec *udev.Specification, plug *snap.PlugInfo) error { 53 spec.AddSnippet("permanent-plug") 54 return nil 55 }, 56 UDevPermanentSlotCallback: func(spec *udev.Specification, slot *snap.SlotInfo) error { 57 spec.AddSnippet("permanent-slot") 58 return nil 59 }, 60 }, 61 }) 62 63 func (s *specSuite) SetUpSuite(c *C) { 64 info1 := snaptest.MockInfo(c, `name: snap1 65 version: 0 66 plugs: 67 name: 68 interface: test 69 apps: 70 foo: 71 command: bin/foo 72 hooks: 73 configure: 74 `, nil) 75 info2 := snaptest.MockInfo(c, `name: snap2 76 version: 0 77 slots: 78 name: 79 interface: test 80 `, nil) 81 s.plugInfo = info1.Plugs["name"] 82 s.plug = interfaces.NewConnectedPlug(s.plugInfo, nil, nil) 83 s.slotInfo = info2.Slots["name"] 84 s.slot = interfaces.NewConnectedSlot(s.slotInfo, nil, nil) 85 } 86 87 func (s *specSuite) SetUpTest(c *C) { 88 s.spec = &udev.Specification{} 89 } 90 91 func (s *specSuite) TestAddSnippte(c *C) { 92 s.spec.AddSnippet("foo") 93 c.Assert(s.spec.Snippets(), DeepEquals, []string{"foo"}) 94 } 95 96 func (s *specSuite) TestTagDevice(c *C) { 97 // TagDevice acts in the scope of the plug/slot (as appropriate) and 98 // affects all of the apps and hooks related to the given plug or slot 99 // (with the exception that slots cannot have hooks). 100 iface := &ifacetest.TestInterface{ 101 InterfaceName: "iface-1", 102 UDevConnectedPlugCallback: func(spec *udev.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { 103 spec.TagDevice(`kernel="voodoo"`) 104 return nil 105 }, 106 } 107 c.Assert(s.spec.AddConnectedPlug(iface, s.plug, s.slot), IsNil) 108 109 iface = &ifacetest.TestInterface{ 110 InterfaceName: "iface-2", 111 UDevConnectedPlugCallback: func(spec *udev.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { 112 spec.TagDevice(`kernel="hoodoo"`) 113 return nil 114 }, 115 } 116 c.Assert(s.spec.AddConnectedPlug(iface, s.plug, s.slot), IsNil) 117 118 c.Assert(s.spec.Snippets(), DeepEquals, []string{ 119 `# iface-1 120 kernel="voodoo", TAG+="snap_snap1_foo"`, 121 `# iface-2 122 kernel="hoodoo", TAG+="snap_snap1_foo"`, 123 `TAG=="snap_snap1_foo", RUN+="/usr/lib/snapd/snap-device-helper $env{ACTION} snap_snap1_foo $devpath $major:$minor"`, 124 `# iface-1 125 kernel="voodoo", TAG+="snap_snap1_hook_configure"`, 126 `# iface-2 127 kernel="hoodoo", TAG+="snap_snap1_hook_configure"`, 128 `TAG=="snap_snap1_hook_configure", RUN+="/usr/lib/snapd/snap-device-helper $env{ACTION} snap_snap1_hook_configure $devpath $major:$minor"`, 129 }) 130 } 131 132 // The spec.Specification can be used through the interfaces.Specification interface 133 func (s *specSuite) TestSpecificationIface(c *C) { 134 var r interfaces.Specification = s.spec 135 c.Assert(r.AddConnectedPlug(s.iface, s.plug, s.slot), IsNil) 136 c.Assert(r.AddConnectedSlot(s.iface, s.plug, s.slot), IsNil) 137 c.Assert(r.AddPermanentPlug(s.iface, s.plugInfo), IsNil) 138 c.Assert(r.AddPermanentSlot(s.iface, s.slotInfo), IsNil) 139 c.Assert(s.spec.Snippets(), DeepEquals, []string{"connected-plug", "connected-slot", "permanent-plug", "permanent-slot"}) 140 } 141 142 func (s *specSuite) TestControlsDeviceCgroup(c *C) { 143 c.Assert(s.spec.ControlsDeviceCgroup(), Equals, false) 144 s.spec.SetControlsDeviceCgroup() 145 c.Assert(s.spec.ControlsDeviceCgroup(), Equals, true) 146 }