gitee.com/mysnapcore/mysnapd@v0.1.0/interfaces/builtin/pwm_test.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2021 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 "os" 24 25 . "gopkg.in/check.v1" 26 27 "gitee.com/mysnapcore/mysnapd/interfaces" 28 "gitee.com/mysnapcore/mysnapd/interfaces/apparmor" 29 "gitee.com/mysnapcore/mysnapd/interfaces/builtin" 30 "gitee.com/mysnapcore/mysnapd/interfaces/systemd" 31 "gitee.com/mysnapcore/mysnapd/logger" 32 "gitee.com/mysnapcore/mysnapd/snap" 33 "gitee.com/mysnapcore/mysnapd/snap/snaptest" 34 "gitee.com/mysnapcore/mysnapd/testutil" 35 ) 36 37 type PwmInterfaceSuite struct { 38 testutil.BaseTest 39 40 iface interfaces.Interface 41 gadgetPwmSlotInfo *snap.SlotInfo 42 gadgetPwmSlot *interfaces.ConnectedSlot 43 gadgetMissingChannelSlotInfo *snap.SlotInfo 44 gadgetMissingChannelSlot *interfaces.ConnectedSlot 45 gadgetBadChannelSlotInfo *snap.SlotInfo 46 gadgetBadChannelSlot *interfaces.ConnectedSlot 47 gadgetMissingChipNumberSlotInfo *snap.SlotInfo 48 gadgetMissingChipNumberSlot *interfaces.ConnectedSlot 49 gadgetBadChipNumberSlotInfo *snap.SlotInfo 50 gadgetBadChipNumberSlot *interfaces.ConnectedSlot 51 gadgetBadInterfaceSlotInfo *snap.SlotInfo 52 gadgetBadInterfaceSlot *interfaces.ConnectedSlot 53 gadgetPlugInfo *snap.PlugInfo 54 gadgetPlug *interfaces.ConnectedPlug 55 gadgetBadInterfacePlugInfo *snap.PlugInfo 56 gadgetBadInterfacePlug *interfaces.ConnectedPlug 57 osPwmSlotInfo *snap.SlotInfo 58 osPwmSlot *interfaces.ConnectedSlot 59 } 60 61 var _ = Suite(&PwmInterfaceSuite{ 62 iface: builtin.MustInterface("pwm"), 63 }) 64 65 func (s *PwmInterfaceSuite) SetUpTest(c *C) { 66 gadgetInfo := snaptest.MockInfo(c, ` 67 name: my-device 68 version: 0 69 type: gadget 70 slots: 71 my-pin: 72 interface: pwm 73 chip-number: 10 74 channel: 100 75 missing-channel: 76 interface: pwm 77 chip-number: 10 78 bad-channel: 79 interface: pwm 80 chip-number: 10 81 channel: forty-two 82 missing-chip-number: 83 interface: pwm 84 channel: 100 85 bad-chip-number: 86 interface: pwm 87 chip-number: forty-two 88 channel: 100 89 bad-interface-slot: other-interface 90 plugs: 91 plug: pwm 92 bad-interface-plug: other-interface 93 apps: 94 svc: 95 command: bin/foo.sh 96 `, nil) 97 s.gadgetPwmSlotInfo = gadgetInfo.Slots["my-pin"] 98 s.gadgetPwmSlot = interfaces.NewConnectedSlot(s.gadgetPwmSlotInfo, nil, nil) 99 s.gadgetMissingChannelSlotInfo = gadgetInfo.Slots["missing-channel"] 100 s.gadgetMissingChannelSlot = interfaces.NewConnectedSlot(s.gadgetMissingChannelSlotInfo, nil, nil) 101 s.gadgetBadChannelSlotInfo = gadgetInfo.Slots["bad-channel"] 102 s.gadgetBadChannelSlot = interfaces.NewConnectedSlot(s.gadgetBadChannelSlotInfo, nil, nil) 103 s.gadgetMissingChipNumberSlotInfo = gadgetInfo.Slots["missing-chip-number"] 104 s.gadgetMissingChipNumberSlot = interfaces.NewConnectedSlot(s.gadgetMissingChipNumberSlotInfo, nil, nil) 105 s.gadgetBadChipNumberSlotInfo = gadgetInfo.Slots["bad-chip-number"] 106 s.gadgetBadChipNumberSlot = interfaces.NewConnectedSlot(s.gadgetBadChipNumberSlotInfo, nil, nil) 107 s.gadgetBadInterfaceSlotInfo = gadgetInfo.Slots["bad-interface-slot"] 108 s.gadgetBadInterfaceSlot = interfaces.NewConnectedSlot(s.gadgetBadInterfaceSlotInfo, nil, nil) 109 s.gadgetPlugInfo = gadgetInfo.Plugs["plug"] 110 s.gadgetPlug = interfaces.NewConnectedPlug(s.gadgetPlugInfo, nil, nil) 111 s.gadgetBadInterfacePlugInfo = gadgetInfo.Plugs["bad-interface-plug"] 112 s.gadgetBadInterfacePlug = interfaces.NewConnectedPlug(s.gadgetBadInterfacePlugInfo, nil, nil) 113 114 osInfo := snaptest.MockInfo(c, ` 115 name: my-core 116 version: 0 117 type: os 118 slots: 119 my-pin: 120 interface: pwm 121 chip-number: 10 122 channel: 7 123 `, nil) 124 s.osPwmSlotInfo = osInfo.Slots["my-pin"] 125 s.osPwmSlot = interfaces.NewConnectedSlot(s.osPwmSlotInfo, nil, nil) 126 } 127 128 func (s *PwmInterfaceSuite) TestName(c *C) { 129 c.Assert(s.iface.Name(), Equals, "pwm") 130 } 131 132 func (s *PwmInterfaceSuite) TestSanitizeSlotGadgetSnap(c *C) { 133 // pwm slot on gadget accepeted 134 c.Assert(interfaces.BeforePrepareSlot(s.iface, s.gadgetPwmSlotInfo), IsNil) 135 136 // slots without channel attribute are rejected 137 c.Assert(interfaces.BeforePrepareSlot(s.iface, s.gadgetMissingChannelSlotInfo), ErrorMatches, 138 "pwm slot must have a channel attribute") 139 140 // slots with channel attribute that isnt a number 141 c.Assert(interfaces.BeforePrepareSlot(s.iface, s.gadgetBadChannelSlotInfo), ErrorMatches, 142 "pwm slot channel attribute must be an int") 143 144 // slots without chip-number attribute are rejected 145 c.Assert(interfaces.BeforePrepareSlot(s.iface, s.gadgetMissingChipNumberSlotInfo), ErrorMatches, 146 "pwm slot must have a chip-number attribute") 147 148 // slots with chip-number attribute that isnt a number 149 c.Assert(interfaces.BeforePrepareSlot(s.iface, s.gadgetBadChipNumberSlotInfo), ErrorMatches, 150 "pwm slot chip-number attribute must be an int") 151 } 152 153 func (s *PwmInterfaceSuite) TestSanitizeSlotOsSnap(c *C) { 154 // pwm slot on OS accepted 155 c.Assert(interfaces.BeforePrepareSlot(s.iface, s.osPwmSlotInfo), IsNil) 156 } 157 158 func (s *PwmInterfaceSuite) TestSanitizePlug(c *C) { 159 c.Assert(interfaces.BeforePreparePlug(s.iface, s.gadgetPlugInfo), IsNil) 160 } 161 162 func (s *PwmInterfaceSuite) TestSystemdConnectedSlot(c *C) { 163 spec := &systemd.Specification{} 164 err := spec.AddConnectedSlot(s.iface, s.gadgetPlug, s.gadgetPwmSlot) 165 c.Assert(err, IsNil) 166 c.Assert(spec.Services(), DeepEquals, map[string]*systemd.Service{ 167 "pwmchip10-pwm100": { 168 Type: "oneshot", 169 RemainAfterExit: true, 170 ExecStart: `/bin/sh -c 'test -e /sys/class/pwm/pwmchip10/pwm100 || echo 100 > /sys/class/pwm/pwmchip10/export'`, 171 ExecStop: `/bin/sh -c 'test ! -e /sys/class/pwm/pwmchip10/pwm100 || echo 100 > /sys/class/pwm/pwmchip10/unexport'`, 172 }, 173 }) 174 } 175 176 func (s *PwmInterfaceSuite) TestApparmorConnectedPlugIgnoresMissingSymlink(c *C) { 177 log, restore := logger.MockLogger() 178 defer restore() 179 180 builtin.MockEvalSymlinks(&s.BaseTest, func(path string) (string, error) { 181 c.Assert(path, Equals, "/sys/class/pwm/pwmchip10") 182 return "", os.ErrNotExist 183 }) 184 185 spec := &apparmor.Specification{} 186 err := spec.AddConnectedPlug(s.iface, s.gadgetPlug, s.gadgetPwmSlot) 187 c.Assert(err, IsNil) 188 c.Assert(spec.Snippets(), HasLen, 0) 189 c.Assert(log.String(), testutil.Contains, "cannot find not existing pwm chipbase /sys/class/pwm/pwmchip10") 190 } 191 192 func (s *PwmInterfaceSuite) TestInterfaces(c *C) { 193 c.Check(builtin.Interfaces(), testutil.DeepContains, s.iface) 194 } 195 196 func (s *PwmInterfaceSuite) TestApparmorConnectedPlug(c *C) { 197 builtin.MockEvalSymlinks(&s.BaseTest, func(path string) (string, error) { 198 c.Assert(path, Equals, "/sys/class/pwm/pwmchip10") 199 // TODO: what is this actually a symlink to on a real device? 200 return "/sys/dev/foo/class/pwm/pwmchip10", nil 201 }) 202 203 spec := &apparmor.Specification{} 204 err := spec.AddConnectedPlug(s.iface, s.gadgetPlug, s.gadgetPwmSlot) 205 c.Assert(err, IsNil) 206 c.Assert(spec.SnippetForTag("snap.my-device.svc"), testutil.Contains, `/sys/dev/foo/class/pwm/pwmchip10/pwm100/* rwk`) 207 }