github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/apiserver/common/credentialcommon/modelcredential_test.go (about) 1 // Copyright 2018 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package credentialcommon_test 5 6 import ( 7 "github.com/juju/errors" 8 "github.com/juju/testing" 9 jc "github.com/juju/testing/checkers" 10 gc "gopkg.in/check.v1" 11 "gopkg.in/juju/names.v2" 12 13 "github.com/juju/juju/apiserver/common" 14 "github.com/juju/juju/apiserver/common/credentialcommon" 15 "github.com/juju/juju/apiserver/params" 16 "github.com/juju/juju/caas" 17 "github.com/juju/juju/cloud" 18 "github.com/juju/juju/core/instance" 19 "github.com/juju/juju/environs" 20 "github.com/juju/juju/environs/config" 21 "github.com/juju/juju/environs/context" 22 "github.com/juju/juju/environs/instances" 23 "github.com/juju/juju/state" 24 statetesting "github.com/juju/juju/state/testing" 25 ) 26 27 var _ = gc.Suite(&CheckMachinesSuite{}) 28 var _ = gc.Suite(&ModelCredentialSuite{}) 29 30 type CheckMachinesSuite struct { 31 testing.IsolationSuite 32 33 provider *mockProvider 34 instance *mockInstance 35 callContext context.ProviderCallContext 36 37 backend *mockPersistedBackend 38 machine *mockMachine 39 } 40 41 func (s *CheckMachinesSuite) SetUpTest(c *gc.C) { 42 s.IsolationSuite.SetUpTest(c) 43 s.backend = createModelBackend(c) 44 45 // This is what the test gets from the state. 46 s.machine = createTestMachine("1", "wind-up") 47 s.backend.allMachinesFunc = func() ([]credentialcommon.Machine, error) { 48 return []credentialcommon.Machine{s.machine}, nil 49 } 50 51 // This is what the test gets from the cloud. 52 s.instance = &mockInstance{id: "wind-up"} 53 s.provider = &mockProvider{ 54 Stub: &testing.Stub{}, 55 allInstancesFunc: func(ctx context.ProviderCallContext) ([]instances.Instance, error) { 56 return []instances.Instance{s.instance}, nil 57 }, 58 } 59 s.callContext = context.NewCloudCallContext() 60 } 61 62 func (s *CheckMachinesSuite) TestCheckMachinesSuccess(c *gc.C) { 63 results, err := credentialcommon.CheckMachineInstances(s.backend, s.provider, s.callContext) 64 c.Assert(err, jc.ErrorIsNil) 65 c.Assert(results, gc.DeepEquals, params.ErrorResults{}) 66 } 67 68 func (s *CheckMachinesSuite) TestCheckMachinesInstancesMissing(c *gc.C) { 69 machine1 := createTestMachine("2", "birds") 70 s.backend.allMachinesFunc = func() ([]credentialcommon.Machine, error) { 71 return []credentialcommon.Machine{s.machine, machine1}, nil 72 } 73 74 results, err := credentialcommon.CheckMachineInstances(s.backend, s.provider, s.callContext) 75 c.Assert(err, jc.ErrorIsNil) 76 77 c.Assert(results.Results, gc.HasLen, 1) 78 c.Assert(results.Results[0].Error, gc.ErrorMatches, `couldn't find instance "birds" for machine 2`) 79 } 80 81 func (s *CheckMachinesSuite) TestCheckMachinesExtraInstances(c *gc.C) { 82 instance2 := &mockInstance{id: "analyse"} 83 s.provider.allInstancesFunc = func(ctx context.ProviderCallContext) ([]instances.Instance, error) { 84 return []instances.Instance{s.instance, instance2}, nil 85 } 86 87 results, err := credentialcommon.CheckMachineInstances(s.backend, s.provider, s.callContext) 88 c.Assert(err, jc.ErrorIsNil) 89 90 c.Assert(results.Results, gc.HasLen, 1) 91 c.Assert(results.Results[0].Error, gc.ErrorMatches, `no machine with instance "analyse"`) 92 } 93 94 func (s *CheckMachinesSuite) TestCheckMachinesErrorGettingMachines(c *gc.C) { 95 s.backend.allMachinesFunc = func() ([]credentialcommon.Machine, error) { 96 return nil, errors.New("boom") 97 } 98 99 results, err := credentialcommon.CheckMachineInstances(s.backend, s.provider, s.callContext) 100 c.Assert(err, gc.ErrorMatches, "boom") 101 c.Assert(results, gc.DeepEquals, params.ErrorResults{}) 102 } 103 104 func (s *CheckMachinesSuite) TestCheckMachinesErrorGettingInstances(c *gc.C) { 105 s.provider.allInstancesFunc = func(ctx context.ProviderCallContext) ([]instances.Instance, error) { 106 return nil, errors.New("kaboom") 107 } 108 109 results, err := credentialcommon.CheckMachineInstances(s.backend, s.provider, s.callContext) 110 c.Assert(err, gc.ErrorMatches, "kaboom") 111 c.Assert(results, gc.DeepEquals, params.ErrorResults{}) 112 } 113 114 func (s *CheckMachinesSuite) TestCheckMachinesHandlesContainers(c *gc.C) { 115 machine1 := createTestMachine("1", "") 116 machine1.container = true 117 s.backend.allMachinesFunc = func() ([]credentialcommon.Machine, error) { 118 return []credentialcommon.Machine{s.machine, machine1}, nil 119 } 120 121 results, err := credentialcommon.CheckMachineInstances(s.backend, s.provider, s.callContext) 122 c.Assert(err, jc.ErrorIsNil) 123 c.Assert(results, gc.DeepEquals, params.ErrorResults{}) 124 } 125 126 func (s *CheckMachinesSuite) TestCheckMachinesHandlesManual(c *gc.C) { 127 machine1 := createTestMachine("2", "") 128 machine1.manualFunc = func() (bool, error) { return false, errors.New("manual retrieval failure") } 129 s.backend.allMachinesFunc = func() ([]credentialcommon.Machine, error) { 130 return []credentialcommon.Machine{s.machine, machine1}, nil 131 } 132 133 results, err := credentialcommon.CheckMachineInstances(s.backend, s.provider, s.callContext) 134 c.Assert(err, gc.ErrorMatches, "manual retrieval failure") 135 c.Assert(results, gc.DeepEquals, params.ErrorResults{}) 136 137 machine1.manualFunc = func() (bool, error) { return true, nil } 138 results, err = credentialcommon.CheckMachineInstances(s.backend, s.provider, s.callContext) 139 c.Assert(err, jc.ErrorIsNil) 140 c.Assert(results, gc.DeepEquals, params.ErrorResults{}) 141 } 142 143 func (s *CheckMachinesSuite) TestCheckMachinesErrorGettingMachineInstanceId(c *gc.C) { 144 machine1 := createTestMachine("2", "") 145 machine1.instanceIdFunc = func() (instance.Id, error) { return "", errors.New("retrieval failure") } 146 s.backend.allMachinesFunc = func() ([]credentialcommon.Machine, error) { 147 return []credentialcommon.Machine{s.machine, machine1}, nil 148 } 149 150 results, err := credentialcommon.CheckMachineInstances(s.backend, s.provider, s.callContext) 151 c.Assert(err, jc.ErrorIsNil) 152 c.Assert(results, gc.DeepEquals, params.ErrorResults{ 153 Results: []params.ErrorResult{ 154 {Error: common.ServerError(errors.Errorf("getting instance id for machine 2: retrieval failure"))}, 155 }, 156 }) 157 } 158 159 func (s *CheckMachinesSuite) TestCheckMachinesErrorGettingMachineInstanceIdNonFatal(c *gc.C) { 160 machine1 := createTestMachine("2", "") 161 machine1.instanceIdFunc = func() (instance.Id, error) { return "", errors.New("retrieval failure") } 162 s.machine.instanceIdFunc = machine1.instanceIdFunc 163 s.backend.allMachinesFunc = func() ([]credentialcommon.Machine, error) { 164 return []credentialcommon.Machine{s.machine, machine1}, nil 165 } 166 167 results, err := credentialcommon.CheckMachineInstances(s.backend, s.provider, s.callContext) 168 c.Assert(err, jc.ErrorIsNil) 169 // There should be 3 errors here: 170 // * 2 of them because failing to get an instance id from one machine should not stop the processing the rest of the machines; 171 // * 1 because we no longer can link test instance (s.instance) to a test machine (s.machine). 172 c.Assert(results, gc.DeepEquals, params.ErrorResults{ 173 Results: []params.ErrorResult{ 174 {Error: common.ServerError(errors.New("getting instance id for machine 1: retrieval failure"))}, 175 {Error: common.ServerError(errors.New("getting instance id for machine 2: retrieval failure"))}, 176 {Error: common.ServerError(errors.New(`no machine with instance "wind-up"`))}, 177 }, 178 }) 179 } 180 181 func (s *CheckMachinesSuite) TestCheckMachinesNotProvisionedError(c *gc.C) { 182 machine2 := createTestMachine("2", "") 183 machine2.instanceIdFunc = func() (instance.Id, error) { return "", errors.NotProvisionedf("machine 2") } 184 s.backend.allMachinesFunc = func() ([]credentialcommon.Machine, error) { 185 return []credentialcommon.Machine{s.machine, machine2}, nil 186 } 187 188 // We should ignore the unprovisioned machine - we wouldn't expect 189 // the cloud to know about it. 190 results, err := credentialcommon.CheckMachineInstances(s.backend, s.provider, s.callContext) 191 c.Assert(err, jc.ErrorIsNil) 192 c.Assert(results, gc.DeepEquals, params.ErrorResults{}) 193 } 194 195 type ModelCredentialSuite struct { 196 testing.IsolationSuite 197 198 backend *mockPersistedBackend 199 callContext context.ProviderCallContext 200 } 201 202 func (s *ModelCredentialSuite) SetUpTest(c *gc.C) { 203 s.IsolationSuite.SetUpTest(c) 204 s.backend = createModelBackend(c) 205 s.callContext = context.NewCloudCallContext() 206 } 207 208 func (s *ModelCredentialSuite) TestValidateNewModelCredentialUnknownModelType(c *gc.C) { 209 unknownModel := createTestModel() 210 unknownModel.modelType = state.ModelType("unknown") 211 s.backend.modelFunc = func() (credentialcommon.Model, error) { 212 return unknownModel, nil 213 } 214 215 results, err := credentialcommon.ValidateNewModelCredential(s.backend, s.callContext, names.CloudCredentialTag{}, &testCredential) 216 c.Assert(err, gc.ErrorMatches, `model type "unknown" not supported`) 217 c.Assert(results, gc.DeepEquals, params.ErrorResults{}) 218 } 219 220 func (s *ModelCredentialSuite) TestBuildingOpenParamsErrorGettingModel(c *gc.C) { 221 s.backend.SetErrors(errors.New("get model error")) 222 results, err := credentialcommon.ValidateNewModelCredential(s.backend, s.callContext, names.CloudCredentialTag{}, nil) 223 c.Assert(err, gc.ErrorMatches, "get model error") 224 c.Assert(results, gc.DeepEquals, params.ErrorResults{}) 225 s.backend.CheckCallNames(c, "Model") 226 } 227 228 func (s *ModelCredentialSuite) TestBuildingOpenParamsErrorGettingCloud(c *gc.C) { 229 s.backend.SetErrors( 230 nil, // getting model 231 errors.New("get cloud error"), 232 ) 233 results, err := credentialcommon.ValidateNewModelCredential(s.backend, s.callContext, names.CloudCredentialTag{}, nil) 234 s.backend.CheckCallNames(c, "Model", "Cloud") 235 c.Assert(err, gc.ErrorMatches, "get cloud error") 236 c.Assert(results, gc.DeepEquals, params.ErrorResults{}) 237 } 238 239 func (s *ModelCredentialSuite) TestBuildingOpenParamsErrorGettingModelConfig(c *gc.C) { 240 model := createTestModel() 241 model.configFunc = func() (*config.Config, error) { 242 return nil, errors.New("get model config error") 243 } 244 245 s.backend.modelFunc = func() (credentialcommon.Model, error) { 246 return model, nil 247 } 248 249 results, err := credentialcommon.ValidateNewModelCredential(s.backend, s.callContext, names.CloudCredentialTag{}, &testCredential) 250 c.Assert(err, gc.ErrorMatches, "get model config error") 251 c.Assert(results, gc.DeepEquals, params.ErrorResults{}) 252 s.backend.CheckCallNames(c, "Model", "Cloud") 253 } 254 255 func (s *ModelCredentialSuite) TestBuildingOpenParamsErrorValidateCredentialForModelCloud(c *gc.C) { 256 model := createTestModel() 257 model.validateCredentialFunc = func(tag names.CloudCredentialTag, credential cloud.Credential) error { 258 return errors.New("credential not for model cloud error") 259 } 260 261 s.backend.modelFunc = func() (credentialcommon.Model, error) { 262 return model, nil 263 } 264 265 results, err := credentialcommon.ValidateNewModelCredential(s.backend, s.callContext, names.CloudCredentialTag{}, &testCredential) 266 c.Assert(err, gc.ErrorMatches, "credential not for model cloud error") 267 c.Assert(results, gc.DeepEquals, params.ErrorResults{}) 268 s.backend.CheckCallNames(c, "Model", "Cloud") 269 } 270 271 func (s *ModelCredentialSuite) TestValidateExistingModelCredentialErrorGettingModel(c *gc.C) { 272 s.backend.SetErrors(errors.New("get model error")) 273 results, err := credentialcommon.ValidateExistingModelCredential(s.backend, s.callContext) 274 c.Assert(err, gc.ErrorMatches, "get model error") 275 c.Assert(results, gc.DeepEquals, params.ErrorResults{}) 276 s.backend.CheckCallNames(c, "Model") 277 } 278 279 func (s *ModelCredentialSuite) TestValidateExistingModelCredentialUnsetCloudCredential(c *gc.C) { 280 model := createTestModel() 281 model.cloudCredentialFunc = func() (names.CloudCredentialTag, bool) { 282 return names.CloudCredentialTag{}, false 283 } 284 285 s.backend.modelFunc = func() (credentialcommon.Model, error) { 286 return model, nil 287 } 288 289 results, err := credentialcommon.ValidateExistingModelCredential(s.backend, s.callContext) 290 c.Assert(err, jc.ErrorIsNil) 291 c.Assert(results, gc.DeepEquals, params.ErrorResults{}) 292 s.backend.CheckCallNames(c, "Model") 293 } 294 295 func (s *ModelCredentialSuite) TestValidateExistingModelCredentialErrorGettingCredential(c *gc.C) { 296 s.backend.cloudCredentialFunc = func(tag names.CloudCredentialTag) (state.Credential, error) { 297 return state.Credential{}, errors.New("no nope niet") 298 } 299 300 results, err := credentialcommon.ValidateExistingModelCredential(s.backend, s.callContext) 301 c.Assert(err, gc.ErrorMatches, "no nope niet") 302 c.Assert(results, gc.DeepEquals, params.ErrorResults{}) 303 s.backend.CheckCallNames(c, "Model", "CloudCredential") 304 } 305 306 func (s *ModelCredentialSuite) TestValidateExistingModelCredentialInvalidCredential(c *gc.C) { 307 s.backend.cloudCredentialFunc = func(tag names.CloudCredentialTag) (state.Credential, error) { 308 cred := statetesting.NewEmptyCredential() 309 cred.Name = "cred" 310 cred.Invalid = true 311 return cred, nil 312 } 313 314 results, err := credentialcommon.ValidateExistingModelCredential(s.backend, s.callContext) 315 c.Assert(err, gc.ErrorMatches, `credential "cred" not valid`) 316 c.Assert(results, gc.DeepEquals, params.ErrorResults{}) 317 s.backend.CheckCallNames(c, "Model", "CloudCredential") 318 } 319 320 func (s *ModelCredentialSuite) TestOpeningProviderFails(c *gc.C) { 321 s.PatchValue(credentialcommon.NewEnv, func(environs.OpenParams) (environs.Environ, error) { 322 return nil, errors.New("explosive") 323 }) 324 results, err := credentialcommon.CheckIAASModelCredential(environs.OpenParams{}, s.backend, s.callContext) 325 c.Assert(err, gc.ErrorMatches, "explosive") 326 c.Assert(results, gc.DeepEquals, params.ErrorResults{}) 327 } 328 329 func (s *ModelCredentialSuite) TestValidateNewModelCredentialForIAASModel(c *gc.C) { 330 s.ensureEnvForIAASModel(c) 331 results, err := credentialcommon.ValidateNewModelCredential(s.backend, s.callContext, names.CloudCredentialTag{}, &testCredential) 332 c.Assert(err, jc.ErrorIsNil) 333 c.Assert(results, gc.DeepEquals, params.ErrorResults{}) 334 } 335 336 func (s *ModelCredentialSuite) TestValidateExistingModelCredentialForIAASModel(c *gc.C) { 337 s.ensureEnvForIAASModel(c) 338 results, err := credentialcommon.ValidateExistingModelCredential(s.backend, s.callContext) 339 c.Assert(err, jc.ErrorIsNil) 340 c.Assert(results, gc.DeepEquals, params.ErrorResults{}) 341 } 342 343 func (s *ModelCredentialSuite) TestOpeningCAASBrokerFails(c *gc.C) { 344 s.PatchValue(credentialcommon.NewCAASBroker, func(environs.OpenParams) (caas.Broker, error) { 345 return nil, errors.New("explosive") 346 }) 347 results, err := credentialcommon.CheckCAASModelCredential(environs.OpenParams{}) 348 c.Assert(err, gc.ErrorMatches, "explosive") 349 c.Assert(results, gc.DeepEquals, params.ErrorResults{}) 350 } 351 352 func (s *ModelCredentialSuite) TestCAASCredentialCheckFailed(c *gc.C) { 353 s.PatchValue(credentialcommon.NewCAASBroker, func(environs.OpenParams) (caas.Broker, error) { 354 return &mockCaasBroker{ 355 namespacesFunc: func() ([]string, error) { return nil, errors.New("fail auth") }, 356 }, nil 357 }) 358 results, err := credentialcommon.CheckCAASModelCredential(environs.OpenParams{}) 359 c.Assert(err, gc.ErrorMatches, "fail auth") 360 c.Assert(results, gc.DeepEquals, params.ErrorResults{}) 361 } 362 363 func (s *ModelCredentialSuite) TestCAASCredentialCheckSucceeds(c *gc.C) { 364 s.PatchValue(credentialcommon.NewCAASBroker, func(environs.OpenParams) (caas.Broker, error) { 365 return &mockCaasBroker{ 366 namespacesFunc: func() ([]string, error) { return []string{}, nil }, 367 }, nil 368 }) 369 results, err := credentialcommon.CheckCAASModelCredential(environs.OpenParams{}) 370 c.Assert(err, jc.ErrorIsNil) 371 c.Assert(results, gc.DeepEquals, params.ErrorResults{}) 372 } 373 374 func (s *ModelCredentialSuite) TestValidateNewModelCredentialForCAASModel(c *gc.C) { 375 s.ensureEnvForCAASModel(c) 376 results, err := credentialcommon.ValidateNewModelCredential(s.backend, s.callContext, names.CloudCredentialTag{}, &testCredential) 377 c.Assert(err, jc.ErrorIsNil) 378 c.Assert(results, gc.DeepEquals, params.ErrorResults{}) 379 } 380 381 func (s *ModelCredentialSuite) TestValidateExistingModelCredentialForCAASSuccess(c *gc.C) { 382 s.ensureEnvForCAASModel(c) 383 results, err := credentialcommon.ValidateExistingModelCredential(s.backend, s.callContext) 384 c.Assert(err, jc.ErrorIsNil) 385 c.Assert(results, gc.DeepEquals, params.ErrorResults{}) 386 } 387 388 func (s *ModelCredentialSuite) ensureEnvForCAASModel(c *gc.C) { 389 caasModel := createTestModel() 390 caasModel.modelType = state.ModelTypeCAAS 391 s.backend.modelFunc = func() (credentialcommon.Model, error) { 392 return caasModel, nil 393 } 394 s.PatchValue(credentialcommon.NewCAASBroker, func(environs.OpenParams) (caas.Broker, error) { 395 return &mockCaasBroker{ 396 namespacesFunc: func() ([]string, error) { return []string{}, nil }, 397 }, nil 398 }) 399 } 400 401 func (s *ModelCredentialSuite) ensureEnvForIAASModel(c *gc.C) { 402 s.PatchValue(credentialcommon.NewEnv, func(environs.OpenParams) (environs.Environ, error) { 403 return &mockEnviron{ 404 mockProvider: &mockProvider{ 405 Stub: &testing.Stub{}, 406 allInstancesFunc: func(ctx context.ProviderCallContext) ([]instances.Instance, error) { 407 return []instances.Instance{}, nil 408 }, 409 }, 410 }, nil 411 }) 412 } 413 414 func createModelBackend(c *gc.C) *mockPersistedBackend { 415 backend := mockPersistedBackend{Stub: &testing.Stub{}} 416 backend.allMachinesFunc = func() ([]credentialcommon.Machine, error) { 417 return []credentialcommon.Machine{}, backend.NextErr() 418 } 419 backend.modelFunc = func() (credentialcommon.Model, error) { 420 return createTestModel(), backend.NextErr() 421 } 422 backend.cloudFunc = func(name string) (cloud.Cloud, error) { 423 return cloud.Cloud{ 424 Name: "nuage", 425 Type: "dummy", 426 AuthTypes: []cloud.AuthType{cloud.EmptyAuthType, cloud.UserPassAuthType}, 427 Regions: []cloud.Region{{Name: "nine", Endpoint: "endpoint"}}, 428 }, backend.NextErr() 429 } 430 backend.cloudCredentialFunc = func(tag names.CloudCredentialTag) (state.Credential, error) { 431 return statetesting.NewEmptyCredential(), backend.NextErr() 432 } 433 return &backend 434 } 435 436 type mockProvider struct { 437 *testing.Stub 438 allInstancesFunc func(ctx context.ProviderCallContext) ([]instances.Instance, error) 439 } 440 441 func (m *mockProvider) AllInstances(ctx context.ProviderCallContext) ([]instances.Instance, error) { 442 m.MethodCall(m, "AllInstances", ctx) 443 return m.allInstancesFunc(ctx) 444 } 445 446 type mockInstance struct { 447 instances.Instance 448 id string 449 } 450 451 func (i *mockInstance) Id() instance.Id { 452 return instance.Id(i.id) 453 } 454 455 type mockMachine struct { 456 id string 457 container bool 458 manualFunc func() (bool, error) 459 instanceIdFunc func() (instance.Id, error) 460 } 461 462 func (m *mockMachine) IsManual() (bool, error) { 463 return m.manualFunc() 464 } 465 466 func (m *mockMachine) IsContainer() bool { 467 return m.container 468 } 469 470 func (m *mockMachine) InstanceId() (instance.Id, error) { 471 return m.instanceIdFunc() 472 } 473 474 func (m *mockMachine) InstanceNames() (instance.Id, string, error) { 475 instId, err := m.instanceIdFunc() 476 return instId, "", err 477 } 478 479 func (m *mockMachine) Id() string { 480 return m.id 481 } 482 483 func createTestMachine(id, instanceId string) *mockMachine { 484 return &mockMachine{ 485 id: id, 486 manualFunc: func() (bool, error) { return false, nil }, 487 instanceIdFunc: func() (instance.Id, error) { return instance.Id(instanceId), nil }, 488 } 489 } 490 491 type mockPersistedBackend struct { 492 *testing.Stub 493 allMachinesFunc func() ([]credentialcommon.Machine, error) 494 495 modelFunc func() (credentialcommon.Model, error) 496 cloudFunc func(name string) (cloud.Cloud, error) 497 cloudCredentialFunc func(tag names.CloudCredentialTag) (state.Credential, error) 498 } 499 500 func (m *mockPersistedBackend) AllMachines() ([]credentialcommon.Machine, error) { 501 m.MethodCall(m, "AllMachines") 502 return m.allMachinesFunc() 503 } 504 505 func (m *mockPersistedBackend) Model() (credentialcommon.Model, error) { 506 m.MethodCall(m, "Model") 507 return m.modelFunc() 508 } 509 510 func (m *mockPersistedBackend) Cloud(name string) (cloud.Cloud, error) { 511 m.MethodCall(m, "Cloud", name) 512 return m.cloudFunc(name) 513 } 514 515 func (m *mockPersistedBackend) CloudCredential(tag names.CloudCredentialTag) (state.Credential, error) { 516 m.MethodCall(m, "CloudCredential", tag) 517 return m.cloudCredentialFunc(tag) 518 } 519 520 type mockModel struct { 521 modelType state.ModelType 522 cloudFunc func() string 523 cloudRegionFunc func() string 524 configFunc func() (*config.Config, error) 525 validateCredentialFunc func(tag names.CloudCredentialTag, credential cloud.Credential) error 526 cloudCredentialFunc func() (names.CloudCredentialTag, bool) 527 } 528 529 func (m *mockModel) Cloud() string { 530 return m.cloudFunc() 531 } 532 533 func (m *mockModel) CloudRegion() string { 534 return m.cloudRegionFunc() 535 } 536 537 func (m *mockModel) Config() (*config.Config, error) { 538 return m.configFunc() 539 } 540 541 func (m *mockModel) Type() state.ModelType { 542 return m.modelType 543 } 544 545 func (m *mockModel) CloudCredential() (names.CloudCredentialTag, bool) { 546 return m.cloudCredentialFunc() 547 } 548 549 func (m *mockModel) ValidateCloudCredential(tag names.CloudCredentialTag, credential cloud.Credential) error { 550 return m.validateCredentialFunc(tag, credential) 551 } 552 553 func createTestModel() *mockModel { 554 return &mockModel{ 555 modelType: state.ModelTypeIAAS, 556 cloudFunc: func() string { return "nuage" }, 557 cloudRegionFunc: func() string { return "nine" }, 558 configFunc: func() (*config.Config, error) { 559 return nil, nil 560 }, 561 validateCredentialFunc: func(tag names.CloudCredentialTag, credential cloud.Credential) error { 562 return nil 563 }, 564 cloudCredentialFunc: func() (names.CloudCredentialTag, bool) { 565 // return true here since, most of the time, we want to test when the cloud credential is set. 566 return names.CloudCredentialTag{}, true 567 }, 568 } 569 } 570 571 var ( 572 testCredential = cloud.NewCredential( 573 cloud.UserPassAuthType, 574 map[string]string{ 575 "username": "user", 576 "password": "password", 577 }, 578 ) 579 ) 580 581 type mockEnviron struct { 582 environs.Environ 583 *mockProvider 584 } 585 586 func (m *mockEnviron) AllInstances(ctx context.ProviderCallContext) ([]instances.Instance, error) { 587 return m.mockProvider.AllInstances(ctx) 588 } 589 590 type mockCaasBroker struct { 591 caas.Broker 592 593 namespacesFunc func() ([]string, error) 594 } 595 596 func (m *mockCaasBroker) Namespaces() ([]string, error) { 597 return m.namespacesFunc() 598 }