github.com/mwhudson/juju@v0.0.0-20160512215208-90ff01f3497f/provider/maas/maas2_test.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package maas 5 6 import ( 7 "github.com/juju/errors" 8 "github.com/juju/gomaasapi" 9 "github.com/juju/testing" 10 jc "github.com/juju/testing/checkers" 11 "github.com/juju/utils/set" 12 gc "gopkg.in/check.v1" 13 14 "github.com/juju/juju/environs/config" 15 coretesting "github.com/juju/juju/testing" 16 "github.com/juju/juju/version" 17 ) 18 19 type maas2Suite struct { 20 baseProviderSuite 21 } 22 23 func (suite *maas2Suite) injectController(controller gomaasapi.Controller) { 24 mockGetController := func(maasServer, apiKey string) (gomaasapi.Controller, error) { 25 return controller, nil 26 } 27 suite.PatchValue(&GetMAAS2Controller, mockGetController) 28 } 29 30 func (suite *maas2Suite) makeEnviron(c *gc.C, controller gomaasapi.Controller) *maasEnviron { 31 if controller != nil { 32 suite.injectController(controller) 33 } 34 testAttrs := coretesting.Attrs{} 35 for k, v := range maasEnvAttrs { 36 testAttrs[k] = v 37 } 38 testAttrs["maas-server"] = "http://any-old-junk.invalid/" 39 testAttrs["agent-version"] = version.Current.String() 40 testAttrs["maas-agent-name"] = "agent-prefix" 41 42 attrs := coretesting.FakeConfig().Merge(testAttrs) 43 cfg, err := config.New(config.NoDefaults, attrs) 44 c.Assert(err, jc.ErrorIsNil) 45 env, err := NewEnviron(cfg) 46 c.Assert(err, jc.ErrorIsNil) 47 c.Assert(env, gc.NotNil) 48 return env 49 } 50 51 type fakeController struct { 52 gomaasapi.Controller 53 *testing.Stub 54 55 bootResources []gomaasapi.BootResource 56 bootResourcesError error 57 machines []gomaasapi.Machine 58 machinesError error 59 machinesArgsCheck func(gomaasapi.MachinesArgs) 60 zones []gomaasapi.Zone 61 zonesError error 62 spaces []gomaasapi.Space 63 spacesError error 64 65 allocateMachine gomaasapi.Machine 66 allocateMachineMatches gomaasapi.ConstraintMatches 67 allocateMachineError error 68 allocateMachineArgsCheck func(gomaasapi.AllocateMachineArgs) 69 70 files []gomaasapi.File 71 72 devices []gomaasapi.Device 73 } 74 75 func newFakeController() *fakeController { 76 return &fakeController{Stub: &testing.Stub{}} 77 } 78 79 func newFakeControllerWithErrors(errors ...error) *fakeController { 80 controller := newFakeController() 81 controller.SetErrors(errors...) 82 return controller 83 } 84 85 func newFakeControllerWithFiles(files ...gomaasapi.File) *fakeController { 86 return &fakeController{Stub: &testing.Stub{}, files: files} 87 } 88 89 func (c *fakeController) Devices(gomaasapi.DevicesArgs) ([]gomaasapi.Device, error) { 90 return c.devices, nil 91 } 92 93 func (c *fakeController) Machines(args gomaasapi.MachinesArgs) ([]gomaasapi.Machine, error) { 94 if c.machinesArgsCheck != nil { 95 c.machinesArgsCheck(args) 96 } 97 if c.machinesError != nil { 98 return nil, c.machinesError 99 } 100 if len(args.SystemIDs) > 0 { 101 result := []gomaasapi.Machine{} 102 systemIds := set.NewStrings(args.SystemIDs...) 103 for _, machine := range c.machines { 104 if systemIds.Contains(machine.SystemID()) { 105 result = append(result, machine) 106 } 107 } 108 return result, nil 109 } 110 return c.machines, nil 111 } 112 113 func (c *fakeController) AllocateMachine(args gomaasapi.AllocateMachineArgs) (gomaasapi.Machine, gomaasapi.ConstraintMatches, error) { 114 if c.allocateMachineArgsCheck != nil { 115 c.allocateMachineArgsCheck(args) 116 } 117 if c.allocateMachineError != nil { 118 return nil, c.allocateMachineMatches, c.allocateMachineError 119 } 120 return c.allocateMachine, c.allocateMachineMatches, nil 121 } 122 123 func (c *fakeController) BootResources() ([]gomaasapi.BootResource, error) { 124 if c.bootResourcesError != nil { 125 return nil, c.bootResourcesError 126 } 127 return c.bootResources, nil 128 } 129 130 func (c *fakeController) Zones() ([]gomaasapi.Zone, error) { 131 if c.zonesError != nil { 132 return nil, c.zonesError 133 } 134 return c.zones, nil 135 } 136 137 func (c *fakeController) Spaces() ([]gomaasapi.Space, error) { 138 if c.spacesError != nil { 139 return nil, c.spacesError 140 } 141 return c.spaces, nil 142 } 143 144 func (c *fakeController) Files(prefix string) ([]gomaasapi.File, error) { 145 c.MethodCall(c, "Files", prefix) 146 return c.files, c.NextErr() 147 } 148 149 func (c *fakeController) GetFile(filename string) (gomaasapi.File, error) { 150 c.MethodCall(c, "GetFile", filename) 151 err := c.NextErr() 152 if err != nil { 153 return nil, err 154 } 155 // Try to find the file by name (needed for testing RemoveAll) 156 for _, file := range c.files { 157 if file.Filename() == filename { 158 return file, nil 159 } 160 } 161 // The test forgot to set up matching files! 162 return nil, errors.Errorf("no file named %v found - did you set up your test correctly?", filename) 163 } 164 165 func (c *fakeController) AddFile(args gomaasapi.AddFileArgs) error { 166 c.MethodCall(c, "AddFile", args) 167 return c.NextErr() 168 } 169 170 func (c *fakeController) ReleaseMachines(args gomaasapi.ReleaseMachinesArgs) error { 171 c.MethodCall(c, "ReleaseMachines", args) 172 return c.NextErr() 173 } 174 175 type fakeBootResource struct { 176 gomaasapi.BootResource 177 name string 178 architecture string 179 } 180 181 func (r *fakeBootResource) Name() string { 182 return r.name 183 } 184 185 func (r *fakeBootResource) Architecture() string { 186 return r.architecture 187 } 188 189 type fakeMachine struct { 190 gomaasapi.Machine 191 *testing.Stub 192 193 zoneName string 194 hostname string 195 systemID string 196 ipAddresses []string 197 statusName string 198 statusMessage string 199 cpuCount int 200 memory int 201 architecture string 202 interfaceSet []gomaasapi.Interface 203 tags []string 204 createDevice gomaasapi.Device 205 } 206 207 func newFakeMachine(systemID, architecture, statusName string) *fakeMachine { 208 return &fakeMachine{ 209 Stub: &testing.Stub{}, 210 systemID: systemID, 211 architecture: architecture, 212 statusName: statusName, 213 } 214 } 215 216 func (m *fakeMachine) Tags() []string { 217 return m.tags 218 } 219 220 func (m *fakeMachine) CPUCount() int { 221 return m.cpuCount 222 } 223 224 func (m *fakeMachine) Memory() int { 225 return m.memory 226 } 227 228 func (m *fakeMachine) Architecture() string { 229 return m.architecture 230 } 231 232 func (m *fakeMachine) SystemID() string { 233 return m.systemID 234 } 235 236 func (m *fakeMachine) Hostname() string { 237 return m.hostname 238 } 239 240 func (m *fakeMachine) IPAddresses() []string { 241 return m.ipAddresses 242 } 243 244 func (m *fakeMachine) StatusName() string { 245 return m.statusName 246 } 247 248 func (m *fakeMachine) StatusMessage() string { 249 return m.statusMessage 250 } 251 252 func (m *fakeMachine) Zone() gomaasapi.Zone { 253 return fakeZone{name: m.zoneName} 254 } 255 256 func (m *fakeMachine) InterfaceSet() []gomaasapi.Interface { 257 return m.interfaceSet 258 } 259 260 func (m *fakeMachine) Start(args gomaasapi.StartArgs) error { 261 m.MethodCall(m, "Start", args) 262 return m.NextErr() 263 } 264 265 func (m *fakeMachine) CreateDevice(args gomaasapi.CreateMachineDeviceArgs) (gomaasapi.Device, error) { 266 m.MethodCall(m, "CreateDevice", args) 267 return m.createDevice, m.NextErr() 268 } 269 270 type fakeZone struct { 271 gomaasapi.Zone 272 name string 273 } 274 275 func (z fakeZone) Name() string { 276 return z.name 277 } 278 279 type fakeSpace struct { 280 gomaasapi.Space 281 name string 282 id int 283 subnets []gomaasapi.Subnet 284 } 285 286 func (s fakeSpace) Name() string { 287 return s.name 288 } 289 290 func (s fakeSpace) ID() int { 291 return s.id 292 } 293 294 func (s fakeSpace) Subnets() []gomaasapi.Subnet { 295 return s.subnets 296 } 297 298 type fakeSubnet struct { 299 gomaasapi.Subnet 300 id int 301 space string 302 vlan gomaasapi.VLAN 303 gateway string 304 cidr string 305 dnsServers []string 306 } 307 308 func (s fakeSubnet) ID() int { 309 return s.id 310 } 311 312 func (s fakeSubnet) Space() string { 313 return s.space 314 } 315 316 func (s fakeSubnet) VLAN() gomaasapi.VLAN { 317 return s.vlan 318 } 319 320 func (s fakeSubnet) Gateway() string { 321 return s.gateway 322 } 323 324 func (s fakeSubnet) CIDR() string { 325 return s.cidr 326 } 327 328 func (s fakeSubnet) DNSServers() []string { 329 return s.dnsServers 330 } 331 332 type fakeVLAN struct { 333 gomaasapi.VLAN 334 id int 335 vid int 336 mtu int 337 } 338 339 func (v fakeVLAN) ID() int { 340 return v.id 341 } 342 343 func (v fakeVLAN) VID() int { 344 return v.vid 345 } 346 347 func (v fakeVLAN) MTU() int { 348 return v.mtu 349 } 350 351 type fakeInterface struct { 352 gomaasapi.Interface 353 *testing.Stub 354 355 id int 356 name string 357 parents []string 358 children []string 359 type_ string 360 enabled bool 361 vlan gomaasapi.VLAN 362 links []gomaasapi.Link 363 macAddress string 364 } 365 366 func (v *fakeInterface) ID() int { 367 return v.id 368 } 369 370 func (v *fakeInterface) Name() string { 371 return v.name 372 } 373 374 func (v *fakeInterface) Parents() []string { 375 return v.parents 376 } 377 378 func (v *fakeInterface) Children() []string { 379 return v.children 380 } 381 382 func (v *fakeInterface) Type() string { 383 return v.type_ 384 } 385 386 func (v *fakeInterface) EffectiveMTU() int { 387 return 1500 388 } 389 390 func (v *fakeInterface) Enabled() bool { 391 return v.enabled 392 } 393 394 func (v *fakeInterface) VLAN() gomaasapi.VLAN { 395 return v.vlan 396 } 397 398 func (v *fakeInterface) Links() []gomaasapi.Link { 399 return v.links 400 } 401 402 func (v *fakeInterface) MACAddress() string { 403 return v.macAddress 404 } 405 406 func (v *fakeInterface) LinkSubnet(args gomaasapi.LinkSubnetArgs) error { 407 v.MethodCall(v, "LinkSubnet", args) 408 return v.NextErr() 409 } 410 411 type fakeLink struct { 412 gomaasapi.Link 413 id int 414 mode string 415 subnet gomaasapi.Subnet 416 ipAddress string 417 } 418 419 func (l *fakeLink) ID() int { 420 return l.id 421 } 422 423 func (l *fakeLink) Mode() string { 424 return l.mode 425 } 426 427 func (l *fakeLink) Subnet() gomaasapi.Subnet { 428 return l.subnet 429 } 430 431 func (l *fakeLink) IPAddress() string { 432 return l.ipAddress 433 } 434 435 type fakeFile struct { 436 gomaasapi.File 437 name string 438 url string 439 contents []byte 440 deleted bool 441 error error 442 } 443 444 func (f *fakeFile) Filename() string { 445 return f.name 446 } 447 448 func (f *fakeFile) AnonymousURL() string { 449 return f.url 450 } 451 452 func (f *fakeFile) Delete() error { 453 f.deleted = true 454 return f.error 455 } 456 457 func (f *fakeFile) ReadAll() ([]byte, error) { 458 if f.error != nil { 459 return nil, f.error 460 } 461 return f.contents, nil 462 } 463 464 type fakeBlockDevice struct { 465 gomaasapi.BlockDevice 466 name string 467 path string 468 size uint64 469 } 470 471 func (bd fakeBlockDevice) Name() string { 472 return bd.name 473 } 474 475 func (bd fakeBlockDevice) Path() string { 476 return bd.path 477 } 478 479 func (bd fakeBlockDevice) Size() uint64 { 480 return bd.size 481 } 482 483 type fakeDevice struct { 484 gomaasapi.Device 485 *testing.Stub 486 487 interfaceSet []gomaasapi.Interface 488 systemID string 489 interface_ gomaasapi.Interface 490 } 491 492 func (d *fakeDevice) InterfaceSet() []gomaasapi.Interface { 493 return d.interfaceSet 494 } 495 496 func (d *fakeDevice) SystemID() string { 497 return d.systemID 498 } 499 500 func (d *fakeDevice) CreateInterface(args gomaasapi.CreateInterfaceArgs) (gomaasapi.Interface, error) { 501 d.MethodCall(d, "CreateInterface", args) 502 d.interfaceSet = append(d.interfaceSet, d.interface_) 503 return d.interface_, d.NextErr() 504 }