github.com/kubiko/snapd@v0.0.0-20201013125620-d4f3094d9ddf/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") 67 c.Assert(err, IsNil) 68 c.Check(cmd.Calls(), DeepEquals, [][]string{ 69 { 70 "fakeroot", 71 "mkfs.ext4", 72 "-T", "default", 73 "-d", "contents", 74 "-L", "my-label", 75 "foo.img", 76 }, 77 }) 78 79 cmd.ForgetCalls() 80 81 // empty label 82 err = internal.MkfsWithContent("ext4", "foo.img", "", "contents") 83 c.Assert(err, IsNil) 84 c.Check(cmd.Calls(), DeepEquals, [][]string{ 85 { 86 "fakeroot", 87 "mkfs.ext4", 88 "-T", "default", 89 "-d", "contents", 90 "foo.img", 91 }, 92 }) 93 94 cmd.ForgetCalls() 95 96 // no content 97 err = internal.Mkfs("ext4", "foo.img", "my-label") 98 c.Assert(err, IsNil) 99 c.Check(cmd.Calls(), DeepEquals, [][]string{ 100 { 101 "fakeroot", 102 "mkfs.ext4", 103 "-T", "default", 104 "-L", "my-label", 105 "foo.img", 106 }, 107 }) 108 109 } 110 111 func (m *mkfsSuite) TestMkfsExt4Error(c *C) { 112 cmd := testutil.MockCommand(c, "fakeroot", "echo 'command failed'; exit 1") 113 defer cmd.Restore() 114 115 err := internal.MkfsWithContent("ext4", "foo.img", "my-label", "contents") 116 c.Assert(err, ErrorMatches, "command failed") 117 } 118 119 func (m *mkfsSuite) TestMkfsVfatHappySimple(c *C) { 120 // no contents, should not fail 121 d := c.MkDir() 122 123 cmd := testutil.MockCommand(c, "mkfs.vfat", "") 124 defer cmd.Restore() 125 126 err := internal.MkfsWithContent("vfat", "foo.img", "my-label", d) 127 c.Assert(err, IsNil) 128 c.Check(cmd.Calls(), DeepEquals, [][]string{ 129 { 130 "mkfs.vfat", 131 "-S", "512", 132 "-s", "1", 133 "-F", "32", 134 "-n", "my-label", 135 "foo.img", 136 }, 137 }) 138 139 cmd.ForgetCalls() 140 141 // empty label 142 err = internal.MkfsWithContent("vfat", "foo.img", "", d) 143 c.Assert(err, IsNil) 144 c.Check(cmd.Calls(), DeepEquals, [][]string{ 145 { 146 "mkfs.vfat", 147 "-S", "512", 148 "-s", "1", 149 "-F", "32", 150 "foo.img", 151 }, 152 }) 153 154 cmd.ForgetCalls() 155 156 // no content 157 err = internal.Mkfs("vfat", "foo.img", "my-label") 158 c.Assert(err, IsNil) 159 c.Check(cmd.Calls(), DeepEquals, [][]string{ 160 { 161 "mkfs.vfat", 162 "-S", "512", 163 "-s", "1", 164 "-F", "32", 165 "-n", "my-label", 166 "foo.img", 167 }, 168 }) 169 } 170 171 func (m *mkfsSuite) TestMkfsVfatHappyContents(c *C) { 172 d := c.MkDir() 173 makeSizedFile(c, filepath.Join(d, "foo"), 128, []byte("foo foo foo")) 174 makeSizedFile(c, filepath.Join(d, "bar/bar-content"), 128, []byte("bar bar bar")) 175 176 cmdMkfs := testutil.MockCommand(c, "mkfs.vfat", "") 177 defer cmdMkfs.Restore() 178 179 cmdMcopy := testutil.MockCommand(c, "mcopy", "") 180 defer cmdMcopy.Restore() 181 182 err := internal.MkfsWithContent("vfat", "foo.img", "my-label", d) 183 c.Assert(err, IsNil) 184 c.Assert(cmdMkfs.Calls(), HasLen, 1) 185 186 c.Assert(cmdMcopy.Calls(), DeepEquals, [][]string{ 187 {"mcopy", "-s", "-i", "foo.img", filepath.Join(d, "bar"), filepath.Join(d, "foo"), "::"}, 188 }) 189 } 190 191 func (m *mkfsSuite) TestMkfsVfatErrorSimpleFail(c *C) { 192 d := c.MkDir() 193 194 cmd := testutil.MockCommand(c, "mkfs.vfat", "echo 'failed'; false") 195 defer cmd.Restore() 196 197 err := internal.MkfsWithContent("vfat", "foo.img", "my-label", d) 198 c.Assert(err, ErrorMatches, "failed") 199 } 200 201 func (m *mkfsSuite) TestMkfsVfatErrorUnreadableDir(c *C) { 202 cmd := testutil.MockCommand(c, "mkfs.vfat", "") 203 defer cmd.Restore() 204 205 err := internal.MkfsWithContent("vfat", "foo.img", "my-label", "dir-does-not-exist") 206 c.Assert(err, ErrorMatches, "cannot list directory contents: .* no such file or directory") 207 c.Assert(cmd.Calls(), HasLen, 1) 208 } 209 210 func (m *mkfsSuite) TestMkfsVfatErrorInMcopy(c *C) { 211 d := c.MkDir() 212 makeSizedFile(c, filepath.Join(d, "foo"), 128, []byte("foo foo foo")) 213 214 cmdMkfs := testutil.MockCommand(c, "mkfs.vfat", "") 215 defer cmdMkfs.Restore() 216 217 cmdMcopy := testutil.MockCommand(c, "mcopy", "echo 'hard fail'; exit 1") 218 defer cmdMcopy.Restore() 219 220 err := internal.MkfsWithContent("vfat", "foo.img", "my-label", d) 221 c.Assert(err, ErrorMatches, "cannot populate vfat filesystem with contents: hard fail") 222 c.Assert(cmdMkfs.Calls(), HasLen, 1) 223 c.Assert(cmdMcopy.Calls(), HasLen, 1) 224 } 225 226 func (m *mkfsSuite) TestMkfsVfatHappyNoContents(c *C) { 227 cmdMkfs := testutil.MockCommand(c, "mkfs.vfat", "") 228 defer cmdMkfs.Restore() 229 230 cmdMcopy := testutil.MockCommand(c, "mcopy", "") 231 defer cmdMcopy.Restore() 232 233 err := internal.MkfsWithContent("vfat", "foo.img", "my-label", "") 234 c.Assert(err, IsNil) 235 c.Assert(cmdMkfs.Calls(), HasLen, 1) 236 // mcopy was not called 237 c.Assert(cmdMcopy.Calls(), HasLen, 0) 238 } 239 240 func (m *mkfsSuite) TestMkfsInvalidFs(c *C) { 241 err := internal.MkfsWithContent("no-fs", "foo.img", "my-label", "") 242 c.Assert(err, ErrorMatches, `cannot create unsupported filesystem "no-fs"`) 243 244 err = internal.Mkfs("no-fs", "foo.img", "my-label") 245 c.Assert(err, ErrorMatches, `cannot create unsupported filesystem "no-fs"`) 246 } 247 248 func makeSizedFile(c *C, path string, size int64, content []byte) { 249 err := os.MkdirAll(filepath.Dir(path), 0755) 250 c.Assert(err, IsNil) 251 252 f, err := os.Create(path) 253 c.Assert(err, IsNil) 254 defer f.Close() 255 if size != 0 { 256 err = f.Truncate(size) 257 c.Assert(err, IsNil) 258 } 259 if content != nil { 260 _, err := io.Copy(f, bytes.NewReader(content)) 261 c.Assert(err, IsNil) 262 } 263 }