github.com/chipaca/snappy@v0.0.0-20210104084008-1f06296fe8ad/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)
    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)
    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)
    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)
   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)
   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  
   142  func (m *mkfsSuite) TestMkfsExt4Error(c *C) {
   143  	cmd := testutil.MockCommand(c, "fakeroot", "echo 'command failed'; exit 1")
   144  	defer cmd.Restore()
   145  
   146  	err := internal.MkfsWithContent("ext4", "foo.img", "my-label", "contents", 0)
   147  	c.Assert(err, ErrorMatches, "command failed")
   148  }
   149  
   150  func (m *mkfsSuite) TestMkfsVfatHappySimple(c *C) {
   151  	// no contents, should not fail
   152  	d := c.MkDir()
   153  
   154  	cmd := testutil.MockCommand(c, "mkfs.vfat", "")
   155  	defer cmd.Restore()
   156  
   157  	err := internal.MkfsWithContent("vfat", "foo.img", "my-label", d, 0)
   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  	cmd.ForgetCalls()
   171  
   172  	// empty label
   173  	err = internal.MkfsWithContent("vfat", "foo.img", "", d, 0)
   174  	c.Assert(err, IsNil)
   175  	c.Check(cmd.Calls(), DeepEquals, [][]string{
   176  		{
   177  			"mkfs.vfat",
   178  			"-S", "512",
   179  			"-s", "1",
   180  			"-F", "32",
   181  			"foo.img",
   182  		},
   183  	})
   184  
   185  	cmd.ForgetCalls()
   186  
   187  	// no content
   188  	err = internal.Mkfs("vfat", "foo.img", "my-label", 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  
   202  func (m *mkfsSuite) TestMkfsVfatWithSize(c *C) {
   203  	d := c.MkDir()
   204  
   205  	cmd := testutil.MockCommand(c, "mkfs.vfat", "")
   206  	defer cmd.Restore()
   207  
   208  	err := internal.MkfsWithContent("vfat", "foo.img", "my-label", d, 32*1024*1024)
   209  	c.Assert(err, IsNil)
   210  	c.Check(cmd.Calls(), DeepEquals, [][]string{
   211  		{
   212  			"mkfs.vfat",
   213  			"-S", "512",
   214  			"-s", "1",
   215  			"-F", "32",
   216  			"-n", "my-label",
   217  			"foo.img",
   218  		},
   219  	})
   220  }
   221  
   222  func (m *mkfsSuite) TestMkfsVfatHappyContents(c *C) {
   223  	d := c.MkDir()
   224  	makeSizedFile(c, filepath.Join(d, "foo"), 128, []byte("foo foo foo"))
   225  	makeSizedFile(c, filepath.Join(d, "bar/bar-content"), 128, []byte("bar bar bar"))
   226  
   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", d, 0)
   234  	c.Assert(err, IsNil)
   235  	c.Assert(cmdMkfs.Calls(), HasLen, 1)
   236  
   237  	c.Assert(cmdMcopy.Calls(), DeepEquals, [][]string{
   238  		{"mcopy", "-s", "-i", "foo.img", filepath.Join(d, "bar"), filepath.Join(d, "foo"), "::"},
   239  	})
   240  }
   241  
   242  func (m *mkfsSuite) TestMkfsVfatErrorSimpleFail(c *C) {
   243  	d := c.MkDir()
   244  
   245  	cmd := testutil.MockCommand(c, "mkfs.vfat", "echo 'failed'; false")
   246  	defer cmd.Restore()
   247  
   248  	err := internal.MkfsWithContent("vfat", "foo.img", "my-label", d, 0)
   249  	c.Assert(err, ErrorMatches, "failed")
   250  }
   251  
   252  func (m *mkfsSuite) TestMkfsVfatErrorUnreadableDir(c *C) {
   253  	cmd := testutil.MockCommand(c, "mkfs.vfat", "")
   254  	defer cmd.Restore()
   255  
   256  	err := internal.MkfsWithContent("vfat", "foo.img", "my-label", "dir-does-not-exist", 0)
   257  	c.Assert(err, ErrorMatches, "cannot list directory contents: .* no such file or directory")
   258  	c.Assert(cmd.Calls(), HasLen, 1)
   259  }
   260  
   261  func (m *mkfsSuite) TestMkfsVfatErrorInMcopy(c *C) {
   262  	d := c.MkDir()
   263  	makeSizedFile(c, filepath.Join(d, "foo"), 128, []byte("foo foo foo"))
   264  
   265  	cmdMkfs := testutil.MockCommand(c, "mkfs.vfat", "")
   266  	defer cmdMkfs.Restore()
   267  
   268  	cmdMcopy := testutil.MockCommand(c, "mcopy", "echo 'hard fail'; exit 1")
   269  	defer cmdMcopy.Restore()
   270  
   271  	err := internal.MkfsWithContent("vfat", "foo.img", "my-label", d, 0)
   272  	c.Assert(err, ErrorMatches, "cannot populate vfat filesystem with contents: hard fail")
   273  	c.Assert(cmdMkfs.Calls(), HasLen, 1)
   274  	c.Assert(cmdMcopy.Calls(), HasLen, 1)
   275  }
   276  
   277  func (m *mkfsSuite) TestMkfsVfatHappyNoContents(c *C) {
   278  	cmdMkfs := testutil.MockCommand(c, "mkfs.vfat", "")
   279  	defer cmdMkfs.Restore()
   280  
   281  	cmdMcopy := testutil.MockCommand(c, "mcopy", "")
   282  	defer cmdMcopy.Restore()
   283  
   284  	err := internal.MkfsWithContent("vfat", "foo.img", "my-label", "", 0)
   285  	c.Assert(err, IsNil)
   286  	c.Assert(cmdMkfs.Calls(), HasLen, 1)
   287  	// mcopy was not called
   288  	c.Assert(cmdMcopy.Calls(), HasLen, 0)
   289  }
   290  
   291  func (m *mkfsSuite) TestMkfsInvalidFs(c *C) {
   292  	err := internal.MkfsWithContent("no-fs", "foo.img", "my-label", "", 0)
   293  	c.Assert(err, ErrorMatches, `cannot create unsupported filesystem "no-fs"`)
   294  
   295  	err = internal.Mkfs("no-fs", "foo.img", "my-label", 0)
   296  	c.Assert(err, ErrorMatches, `cannot create unsupported filesystem "no-fs"`)
   297  }
   298  
   299  func makeSizedFile(c *C, path string, size int64, content []byte) {
   300  	err := os.MkdirAll(filepath.Dir(path), 0755)
   301  	c.Assert(err, IsNil)
   302  
   303  	f, err := os.Create(path)
   304  	c.Assert(err, IsNil)
   305  	defer f.Close()
   306  	if size != 0 {
   307  		err = f.Truncate(size)
   308  		c.Assert(err, IsNil)
   309  	}
   310  	if content != nil {
   311  		_, err := io.Copy(f, bytes.NewReader(content))
   312  		c.Assert(err, IsNil)
   313  	}
   314  }