github.com/hugh712/snapd@v0.0.0-20200910133618-1a99902bd583/osutil/disks/mockdisk_test.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2020 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 disks_test
    21  
    22  import (
    23  	. "gopkg.in/check.v1"
    24  
    25  	"golang.org/x/xerrors"
    26  
    27  	"github.com/snapcore/snapd/dirs"
    28  	"github.com/snapcore/snapd/osutil/disks"
    29  	"github.com/snapcore/snapd/testutil"
    30  )
    31  
    32  type mockDiskSuite struct {
    33  	testutil.BaseTest
    34  }
    35  
    36  var _ = Suite(&mockDiskSuite{})
    37  
    38  func (s *mockDiskSuite) SetUpTest(c *C) {
    39  	dirs.SetRootDir(c.MkDir())
    40  }
    41  
    42  func (s *mockDiskSuite) TestMockMountPointDisksToPartitionMappingVerifiesUniqueness(c *C) {
    43  	// two different disks with different DevNum's
    44  	d1 := &disks.MockDiskMapping{
    45  		FilesystemLabelToPartUUID: map[string]string{
    46  			"label1": "part1",
    47  		},
    48  		DiskHasPartitions: true,
    49  		DevNum:            "d1",
    50  	}
    51  
    52  	d2 := &disks.MockDiskMapping{
    53  		FilesystemLabelToPartUUID: map[string]string{
    54  			"label1": "part1",
    55  		},
    56  		DiskHasPartitions: false,
    57  		DevNum:            "d2",
    58  	}
    59  
    60  	// the pointers are different, and they are not the same
    61  	c.Assert(d1, Not(Equals), d2)
    62  	c.Assert(d1, Not(DeepEquals), d2)
    63  
    64  	m := map[disks.Mountpoint]*disks.MockDiskMapping{
    65  		{Mountpoint: "mount1"}: d1,
    66  		{Mountpoint: "mount2"}: d1,
    67  		{Mountpoint: "mount3"}: d2,
    68  	}
    69  
    70  	// mocking works
    71  	r := disks.MockMountPointDisksToPartitionMapping(m)
    72  	defer r()
    73  
    74  	// changing so they have the same DevNum doesn't work though
    75  	d2.DevNum = "d1"
    76  	c.Assert(
    77  		func() { disks.MockMountPointDisksToPartitionMapping(m) },
    78  		PanicMatches,
    79  		`mocked disks .* and .* have the same DevNum \(d1\) but are not the same object`,
    80  	)
    81  
    82  	// mocking with just one disk at multiple mount points works too
    83  	m2 := map[disks.Mountpoint]*disks.MockDiskMapping{
    84  		{Mountpoint: "mount1"}: d1,
    85  		{Mountpoint: "mount2"}: d1,
    86  	}
    87  	r = disks.MockMountPointDisksToPartitionMapping(m2)
    88  	defer r()
    89  }
    90  
    91  func (s *mockDiskSuite) TestMockMountPointDisksToPartitionMapping(c *C) {
    92  	d1 := &disks.MockDiskMapping{
    93  		FilesystemLabelToPartUUID: map[string]string{
    94  			"label1": "part1",
    95  		},
    96  		DiskHasPartitions: true,
    97  		DevNum:            "d1",
    98  	}
    99  
   100  	d2 := &disks.MockDiskMapping{
   101  		FilesystemLabelToPartUUID: map[string]string{
   102  			"label2": "part2",
   103  		},
   104  		DiskHasPartitions: true,
   105  		DevNum:            "d2",
   106  	}
   107  
   108  	r := disks.MockMountPointDisksToPartitionMapping(
   109  		map[disks.Mountpoint]*disks.MockDiskMapping{
   110  			{Mountpoint: "mount1"}: d1,
   111  			{Mountpoint: "mount2"}: d1,
   112  			{Mountpoint: "mount3"}: d2,
   113  		},
   114  	)
   115  	defer r()
   116  
   117  	// we can find the mock disk
   118  	foundDisk, err := disks.DiskFromMountPoint("mount1", nil)
   119  	c.Assert(err, IsNil)
   120  
   121  	// and it has labels
   122  	label, err := foundDisk.FindMatchingPartitionUUID("label1")
   123  	c.Assert(err, IsNil)
   124  	c.Assert(label, Equals, "part1")
   125  
   126  	// the same mount point is always from the same disk
   127  	matches, err := foundDisk.MountPointIsFromDisk("mount1", nil)
   128  	c.Assert(err, IsNil)
   129  	c.Assert(matches, Equals, true)
   130  
   131  	// mount2 goes to the same disk, as per the mapping above
   132  	matches, err = foundDisk.MountPointIsFromDisk("mount2", nil)
   133  	c.Assert(err, IsNil)
   134  	c.Assert(matches, Equals, true)
   135  
   136  	// mount3 does not however
   137  	matches, err = foundDisk.MountPointIsFromDisk("mount3", nil)
   138  	c.Assert(err, IsNil)
   139  	c.Assert(matches, Equals, false)
   140  
   141  	// a disk from mount3 is also able to be found
   142  	foundDisk2, err := disks.DiskFromMountPoint("mount3", nil)
   143  	c.Assert(err, IsNil)
   144  
   145  	// we can find label2 from mount3's disk
   146  	label, err = foundDisk2.FindMatchingPartitionUUID("label2")
   147  	c.Assert(err, IsNil)
   148  	c.Assert(label, Equals, "part2")
   149  
   150  	// we can't find label1 from mount1's or mount2's disk
   151  	_, err = foundDisk2.FindMatchingPartitionUUID("label1")
   152  	c.Assert(err, ErrorMatches, "filesystem label \"label1\" not found")
   153  	var errNotFound disks.FilesystemLabelNotFoundError
   154  	c.Assert(xerrors.As(err, &errNotFound), Equals, true)
   155  
   156  	// mount1 and mount2 do not match mount3 disk
   157  	matches, err = foundDisk2.MountPointIsFromDisk("mount1", nil)
   158  	c.Assert(err, IsNil)
   159  	c.Assert(matches, Equals, false)
   160  	matches, err = foundDisk2.MountPointIsFromDisk("mount2", nil)
   161  	c.Assert(err, IsNil)
   162  	c.Assert(matches, Equals, false)
   163  }
   164  
   165  func (s *mockDiskSuite) TestMockMountPointDisksToPartitionMappingDecryptedDevices(c *C) {
   166  	d1 := &disks.MockDiskMapping{
   167  		FilesystemLabelToPartUUID: map[string]string{
   168  			"ubuntu-seed":     "ubuntu-seed-part",
   169  			"ubuntu-boot":     "ubuntu-boot-part",
   170  			"ubuntu-data-enc": "ubuntu-data-enc-part",
   171  		},
   172  		DiskHasPartitions: true,
   173  		DevNum:            "d1",
   174  	}
   175  
   176  	r := disks.MockMountPointDisksToPartitionMapping(
   177  		map[disks.Mountpoint]*disks.MockDiskMapping{
   178  			{Mountpoint: "/run/mnt/ubuntu-boot"}: d1,
   179  			{Mountpoint: "/run/mnt/ubuntu-seed"}: d1,
   180  			{
   181  				Mountpoint:        "/run/mnt/ubuntu-data",
   182  				IsDecryptedDevice: true,
   183  			}: d1,
   184  		},
   185  	)
   186  	defer r()
   187  
   188  	// first we get ubuntu-boot (which is not a decrypted device)
   189  	d, err := disks.DiskFromMountPoint("/run/mnt/ubuntu-boot", nil)
   190  	c.Assert(err, IsNil)
   191  
   192  	// next we find ubuntu-seed (also not decrypted)
   193  	label, err := d.FindMatchingPartitionUUID("ubuntu-seed")
   194  	c.Assert(err, IsNil)
   195  	c.Assert(label, Equals, "ubuntu-seed-part")
   196  
   197  	// then we find ubuntu-data-enc, which is not a decrypted device
   198  	label, err = d.FindMatchingPartitionUUID("ubuntu-data-enc")
   199  	c.Assert(err, IsNil)
   200  	c.Assert(label, Equals, "ubuntu-data-enc-part")
   201  
   202  	// and then finally ubuntu-data enc is from the same disk as ubuntu-boot
   203  	// with IsDecryptedDevice = true
   204  	opts := &disks.Options{IsDecryptedDevice: true}
   205  	matches, err := d.MountPointIsFromDisk("/run/mnt/ubuntu-data", opts)
   206  	c.Assert(err, IsNil)
   207  	c.Assert(matches, Equals, true)
   208  }