github.com/kubiko/snapd@v0.0.0-20201013125620-d4f3094d9ddf/interfaces/builtin/common_test.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2016-2018 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 21 22 import ( 23 "os" 24 25 . "gopkg.in/check.v1" 26 27 "github.com/snapcore/snapd/interfaces/apparmor" 28 "github.com/snapcore/snapd/interfaces/udev" 29 "github.com/snapcore/snapd/testutil" 30 ) 31 32 type commonIfaceSuite struct{} 33 34 var _ = Suite(&commonIfaceSuite{}) 35 36 func (s *commonIfaceSuite) TestUDevSpec(c *C) { 37 plug, _ := MockConnectedPlug(c, ` 38 name: consumer 39 version: 0 40 apps: 41 app-a: 42 plugs: [common] 43 app-b: 44 app-c: 45 plugs: [common] 46 `, nil, "common") 47 slot, _ := MockConnectedSlot(c, ` 48 name: producer 49 version: 0 50 slots: 51 common: 52 `, nil, "common") 53 54 // common interface can define connected plug udev rules 55 iface := &commonInterface{ 56 name: "common", 57 connectedPlugUDev: []string{`KERNEL=="foo"`}, 58 } 59 spec := &udev.Specification{} 60 c.Assert(spec.AddConnectedPlug(iface, plug, slot), IsNil) 61 c.Assert(spec.Snippets(), DeepEquals, []string{ 62 `# common 63 KERNEL=="foo", TAG+="snap_consumer_app-a"`, 64 `TAG=="snap_consumer_app-a", RUN+="/usr/lib/snapd/snap-device-helper $env{ACTION} snap_consumer_app-a $devpath $major:$minor"`, 65 // NOTE: app-b is unaffected as it doesn't have a plug reference. 66 `# common 67 KERNEL=="foo", TAG+="snap_consumer_app-c"`, 68 `TAG=="snap_consumer_app-c", RUN+="/usr/lib/snapd/snap-device-helper $env{ACTION} snap_consumer_app-c $devpath $major:$minor"`, 69 }) 70 71 // connected plug udev rules are optional 72 iface = &commonInterface{ 73 name: "common", 74 } 75 spec = &udev.Specification{} 76 c.Assert(spec.AddConnectedPlug(iface, plug, slot), IsNil) 77 c.Assert(spec.Snippets(), HasLen, 0) 78 } 79 80 // MockEvalSymlinks replaces the path/filepath.EvalSymlinks function used inside the caps package. 81 func MockEvalSymlinks(test *testutil.BaseTest, fn func(string) (string, error)) { 82 orig := evalSymlinks 83 evalSymlinks = fn 84 test.AddCleanup(func() { 85 evalSymlinks = orig 86 }) 87 } 88 89 // MockReadDir replaces the io/ioutil.ReadDir function used inside the caps package. 90 func MockReadDir(test *testutil.BaseTest, fn func(string) ([]os.FileInfo, error)) { 91 orig := readDir 92 readDir = fn 93 test.AddCleanup(func() { 94 readDir = orig 95 }) 96 } 97 98 func (s *commonIfaceSuite) TestSuppressPtraceTrace(c *C) { 99 plug, _ := MockConnectedPlug(c, ` 100 name: consumer 101 version: 0 102 apps: 103 app: 104 plugs: [common] 105 `, nil, "common") 106 slot, _ := MockConnectedSlot(c, ` 107 name: producer 108 version: 0 109 slots: 110 common: 111 `, nil, "common") 112 113 // setting nothing 114 iface := &commonInterface{ 115 name: "common", 116 suppressPtraceTrace: false, 117 usesPtraceTrace: false, 118 } 119 spec := &apparmor.Specification{} 120 c.Assert(spec.UsesPtraceTrace(), Equals, false) 121 c.Assert(spec.SuppressPtraceTrace(), Equals, false) 122 c.Assert(spec.AddConnectedPlug(iface, plug, slot), IsNil) 123 c.Assert(spec.UsesPtraceTrace(), Equals, false) 124 c.Assert(spec.SuppressPtraceTrace(), Equals, false) 125 126 // setting only uses 127 iface = &commonInterface{ 128 name: "common", 129 suppressPtraceTrace: false, 130 usesPtraceTrace: true, 131 } 132 spec = &apparmor.Specification{} 133 c.Assert(spec.UsesPtraceTrace(), Equals, false) 134 c.Assert(spec.SuppressPtraceTrace(), Equals, false) 135 c.Assert(spec.AddConnectedPlug(iface, plug, slot), IsNil) 136 c.Assert(spec.UsesPtraceTrace(), Equals, true) 137 c.Assert(spec.SuppressPtraceTrace(), Equals, false) 138 139 // setting only suppress 140 iface = &commonInterface{ 141 name: "common", 142 suppressPtraceTrace: true, 143 usesPtraceTrace: false, 144 } 145 spec = &apparmor.Specification{} 146 c.Assert(spec.UsesPtraceTrace(), Equals, false) 147 c.Assert(spec.SuppressPtraceTrace(), Equals, false) 148 c.Assert(spec.AddConnectedPlug(iface, plug, slot), IsNil) 149 c.Assert(spec.UsesPtraceTrace(), Equals, false) 150 c.Assert(spec.SuppressPtraceTrace(), Equals, true) 151 152 // setting both, only uses is set 153 iface = &commonInterface{ 154 name: "common", 155 suppressPtraceTrace: true, 156 usesPtraceTrace: true, 157 } 158 spec = &apparmor.Specification{} 159 c.Assert(spec.UsesPtraceTrace(), Equals, false) 160 c.Assert(spec.SuppressPtraceTrace(), Equals, false) 161 c.Assert(spec.AddConnectedPlug(iface, plug, slot), IsNil) 162 c.Assert(spec.UsesPtraceTrace(), Equals, true) 163 c.Assert(spec.SuppressPtraceTrace(), Equals, false) 164 } 165 166 func (s *commonIfaceSuite) TestSuppressHomeIx(c *C) { 167 plug, _ := MockConnectedPlug(c, ` 168 name: consumer 169 version: 0 170 apps: 171 app: 172 plugs: [common] 173 `, nil, "common") 174 slot, _ := MockConnectedSlot(c, ` 175 name: producer 176 version: 0 177 slots: 178 common: 179 `, nil, "common") 180 181 // setting nothing 182 iface := &commonInterface{ 183 name: "common", 184 suppressHomeIx: false, 185 } 186 spec := &apparmor.Specification{} 187 c.Assert(spec.SuppressHomeIx(), Equals, false) 188 c.Assert(spec.AddConnectedPlug(iface, plug, slot), IsNil) 189 c.Assert(spec.SuppressHomeIx(), Equals, false) 190 191 iface = &commonInterface{ 192 name: "common", 193 suppressHomeIx: true, 194 } 195 spec = &apparmor.Specification{} 196 c.Assert(spec.SuppressHomeIx(), Equals, false) 197 c.Assert(spec.AddConnectedPlug(iface, plug, slot), IsNil) 198 c.Assert(spec.SuppressHomeIx(), Equals, true) 199 } 200 201 func (s *commonIfaceSuite) TestControlsDeviceCgroup(c *C) { 202 plug, _ := MockConnectedPlug(c, ` 203 name: consumer 204 version: 0 205 apps: 206 app: 207 plugs: [common] 208 `, nil, "common") 209 slot, _ := MockConnectedSlot(c, ` 210 name: producer 211 version: 0 212 slots: 213 common: 214 `, nil, "common") 215 216 // setting nothing 217 iface := &commonInterface{ 218 name: "common", 219 controlsDeviceCgroup: false, 220 } 221 spec := &udev.Specification{} 222 c.Assert(spec.ControlsDeviceCgroup(), Equals, false) 223 c.Assert(spec.AddConnectedPlug(iface, plug, slot), IsNil) 224 c.Assert(spec.ControlsDeviceCgroup(), Equals, false) 225 226 iface = &commonInterface{ 227 name: "common", 228 controlsDeviceCgroup: true, 229 } 230 spec = &udev.Specification{} 231 c.Assert(spec.ControlsDeviceCgroup(), Equals, false) 232 c.Assert(spec.AddConnectedPlug(iface, plug, slot), IsNil) 233 c.Assert(spec.ControlsDeviceCgroup(), Equals, true) 234 }