github.com/Lephar/snapd@v0.0.0-20210825215435-c7fba9cef4d2/snap/snaptest/snaptest_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 snaptest_test 21 22 import ( 23 "os" 24 "path/filepath" 25 "testing" 26 27 . "gopkg.in/check.v1" 28 29 "github.com/snapcore/snapd/dirs" 30 "github.com/snapcore/snapd/snap" 31 "github.com/snapcore/snapd/snap/snapfile" 32 "github.com/snapcore/snapd/snap/snaptest" 33 "github.com/snapcore/snapd/snap/squashfs" 34 "github.com/snapcore/snapd/testutil" 35 ) 36 37 func TestSnapTest(t *testing.T) { TestingT(t) } 38 39 const sampleYaml = ` 40 name: sample 41 version: 1 42 apps: 43 app: 44 command: foo 45 plugs: 46 network: 47 interface: network 48 ` 49 50 type snapTestSuite struct{} 51 52 var _ = Suite(&snapTestSuite{}) 53 54 func (s *snapTestSuite) SetUpTest(c *C) { 55 dirs.SetRootDir(c.MkDir()) 56 } 57 58 func (s *snapTestSuite) TearDownTest(c *C) { 59 dirs.SetRootDir("") 60 } 61 62 func (s *snapTestSuite) TestMockSnap(c *C) { 63 snapInfo := snaptest.MockSnap(c, sampleYaml, &snap.SideInfo{Revision: snap.R(42)}) 64 // Data from YAML is used 65 c.Check(snapInfo.InstanceName(), Equals, "sample") 66 // Data from SideInfo is used 67 c.Check(snapInfo.Revision, Equals, snap.R(42)) 68 // The YAML is placed on disk 69 c.Check(filepath.Join(dirs.SnapMountDir, "sample", "42", "meta", "snap.yaml"), 70 testutil.FileEquals, sampleYaml) 71 72 // More 73 c.Check(snapInfo.Apps["app"].Command, Equals, "foo") 74 c.Check(snapInfo.Plugs["network"].Interface, Equals, "network") 75 } 76 77 func (s *snapTestSuite) TestMockSnapInstance(c *C) { 78 snapInfo := snaptest.MockSnapInstance(c, "sample_instance", sampleYaml, &snap.SideInfo{Revision: snap.R(42)}) 79 // Data from YAML and parameters is used 80 c.Check(snapInfo.InstanceName(), Equals, "sample_instance") 81 c.Check(snapInfo.SnapName(), Equals, "sample") 82 c.Check(snapInfo.InstanceKey, Equals, "instance") 83 84 // Data from SideInfo is used 85 c.Check(snapInfo.Revision, Equals, snap.R(42)) 86 // The YAML is placed on disk 87 c.Check(filepath.Join(dirs.SnapMountDir, "sample_instance", "42", "meta", "snap.yaml"), 88 testutil.FileEquals, sampleYaml) 89 90 // More 91 c.Check(snapInfo.Apps["app"].Command, Equals, "foo") 92 c.Check(snapInfo.Plugs["network"].Interface, Equals, "network") 93 } 94 95 func (s *snapTestSuite) TestMockSnapCurrent(c *C) { 96 snapInfo := snaptest.MockSnapCurrent(c, sampleYaml, &snap.SideInfo{Revision: snap.R(42)}) 97 // Data from YAML is used 98 c.Check(snapInfo.InstanceName(), Equals, "sample") 99 // Data from SideInfo is used 100 c.Check(snapInfo.Revision, Equals, snap.R(42)) 101 // The YAML is placed on disk 102 c.Check(filepath.Join(dirs.SnapMountDir, "sample", "42", "meta", "snap.yaml"), 103 testutil.FileEquals, sampleYaml) 104 link, err := os.Readlink(filepath.Join(dirs.SnapMountDir, "sample", "current")) 105 c.Check(err, IsNil) 106 c.Check(link, Equals, "42") 107 } 108 109 func (s *snapTestSuite) TestMockSnapInstanceCurrent(c *C) { 110 snapInfo := snaptest.MockSnapInstanceCurrent(c, "sample_instance", sampleYaml, &snap.SideInfo{Revision: snap.R(42)}) 111 // Data from YAML and parameters is used 112 c.Check(snapInfo.InstanceName(), Equals, "sample_instance") 113 c.Check(snapInfo.SnapName(), Equals, "sample") 114 c.Check(snapInfo.InstanceKey, Equals, "instance") 115 // Data from SideInfo is used 116 c.Check(snapInfo.Revision, Equals, snap.R(42)) 117 // The YAML is placed on disk 118 c.Check(filepath.Join(dirs.SnapMountDir, "sample_instance", "42", "meta", "snap.yaml"), 119 testutil.FileEquals, sampleYaml) 120 link, err := os.Readlink(filepath.Join(dirs.SnapMountDir, "sample_instance", "current")) 121 c.Check(err, IsNil) 122 c.Check(link, Equals, filepath.Join(dirs.SnapMountDir, "sample_instance", "42")) 123 } 124 125 func (s *snapTestSuite) TestMockInfo(c *C) { 126 snapInfo := snaptest.MockInfo(c, sampleYaml, &snap.SideInfo{Revision: snap.R(42)}) 127 // Data from YAML is used 128 c.Check(snapInfo.InstanceName(), Equals, "sample") 129 // Data from SideInfo is used 130 c.Check(snapInfo.Revision, Equals, snap.R(42)) 131 // The YAML is *not* placed on disk 132 _, err := os.Stat(filepath.Join(dirs.SnapMountDir, "sample", "42", "meta", "snap.yaml")) 133 c.Assert(os.IsNotExist(err), Equals, true) 134 // More 135 c.Check(snapInfo.Apps["app"].Command, Equals, "foo") 136 c.Check(snapInfo.Plugs["network"].Interface, Equals, "network") 137 } 138 139 func (s *snapTestSuite) TestMockInvalidInfo(c *C) { 140 snapInfo := snaptest.MockInvalidInfo(c, sampleYaml+"\nslots:\n network:\n", &snap.SideInfo{Revision: snap.R(42)}) 141 // Data from YAML is used 142 c.Check(snapInfo.InstanceName(), Equals, "sample") 143 // Data from SideInfo is used 144 c.Check(snapInfo.Revision, Equals, snap.R(42)) 145 // The YAML is *not* placed on disk 146 _, err := os.Stat(filepath.Join(dirs.SnapMountDir, "sample", "42", "meta", "snap.yaml")) 147 c.Assert(os.IsNotExist(err), Equals, true) 148 // More 149 c.Check(snapInfo.Apps["app"].Command, Equals, "foo") 150 c.Check(snapInfo.Plugs["network"].Interface, Equals, "network") 151 c.Check(snapInfo.Slots["network"].Interface, Equals, "network") 152 // They info object is not valid 153 c.Check(snap.Validate(snapInfo), ErrorMatches, `cannot have plug and slot with the same name: "network"`) 154 } 155 156 func (s *snapTestSuite) TestRenameSlot(c *C) { 157 snapInfo := snaptest.MockInfo(c, `name: core 158 type: os 159 version: 0 160 slots: 161 old: 162 interface: interface 163 slot: 164 interface: interface 165 plugs: 166 plug: 167 interface: interface 168 apps: 169 app: 170 hooks: 171 configure: 172 `, nil) 173 174 // Rename "old" to "plug" 175 err := snaptest.RenameSlot(snapInfo, "old", "plug") 176 c.Assert(err, ErrorMatches, `cannot rename slot "old" to "plug": existing plug with that name`) 177 178 // Rename "old" to "slot" 179 err = snaptest.RenameSlot(snapInfo, "old", "slot") 180 c.Assert(err, ErrorMatches, `cannot rename slot "old" to "slot": existing slot with that name`) 181 182 // Rename "old" to "bad name" 183 err = snaptest.RenameSlot(snapInfo, "old", "bad name") 184 c.Assert(err, ErrorMatches, `cannot rename slot "old" to "bad name": invalid slot name: "bad name"`) 185 186 // Rename "old" to "new" 187 err = snaptest.RenameSlot(snapInfo, "old", "new") 188 c.Assert(err, IsNil) 189 190 // Check that there's no trace of the old slot name. 191 c.Assert(snapInfo.Slots["old"], IsNil) 192 c.Assert(snapInfo.Slots["new"], NotNil) 193 c.Assert(snapInfo.Slots["new"].Name, Equals, "new") 194 c.Assert(snapInfo.Apps["app"].Slots["old"], IsNil) 195 c.Assert(snapInfo.Apps["app"].Slots["new"], DeepEquals, snapInfo.Slots["new"]) 196 c.Assert(snapInfo.Hooks["configure"].Slots["old"], IsNil) 197 c.Assert(snapInfo.Hooks["configure"].Slots["new"], DeepEquals, snapInfo.Slots["new"]) 198 199 // Rename "old" to "new" (again) 200 err = snaptest.RenameSlot(snapInfo, "old", "new") 201 c.Assert(err, ErrorMatches, `cannot rename slot "old" to "new": no such slot`) 202 203 } 204 205 func (s *snapTestSuite) TestMockSnapWithFiles(c *C) { 206 snapInfo := snaptest.MockSnapWithFiles(c, sampleYaml, &snap.SideInfo{Revision: snap.R(42)}, [][]string{ 207 {"foo/bar", "bar"}, 208 {"bar", "not foo"}, 209 {"meta/gadget.yaml", "gadget yaml\nmulti line"}, 210 }) 211 // Data from YAML is used 212 c.Check(snapInfo.InstanceName(), Equals, "sample") 213 // Data from SideInfo is used 214 c.Check(snapInfo.Revision, Equals, snap.R(42)) 215 c.Check(filepath.Join(snapInfo.MountDir(), "bar"), testutil.FileEquals, "not foo") 216 c.Check(filepath.Join(snapInfo.MountDir(), "foo/bar"), testutil.FileEquals, "bar") 217 c.Check(filepath.Join(snapInfo.MountDir(), "meta/gadget.yaml"), testutil.FileEquals, "gadget yaml\nmulti line") 218 } 219 220 func (s *snapTestSuite) TestMockContainerMinimal(c *C) { 221 cont := snaptest.MockContainer(c, nil) 222 err := snap.ValidateContainer(cont, &snap.Info{}, nil) 223 c.Check(err, IsNil) 224 } 225 226 func (s *snapTestSuite) TestMockContainer(c *C) { 227 defer snap.MockSanitizePlugsSlots(func(snapInfo *snap.Info) {})() 228 229 const snapYaml = `name: gadget 230 type: gadget 231 version: 1.0` 232 const gadgetYaml = `defaults: 233 ` 234 cont := snaptest.MockContainer(c, [][]string{ 235 {"meta/snap.yaml", snapYaml}, 236 {"meta/gadget.yaml", gadgetYaml}, 237 }) 238 239 info, err := snap.ReadInfoFromSnapFile(cont, nil) 240 c.Assert(err, IsNil) 241 c.Check(info.SnapName(), Equals, "gadget") 242 err = snap.ValidateContainer(cont, info, nil) 243 c.Assert(err, IsNil) 244 readGadgetYaml, err := cont.ReadFile("meta/gadget.yaml") 245 c.Assert(err, IsNil) 246 c.Check(readGadgetYaml, DeepEquals, []byte(gadgetYaml)) 247 } 248 249 func (s *snapTestSuite) TestMakeSnapFileAndDir(c *C) { 250 files := [][]string{ 251 {"canary", "canary"}, 252 {"foo", "foo"}, 253 } 254 info := snaptest.MakeSnapFileAndDir(c, sampleYaml, files, &snap.SideInfo{ 255 Revision: snap.R(3), 256 }) 257 c.Check(filepath.Join(info.MountDir(), "canary"), testutil.FileEquals, "canary") 258 c.Assert(info.MountFile(), testutil.FilePresent) 259 c.Check(squashfs.FileHasSquashfsHeader(info.MountFile()), Equals, true) 260 f, err := snapfile.Open(info.MountFile()) 261 c.Assert(err, IsNil) 262 can, err := f.ReadFile("canary") 263 c.Assert(err, IsNil) 264 c.Check(can, DeepEquals, []byte("canary")) 265 }