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 }