github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/state/blockdevices_test.go (about) 1 // Copyright 2014 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package state_test 5 6 import ( 7 "github.com/juju/errors" 8 "github.com/juju/names/v5" 9 jc "github.com/juju/testing/checkers" 10 gc "gopkg.in/check.v1" 11 12 "github.com/juju/juju/state" 13 "github.com/juju/juju/state/testing" 14 ) 15 16 type BlockDevicesSuite struct { 17 ConnSuite 18 machine *state.Machine 19 } 20 21 var _ = gc.Suite(&BlockDevicesSuite{}) 22 23 func (s *BlockDevicesSuite) SetUpTest(c *gc.C) { 24 s.ConnSuite.SetUpTest(c) 25 var err error 26 s.machine, err = s.State.AddMachine(state.UbuntuBase("12.10"), state.JobHostUnits) 27 c.Assert(err, jc.ErrorIsNil) 28 } 29 30 func (s *BlockDevicesSuite) assertBlockDevices(c *gc.C, tag names.MachineTag, expected []state.BlockDeviceInfo) { 31 sb, err := state.NewStorageBackend(s.State) 32 c.Assert(err, jc.ErrorIsNil) 33 info, err := sb.BlockDevices(tag) 34 c.Assert(err, jc.ErrorIsNil) 35 c.Assert(info, gc.DeepEquals, expected) 36 } 37 38 func (s *BlockDevicesSuite) TestSetMachineBlockDevices(c *gc.C) { 39 sda := state.BlockDeviceInfo{DeviceName: "sda"} 40 err := s.machine.SetMachineBlockDevices(sda) 41 c.Assert(err, jc.ErrorIsNil) 42 s.assertBlockDevices(c, s.machine.MachineTag(), []state.BlockDeviceInfo{sda}) 43 } 44 45 func (s *BlockDevicesSuite) TestSetMachineBlockDevicesReplaces(c *gc.C) { 46 sda := state.BlockDeviceInfo{DeviceName: "sda"} 47 err := s.machine.SetMachineBlockDevices(sda) 48 c.Assert(err, jc.ErrorIsNil) 49 50 sdb := state.BlockDeviceInfo{DeviceName: "sdb"} 51 err = s.machine.SetMachineBlockDevices(sdb) 52 c.Assert(err, jc.ErrorIsNil) 53 s.assertBlockDevices(c, s.machine.MachineTag(), []state.BlockDeviceInfo{sdb}) 54 } 55 56 func (s *BlockDevicesSuite) TestSetMachineBlockDevicesUpdates(c *gc.C) { 57 sda := state.BlockDeviceInfo{DeviceName: "sda"} 58 sdb := state.BlockDeviceInfo{DeviceName: "sdb"} 59 err := s.machine.SetMachineBlockDevices(sda, sdb) 60 c.Assert(err, jc.ErrorIsNil) 61 s.assertBlockDevices(c, s.machine.MachineTag(), []state.BlockDeviceInfo{sda, sdb}) 62 63 sdb.Label = "root" 64 err = s.machine.SetMachineBlockDevices(sdb) 65 c.Assert(err, jc.ErrorIsNil) 66 s.assertBlockDevices(c, s.machine.MachineTag(), []state.BlockDeviceInfo{sdb}) 67 68 // If a device is attached, unattached, then attached again, 69 // then it gets a new name. 70 sdb.Label = "" // Label should be reset. 71 sdb.FilesystemType = "ext4" 72 err = s.machine.SetMachineBlockDevices(sda, sdb) 73 c.Assert(err, jc.ErrorIsNil) 74 s.assertBlockDevices(c, s.machine.MachineTag(), []state.BlockDeviceInfo{ 75 sda, 76 sdb, 77 }) 78 } 79 80 func (s *BlockDevicesSuite) TestSetMachineBlockDevicesMachineDying(c *gc.C) { 81 err := s.machine.Destroy() 82 c.Assert(err, jc.ErrorIsNil) 83 84 sda := state.BlockDeviceInfo{DeviceName: "sda"} 85 err = s.machine.SetMachineBlockDevices(sda) 86 c.Assert(err, jc.ErrorIsNil) 87 s.assertBlockDevices(c, s.machine.MachineTag(), []state.BlockDeviceInfo{sda}) 88 } 89 90 func (s *BlockDevicesSuite) TestSetMachineBlockDevicesUnchanged(c *gc.C) { 91 sda := state.BlockDeviceInfo{DeviceName: "sda"} 92 err := s.machine.SetMachineBlockDevices(sda) 93 c.Assert(err, jc.ErrorIsNil) 94 s.assertBlockDevices(c, s.machine.MachineTag(), []state.BlockDeviceInfo{sda}) 95 96 // Setting the same should not change txn-revno. 97 docID := state.DocID(s.State, s.machine.Id()) 98 before, err := state.TxnRevno(s.State, state.BlockDevicesC, docID) 99 c.Assert(err, jc.ErrorIsNil) 100 101 err = s.machine.SetMachineBlockDevices(sda) 102 c.Assert(err, jc.ErrorIsNil) 103 104 after, err := state.TxnRevno(s.State, state.BlockDevicesC, docID) 105 c.Assert(err, jc.ErrorIsNil) 106 c.Assert(after, gc.Equals, before) 107 } 108 109 func (s *BlockDevicesSuite) TestSetMachineBlockDevicesConcurrently(c *gc.C) { 110 sdaInner := state.BlockDeviceInfo{DeviceName: "sda"} 111 defer state.SetBeforeHooks(c, s.State, func() { 112 err := s.machine.SetMachineBlockDevices(sdaInner) 113 c.Assert(err, jc.ErrorIsNil) 114 }).Check() 115 116 sdaOuter := state.BlockDeviceInfo{ 117 DeviceName: "sda", 118 Label: "root", 119 } 120 err := s.machine.SetMachineBlockDevices(sdaOuter) 121 c.Assert(err, jc.ErrorIsNil) 122 123 // the outer call should wipe out the inner one's update. 124 s.assertBlockDevices(c, s.machine.MachineTag(), []state.BlockDeviceInfo{ 125 sdaOuter, 126 }) 127 } 128 129 func (s *BlockDevicesSuite) TestSetMachineBlockDevicesEmpty(c *gc.C) { 130 sda := state.BlockDeviceInfo{DeviceName: "sda"} 131 err := s.machine.SetMachineBlockDevices(sda) 132 c.Assert(err, jc.ErrorIsNil) 133 s.assertBlockDevices(c, s.machine.MachineTag(), []state.BlockDeviceInfo{sda}) 134 135 err = s.machine.SetMachineBlockDevices() 136 c.Assert(err, jc.ErrorIsNil) 137 s.assertBlockDevices(c, s.machine.MachineTag(), []state.BlockDeviceInfo{}) 138 } 139 140 func (s *BlockDevicesSuite) TestBlockDevicesMachineRemove(c *gc.C) { 141 sda := state.BlockDeviceInfo{DeviceName: "sda"} 142 err := s.machine.SetMachineBlockDevices(sda) 143 c.Assert(err, jc.ErrorIsNil) 144 145 err = s.machine.EnsureDead() 146 c.Assert(err, jc.ErrorIsNil) 147 err = s.machine.Remove() 148 c.Assert(err, jc.ErrorIsNil) 149 150 sb, err := state.NewStorageBackend(s.State) 151 c.Assert(err, jc.ErrorIsNil) 152 _, err = sb.BlockDevices(s.machine.MachineTag()) 153 c.Assert(err, jc.Satisfies, errors.IsNotFound) 154 } 155 156 func (s *BlockDevicesSuite) TestWatchBlockDevices(c *gc.C) { 157 sda := state.BlockDeviceInfo{DeviceName: "sda"} 158 sdb := state.BlockDeviceInfo{DeviceName: "sdb"} 159 sdc := state.BlockDeviceInfo{DeviceName: "sdc"} 160 err := s.machine.SetMachineBlockDevices(sda, sdb, sdc) 161 c.Assert(err, jc.ErrorIsNil) 162 163 // Start block device watcher. 164 sb, err := state.NewStorageBackend(s.State) 165 c.Assert(err, jc.ErrorIsNil) 166 w := sb.WatchBlockDevices(s.machine.MachineTag()) 167 defer testing.AssertStop(c, w) 168 wc := testing.NewNotifyWatcherC(c, w) 169 wc.AssertOneChange() 170 171 // Setting the same should not trigger the watcher. 172 err = s.machine.SetMachineBlockDevices(sdc, sdb, sda) 173 c.Assert(err, jc.ErrorIsNil) 174 wc.AssertNoChange() 175 176 // change sdb's label. 177 sdb.Label = "fatty" 178 err = s.machine.SetMachineBlockDevices(sda, sdb, sdc) 179 c.Assert(err, jc.ErrorIsNil) 180 wc.AssertOneChange() 181 182 // change sda's label and sdb's UUID at once. 183 sda.Label = "giggly" 184 sdb.UUID = "4c062658-6225-4f4b-96f3-debf00b964b4" 185 err = s.machine.SetMachineBlockDevices(sda, sdb, sdc) 186 c.Assert(err, jc.ErrorIsNil) 187 wc.AssertOneChange() 188 189 // drop sdc. 190 err = s.machine.SetMachineBlockDevices(sda, sdb) 191 c.Assert(err, jc.ErrorIsNil) 192 wc.AssertOneChange() 193 194 // add sdc again: should get a new name. 195 err = s.machine.SetMachineBlockDevices(sda, sdb, sdc) 196 c.Assert(err, jc.ErrorIsNil) 197 wc.AssertOneChange() 198 }