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  }