github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/apiserver/common/firewall/mock_test.go (about) 1 // Copyright 2017 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package firewall_test 5 6 import ( 7 "sync" 8 9 "github.com/juju/errors" 10 "github.com/juju/testing" 11 "gopkg.in/juju/names.v2" 12 "gopkg.in/macaroon.v2-unstable" 13 "gopkg.in/tomb.v2" 14 15 "github.com/juju/juju/apiserver/common/cloudspec" 16 "github.com/juju/juju/apiserver/common/firewall" 17 "github.com/juju/juju/apiserver/params" 18 "github.com/juju/juju/controller" 19 "github.com/juju/juju/core/crossmodel" 20 "github.com/juju/juju/environs/config" 21 "github.com/juju/juju/network" 22 "github.com/juju/juju/state" 23 coretesting "github.com/juju/juju/testing" 24 ) 25 26 type mockCloudSpecAPI struct { 27 // TODO - implement when remaining firewaller tests become unit tests 28 cloudspec.CloudSpecAPI 29 } 30 31 type mockState struct { 32 // TODO - implement when remaining firewaller tests become unit tests 33 state.ModelMachinesWatcher 34 35 testing.Stub 36 modelUUID string 37 remoteEntities map[names.Tag]string 38 macaroons map[names.Tag]*macaroon.Macaroon 39 applications map[string]*mockApplication 40 units map[string]*mockUnit 41 machines map[string]*mockMachine 42 relations map[string]*mockRelation 43 controllerInfo map[string]*mockControllerInfo 44 subnetsWatcher *mockStringsWatcher 45 modelWatcher *mockNotifyWatcher 46 configAttrs map[string]interface{} 47 } 48 49 func newMockState(modelUUID string) *mockState { 50 return &mockState{ 51 modelUUID: modelUUID, 52 relations: make(map[string]*mockRelation), 53 applications: make(map[string]*mockApplication), 54 units: make(map[string]*mockUnit), 55 machines: make(map[string]*mockMachine), 56 remoteEntities: make(map[names.Tag]string), 57 macaroons: make(map[names.Tag]*macaroon.Macaroon), 58 controllerInfo: make(map[string]*mockControllerInfo), 59 subnetsWatcher: newMockStringsWatcher(), 60 modelWatcher: newMockNotifyWatcher(), 61 configAttrs: coretesting.FakeConfig(), 62 } 63 } 64 65 func (st *mockState) WatchForModelConfigChanges() state.NotifyWatcher { 66 return st.modelWatcher 67 } 68 69 func (st *mockState) ModelConfig() (*config.Config, error) { 70 return config.New(config.UseDefaults, st.configAttrs) 71 } 72 73 func (st *mockState) ControllerConfig() (controller.Config, error) { 74 return nil, errors.NotImplementedf("ControllerConfig") 75 } 76 77 func (st *mockState) ControllerInfo(modelUUID string) ([]string, string, error) { 78 if info, ok := st.controllerInfo[modelUUID]; !ok { 79 return nil, "", errors.NotFoundf("controller info for %v", modelUUID) 80 } else { 81 return info.ControllerInfo().Addrs, info.ControllerInfo().CACert, nil 82 } 83 } 84 85 func (st *mockState) GetMacaroon(model names.ModelTag, entity names.Tag) (*macaroon.Macaroon, error) { 86 st.MethodCall(st, "GetMacaroon", model, entity) 87 if err := st.NextErr(); err != nil { 88 return nil, err 89 } 90 mac, ok := st.macaroons[entity] 91 if !ok { 92 return nil, errors.NotFoundf("macaroon for %v", entity) 93 } 94 return mac, nil 95 } 96 97 func (st *mockState) ModelUUID() string { 98 return st.modelUUID 99 } 100 101 func (st *mockState) Application(id string) (firewall.Application, error) { 102 st.MethodCall(st, "Application", id) 103 if err := st.NextErr(); err != nil { 104 return nil, err 105 } 106 a, ok := st.applications[id] 107 if !ok { 108 return nil, errors.NotFoundf("application %q", id) 109 } 110 return a, nil 111 } 112 113 func (st *mockState) Unit(name string) (firewall.Unit, error) { 114 st.MethodCall(st, "Unit", name) 115 if err := st.NextErr(); err != nil { 116 return nil, err 117 } 118 u, ok := st.units[name] 119 if !ok { 120 return nil, errors.NotFoundf("unit %q", name) 121 } 122 return u, nil 123 } 124 125 func (st *mockState) Machine(id string) (firewall.Machine, error) { 126 st.MethodCall(st, "Machine", id) 127 if err := st.NextErr(); err != nil { 128 return nil, err 129 } 130 m, ok := st.machines[id] 131 if !ok { 132 return nil, errors.NotFoundf("machine %q", id) 133 } 134 return m, nil 135 } 136 137 func (st *mockState) WatchSubnets(func(id interface{}) bool) state.StringsWatcher { 138 st.MethodCall(st, "WatchSubnets") 139 return st.subnetsWatcher 140 } 141 142 func (st *mockState) WatchOpenedPorts() state.StringsWatcher { 143 st.MethodCall(st, "WatchOpenedPorts") 144 // TODO - implement when remaining firewaller tests become unit tests 145 return nil 146 } 147 148 func (st *mockState) FindEntity(tag names.Tag) (state.Entity, error) { 149 st.MethodCall(st, "FindEntity") 150 // TODO - implement when remaining firewaller tests become unit tests 151 return nil, errors.NotImplementedf("FindEntity") 152 } 153 154 func (st *mockState) GetModel(tag names.ModelTag) (*state.Model, error) { 155 st.MethodCall(st, "GetModel", tag) 156 // TODO - implement when remaining firewaller tests become unit tests 157 return nil, errors.NotImplementedf("GetModel") 158 } 159 160 type mockWatcher struct { 161 testing.Stub 162 tomb.Tomb 163 } 164 165 func (w *mockWatcher) Kill() { 166 w.MethodCall(w, "Kill") 167 w.Tomb.Kill(nil) 168 } 169 170 func (w *mockWatcher) Stop() error { 171 w.MethodCall(w, "Stop") 172 if err := w.NextErr(); err != nil { 173 return err 174 } 175 w.Tomb.Kill(nil) 176 return w.Tomb.Wait() 177 } 178 179 func (w *mockWatcher) Err() error { 180 w.MethodCall(w, "Err") 181 return w.Tomb.Err() 182 } 183 184 type mockStringsWatcher struct { 185 mockWatcher 186 changes chan []string 187 } 188 189 func newMockStringsWatcher() *mockStringsWatcher { 190 w := &mockStringsWatcher{changes: make(chan []string, 1)} 191 w.Tomb.Go(func() error { 192 <-w.Tomb.Dying() 193 return nil 194 }) 195 return w 196 } 197 198 func (w *mockStringsWatcher) Changes() <-chan []string { 199 w.MethodCall(w, "Changes") 200 return w.changes 201 } 202 203 func newMockNotifyWatcher() *mockNotifyWatcher { 204 w := &mockNotifyWatcher{changes: make(chan struct{}, 1)} 205 // Initial event 206 w.changes <- struct{}{} 207 w.Tomb.Go(func() error { 208 <-w.Tomb.Dying() 209 return nil 210 }) 211 return w 212 } 213 214 type mockNotifyWatcher struct { 215 mockWatcher 216 changes chan struct{} 217 } 218 219 func (w *mockNotifyWatcher) Changes() <-chan struct{} { 220 w.MethodCall(w, "Changes") 221 return w.changes 222 } 223 224 type mockApplication struct { 225 testing.Stub 226 name string 227 units []*mockUnit 228 } 229 230 func newMockApplication(name string) *mockApplication { 231 return &mockApplication{ 232 name: name, 233 } 234 } 235 236 func (a *mockApplication) Name() string { 237 a.MethodCall(a, "Name") 238 return a.name 239 } 240 241 func (a *mockApplication) AllUnits() (results []firewall.Unit, err error) { 242 a.MethodCall(a, "AllUnits") 243 for _, unit := range a.units { 244 results = append(results, unit) 245 } 246 return results, a.NextErr() 247 } 248 249 type mockControllerInfo struct { 250 uuid string 251 info crossmodel.ControllerInfo 252 } 253 254 func (c *mockControllerInfo) Id() string { 255 return c.uuid 256 } 257 258 func (c *mockControllerInfo) ControllerInfo() crossmodel.ControllerInfo { 259 return c.info 260 } 261 262 type mockRelation struct { 263 testing.Stub 264 firewall.Relation 265 id int 266 key string 267 endpoints []state.Endpoint 268 ruw *mockRelationUnitsWatcher 269 ew *mockStringsWatcher 270 ruwApp string 271 } 272 273 func newMockRelation(id int) *mockRelation { 274 return &mockRelation{ 275 id: id, 276 ruw: newMockRelationUnitsWatcher(), 277 ew: newMockStringsWatcher(), 278 } 279 } 280 281 func (r *mockRelation) Id() int { 282 r.MethodCall(r, "Id") 283 return r.id 284 } 285 286 func (r *mockRelation) Endpoints() []state.Endpoint { 287 r.MethodCall(r, "Endpoints") 288 return r.endpoints 289 } 290 291 func (r *mockRelation) WatchUnits(applicationName string) (state.RelationUnitsWatcher, error) { 292 if r.ruwApp != applicationName { 293 return nil, errors.Errorf("unexpected app %v", applicationName) 294 } 295 return r.ruw, nil 296 } 297 298 func (r *mockRelation) WatchRelationEgressNetworks() state.StringsWatcher { 299 return r.ew 300 } 301 302 func newMockRelationUnitsWatcher() *mockRelationUnitsWatcher { 303 w := &mockRelationUnitsWatcher{changes: make(chan params.RelationUnitsChange, 1)} 304 w.Tomb.Go(func() error { 305 <-w.Tomb.Dying() 306 return nil 307 }) 308 return w 309 } 310 311 type mockRelationUnitsWatcher struct { 312 mockWatcher 313 changes chan params.RelationUnitsChange 314 } 315 316 func (w *mockRelationUnitsWatcher) Changes() <-chan params.RelationUnitsChange { 317 return w.changes 318 } 319 320 func (st *mockState) GetRemoteEntity(sourceModel names.ModelTag, token string) (names.Tag, error) { 321 st.MethodCall(st, "GetRemoteEntity", sourceModel, token) 322 if err := st.NextErr(); err != nil { 323 return nil, err 324 } 325 for e, t := range st.remoteEntities { 326 if t == token { 327 return e, nil 328 } 329 } 330 return nil, errors.NotFoundf("token %v", token) 331 } 332 333 func (st *mockState) KeyRelation(key string) (firewall.Relation, error) { 334 st.MethodCall(st, "KeyRelation", key) 335 if err := st.NextErr(); err != nil { 336 return nil, err 337 } 338 r, ok := st.relations[key] 339 if !ok { 340 return nil, errors.NotFoundf("relation %q", key) 341 } 342 return r, nil 343 } 344 345 type mockUnit struct { 346 testing.Stub 347 mu sync.Mutex 348 name string 349 assigned bool 350 publicAddress network.Address 351 machineId string 352 } 353 354 func newMockUnit(name string) *mockUnit { 355 return &mockUnit{ 356 name: name, 357 assigned: true, 358 } 359 } 360 361 func (u *mockUnit) Name() string { 362 u.MethodCall(u, "Name") 363 return u.name 364 } 365 366 func (u *mockUnit) PublicAddress() (network.Address, error) { 367 u.MethodCall(u, "PublicAddress") 368 u.mu.Lock() 369 defer u.mu.Unlock() 370 371 if err := u.NextErr(); err != nil { 372 return network.Address{}, err 373 } 374 if !u.assigned { 375 return network.Address{}, errors.NotAssignedf(u.name) 376 } 377 if u.publicAddress.Value == "" { 378 return network.Address{}, network.NoAddressError("public") 379 } 380 return u.publicAddress, nil 381 } 382 383 func (u *mockUnit) AssignedMachineId() (string, error) { 384 u.MethodCall(u, "AssignedMachineId") 385 if err := u.NextErr(); err != nil { 386 return "", err 387 } 388 if !u.assigned { 389 return "", errors.NotAssignedf(u.name) 390 } 391 return u.machineId, nil 392 } 393 394 func (u *mockUnit) updateAddress(value string) { 395 u.mu.Lock() 396 defer u.mu.Unlock() 397 398 u.publicAddress = network.Address{Value: value} 399 } 400 401 type mockMachine struct { 402 testing.Stub 403 id string 404 watcher *mockAddressWatcher 405 } 406 407 func newMockMachine(id string) *mockMachine { 408 return &mockMachine{ 409 id: id, 410 watcher: newMockAddressWatcher(), 411 } 412 } 413 414 func (m *mockMachine) Id() string { 415 m.MethodCall(m, "Id") 416 return m.id 417 } 418 419 func (m *mockMachine) WatchAddresses() state.NotifyWatcher { 420 m.MethodCall(m, "WatchAddresses") 421 return m.watcher 422 } 423 424 type mockAddressWatcher struct { 425 mockWatcher 426 changes chan struct{} 427 } 428 429 func newMockAddressWatcher() *mockAddressWatcher { 430 w := &mockAddressWatcher{changes: make(chan struct{}, 1)} 431 w.Tomb.Go(func() error { 432 <-w.Tomb.Dying() 433 return nil 434 }) 435 return w 436 } 437 438 func (w *mockAddressWatcher) Changes() <-chan struct{} { 439 w.MethodCall(w, "Changes") 440 return w.changes 441 }