github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/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 "github.com/juju/juju/feature" 16 coretesting "github.com/juju/juju/testing" 17 "github.com/juju/juju/version" 18 ) 19 20 type maas2Suite struct { 21 baseProviderSuite 22 } 23 24 func (suite *maas2Suite) SetUpTest(c *gc.C) { 25 suite.baseProviderSuite.SetUpTest(c) 26 suite.SetFeatureFlags(feature.MAAS2) 27 } 28 29 func (suite *maas2Suite) injectController(controller gomaasapi.Controller) { 30 mockGetController := func(maasServer, apiKey string) (gomaasapi.Controller, error) { 31 return controller, nil 32 } 33 suite.PatchValue(&GetMAAS2Controller, mockGetController) 34 } 35 36 func (suite *maas2Suite) makeEnviron(c *gc.C, controller gomaasapi.Controller) *maasEnviron { 37 if controller != nil { 38 suite.injectController(controller) 39 } 40 testAttrs := coretesting.Attrs{} 41 for k, v := range maasEnvAttrs { 42 testAttrs[k] = v 43 } 44 testAttrs["maas-server"] = "http://any-old-junk.invalid/" 45 testAttrs["agent-version"] = version.Current.String() 46 testAttrs["maas-agent-name"] = "agent-prefix" 47 48 attrs := coretesting.FakeConfig().Merge(testAttrs) 49 cfg, err := config.New(config.NoDefaults, attrs) 50 c.Assert(err, jc.ErrorIsNil) 51 env, err := NewEnviron(cfg) 52 c.Assert(err, jc.ErrorIsNil) 53 c.Assert(env, gc.NotNil) 54 return env 55 } 56 57 type fakeController struct { 58 gomaasapi.Controller 59 *testing.Stub 60 61 bootResources []gomaasapi.BootResource 62 bootResourcesError error 63 machines []gomaasapi.Machine 64 machinesError error 65 machinesArgsCheck func(gomaasapi.MachinesArgs) 66 zones []gomaasapi.Zone 67 zonesError error 68 spaces []gomaasapi.Space 69 spacesError error 70 71 allocateMachine gomaasapi.Machine 72 allocateMachineMatches gomaasapi.ConstraintMatches 73 allocateMachineError error 74 allocateMachineArgsCheck func(gomaasapi.AllocateMachineArgs) 75 76 files []gomaasapi.File 77 } 78 79 func newFakeController() *fakeController { 80 return &fakeController{Stub: &testing.Stub{}} 81 } 82 83 func newFakeControllerWithErrors(errors ...error) *fakeController { 84 controller := newFakeController() 85 controller.SetErrors(errors...) 86 return controller 87 } 88 89 func newFakeControllerWithFiles(files ...gomaasapi.File) *fakeController { 90 return &fakeController{Stub: &testing.Stub{}, files: files} 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 zoneName string 192 hostname string 193 systemID string 194 ipAddresses []string 195 statusName string 196 statusMessage string 197 cpuCount int 198 memory int 199 architecture string 200 interfaceSet []gomaasapi.Interface 201 tags []string 202 } 203 204 func (m *fakeMachine) Tags() []string { 205 return m.tags 206 } 207 208 func (m *fakeMachine) CPUCount() int { 209 return m.cpuCount 210 } 211 212 func (m *fakeMachine) Memory() int { 213 return m.memory 214 } 215 216 func (m *fakeMachine) Architecture() string { 217 return m.architecture 218 } 219 220 func (m *fakeMachine) SystemID() string { 221 return m.systemID 222 } 223 224 func (m *fakeMachine) Hostname() string { 225 return m.hostname 226 } 227 228 func (m *fakeMachine) IPAddresses() []string { 229 return m.ipAddresses 230 } 231 232 func (m *fakeMachine) StatusName() string { 233 return m.statusName 234 } 235 236 func (m *fakeMachine) StatusMessage() string { 237 return m.statusMessage 238 } 239 240 func (m *fakeMachine) Zone() gomaasapi.Zone { 241 return fakeZone{name: m.zoneName} 242 } 243 244 func (m *fakeMachine) InterfaceSet() []gomaasapi.Interface { 245 return m.interfaceSet 246 } 247 248 func (m *fakeMachine) Start(args gomaasapi.StartArgs) error { 249 return nil 250 } 251 252 type fakeZone struct { 253 gomaasapi.Zone 254 name string 255 } 256 257 func (z fakeZone) Name() string { 258 return z.name 259 } 260 261 type fakeSpace struct { 262 gomaasapi.Space 263 name string 264 id int 265 subnets []gomaasapi.Subnet 266 } 267 268 func (s fakeSpace) Name() string { 269 return s.name 270 } 271 272 func (s fakeSpace) ID() int { 273 return s.id 274 } 275 276 func (s fakeSpace) Subnets() []gomaasapi.Subnet { 277 return s.subnets 278 } 279 280 type fakeSubnet struct { 281 gomaasapi.Subnet 282 id int 283 space string 284 vlan gomaasapi.VLAN 285 gateway string 286 cidr string 287 dnsServers []string 288 } 289 290 func (s fakeSubnet) ID() int { 291 return s.id 292 } 293 294 func (s fakeSubnet) Space() string { 295 return s.space 296 } 297 298 func (s fakeSubnet) VLAN() gomaasapi.VLAN { 299 return s.vlan 300 } 301 302 func (s fakeSubnet) Gateway() string { 303 return s.gateway 304 } 305 306 func (s fakeSubnet) CIDR() string { 307 return s.cidr 308 } 309 310 func (s fakeSubnet) DNSServers() []string { 311 return s.dnsServers 312 } 313 314 type fakeVLAN struct { 315 gomaasapi.VLAN 316 id int 317 vid int 318 mtu int 319 } 320 321 func (v fakeVLAN) ID() int { 322 return v.id 323 } 324 325 func (v fakeVLAN) VID() int { 326 return v.vid 327 } 328 329 func (v fakeVLAN) MTU() int { 330 return v.mtu 331 } 332 333 type fakeInterface struct { 334 gomaasapi.Interface 335 id int 336 name string 337 parents []string 338 children []string 339 type_ string 340 enabled bool 341 vlan gomaasapi.VLAN 342 links []gomaasapi.Link 343 macAddress string 344 } 345 346 func (v *fakeInterface) ID() int { 347 return v.id 348 } 349 350 func (v *fakeInterface) Name() string { 351 return v.name 352 } 353 354 func (v *fakeInterface) Parents() []string { 355 return v.parents 356 } 357 358 func (v *fakeInterface) Children() []string { 359 return v.children 360 } 361 362 func (v *fakeInterface) Type() string { 363 return v.type_ 364 } 365 366 func (v *fakeInterface) Enabled() bool { 367 return v.enabled 368 } 369 370 func (v *fakeInterface) VLAN() gomaasapi.VLAN { 371 return v.vlan 372 } 373 374 func (v *fakeInterface) Links() []gomaasapi.Link { 375 return v.links 376 } 377 378 func (v *fakeInterface) MACAddress() string { 379 return v.macAddress 380 } 381 382 type fakeLink struct { 383 gomaasapi.Link 384 id int 385 mode string 386 subnet gomaasapi.Subnet 387 ipAddress string 388 } 389 390 func (l *fakeLink) ID() int { 391 return l.id 392 } 393 394 func (l *fakeLink) Mode() string { 395 return l.mode 396 } 397 398 func (l *fakeLink) Subnet() gomaasapi.Subnet { 399 return l.subnet 400 } 401 402 func (l *fakeLink) IPAddress() string { 403 return l.ipAddress 404 } 405 406 type fakeFile struct { 407 gomaasapi.File 408 name string 409 url string 410 contents []byte 411 deleted bool 412 error error 413 } 414 415 func (f *fakeFile) Filename() string { 416 return f.name 417 } 418 419 func (f *fakeFile) AnonymousURL() string { 420 return f.url 421 } 422 423 func (f *fakeFile) Delete() error { 424 f.deleted = true 425 return f.error 426 } 427 428 func (f *fakeFile) ReadAll() ([]byte, error) { 429 if f.error != nil { 430 return nil, f.error 431 } 432 return f.contents, nil 433 } 434 435 type fakeBlockDevice struct { 436 gomaasapi.BlockDevice 437 name string 438 path string 439 size uint64 440 } 441 442 func (bd fakeBlockDevice) Name() string { 443 return bd.name 444 } 445 446 func (bd fakeBlockDevice) Path() string { 447 return bd.path 448 } 449 450 func (bd fakeBlockDevice) Size() uint64 { 451 return bd.size 452 }