github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/apiserver/facades/agent/storageprovisioner/internal/filesystemwatcher/watchers_test.go (about) 1 // Copyright 2017 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package filesystemwatcher_test 5 6 import ( 7 "errors" 8 9 "github.com/juju/testing" 10 gc "gopkg.in/check.v1" 11 "gopkg.in/juju/names.v2" 12 13 "github.com/juju/juju/apiserver/facades/agent/storageprovisioner/internal/filesystemwatcher" 14 "github.com/juju/juju/state" 15 statetesting "github.com/juju/juju/state/testing" 16 ) 17 18 var _ = gc.Suite(&WatchersSuite{}) 19 20 type WatchersSuite struct { 21 testing.IsolationSuite 22 backend *mockBackend 23 watchers filesystemwatcher.Watchers 24 } 25 26 func (s *WatchersSuite) SetUpTest(c *gc.C) { 27 s.IsolationSuite.SetUpTest(c) 28 s.backend = &mockBackend{ 29 machineFilesystemsW: newStringsWatcher(), 30 unitFilesystemsW: newStringsWatcher(), 31 machineFilesystemAttachmentsW: newStringsWatcher(), 32 unitFilesystemAttachmentsW: newStringsWatcher(), 33 modelFilesystemsW: newStringsWatcher(), 34 modelFilesystemAttachmentsW: newStringsWatcher(), 35 modelVolumeAttachmentsW: newStringsWatcher(), 36 filesystems: map[string]*mockFilesystem{ 37 // filesystem 0 has no backing volume. 38 "0": {}, 39 // filesystem 1 is backed by volume 1. 40 "1": {volume: names.NewVolumeTag("1")}, 41 // filesystem 2 is backed by volume 2. 42 "2": {volume: names.NewVolumeTag("2")}, 43 }, 44 volumeAttachments: map[string]*mockVolumeAttachment{ 45 "1": {life: state.Alive}, 46 "2": {life: state.Alive}, 47 }, 48 volumeAttachmentRequested: make(chan names.VolumeTag, 10), 49 } 50 s.AddCleanup(func(*gc.C) { 51 s.backend.machineFilesystemsW.Stop() 52 s.backend.machineFilesystemAttachmentsW.Stop() 53 s.backend.modelFilesystemsW.Stop() 54 s.backend.modelFilesystemAttachmentsW.Stop() 55 s.backend.modelVolumeAttachmentsW.Stop() 56 }) 57 s.watchers.Backend = s.backend 58 } 59 60 func (s *WatchersSuite) TestWatchModelManagedFilesystems(c *gc.C) { 61 w := s.watchers.WatchModelManagedFilesystems() 62 defer statetesting.AssertKillAndWait(c, w) 63 s.backend.modelFilesystemsW.C <- []string{"0", "1"} 64 65 // Filesystem 1 has a backing volume, so should not be reported. 66 wc := statetesting.NewStringsWatcherC(c, nopSyncStarter{}, w) 67 wc.AssertChangeInSingleEvent("0") 68 wc.AssertNoChange() 69 } 70 71 func (s *WatchersSuite) TestWatchModelManagedFilesystemsWatcherErrorsPropagate(c *gc.C) { 72 w := s.watchers.WatchModelManagedFilesystems() 73 s.backend.modelFilesystemsW.T.Kill(errors.New("rah")) 74 c.Assert(w.Wait(), gc.ErrorMatches, "rah") 75 } 76 77 func (s *WatchersSuite) TestWatchModelManagedFilesystemAttachments(c *gc.C) { 78 w := s.watchers.WatchModelManagedFilesystemAttachments() 79 defer statetesting.AssertKillAndWait(c, w) 80 s.backend.modelFilesystemAttachmentsW.C <- []string{"0:0", "0:1"} 81 82 // Filesystem 1 has a backing volume, so should not be reported. 83 wc := statetesting.NewStringsWatcherC(c, nopSyncStarter{}, w) 84 wc.AssertChangeInSingleEvent("0:0") 85 wc.AssertNoChange() 86 } 87 88 func (s *WatchersSuite) TestWatchModelManagedFilesystemAttachmentsWatcherErrorsPropagate(c *gc.C) { 89 w := s.watchers.WatchModelManagedFilesystemAttachments() 90 s.backend.modelFilesystemAttachmentsW.T.Kill(errors.New("rah")) 91 c.Assert(w.Wait(), gc.ErrorMatches, "rah") 92 } 93 94 func (s *WatchersSuite) TestWatchMachineManagedFilesystems(c *gc.C) { 95 w := s.watchers.WatchMachineManagedFilesystems(names.NewMachineTag("0")) 96 defer statetesting.AssertKillAndWait(c, w) 97 s.backend.modelFilesystemsW.C <- []string{"0", "1"} 98 s.backend.machineFilesystemsW.C <- []string{"0/2", "0/3"} 99 s.backend.modelVolumeAttachmentsW.C <- []string{"0:1", "0:2", "1:3"} 100 101 wc := statetesting.NewStringsWatcherC(c, nopSyncStarter{}, w) 102 wc.AssertChangeInSingleEvent("0/2", "0/3", "1") 103 wc.AssertNoChange() 104 } 105 106 func (s *WatchersSuite) TestWatchMachineManagedFilesystemsErrorsPropagate(c *gc.C) { 107 w := s.watchers.WatchMachineManagedFilesystems(names.NewMachineTag("0")) 108 s.backend.modelFilesystemsW.T.Kill(errors.New("rah")) 109 c.Assert(w.Wait(), gc.ErrorMatches, "rah") 110 } 111 112 // TestWatchMachineManagedFilesystemsVolumeAttachedFirst is the same as 113 // TestWatchMachineManagedFilesystems, but the order of volume attachment 114 // and model filesystem events is swapped. 115 func (s *WatchersSuite) TestWatchMachineManagedFilesystemsVolumeAttachedFirst(c *gc.C) { 116 w := s.watchers.WatchMachineManagedFilesystems(names.NewMachineTag("0")) 117 defer statetesting.AssertKillAndWait(c, w) 118 s.backend.modelVolumeAttachmentsW.C <- []string{"0:1", "0:2", "1:3"} 119 s.backend.modelFilesystemsW.C <- []string{"0", "1"} 120 s.backend.machineFilesystemsW.C <- []string{"0/2", "0/3"} 121 122 wc := statetesting.NewStringsWatcherC(c, nopSyncStarter{}, w) 123 wc.AssertChangeInSingleEvent("0/2", "0/3", "1") 124 wc.AssertNoChange() 125 } 126 127 func (s *WatchersSuite) TestWatchMachineManagedFilesystemsVolumeAttachedLater(c *gc.C) { 128 w := s.watchers.WatchMachineManagedFilesystems(names.NewMachineTag("0")) 129 defer statetesting.AssertKillAndWait(c, w) 130 s.backend.modelFilesystemsW.C <- []string{"0", "1"} 131 s.backend.machineFilesystemsW.C <- []string{"0/2", "0/3"} 132 // No volumes are attached to begin with. 133 s.backend.modelVolumeAttachmentsW.C <- []string{} 134 135 wc := statetesting.NewStringsWatcherC(c, nopSyncStarter{}, w) 136 wc.AssertChangeInSingleEvent("0/2", "0/3") 137 wc.AssertNoChange() 138 139 s.backend.modelVolumeAttachmentsW.C <- []string{"0:1", "0:2", "1:3"} 140 wc.AssertChangeInSingleEvent("1") 141 wc.AssertNoChange() 142 } 143 144 func (s *WatchersSuite) TestWatchMachineManagedFilesystemsVolumeAttachmentDead(c *gc.C) { 145 w := s.watchers.WatchMachineManagedFilesystems(names.NewMachineTag("0")) 146 defer statetesting.AssertKillAndWait(c, w) 147 148 s.backend.machineFilesystemsW.C <- []string{} 149 // Volume-backed filesystems 1 and 2 change. 150 s.backend.modelFilesystemsW.C <- []string{"1", "2"} 151 // The volumes are attached initially... 152 s.backend.modelVolumeAttachmentsW.C <- []string{"0:1", "0:2"} 153 // ... but before the client consumes the event, the backing volume 154 // attachments 0:1 and 0:2 become Dead and removed respectively, 155 // negating the previous change. 156 <-s.backend.volumeAttachmentRequested 157 <-s.backend.volumeAttachmentRequested 158 s.backend.volumeAttachments["1"].life = state.Dead 159 delete(s.backend.volumeAttachments, "2") 160 s.backend.modelVolumeAttachmentsW.C <- []string{"0:1", "0:2"} 161 162 // In order to not start the watcher until it has finished processing 163 // the previous event, we send another empty list through the channel 164 // which does nothing. 165 s.backend.modelVolumeAttachmentsW.C <- []string{} 166 167 wc := statetesting.NewStringsWatcherC(c, nopSyncStarter{}, w) 168 wc.AssertChangeInSingleEvent() 169 wc.AssertNoChange() 170 } 171 172 func (s *WatchersSuite) TestWatchMachineManagedFilesystemAttachments(c *gc.C) { 173 w := s.watchers.WatchMachineManagedFilesystemAttachments(names.NewMachineTag("0")) 174 defer statetesting.AssertKillAndWait(c, w) 175 s.backend.modelFilesystemAttachmentsW.C <- []string{"0:0", "0:1"} 176 s.backend.machineFilesystemAttachmentsW.C <- []string{"0:0/2", "0:0/3"} 177 s.backend.modelVolumeAttachmentsW.C <- []string{"0:1", "0:2", "1:3"} 178 179 wc := statetesting.NewStringsWatcherC(c, nopSyncStarter{}, w) 180 wc.AssertChangeInSingleEvent("0:0/2", "0:0/3", "0:1") 181 wc.AssertNoChange() 182 } 183 184 func (s *WatchersSuite) TestWatchMachineManagedFilesystemAttachmentsErrorsPropagate(c *gc.C) { 185 w := s.watchers.WatchMachineManagedFilesystemAttachments(names.NewMachineTag("0")) 186 s.backend.modelFilesystemAttachmentsW.T.Kill(errors.New("rah")) 187 c.Assert(w.Wait(), gc.ErrorMatches, "rah") 188 } 189 190 // TestWatchMachineManagedFilesystemAttachmentsVolumeAttachedFirst is the same as 191 // TestWatchMachineManagedFilesystemAttachments, but the order of volume attachment 192 // and model filesystem attachment events is swapped. 193 func (s *WatchersSuite) TestWatchMachineManagedFilesystemAttachmentsVolumeAttachedFirst(c *gc.C) { 194 w := s.watchers.WatchMachineManagedFilesystemAttachments(names.NewMachineTag("0")) 195 defer statetesting.AssertKillAndWait(c, w) 196 s.backend.modelVolumeAttachmentsW.C <- []string{"0:1", "0:2", "1:3"} 197 s.backend.modelFilesystemAttachmentsW.C <- []string{"0:0", "0:1"} 198 s.backend.machineFilesystemAttachmentsW.C <- []string{"0:0/2", "0:0/3"} 199 200 wc := statetesting.NewStringsWatcherC(c, nopSyncStarter{}, w) 201 wc.AssertChangeInSingleEvent("0:0/2", "0:0/3", "0:1") 202 wc.AssertNoChange() 203 } 204 205 func (s *WatchersSuite) TestWatchMachineManagedFilesystemAttachmentsVolumeAttachedLater(c *gc.C) { 206 w := s.watchers.WatchMachineManagedFilesystemAttachments(names.NewMachineTag("0")) 207 defer statetesting.AssertKillAndWait(c, w) 208 s.backend.modelFilesystemAttachmentsW.C <- []string{"0:0", "0:1"} 209 s.backend.machineFilesystemAttachmentsW.C <- []string{"0:0/2", "0:0/3"} 210 // No volumes are attached to begin with. 211 s.backend.modelVolumeAttachmentsW.C <- []string{} 212 213 wc := statetesting.NewStringsWatcherC(c, nopSyncStarter{}, w) 214 wc.AssertChangeInSingleEvent("0:0/2", "0:0/3") 215 wc.AssertNoChange() 216 217 s.backend.modelVolumeAttachmentsW.C <- []string{"0:1", "0:2", "1:3"} 218 wc.AssertChangeInSingleEvent("0:1") 219 wc.AssertNoChange() 220 } 221 222 func (s *WatchersSuite) TestWatchMachineManagedFilesystemAttachmentsVolumeAttachmentDead(c *gc.C) { 223 w := s.watchers.WatchMachineManagedFilesystemAttachments(names.NewMachineTag("0")) 224 defer statetesting.AssertKillAndWait(c, w) 225 226 s.backend.machineFilesystemAttachmentsW.C <- []string{} 227 // Volume-backed filesystems attachments 0:1 and 0:2 change. 228 s.backend.modelFilesystemAttachmentsW.C <- []string{"0:1", "0:2"} 229 // The volumes are attached initially... 230 s.backend.modelVolumeAttachmentsW.C <- []string{"0:1", "0:2"} 231 // ... but before the client consumes the event, the backing volume 232 // attachments 0:1 and 0:2 become Dead and removed respectively, 233 // negating the previous change. 234 <-s.backend.volumeAttachmentRequested 235 <-s.backend.volumeAttachmentRequested 236 s.backend.volumeAttachments["1"].life = state.Dead 237 delete(s.backend.volumeAttachments, "2") 238 s.backend.modelVolumeAttachmentsW.C <- []string{"0:1", "0:2"} 239 240 // In order to not start the watcher until it has finished processing 241 // the previous event, we send another empty list through the channel 242 // which does nothing. 243 s.backend.modelVolumeAttachmentsW.C <- []string{} 244 245 wc := statetesting.NewStringsWatcherC(c, nopSyncStarter{}, w) 246 wc.AssertChangeInSingleEvent() 247 wc.AssertNoChange() 248 } 249 250 func (s *WatchersSuite) TestWatchUnitManagedFilesystems(c *gc.C) { 251 w := s.watchers.WatchUnitManagedFilesystems(names.NewApplicationTag("mariadb")) 252 defer statetesting.AssertKillAndWait(c, w) 253 s.backend.modelFilesystemsW.C <- []string{"0", "1"} 254 s.backend.unitFilesystemsW.C <- []string{"mariadb/0/2", "mariadb/0/3"} 255 s.backend.modelVolumeAttachmentsW.C <- []string{"mariadb/0:1", "mariadb/0:2", "mysql/1:3"} 256 257 wc := statetesting.NewStringsWatcherC(c, nopSyncStarter{}, w) 258 wc.AssertChangeInSingleEvent("1", "mariadb/0/2", "mariadb/0/3") 259 wc.AssertNoChange() 260 } 261 262 func (s *WatchersSuite) TestWatchUnitManagedFilesystemsErrorsPropagate(c *gc.C) { 263 w := s.watchers.WatchUnitManagedFilesystems(names.NewApplicationTag("mariadb")) 264 s.backend.modelFilesystemsW.T.Kill(errors.New("rah")) 265 c.Assert(w.Wait(), gc.ErrorMatches, "rah") 266 } 267 268 func (s *WatchersSuite) TestWatchUnitManagedFilesystemAttachments(c *gc.C) { 269 w := s.watchers.WatchUnitManagedFilesystemAttachments(names.NewApplicationTag("mariadb")) 270 defer statetesting.AssertKillAndWait(c, w) 271 s.backend.modelFilesystemAttachmentsW.C <- []string{"mariadb/0:0", "mariadb/0:1"} 272 s.backend.unitFilesystemAttachmentsW.C <- []string{"mariadb/0:mariadb/0/2", "mariadb/0:mariadb/0/3"} 273 s.backend.modelVolumeAttachmentsW.C <- []string{"mariadb/0:1", "mariadb/0:2", "mysql/0:3"} 274 275 wc := statetesting.NewStringsWatcherC(c, nopSyncStarter{}, w) 276 wc.AssertChangeInSingleEvent("mariadb/0:mariadb/0/2", "mariadb/0:mariadb/0/3", "mariadb/0:1") 277 wc.AssertNoChange() 278 } 279 280 func (s *WatchersSuite) TestWatchUnitManagedFilesystemAttachmentsErrorsPropagate(c *gc.C) { 281 w := s.watchers.WatchUnitManagedFilesystemAttachments(names.NewApplicationTag("mariadb")) 282 s.backend.modelFilesystemAttachmentsW.T.Kill(errors.New("rah")) 283 c.Assert(w.Wait(), gc.ErrorMatches, "rah") 284 }