gitee.com/mysnapcore/mysnapd@v0.1.0/interfaces/kmod/backend_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 kmod_test 21 22 import ( 23 "path/filepath" 24 "testing" 25 26 . "gopkg.in/check.v1" 27 28 "gitee.com/mysnapcore/mysnapd/dirs" 29 "gitee.com/mysnapcore/mysnapd/interfaces" 30 "gitee.com/mysnapcore/mysnapd/interfaces/ifacetest" 31 "gitee.com/mysnapcore/mysnapd/interfaces/kmod" 32 "gitee.com/mysnapcore/mysnapd/osutil" 33 "gitee.com/mysnapcore/mysnapd/snap" 34 "gitee.com/mysnapcore/mysnapd/testutil" 35 "gitee.com/mysnapcore/mysnapd/timings" 36 ) 37 38 func Test(t *testing.T) { 39 TestingT(t) 40 } 41 42 type backendSuite struct { 43 ifacetest.BackendSuite 44 modprobeCmd *testutil.MockCmd 45 meas *timings.Span 46 } 47 48 var _ = Suite(&backendSuite{}) 49 50 var testedConfinementOpts = []interfaces.ConfinementOptions{ 51 {}, 52 {DevMode: true}, 53 {JailMode: true}, 54 {Classic: true}, 55 } 56 57 func (s *backendSuite) SetUpTest(c *C) { 58 s.Backend = &kmod.Backend{} 59 s.BackendSuite.SetUpTest(c) 60 c.Assert(s.Repo.AddBackend(s.Backend), IsNil) 61 s.modprobeCmd = testutil.MockCommand(c, "modprobe", "") 62 63 perf := timings.New(nil) 64 s.meas = perf.StartSpan("", "") 65 } 66 67 func (s *backendSuite) TearDownTest(c *C) { 68 s.modprobeCmd.Restore() 69 s.BackendSuite.TearDownTest(c) 70 } 71 72 func (s *backendSuite) TestName(c *C) { 73 c.Check(s.Backend.Name(), Equals, interfaces.SecurityKMod) 74 } 75 76 func (s *backendSuite) TestInstallingSnapCreatesModulesConf(c *C) { 77 // NOTE: Hand out a permanent snippet so that .conf file is generated. 78 s.Iface.KModPermanentSlotCallback = func(spec *kmod.Specification, slot *snap.SlotInfo) error { 79 spec.AddModule("module1") 80 spec.AddModule("module2") 81 return nil 82 } 83 84 path := filepath.Join(dirs.SnapKModModulesDir, "snap.samba.conf") 85 c.Assert(osutil.FileExists(path), Equals, false) 86 87 for _, opts := range testedConfinementOpts { 88 s.modprobeCmd.ForgetCalls() 89 snapInfo := s.InstallSnap(c, opts, "", ifacetest.SambaYamlV1, 0) 90 91 c.Assert(osutil.FileExists(path), Equals, true) 92 c.Assert(path, testutil.FileEquals, "# This file is automatically generated.\nmodule1\nmodule2\n") 93 94 c.Assert(s.modprobeCmd.Calls(), DeepEquals, [][]string{ 95 {"modprobe", "--syslog", "module1"}, 96 {"modprobe", "--syslog", "module2"}, 97 }) 98 s.RemoveSnap(c, snapInfo) 99 } 100 } 101 102 func (s *backendSuite) TestRemovingSnapRemovesModulesConf(c *C) { 103 // NOTE: Hand out a permanent snippet so that .conf file is generated. 104 s.Iface.KModPermanentSlotCallback = func(spec *kmod.Specification, slot *snap.SlotInfo) error { 105 spec.AddModule("module1") 106 spec.AddModule("module2") 107 return nil 108 } 109 110 path := filepath.Join(dirs.SnapKModModulesDir, "snap.samba.conf") 111 c.Assert(osutil.FileExists(path), Equals, false) 112 113 for _, opts := range testedConfinementOpts { 114 snapInfo := s.InstallSnap(c, opts, "", ifacetest.SambaYamlV1, 0) 115 c.Assert(osutil.FileExists(path), Equals, true) 116 s.RemoveSnap(c, snapInfo) 117 c.Assert(osutil.FileExists(path), Equals, false) 118 } 119 } 120 121 func (s *backendSuite) TestInstallingSnapCreatesModprobeConf(c *C) { 122 s.Iface.KModPermanentSlotCallback = func(spec *kmod.Specification, slot *snap.SlotInfo) error { 123 spec.AddModule("module1") 124 spec.SetModuleOptions("module1", "opt1=true opt2=2") 125 spec.DisallowModule("module2") 126 return nil 127 } 128 129 modulesPath := filepath.Join(dirs.SnapKModModulesDir, "snap.samba.conf") 130 c.Assert(osutil.FileExists(modulesPath), Equals, false) 131 modprobePath := filepath.Join(dirs.SnapKModModprobeDir, "snap.samba.conf") 132 c.Assert(osutil.FileExists(modprobePath), Equals, false) 133 134 for _, opts := range testedConfinementOpts { 135 s.modprobeCmd.ForgetCalls() 136 snapInfo := s.InstallSnap(c, opts, "", ifacetest.SambaYamlV1, 0) 137 138 c.Assert(osutil.FileExists(modulesPath), Equals, true) 139 c.Assert(modulesPath, testutil.FileEquals, "# This file is automatically generated.\nmodule1\n") 140 141 c.Assert(osutil.FileExists(modprobePath), Equals, true) 142 c.Assert(modprobePath, testutil.FileEquals, `# Generated by snapd. Do not edit 143 144 blacklist module2 145 options module1 opt1=true opt2=2 146 `) 147 148 c.Assert(s.modprobeCmd.Calls(), DeepEquals, [][]string{ 149 {"modprobe", "--syslog", "module1"}, 150 }) 151 s.RemoveSnap(c, snapInfo) 152 } 153 } 154 155 func (s *backendSuite) TestRemovingSnapRemovesModprobeConf(c *C) { 156 s.Iface.KModPermanentSlotCallback = func(spec *kmod.Specification, slot *snap.SlotInfo) error { 157 spec.AddModule("module1") 158 spec.SetModuleOptions("module1", "opt1=true opt2=2") 159 spec.DisallowModule("module2") 160 return nil 161 } 162 163 modulesPath := filepath.Join(dirs.SnapKModModulesDir, "snap.samba.conf") 164 c.Assert(osutil.FileExists(modulesPath), Equals, false) 165 modprobePath := filepath.Join(dirs.SnapKModModprobeDir, "snap.samba.conf") 166 c.Assert(osutil.FileExists(modprobePath), Equals, false) 167 168 for _, opts := range testedConfinementOpts { 169 snapInfo := s.InstallSnap(c, opts, "", ifacetest.SambaYamlV1, 0) 170 c.Assert(osutil.FileExists(modulesPath), Equals, true) 171 c.Assert(osutil.FileExists(modprobePath), Equals, true) 172 s.RemoveSnap(c, snapInfo) 173 c.Assert(osutil.FileExists(modulesPath), Equals, false) 174 c.Assert(osutil.FileExists(modprobePath), Equals, false) 175 } 176 } 177 178 func (s *backendSuite) TestSecurityIsStable(c *C) { 179 // NOTE: Hand out a permanent snippet so that .conf file is generated. 180 s.Iface.KModPermanentSlotCallback = func(spec *kmod.Specification, slot *snap.SlotInfo) error { 181 spec.AddModule("module1") 182 spec.AddModule("module2") 183 return nil 184 } 185 186 for _, opts := range testedConfinementOpts { 187 snapInfo := s.InstallSnap(c, opts, "", ifacetest.SambaYamlV1, 0) 188 s.modprobeCmd.ForgetCalls() 189 err := s.Backend.Setup(snapInfo, opts, s.Repo, s.meas) 190 c.Assert(err, IsNil) 191 // modules conf is not re-loaded when nothing changes 192 c.Check(s.modprobeCmd.Calls(), HasLen, 0) 193 s.RemoveSnap(c, snapInfo) 194 } 195 } 196 197 func (s *backendSuite) TestSandboxFeatures(c *C) { 198 c.Assert(s.Backend.SandboxFeatures(), DeepEquals, []string{"mediated-modprobe"}) 199 }