github.com/david-imola/snapd@v0.0.0-20210611180407-2de8ddeece6d/sanity/squashfs_test.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2018 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 sanity_test
    21  
    22  import (
    23  	. "gopkg.in/check.v1"
    24  
    25  	"github.com/snapcore/snapd/osutil/squashfs"
    26  	"github.com/snapcore/snapd/sandbox/selinux"
    27  	"github.com/snapcore/snapd/sanity"
    28  	"github.com/snapcore/snapd/testutil"
    29  )
    30  
    31  func (s *sanitySuite) TestCheckSquashfsMountHappy(c *C) {
    32  	restore := squashfs.MockNeedsFuse(false)
    33  	defer restore()
    34  
    35  	// we create a canary.txt with the same prefix as the real one
    36  	mockMount := testutil.MockCommand(c, "mount", `echo 'This file is used to check that snapd can read a squashfs image.' > "$4"/canary.txt`)
    37  	defer mockMount.Restore()
    38  
    39  	mockUmount := testutil.MockCommand(c, "umount", "")
    40  	defer mockUmount.Restore()
    41  
    42  	err := sanity.CheckSquashfsMount()
    43  	c.Check(err, IsNil)
    44  
    45  	c.Check(mockMount.Calls(), HasLen, 1)
    46  	c.Check(mockUmount.Calls(), HasLen, 1)
    47  
    48  	squashfsFile := mockMount.Calls()[0][3]
    49  	mountPoint := mockMount.Calls()[0][4]
    50  	c.Check(mockMount.Calls(), DeepEquals, [][]string{
    51  		{"mount", "-t", "squashfs", squashfsFile, mountPoint},
    52  	})
    53  	c.Check(mockUmount.Calls(), DeepEquals, [][]string{
    54  		{"umount", "-l", mountPoint},
    55  	})
    56  }
    57  
    58  func (s *sanitySuite) TestCheckSquashfsMountNotHappy(c *C) {
    59  	restore := squashfs.MockNeedsFuse(false)
    60  	defer restore()
    61  
    62  	mockMount := testutil.MockCommand(c, "mount", "echo iz-broken;false")
    63  	defer mockMount.Restore()
    64  
    65  	mockUmount := testutil.MockCommand(c, "umount", "")
    66  	defer mockUmount.Restore()
    67  
    68  	err := sanity.CheckSquashfsMount()
    69  	c.Check(err, ErrorMatches, "cannot mount squashfs image using.*")
    70  
    71  	c.Check(mockMount.Calls(), HasLen, 1)
    72  	c.Check(mockUmount.Calls(), HasLen, 0)
    73  
    74  	squashfsFile := mockMount.Calls()[0][3]
    75  	mountPoint := mockMount.Calls()[0][4]
    76  	c.Check(mockMount.Calls(), DeepEquals, [][]string{
    77  		{"mount", "-t", "squashfs", squashfsFile, mountPoint},
    78  	})
    79  }
    80  
    81  func (s *sanitySuite) TestCheckSquashfsMountWrongContent(c *C) {
    82  	restore := squashfs.MockNeedsFuse(false)
    83  	defer restore()
    84  
    85  	mockMount := testutil.MockCommand(c, "mount", `echo 'wrong content' > "$4"/canary.txt`)
    86  	defer mockMount.Restore()
    87  
    88  	mockUmount := testutil.MockCommand(c, "umount", "")
    89  	defer mockUmount.Restore()
    90  
    91  	err := sanity.CheckSquashfsMount()
    92  	c.Check(err, ErrorMatches, `unexpected squashfs canary content: "wrong content\\n"`)
    93  
    94  	c.Check(mockMount.Calls(), HasLen, 1)
    95  	c.Check(mockUmount.Calls(), HasLen, 1)
    96  }
    97  
    98  func (s *sanitySuite) TestCheckSquashfsMountSELinuxContext(c *C) {
    99  	restore := squashfs.MockNeedsFuse(false)
   100  	defer restore()
   101  
   102  	mockMount := testutil.MockCommand(c, "mount", "echo 'mock ran'")
   103  	defer mockMount.Restore()
   104  
   105  	mockUmount := testutil.MockCommand(c, "umount", "")
   106  	defer mockUmount.Restore()
   107  
   108  	mockSELinux := selinux.MockIsEnabled(func() (bool, error) { return true, nil })
   109  	defer mockSELinux()
   110  
   111  	err := sanity.CheckSquashfsMount()
   112  	c.Assert(err, ErrorMatches, `squashfs mount returned no err but canary file cannot be read`)
   113  
   114  	c.Check(mockMount.Calls(), HasLen, 1)
   115  	c.Check(mockUmount.Calls(), HasLen, 1)
   116  	squashfsFile := mockMount.Calls()[0][5]
   117  	mountPoint := mockMount.Calls()[0][6]
   118  
   119  	c.Check(mockMount.Calls(), DeepEquals, [][]string{
   120  		{"mount", "-t", "squashfs", "-o", "context=system_u:object_r:snappy_snap_t:s0", squashfsFile, mountPoint},
   121  	})
   122  }
   123  
   124  func (s *sanitySuite) TestCheckFuseNoFuseHappy(c *C) {
   125  	restore := squashfs.MockNeedsFuse(false)
   126  	defer restore()
   127  
   128  	c.Assert(sanity.CheckFuse(), IsNil)
   129  }
   130  
   131  func (s *sanitySuite) TestCheckFuseNeedsFuseAndHasFuse(c *C) {
   132  	restore := squashfs.MockNeedsFuse(true)
   133  	defer restore()
   134  
   135  	restore = sanity.MockFuseBinary("true")
   136  	defer restore()
   137  
   138  	c.Assert(sanity.CheckFuse(), IsNil)
   139  }
   140  
   141  func (s *sanitySuite) TestCheckFuseNoDevFuseUnhappy(c *C) {
   142  	restore := squashfs.MockNeedsFuse(true)
   143  	defer restore()
   144  
   145  	restore = sanity.MockFuseBinary("/it/does/not/exist")
   146  	defer restore()
   147  
   148  	c.Assert(sanity.CheckFuse(), ErrorMatches, `The "fuse" filesystem is required on this system but not available. Please try to install the fuse package.`)
   149  }