github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/storage/provider/managedfs_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package provider_test
     5  
     6  import (
     7  	"fmt"
     8  	"io/ioutil"
     9  	"path/filepath"
    10  
    11  	jc "github.com/juju/testing/checkers"
    12  	gc "gopkg.in/check.v1"
    13  	"gopkg.in/juju/names.v2"
    14  
    15  	"github.com/juju/juju/environs/context"
    16  	"github.com/juju/juju/storage"
    17  	"github.com/juju/juju/storage/provider"
    18  	"github.com/juju/juju/testing"
    19  )
    20  
    21  var _ = gc.Suite(&managedfsSuite{})
    22  
    23  type managedfsSuite struct {
    24  	testing.BaseSuite
    25  	commands     *mockRunCommand
    26  	dirFuncs     *provider.MockDirFuncs
    27  	blockDevices map[names.VolumeTag]storage.BlockDevice
    28  	filesystems  map[names.FilesystemTag]storage.Filesystem
    29  	fakeEtcDir   string
    30  
    31  	callCtx context.ProviderCallContext
    32  }
    33  
    34  func (s *managedfsSuite) SetUpTest(c *gc.C) {
    35  	s.BaseSuite.SetUpTest(c)
    36  	s.blockDevices = make(map[names.VolumeTag]storage.BlockDevice)
    37  	s.filesystems = make(map[names.FilesystemTag]storage.Filesystem)
    38  	s.callCtx = context.NewCloudCallContext()
    39  	s.fakeEtcDir = c.MkDir()
    40  }
    41  
    42  func (s *managedfsSuite) TearDownTest(c *gc.C) {
    43  	if s.commands != nil {
    44  		s.commands.assertDrained()
    45  	}
    46  	s.BaseSuite.TearDownTest(c)
    47  }
    48  
    49  func (s *managedfsSuite) initSource(c *gc.C) storage.FilesystemSource {
    50  	s.commands = &mockRunCommand{c: c}
    51  	source, mockDirFuncs := provider.NewMockManagedFilesystemSource(
    52  		s.fakeEtcDir,
    53  		s.commands.run,
    54  		s.blockDevices,
    55  		s.filesystems,
    56  	)
    57  	s.dirFuncs = mockDirFuncs
    58  	return source
    59  }
    60  
    61  func (s *managedfsSuite) TestCreateFilesystems(c *gc.C) {
    62  	source := s.initSource(c)
    63  	// sda is (re)partitioned and the filesystem created
    64  	// on the partition.
    65  	s.commands.expect("sgdisk", "--zap-all", "/dev/sda")
    66  	s.commands.expect("sgdisk", "-n", "1:0:-1", "/dev/sda")
    67  	s.commands.expect("mkfs.ext4", "/dev/sda1")
    68  	// xvdf1 is assumed to not require a partition, on
    69  	// account of ending with a digit.
    70  	s.commands.expect("mkfs.ext4", "/dev/xvdf1")
    71  
    72  	s.blockDevices[names.NewVolumeTag("0")] = storage.BlockDevice{
    73  		DeviceName: "sda",
    74  		HardwareId: "capncrunch",
    75  		Size:       2,
    76  	}
    77  	s.blockDevices[names.NewVolumeTag("1")] = storage.BlockDevice{
    78  		DeviceName: "xvdf1",
    79  		HardwareId: "weetbix",
    80  		Size:       3,
    81  	}
    82  	results, err := source.CreateFilesystems(s.callCtx, []storage.FilesystemParams{{
    83  		Tag:    names.NewFilesystemTag("0/0"),
    84  		Volume: names.NewVolumeTag("0"),
    85  		Size:   2,
    86  	}, {
    87  		Tag:    names.NewFilesystemTag("0/1"),
    88  		Volume: names.NewVolumeTag("1"),
    89  		Size:   3,
    90  	}})
    91  	c.Assert(err, jc.ErrorIsNil)
    92  	c.Assert(results, jc.DeepEquals, []storage.CreateFilesystemsResult{{
    93  		Filesystem: &storage.Filesystem{
    94  			names.NewFilesystemTag("0/0"),
    95  			names.NewVolumeTag("0"),
    96  			storage.FilesystemInfo{
    97  				FilesystemId: "filesystem-0-0",
    98  				Size:         2,
    99  			},
   100  		},
   101  	}, {
   102  		Filesystem: &storage.Filesystem{
   103  			names.NewFilesystemTag("0/1"),
   104  			names.NewVolumeTag("1"),
   105  			storage.FilesystemInfo{
   106  				FilesystemId: "filesystem-0-1",
   107  				Size:         3,
   108  			},
   109  		},
   110  	}})
   111  }
   112  
   113  func (s *managedfsSuite) TestCreateFilesystemsNoBlockDevice(c *gc.C) {
   114  	source := s.initSource(c)
   115  	results, err := source.CreateFilesystems(s.callCtx, []storage.FilesystemParams{{
   116  		Tag:    names.NewFilesystemTag("0/0"),
   117  		Volume: names.NewVolumeTag("0"),
   118  		Size:   2,
   119  	}})
   120  	c.Assert(err, jc.ErrorIsNil)
   121  	c.Assert(results[0].Error, gc.ErrorMatches, "backing-volume 0 is not yet attached")
   122  }
   123  
   124  const testMountPoint = "/in/the/place"
   125  
   126  func (s *managedfsSuite) TestAttachFilesystems(c *gc.C) {
   127  	nonRelatedFstabEntry := "/dev/foo /mount/point stuff"
   128  	err := ioutil.WriteFile(filepath.Join(s.fakeEtcDir, "fstab"), []byte(nonRelatedFstabEntry), 0644)
   129  	c.Assert(err, jc.ErrorIsNil)
   130  
   131  	mtabEntry := fmt.Sprintf("/dev/sda1 %s other mtab stuff", testMountPoint)
   132  	s.testAttachFilesystems(c, false, false, mtabEntry, nonRelatedFstabEntry+"\n"+mtabEntry+"\n")
   133  }
   134  
   135  func (s *managedfsSuite) TestAttachFilesystemsMissingMtab(c *gc.C) {
   136  	nonRelatedFstabEntry := "/dev/foo /mount/point stuff\n"
   137  	err := ioutil.WriteFile(filepath.Join(s.fakeEtcDir, "fstab"), []byte(nonRelatedFstabEntry), 0644)
   138  	c.Assert(err, jc.ErrorIsNil)
   139  
   140  	s.testAttachFilesystems(c, false, false, "", nonRelatedFstabEntry)
   141  }
   142  
   143  func (s *managedfsSuite) TestAttachFilesystemsExistingFstabEntry(c *gc.C) {
   144  	existingFstabEntry := fmt.Sprintf("/dev/sda1 %s existing mtab stuff\n", testMountPoint)
   145  	err := ioutil.WriteFile(filepath.Join(s.fakeEtcDir, "fstab"), []byte(existingFstabEntry), 0644)
   146  	c.Assert(err, jc.ErrorIsNil)
   147  
   148  	mtabEntry := fmt.Sprintf("/dev/sda1 %s other mtab stuff", testMountPoint)
   149  	s.testAttachFilesystems(c, false, false, mtabEntry, existingFstabEntry)
   150  }
   151  
   152  func (s *managedfsSuite) TestAttachFilesystemsReadOnly(c *gc.C) {
   153  	mtabEntry := fmt.Sprintf("\n/dev/sda1 %s other mtab stuff", testMountPoint)
   154  	s.testAttachFilesystems(c, true, false, mtabEntry, mtabEntry+"\n")
   155  }
   156  
   157  func (s *managedfsSuite) TestAttachFilesystemsReattach(c *gc.C) {
   158  	mtabEntry := fmt.Sprintf("/dev/sda1 %s other mtab stuff", testMountPoint)
   159  	s.testAttachFilesystems(c, true, true, mtabEntry, "")
   160  }
   161  
   162  func (s *managedfsSuite) testAttachFilesystems(c *gc.C, readOnly, reattach bool, mtab, fstab string) {
   163  	source := s.initSource(c)
   164  	cmd := s.commands.expect("df", "--output=source", filepath.Dir(testMountPoint))
   165  	cmd.respond("headers\n/same/as/rootfs", nil)
   166  	cmd = s.commands.expect("df", "--output=source", testMountPoint)
   167  
   168  	if mtab != "" {
   169  		err := ioutil.WriteFile(filepath.Join(s.fakeEtcDir, "mtab"), []byte(mtab), 0644)
   170  		c.Assert(err, jc.ErrorIsNil)
   171  	}
   172  
   173  	if reattach {
   174  		cmd.respond("headers\n/different/to/rootfs", nil)
   175  	} else {
   176  		cmd.respond("headers\n/same/as/rootfs", nil)
   177  		var args []string
   178  		if readOnly {
   179  			args = append(args, "-o", "ro")
   180  		}
   181  		args = append(args, "/dev/sda1", testMountPoint)
   182  		s.commands.expect("mount", args...)
   183  	}
   184  
   185  	s.blockDevices[names.NewVolumeTag("0")] = storage.BlockDevice{
   186  		DeviceName: "sda",
   187  		HardwareId: "capncrunch",
   188  		Size:       2,
   189  	}
   190  	s.filesystems[names.NewFilesystemTag("0/0")] = storage.Filesystem{
   191  		Tag:    names.NewFilesystemTag("0/0"),
   192  		Volume: names.NewVolumeTag("0"),
   193  	}
   194  
   195  	results, err := source.AttachFilesystems(s.callCtx, []storage.FilesystemAttachmentParams{{
   196  		Filesystem:   names.NewFilesystemTag("0/0"),
   197  		FilesystemId: "filesystem-0-0",
   198  		AttachmentParams: storage.AttachmentParams{
   199  			Machine:    names.NewMachineTag("0"),
   200  			InstanceId: "inst-ance",
   201  			ReadOnly:   readOnly,
   202  		},
   203  		Path: testMountPoint,
   204  	}})
   205  	c.Assert(err, jc.ErrorIsNil)
   206  	c.Assert(results, jc.DeepEquals, []storage.AttachFilesystemsResult{{
   207  		FilesystemAttachment: &storage.FilesystemAttachment{
   208  			names.NewFilesystemTag("0/0"),
   209  			names.NewMachineTag("0"),
   210  			storage.FilesystemAttachmentInfo{
   211  				Path:     testMountPoint,
   212  				ReadOnly: readOnly,
   213  			},
   214  		},
   215  	}})
   216  
   217  	if fstab != "" {
   218  		data, err := ioutil.ReadFile(filepath.Join(s.fakeEtcDir, "fstab"))
   219  		c.Assert(err, jc.ErrorIsNil)
   220  		c.Assert(string(data), gc.Equals, fstab)
   221  	}
   222  }
   223  
   224  func (s *managedfsSuite) TestDetachFilesystems(c *gc.C) {
   225  	nonRelatedFstabEntry := "/dev/foo /mount/point stuff\n"
   226  	fstabEntry := fmt.Sprintf("%s %s other mtab stuff", "/dev/sda1", testMountPoint)
   227  	err := ioutil.WriteFile(filepath.Join(s.fakeEtcDir, "fstab"), []byte(nonRelatedFstabEntry+fstabEntry), 0644)
   228  	c.Assert(err, jc.ErrorIsNil)
   229  	source := s.initSource(c)
   230  	testDetachFilesystems(c, s.commands, source, s.callCtx, true, s.fakeEtcDir, nonRelatedFstabEntry)
   231  }
   232  
   233  func (s *managedfsSuite) TestDetachFilesystemsUnattached(c *gc.C) {
   234  	source := s.initSource(c)
   235  	testDetachFilesystems(c, s.commands, source, s.callCtx, false, s.fakeEtcDir, "")
   236  }