github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/uniter/remotestate/mock_test.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package remotestate_test 5 6 import ( 7 "sync" 8 "time" 9 10 "github.com/juju/juju/core/model" 11 "gopkg.in/juju/charm.v6" 12 "gopkg.in/juju/names.v2" 13 14 "github.com/juju/juju/apiserver/params" 15 "github.com/juju/juju/core/leadership" 16 "github.com/juju/juju/core/watcher" 17 "github.com/juju/juju/worker/uniter/remotestate" 18 ) 19 20 func newMockWatcher() *mockWatcher { 21 return &mockWatcher{ 22 stopped: make(chan struct{}), 23 } 24 } 25 26 type mockWatcher struct { 27 mu sync.Mutex 28 stopped chan struct{} 29 } 30 31 func (w *mockWatcher) Kill() { 32 w.mu.Lock() 33 defer w.mu.Unlock() 34 if !w.Stopped() { 35 close(w.stopped) 36 } 37 } 38 39 func (w *mockWatcher) Wait() error { 40 <-w.stopped 41 return nil 42 } 43 44 func (w *mockWatcher) Stopped() bool { 45 select { 46 case <-w.stopped: 47 return true 48 default: 49 return false 50 } 51 } 52 53 func newMockNotifyWatcher() *mockNotifyWatcher { 54 return &mockNotifyWatcher{ 55 mockWatcher: newMockWatcher(), 56 changes: make(chan struct{}, 1), 57 } 58 } 59 60 type mockNotifyWatcher struct { 61 *mockWatcher 62 changes chan struct{} 63 } 64 65 func (w *mockNotifyWatcher) Changes() watcher.NotifyChannel { 66 return w.changes 67 } 68 69 func newMockStringsWatcher() *mockStringsWatcher { 70 return &mockStringsWatcher{ 71 mockWatcher: newMockWatcher(), 72 changes: make(chan []string, 1), 73 } 74 } 75 76 type mockStringsWatcher struct { 77 *mockWatcher 78 changes chan []string 79 } 80 81 func (w *mockStringsWatcher) Changes() watcher.StringsChannel { 82 return w.changes 83 } 84 85 func newMockRelationUnitsWatcher() *mockRelationUnitsWatcher { 86 return &mockRelationUnitsWatcher{ 87 mockWatcher: newMockWatcher(), 88 changes: make(chan watcher.RelationUnitsChange, 1), 89 } 90 } 91 92 type mockRelationUnitsWatcher struct { 93 *mockWatcher 94 changes chan watcher.RelationUnitsChange 95 } 96 97 func (w *mockRelationUnitsWatcher) Changes() watcher.RelationUnitsChannel { 98 return w.changes 99 } 100 101 type mockState struct { 102 modelType model.ModelType 103 unit mockUnit 104 relations map[names.RelationTag]*mockRelation 105 storageAttachment map[params.StorageAttachmentId]params.StorageAttachment 106 relationUnitsWatchers map[names.RelationTag]*mockRelationUnitsWatcher 107 storageAttachmentWatchers map[names.StorageTag]*mockNotifyWatcher 108 updateStatusInterval time.Duration 109 updateStatusIntervalWatcher *mockNotifyWatcher 110 } 111 112 func (st *mockState) Relation(tag names.RelationTag) (remotestate.Relation, error) { 113 r, ok := st.relations[tag] 114 if !ok { 115 return nil, ¶ms.Error{Code: params.CodeNotFound} 116 } 117 return r, nil 118 } 119 120 func (st *mockState) StorageAttachment( 121 storageTag names.StorageTag, unitTag names.UnitTag, 122 ) (params.StorageAttachment, error) { 123 if unitTag != st.unit.tag { 124 return params.StorageAttachment{}, ¶ms.Error{Code: params.CodeNotFound} 125 } 126 attachment, ok := st.storageAttachment[params.StorageAttachmentId{ 127 UnitTag: unitTag.String(), 128 StorageTag: storageTag.String(), 129 }] 130 if !ok { 131 return params.StorageAttachment{}, ¶ms.Error{Code: params.CodeNotFound} 132 } 133 if attachment.Kind == params.StorageKindUnknown { 134 return params.StorageAttachment{}, ¶ms.Error{Code: params.CodeNotProvisioned} 135 } 136 return attachment, nil 137 } 138 139 func (st *mockState) StorageAttachmentLife( 140 ids []params.StorageAttachmentId, 141 ) ([]params.LifeResult, error) { 142 results := make([]params.LifeResult, len(ids)) 143 for i, id := range ids { 144 attachment, ok := st.storageAttachment[id] 145 if !ok { 146 results[i] = params.LifeResult{ 147 Error: ¶ms.Error{Code: params.CodeNotFound}, 148 } 149 continue 150 } 151 results[i] = params.LifeResult{Life: attachment.Life} 152 } 153 return results, nil 154 } 155 156 func (st *mockState) Unit(tag names.UnitTag) (remotestate.Unit, error) { 157 if tag != st.unit.tag { 158 return nil, ¶ms.Error{Code: params.CodeNotFound} 159 } 160 return &st.unit, nil 161 } 162 163 func (st *mockState) WatchRelationUnits( 164 relationTag names.RelationTag, unitTag names.UnitTag, 165 ) (watcher.RelationUnitsWatcher, error) { 166 if unitTag != st.unit.tag { 167 return nil, ¶ms.Error{Code: params.CodeNotFound} 168 } 169 watcher, ok := st.relationUnitsWatchers[relationTag] 170 if !ok { 171 return nil, ¶ms.Error{Code: params.CodeNotFound} 172 } 173 return watcher, nil 174 } 175 176 func (st *mockState) WatchStorageAttachment( 177 storageTag names.StorageTag, unitTag names.UnitTag, 178 ) (watcher.NotifyWatcher, error) { 179 if unitTag != st.unit.tag { 180 return nil, ¶ms.Error{Code: params.CodeNotFound} 181 } 182 watcher, ok := st.storageAttachmentWatchers[storageTag] 183 if !ok { 184 return nil, ¶ms.Error{Code: params.CodeNotFound} 185 } 186 return watcher, nil 187 } 188 189 func (st *mockState) UpdateStatusHookInterval() (time.Duration, error) { 190 return st.updateStatusInterval, nil 191 } 192 193 func (st *mockState) WatchUpdateStatusHookInterval() (watcher.NotifyWatcher, error) { 194 return st.updateStatusIntervalWatcher, nil 195 } 196 197 type mockUnit struct { 198 tag names.UnitTag 199 life params.Life 200 resolved params.ResolvedMode 201 application mockApplication 202 unitWatcher *mockNotifyWatcher 203 addressesWatcher *mockStringsWatcher 204 configSettingsWatcher *mockStringsWatcher 205 applicationConfigSettingsWatcher *mockStringsWatcher 206 upgradeSeriesWatcher *mockNotifyWatcher 207 storageWatcher *mockStringsWatcher 208 actionWatcher *mockStringsWatcher 209 relationsWatcher *mockStringsWatcher 210 upgradeLXDProfileUpgradeWatcher *mockStringsWatcher 211 } 212 213 func (u *mockUnit) Life() params.Life { 214 return u.life 215 } 216 217 func (u *mockUnit) Refresh() error { 218 return nil 219 } 220 221 func (u *mockUnit) Resolved() params.ResolvedMode { 222 return u.resolved 223 } 224 225 func (u *mockUnit) Application() (remotestate.Application, error) { 226 return &u.application, nil 227 } 228 229 func (u *mockUnit) Tag() names.UnitTag { 230 return u.tag 231 } 232 233 func (u *mockUnit) Watch() (watcher.NotifyWatcher, error) { 234 return u.unitWatcher, nil 235 } 236 237 func (u *mockUnit) WatchAddressesHash() (watcher.StringsWatcher, error) { 238 return u.addressesWatcher, nil 239 } 240 241 func (u *mockUnit) WatchConfigSettingsHash() (watcher.StringsWatcher, error) { 242 return u.configSettingsWatcher, nil 243 } 244 245 func (u *mockUnit) WatchTrustConfigSettingsHash() (watcher.StringsWatcher, error) { 246 return u.applicationConfigSettingsWatcher, nil 247 } 248 249 func (u *mockUnit) WatchStorage() (watcher.StringsWatcher, error) { 250 return u.storageWatcher, nil 251 } 252 253 func (u *mockUnit) WatchActionNotifications() (watcher.StringsWatcher, error) { 254 return u.actionWatcher, nil 255 } 256 257 func (u *mockUnit) WatchRelations() (watcher.StringsWatcher, error) { 258 return u.relationsWatcher, nil 259 } 260 261 func (u *mockUnit) WatchUpgradeSeriesNotifications() (watcher.NotifyWatcher, error) { 262 return u.upgradeSeriesWatcher, nil 263 } 264 265 func (u *mockUnit) UpgradeSeriesStatus() (model.UpgradeSeriesStatus, error) { 266 return model.UpgradeSeriesPrepareStarted, nil 267 } 268 269 func (u *mockUnit) SetUpgradeSeriesStatus(status model.UpgradeSeriesStatus) error { 270 return nil 271 } 272 273 func (u *mockUnit) WatchLXDProfileUpgradeNotifications() (watcher.StringsWatcher, error) { 274 return u.upgradeLXDProfileUpgradeWatcher, nil 275 } 276 277 type mockApplication struct { 278 tag names.ApplicationTag 279 life params.Life 280 curl *charm.URL 281 charmModifiedVersion int 282 forceUpgrade bool 283 applicationWatcher *mockNotifyWatcher 284 leaderSettingsWatcher *mockNotifyWatcher 285 } 286 287 func (s *mockApplication) CharmModifiedVersion() (int, error) { 288 return s.charmModifiedVersion, nil 289 } 290 291 func (s *mockApplication) CharmURL() (*charm.URL, bool, error) { 292 return s.curl, s.forceUpgrade, nil 293 } 294 295 func (s *mockApplication) Life() params.Life { 296 return s.life 297 } 298 299 func (s *mockApplication) Refresh() error { 300 return nil 301 } 302 303 func (s *mockApplication) Tag() names.ApplicationTag { 304 return s.tag 305 } 306 307 func (s *mockApplication) Watch() (watcher.NotifyWatcher, error) { 308 return s.applicationWatcher, nil 309 } 310 311 func (s *mockApplication) WatchLeadershipSettings() (watcher.NotifyWatcher, error) { 312 return s.leaderSettingsWatcher, nil 313 } 314 315 type mockRelation struct { 316 id int 317 life params.Life 318 suspended bool 319 } 320 321 func (r *mockRelation) Id() int { 322 return r.id 323 } 324 325 func (r *mockRelation) Life() params.Life { 326 return r.life 327 } 328 329 func (r *mockRelation) Suspended() bool { 330 return r.suspended 331 } 332 333 func (r *mockRelation) UpdateSuspended(suspended bool) { 334 r.suspended = suspended 335 } 336 337 type mockLeadershipTracker struct { 338 leadership.Tracker 339 claimTicket mockTicket 340 leaderTicket mockTicket 341 minionTicket mockTicket 342 } 343 344 func (mock *mockLeadershipTracker) ClaimLeader() leadership.Ticket { 345 return &mock.claimTicket 346 } 347 348 func (mock *mockLeadershipTracker) WaitLeader() leadership.Ticket { 349 return &mock.leaderTicket 350 } 351 352 func (mock *mockLeadershipTracker) WaitMinion() leadership.Ticket { 353 return &mock.minionTicket 354 } 355 356 type mockTicket struct { 357 ch chan struct{} 358 result bool 359 } 360 361 func (t *mockTicket) Ready() <-chan struct{} { 362 return t.ch 363 } 364 365 func (t *mockTicket) Wait() bool { 366 return t.result 367 }