github.com/meulengracht/snapd@v0.0.0-20210719210640-8bde69bcc84e/gadget/internal/mkfs_test.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2019 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 internal_test 21 22 import ( 23 "bytes" 24 "io" 25 "os" 26 "path/filepath" 27 "testing" 28 29 . "gopkg.in/check.v1" 30 31 "github.com/snapcore/snapd/gadget/internal" 32 "github.com/snapcore/snapd/testutil" 33 ) 34 35 func TestRun(t *testing.T) { TestingT(t) } 36 37 type mkfsSuite struct { 38 testutil.BaseTest 39 } 40 41 var _ = Suite(&mkfsSuite{}) 42 43 func (m *mkfsSuite) SetUpTest(c *C) { 44 m.BaseTest.SetUpTest(c) 45 46 // fakeroot, mkfs.ext4, mkfs.vfat and mcopy are commonly installed in 47 // the host system, set up some overrides so that we avoid calling the 48 // host tools 49 cmdFakeroot := testutil.MockCommand(c, "fakeroot", "echo 'override in test' ; exit 1") 50 m.AddCleanup(cmdFakeroot.Restore) 51 52 cmdMkfsExt4 := testutil.MockCommand(c, "mkfs.ext4", "echo 'override in test' ; exit 1") 53 m.AddCleanup(cmdMkfsExt4.Restore) 54 55 cmdMkfsVfat := testutil.MockCommand(c, "mkfs.vfat", "echo 'override in test'; exit 1") 56 m.AddCleanup(cmdMkfsVfat.Restore) 57 58 cmdMcopy := testutil.MockCommand(c, "mcopy", "echo 'override in test'; exit 1") 59 m.AddCleanup(cmdMcopy.Restore) 60 } 61 62 func (m *mkfsSuite) TestMkfsExt4Happy(c *C) { 63 cmd := testutil.MockCommand(c, "fakeroot", "") 64 defer cmd.Restore() 65 66 err := internal.MkfsWithContent("ext4", "foo.img", "my-label", "contents", 0, 0) 67 c.Assert(err, IsNil) 68 c.Check(cmd.Calls(), DeepEquals, [][]string{ 69 { 70 "fakeroot", 71 "mkfs.ext4", 72 "-d", "contents", 73 "-L", "my-label", 74 "foo.img", 75 }, 76 }) 77 78 cmd.ForgetCalls() 79 80 // empty label 81 err = internal.MkfsWithContent("ext4", "foo.img", "", "contents", 0, 0) 82 c.Assert(err, IsNil) 83 c.Check(cmd.Calls(), DeepEquals, [][]string{ 84 { 85 "fakeroot", 86 "mkfs.ext4", 87 "-d", "contents", 88 "foo.img", 89 }, 90 }) 91 92 cmd.ForgetCalls() 93 94 // no content 95 err = internal.Mkfs("ext4", "foo.img", "my-label", 0, 0) 96 c.Assert(err, IsNil) 97 c.Check(cmd.Calls(), DeepEquals, [][]string{ 98 { 99 "fakeroot", 100 "mkfs.ext4", 101 "-L", "my-label", 102 "foo.img", 103 }, 104 }) 105 106 } 107 108 func (m *mkfsSuite) TestMkfsExt4WithSize(c *C) { 109 cmd := testutil.MockCommand(c, "fakeroot", "") 110 defer cmd.Restore() 111 112 err := internal.MkfsWithContent("ext4", "foo.img", "my-label", "contents", 250*1024*1024, 0) 113 c.Assert(err, IsNil) 114 c.Check(cmd.Calls(), DeepEquals, [][]string{ 115 { 116 "fakeroot", 117 "mkfs.ext4", 118 "-d", "contents", 119 "-L", "my-label", 120 "foo.img", 121 }, 122 }) 123 124 cmd.ForgetCalls() 125 126 // empty label 127 err = internal.MkfsWithContent("ext4", "foo.img", "", "contents", 32*1024*1024, 0) 128 c.Assert(err, IsNil) 129 c.Check(cmd.Calls(), DeepEquals, [][]string{ 130 { 131 "fakeroot", 132 "mkfs.ext4", 133 "-b", "1024", 134 "-d", "contents", 135 "foo.img", 136 }, 137 }) 138 139 cmd.ForgetCalls() 140 141 // with sector size of 512 142 err = internal.MkfsWithContent("ext4", "foo.img", "", "contents", 32*1024*1024, 512) 143 c.Assert(err, IsNil) 144 c.Check(cmd.Calls(), DeepEquals, [][]string{ 145 { 146 "fakeroot", 147 "mkfs.ext4", 148 "-b", "1024", 149 "-d", "contents", 150 "foo.img", 151 }, 152 }) 153 154 cmd.ForgetCalls() 155 156 // with sector size of 4096 157 err = internal.MkfsWithContent("ext4", "foo.img", "", "contents", 32*1024*1024, 4096) 158 c.Assert(err, IsNil) 159 c.Check(cmd.Calls(), DeepEquals, [][]string{ 160 { 161 "fakeroot", 162 "mkfs.ext4", 163 "-b", "4096", 164 "-d", "contents", 165 "foo.img", 166 }, 167 }) 168 169 cmd.ForgetCalls() 170 171 } 172 173 func (m *mkfsSuite) TestMkfsExt4Error(c *C) { 174 cmd := testutil.MockCommand(c, "fakeroot", "echo 'command failed'; exit 1") 175 defer cmd.Restore() 176 177 err := internal.MkfsWithContent("ext4", "foo.img", "my-label", "contents", 0, 0) 178 c.Assert(err, ErrorMatches, "command failed") 179 } 180 181 func (m *mkfsSuite) TestMkfsVfatHappySimple(c *C) { 182 // no contents, should not fail 183 d := c.MkDir() 184 185 cmd := testutil.MockCommand(c, "mkfs.vfat", "") 186 defer cmd.Restore() 187 188 err := internal.MkfsWithContent("vfat", "foo.img", "my-label", d, 0, 0) 189 c.Assert(err, IsNil) 190 c.Check(cmd.Calls(), DeepEquals, [][]string{ 191 { 192 "mkfs.vfat", 193 "-S", "512", 194 "-s", "1", 195 "-F", "32", 196 "-n", "my-label", 197 "foo.img", 198 }, 199 }) 200 201 cmd.ForgetCalls() 202 203 // empty label 204 err = internal.MkfsWithContent("vfat", "foo.img", "", d, 0, 0) 205 c.Assert(err, IsNil) 206 c.Check(cmd.Calls(), DeepEquals, [][]string{ 207 { 208 "mkfs.vfat", 209 "-S", "512", 210 "-s", "1", 211 "-F", "32", 212 "foo.img", 213 }, 214 }) 215 216 cmd.ForgetCalls() 217 218 // no content 219 err = internal.Mkfs("vfat", "foo.img", "my-label", 0, 0) 220 c.Assert(err, IsNil) 221 c.Check(cmd.Calls(), DeepEquals, [][]string{ 222 { 223 "mkfs.vfat", 224 "-S", "512", 225 "-s", "1", 226 "-F", "32", 227 "-n", "my-label", 228 "foo.img", 229 }, 230 }) 231 } 232 233 func (m *mkfsSuite) TestMkfsVfatWithSize(c *C) { 234 d := c.MkDir() 235 236 cmd := testutil.MockCommand(c, "mkfs.vfat", "") 237 defer cmd.Restore() 238 239 err := internal.MkfsWithContent("vfat", "foo.img", "my-label", d, 32*1024*1024, 0) 240 c.Assert(err, IsNil) 241 c.Check(cmd.Calls(), DeepEquals, [][]string{ 242 { 243 "mkfs.vfat", 244 "-S", "512", 245 "-s", "1", 246 "-F", "32", 247 "-n", "my-label", 248 "foo.img", 249 }, 250 }) 251 252 cmd.ForgetCalls() 253 254 // with sector size of 512 255 err = internal.MkfsWithContent("vfat", "foo.img", "my-label", d, 32*1024*1024, 512) 256 c.Assert(err, IsNil) 257 c.Check(cmd.Calls(), DeepEquals, [][]string{ 258 { 259 "mkfs.vfat", 260 "-S", "512", 261 "-s", "1", 262 "-F", "32", 263 "-n", "my-label", 264 "foo.img", 265 }, 266 }) 267 268 cmd.ForgetCalls() 269 270 // with sector size of 4096 271 err = internal.MkfsWithContent("vfat", "foo.img", "my-label", d, 32*1024*1024, 4096) 272 c.Assert(err, IsNil) 273 c.Check(cmd.Calls(), DeepEquals, [][]string{ 274 { 275 "mkfs.vfat", 276 "-S", "4096", 277 "-s", "1", 278 "-F", "32", 279 "-n", "my-label", 280 "foo.img", 281 }, 282 }) 283 284 } 285 286 func (m *mkfsSuite) TestMkfsVfatHappyContents(c *C) { 287 d := c.MkDir() 288 makeSizedFile(c, filepath.Join(d, "foo"), 128, []byte("foo foo foo")) 289 makeSizedFile(c, filepath.Join(d, "bar/bar-content"), 128, []byte("bar bar bar")) 290 291 cmdMkfs := testutil.MockCommand(c, "mkfs.vfat", "") 292 defer cmdMkfs.Restore() 293 294 cmdMcopy := testutil.MockCommand(c, "mcopy", "") 295 defer cmdMcopy.Restore() 296 297 err := internal.MkfsWithContent("vfat", "foo.img", "my-label", d, 0, 0) 298 c.Assert(err, IsNil) 299 c.Assert(cmdMkfs.Calls(), HasLen, 1) 300 301 c.Assert(cmdMcopy.Calls(), DeepEquals, [][]string{ 302 {"mcopy", "-s", "-i", "foo.img", filepath.Join(d, "bar"), filepath.Join(d, "foo"), "::"}, 303 }) 304 } 305 306 func (m *mkfsSuite) TestMkfsVfatErrorSimpleFail(c *C) { 307 d := c.MkDir() 308 309 cmd := testutil.MockCommand(c, "mkfs.vfat", "echo 'failed'; false") 310 defer cmd.Restore() 311 312 err := internal.MkfsWithContent("vfat", "foo.img", "my-label", d, 0, 0) 313 c.Assert(err, ErrorMatches, "failed") 314 } 315 316 func (m *mkfsSuite) TestMkfsVfatErrorUnreadableDir(c *C) { 317 cmd := testutil.MockCommand(c, "mkfs.vfat", "") 318 defer cmd.Restore() 319 320 err := internal.MkfsWithContent("vfat", "foo.img", "my-label", "dir-does-not-exist", 0, 0) 321 c.Assert(err, ErrorMatches, "cannot list directory contents: .* no such file or directory") 322 c.Assert(cmd.Calls(), HasLen, 1) 323 } 324 325 func (m *mkfsSuite) TestMkfsVfatErrorInMcopy(c *C) { 326 d := c.MkDir() 327 makeSizedFile(c, filepath.Join(d, "foo"), 128, []byte("foo foo foo")) 328 329 cmdMkfs := testutil.MockCommand(c, "mkfs.vfat", "") 330 defer cmdMkfs.Restore() 331 332 cmdMcopy := testutil.MockCommand(c, "mcopy", "echo 'hard fail'; exit 1") 333 defer cmdMcopy.Restore() 334 335 err := internal.MkfsWithContent("vfat", "foo.img", "my-label", d, 0, 0) 336 c.Assert(err, ErrorMatches, "cannot populate vfat filesystem with contents: hard fail") 337 c.Assert(cmdMkfs.Calls(), HasLen, 1) 338 c.Assert(cmdMcopy.Calls(), HasLen, 1) 339 } 340 341 func (m *mkfsSuite) TestMkfsVfatHappyNoContents(c *C) { 342 cmdMkfs := testutil.MockCommand(c, "mkfs.vfat", "") 343 defer cmdMkfs.Restore() 344 345 cmdMcopy := testutil.MockCommand(c, "mcopy", "") 346 defer cmdMcopy.Restore() 347 348 err := internal.MkfsWithContent("vfat", "foo.img", "my-label", "", 0, 0) 349 c.Assert(err, IsNil) 350 c.Assert(cmdMkfs.Calls(), HasLen, 1) 351 // mcopy was not called 352 c.Assert(cmdMcopy.Calls(), HasLen, 0) 353 } 354 355 func (m *mkfsSuite) TestMkfsInvalidFs(c *C) { 356 err := internal.MkfsWithContent("no-fs", "foo.img", "my-label", "", 0, 0) 357 c.Assert(err, ErrorMatches, `cannot create unsupported filesystem "no-fs"`) 358 359 err = internal.Mkfs("no-fs", "foo.img", "my-label", 0, 0) 360 c.Assert(err, ErrorMatches, `cannot create unsupported filesystem "no-fs"`) 361 } 362 363 func makeSizedFile(c *C, path string, size int64, content []byte) { 364 err := os.MkdirAll(filepath.Dir(path), 0755) 365 c.Assert(err, IsNil) 366 367 f, err := os.Create(path) 368 c.Assert(err, IsNil) 369 defer f.Close() 370 if size != 0 { 371 err = f.Truncate(size) 372 c.Assert(err, IsNil) 373 } 374 if content != nil { 375 _, err := io.Copy(f, bytes.NewReader(content)) 376 c.Assert(err, IsNil) 377 } 378 }