github.com/juju/juju@v0.0.0-20240327075706-a90865de2538/worker/instancemutater/manifold_test.go (about) 1 // Copyright 2019 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package instancemutater_test 5 6 import ( 7 "github.com/juju/errors" 8 "github.com/juju/names/v5" 9 "github.com/juju/testing" 10 worker "github.com/juju/worker/v3" 11 "github.com/juju/worker/v3/dependency" 12 "go.uber.org/mock/gomock" 13 gc "gopkg.in/check.v1" 14 15 "github.com/juju/juju/agent" 16 "github.com/juju/juju/api/base" 17 "github.com/juju/juju/environs" 18 "github.com/juju/juju/worker/instancemutater" 19 "github.com/juju/juju/worker/instancemutater/mocks" 20 ) 21 22 type modelManifoldConfigSuite struct { 23 testing.IsolationSuite 24 } 25 26 var _ = gc.Suite(&modelManifoldConfigSuite{}) 27 28 func (s *modelManifoldConfigSuite) TestInvalidConfigValidate(c *gc.C) { 29 ctrl := gomock.NewController(c) 30 defer ctrl.Finish() 31 32 testcases := []struct { 33 description string 34 config instancemutater.ModelManifoldConfig 35 err string 36 }{ 37 { 38 description: "Test empty configuration", 39 config: instancemutater.ModelManifoldConfig{}, 40 err: "nil Logger not valid", 41 }, 42 { 43 description: "Test no Logger", 44 config: instancemutater.ModelManifoldConfig{}, 45 err: "nil Logger not valid", 46 }, 47 { 48 description: "Test no new worker constructor", 49 config: instancemutater.ModelManifoldConfig{ 50 Logger: mocks.NewMockLogger(ctrl), 51 }, 52 err: "nil NewWorker not valid", 53 }, 54 { 55 description: "Test no new client constructor", 56 config: instancemutater.ModelManifoldConfig{ 57 Logger: mocks.NewMockLogger(ctrl), 58 NewWorker: func(cfg instancemutater.Config) (worker.Worker, error) { 59 return mocks.NewMockWorker(ctrl), nil 60 }, 61 }, 62 err: "nil NewClient not valid", 63 }, 64 { 65 description: "Test no agent name", 66 config: instancemutater.ModelManifoldConfig{ 67 Logger: mocks.NewMockLogger(ctrl), 68 NewWorker: func(cfg instancemutater.Config) (worker.Worker, error) { 69 return mocks.NewMockWorker(ctrl), nil 70 }, 71 NewClient: func(base.APICaller) instancemutater.InstanceMutaterAPI { 72 return mocks.NewMockInstanceMutaterAPI(ctrl) 73 }, 74 }, 75 err: "empty AgentName not valid", 76 }, 77 { 78 description: "Test no environ name", 79 config: instancemutater.ModelManifoldConfig{ 80 Logger: mocks.NewMockLogger(ctrl), 81 NewWorker: func(cfg instancemutater.Config) (worker.Worker, error) { 82 return mocks.NewMockWorker(ctrl), nil 83 }, 84 NewClient: func(base.APICaller) instancemutater.InstanceMutaterAPI { 85 return mocks.NewMockInstanceMutaterAPI(ctrl) 86 }, 87 AgentName: "agent", 88 }, 89 err: "empty EnvironName not valid", 90 }, 91 { 92 description: "Test no api caller name", 93 config: instancemutater.ModelManifoldConfig{ 94 Logger: mocks.NewMockLogger(ctrl), 95 NewWorker: func(cfg instancemutater.Config) (worker.Worker, error) { 96 return mocks.NewMockWorker(ctrl), nil 97 }, 98 NewClient: func(base.APICaller) instancemutater.InstanceMutaterAPI { 99 return mocks.NewMockInstanceMutaterAPI(ctrl) 100 }, 101 AgentName: "agent", 102 EnvironName: "environ", 103 }, 104 err: "empty APICallerName not valid", 105 }, 106 } 107 for i, test := range testcases { 108 c.Logf("%d %s", i, test.description) 109 err := test.config.Validate() 110 c.Assert(err, gc.ErrorMatches, test.err) 111 } 112 } 113 114 func (s *modelManifoldConfigSuite) TestValidConfigValidate(c *gc.C) { 115 ctrl := gomock.NewController(c) 116 defer ctrl.Finish() 117 118 config := instancemutater.ModelManifoldConfig{ 119 Logger: mocks.NewMockLogger(ctrl), 120 NewWorker: func(cfg instancemutater.Config) (worker.Worker, error) { 121 return mocks.NewMockWorker(ctrl), nil 122 }, 123 NewClient: func(base.APICaller) instancemutater.InstanceMutaterAPI { 124 return mocks.NewMockInstanceMutaterAPI(ctrl) 125 }, 126 AgentName: "agent", 127 EnvironName: "environ", 128 APICallerName: "api-caller", 129 } 130 err := config.Validate() 131 c.Assert(err, gc.IsNil) 132 } 133 134 type environAPIManifoldSuite struct { 135 testing.IsolationSuite 136 137 logger *mocks.MockLogger 138 context *mocks.MockContext 139 agent *mocks.MockAgent 140 environ *mocks.MockEnviron 141 apiCaller *mocks.MockAPICaller 142 worker *mocks.MockWorker 143 } 144 145 var _ = gc.Suite(&environAPIManifoldSuite{}) 146 147 func (s *environAPIManifoldSuite) setup(c *gc.C) *gomock.Controller { 148 ctrl := gomock.NewController(c) 149 150 s.logger = mocks.NewMockLogger(ctrl) 151 s.context = mocks.NewMockContext(ctrl) 152 s.agent = mocks.NewMockAgent(ctrl) 153 s.environ = mocks.NewMockEnviron(ctrl) 154 s.apiCaller = mocks.NewMockAPICaller(ctrl) 155 s.worker = mocks.NewMockWorker(ctrl) 156 157 return ctrl 158 } 159 160 func (s *environAPIManifoldSuite) TestStartReturnsWorker(c *gc.C) { 161 defer s.setup(c).Finish() 162 163 cExp := s.context.EXPECT() 164 cExp.Get("moon", gomock.Any()).SetArg(1, s.agent).Return(nil) 165 cExp.Get("foobar", gomock.Any()).SetArg(1, s.environ).Return(nil) 166 cExp.Get("baz", gomock.Any()).SetArg(1, s.apiCaller).Return(nil) 167 168 config := instancemutater.EnvironAPIConfig{ 169 EnvironName: "foobar", 170 APICallerName: "baz", 171 AgentName: "moon", 172 } 173 manifold := instancemutater.EnvironAPIManifold(config, func(environ environs.Environ, apiCaller base.APICaller, agent agent.Agent) (worker.Worker, error) { 174 c.Assert(environ, gc.Equals, s.environ) 175 c.Assert(apiCaller, gc.Equals, s.apiCaller) 176 c.Assert(agent, gc.Equals, s.agent) 177 178 return s.worker, nil 179 }) 180 result, err := manifold.Start(s.context) 181 c.Assert(err, gc.IsNil) 182 c.Assert(result, gc.Equals, s.worker) 183 } 184 185 func (s *environAPIManifoldSuite) TestMissingEnvironFromContext(c *gc.C) { 186 defer s.setup(c).Finish() 187 188 cExp := s.context.EXPECT() 189 cExp.Get("moon", gomock.Any()).SetArg(1, s.agent).Return(nil) 190 cExp.Get("foobar", gomock.Any()).Return(errors.New("missing")) 191 192 config := instancemutater.EnvironAPIConfig{ 193 EnvironName: "foobar", 194 APICallerName: "baz", 195 AgentName: "moon", 196 } 197 manifold := instancemutater.EnvironAPIManifold(config, func(environs.Environ, base.APICaller, agent.Agent) (worker.Worker, error) { 198 c.Fail() 199 return nil, nil 200 }) 201 _, err := manifold.Start(s.context) 202 c.Assert(err, gc.ErrorMatches, "missing") 203 } 204 205 func (s *environAPIManifoldSuite) TestMissingAPICallerFromContext(c *gc.C) { 206 defer s.setup(c).Finish() 207 208 cExp := s.context.EXPECT() 209 cExp.Get("moon", gomock.Any()).SetArg(1, s.agent).Return(nil) 210 cExp.Get("foobar", gomock.Any()).SetArg(1, s.environ).Return(nil) 211 cExp.Get("baz", gomock.Any()).Return(errors.New("missing")) 212 213 config := instancemutater.EnvironAPIConfig{ 214 EnvironName: "foobar", 215 APICallerName: "baz", 216 AgentName: "moon", 217 } 218 manifold := instancemutater.EnvironAPIManifold(config, func(environs.Environ, base.APICaller, agent.Agent) (worker.Worker, error) { 219 c.Fail() 220 return nil, nil 221 }) 222 _, err := manifold.Start(s.context) 223 c.Assert(err, gc.ErrorMatches, "missing") 224 } 225 226 type modelManifoldSuite struct { 227 testing.IsolationSuite 228 229 logger *mocks.MockLogger 230 context *mocks.MockContext 231 agent *mocks.MockAgent 232 agentConfig *mocks.MockConfig 233 environ environShim 234 apiCaller *mocks.MockAPICaller 235 worker *mocks.MockWorker 236 api *mocks.MockInstanceMutaterAPI 237 } 238 239 var _ = gc.Suite(&modelManifoldSuite{}) 240 241 func (s *modelManifoldSuite) setup(c *gc.C) *gomock.Controller { 242 ctrl := gomock.NewController(c) 243 244 s.logger = mocks.NewMockLogger(ctrl) 245 s.context = mocks.NewMockContext(ctrl) 246 s.agent = mocks.NewMockAgent(ctrl) 247 s.agentConfig = mocks.NewMockConfig(ctrl) 248 s.environ = environShim{ 249 MockEnviron: mocks.NewMockEnviron(ctrl), 250 MockLXDProfiler: mocks.NewMockLXDProfiler(ctrl), 251 } 252 s.apiCaller = mocks.NewMockAPICaller(ctrl) 253 s.worker = mocks.NewMockWorker(ctrl) 254 s.api = mocks.NewMockInstanceMutaterAPI(ctrl) 255 256 return ctrl 257 } 258 259 func (s *modelManifoldSuite) TestNewWorkerIsCalled(c *gc.C) { 260 defer s.setup(c).Finish() 261 262 s.behaviourContext() 263 s.behaviourAgent() 264 265 config := instancemutater.ModelManifoldConfig{ 266 EnvironName: "foobar", 267 APICallerName: "baz", 268 AgentName: "moon", 269 Logger: s.logger, 270 NewWorker: func(cfg instancemutater.Config) (worker.Worker, error) { 271 return s.worker, nil 272 }, 273 NewClient: func(base.APICaller) instancemutater.InstanceMutaterAPI { 274 return s.api 275 }, 276 } 277 manifold := instancemutater.ModelManifold(config) 278 result, err := manifold.Start(s.context) 279 c.Assert(err, gc.IsNil) 280 c.Assert(result, gc.Equals, s.worker) 281 } 282 283 func (s *modelManifoldSuite) TestNewWorkerFromK8sController(c *gc.C) { 284 defer s.setup(c).Finish() 285 286 s.behaviourContext() 287 s.behaviorK8sController() 288 289 config := instancemutater.ModelManifoldConfig{ 290 EnvironName: "foobar", 291 APICallerName: "baz", 292 AgentName: "moon", 293 Logger: s.logger, 294 NewWorker: func(cfg instancemutater.Config) (worker.Worker, error) { 295 return s.worker, nil 296 }, 297 NewClient: func(base.APICaller) instancemutater.InstanceMutaterAPI { 298 return s.api 299 }, 300 } 301 manifold := instancemutater.ModelManifold(config) 302 result, err := manifold.Start(s.context) 303 c.Assert(err, gc.IsNil) 304 c.Assert(result, gc.Equals, s.worker) 305 } 306 307 func (s *modelManifoldSuite) TestNewWorkerReturnsError(c *gc.C) { 308 defer s.setup(c).Finish() 309 310 s.behaviourContext() 311 s.behaviourAgent() 312 313 config := instancemutater.ModelManifoldConfig{ 314 EnvironName: "foobar", 315 APICallerName: "baz", 316 AgentName: "moon", 317 Logger: s.logger, 318 NewWorker: func(cfg instancemutater.Config) (worker.Worker, error) { 319 return nil, errors.New("errored") 320 }, 321 NewClient: func(base.APICaller) instancemutater.InstanceMutaterAPI { 322 return s.api 323 }, 324 } 325 manifold := instancemutater.ModelManifold(config) 326 _, err := manifold.Start(s.context) 327 c.Assert(err, gc.ErrorMatches, "cannot start model instance-mutater worker: errored") 328 } 329 330 func (s *modelManifoldSuite) TestConfigValidatesForMissingWorker(c *gc.C) { 331 defer s.setup(c).Finish() 332 333 s.behaviourContext() 334 335 config := instancemutater.ModelManifoldConfig{ 336 EnvironName: "foobar", 337 APICallerName: "baz", 338 AgentName: "moon", 339 Logger: s.logger, 340 } 341 manifold := instancemutater.ModelManifold(config) 342 _, err := manifold.Start(s.context) 343 c.Assert(err, gc.ErrorMatches, "nil NewWorker not valid") 344 } 345 346 func (s *modelManifoldSuite) TestConfigValidatesForMissingClient(c *gc.C) { 347 defer s.setup(c).Finish() 348 349 s.behaviourContext() 350 351 config := instancemutater.ModelManifoldConfig{ 352 EnvironName: "foobar", 353 APICallerName: "baz", 354 AgentName: "moon", 355 Logger: s.logger, 356 NewWorker: func(cfg instancemutater.Config) (worker.Worker, error) { 357 return s.worker, nil 358 }, 359 } 360 manifold := instancemutater.ModelManifold(config) 361 _, err := manifold.Start(s.context) 362 c.Assert(err, gc.ErrorMatches, "nil NewClient not valid") 363 } 364 365 func (s *modelManifoldSuite) behaviourContext() { 366 cExp := s.context.EXPECT() 367 cExp.Get("moon", gomock.Any()).SetArg(1, s.agent).Return(nil) 368 cExp.Get("foobar", gomock.Any()).SetArg(1, s.environ).Return(nil) 369 cExp.Get("baz", gomock.Any()).SetArg(1, s.apiCaller).Return(nil) 370 } 371 372 func (s *modelManifoldSuite) behaviourAgent() { 373 aExp := s.agent.EXPECT() 374 aExp.CurrentConfig().Return(s.agentConfig) 375 376 cExp := s.agentConfig.EXPECT() 377 cExp.Tag().Return(names.MachineTag{}) 378 } 379 380 func (s *modelManifoldSuite) behaviorK8sController() { 381 aExp := s.agent.EXPECT() 382 aExp.CurrentConfig().Return(s.agentConfig) 383 384 cExp := s.agentConfig.EXPECT() 385 cExp.Tag().Return(names.ControllerAgentTag{}) 386 } 387 388 type environShim struct { 389 *mocks.MockEnviron 390 *mocks.MockLXDProfiler 391 } 392 393 type machineManifoldConfigSuite struct { 394 testing.IsolationSuite 395 } 396 397 var _ = gc.Suite(&machineManifoldConfigSuite{}) 398 399 func (s *machineManifoldConfigSuite) TestInvalidConfigValidate(c *gc.C) { 400 ctrl := gomock.NewController(c) 401 defer ctrl.Finish() 402 403 testcases := []struct { 404 description string 405 config instancemutater.MachineManifoldConfig 406 err string 407 }{ 408 { 409 description: "Test empty configuration", 410 config: instancemutater.MachineManifoldConfig{}, 411 err: "nil Logger not valid", 412 }, 413 { 414 description: "Test no Logger", 415 config: instancemutater.MachineManifoldConfig{}, 416 err: "nil Logger not valid", 417 }, 418 { 419 description: "Test no new worker constructor", 420 config: instancemutater.MachineManifoldConfig{ 421 Logger: mocks.NewMockLogger(ctrl), 422 }, 423 err: "nil NewWorker not valid", 424 }, 425 { 426 description: "Test no new client constructor", 427 config: instancemutater.MachineManifoldConfig{ 428 Logger: mocks.NewMockLogger(ctrl), 429 NewWorker: func(cfg instancemutater.Config) (worker.Worker, error) { 430 return mocks.NewMockWorker(ctrl), nil 431 }, 432 }, 433 err: "nil NewClient not valid", 434 }, 435 { 436 description: "Test no agent name", 437 config: instancemutater.MachineManifoldConfig{ 438 Logger: mocks.NewMockLogger(ctrl), 439 NewWorker: func(cfg instancemutater.Config) (worker.Worker, error) { 440 return mocks.NewMockWorker(ctrl), nil 441 }, 442 NewClient: func(base.APICaller) instancemutater.InstanceMutaterAPI { 443 return mocks.NewMockInstanceMutaterAPI(ctrl) 444 }, 445 }, 446 err: "empty AgentName not valid", 447 }, 448 { 449 description: "Test no environ name", 450 config: instancemutater.MachineManifoldConfig{ 451 Logger: mocks.NewMockLogger(ctrl), 452 NewWorker: func(cfg instancemutater.Config) (worker.Worker, error) { 453 return mocks.NewMockWorker(ctrl), nil 454 }, 455 NewClient: func(base.APICaller) instancemutater.InstanceMutaterAPI { 456 return mocks.NewMockInstanceMutaterAPI(ctrl) 457 }, 458 AgentName: "agent", 459 }, 460 err: "empty BrokerName not valid", 461 }, 462 { 463 description: "Test no api caller name", 464 config: instancemutater.MachineManifoldConfig{ 465 Logger: mocks.NewMockLogger(ctrl), 466 NewWorker: func(cfg instancemutater.Config) (worker.Worker, error) { 467 return mocks.NewMockWorker(ctrl), nil 468 }, 469 NewClient: func(base.APICaller) instancemutater.InstanceMutaterAPI { 470 return mocks.NewMockInstanceMutaterAPI(ctrl) 471 }, 472 AgentName: "agent", 473 BrokerName: "broker", 474 }, 475 err: "empty APICallerName not valid", 476 }, 477 } 478 for i, test := range testcases { 479 c.Logf("%d %s", i, test.description) 480 err := test.config.Validate() 481 c.Assert(err, gc.ErrorMatches, test.err) 482 } 483 } 484 485 func (s *machineManifoldConfigSuite) TestValidConfigValidate(c *gc.C) { 486 ctrl := gomock.NewController(c) 487 defer ctrl.Finish() 488 489 config := instancemutater.MachineManifoldConfig{ 490 Logger: mocks.NewMockLogger(ctrl), 491 NewWorker: func(cfg instancemutater.Config) (worker.Worker, error) { 492 return mocks.NewMockWorker(ctrl), nil 493 }, 494 NewClient: func(base.APICaller) instancemutater.InstanceMutaterAPI { 495 return mocks.NewMockInstanceMutaterAPI(ctrl) 496 }, 497 AgentName: "agent", 498 BrokerName: "broker", 499 APICallerName: "api-caller", 500 } 501 err := config.Validate() 502 c.Assert(err, gc.IsNil) 503 } 504 505 type brokerAPIManifoldSuite struct { 506 testing.IsolationSuite 507 508 logger *mocks.MockLogger 509 context *mocks.MockContext 510 agent *mocks.MockAgent 511 broker *mocks.MockInstanceBroker 512 apiCaller *mocks.MockAPICaller 513 worker *mocks.MockWorker 514 } 515 516 var _ = gc.Suite(&brokerAPIManifoldSuite{}) 517 518 func (s *brokerAPIManifoldSuite) setup(c *gc.C) *gomock.Controller { 519 ctrl := gomock.NewController(c) 520 521 s.logger = mocks.NewMockLogger(ctrl) 522 s.context = mocks.NewMockContext(ctrl) 523 s.agent = mocks.NewMockAgent(ctrl) 524 s.broker = mocks.NewMockInstanceBroker(ctrl) 525 s.apiCaller = mocks.NewMockAPICaller(ctrl) 526 s.worker = mocks.NewMockWorker(ctrl) 527 528 return ctrl 529 } 530 531 func (s *brokerAPIManifoldSuite) TestStartReturnsWorker(c *gc.C) { 532 defer s.setup(c).Finish() 533 534 cExp := s.context.EXPECT() 535 cExp.Get("moon", gomock.Any()).SetArg(1, s.agent).Return(nil) 536 cExp.Get("foobar", gomock.Any()).SetArg(1, s.broker).Return(nil) 537 cExp.Get("baz", gomock.Any()).SetArg(1, s.apiCaller).Return(nil) 538 539 config := instancemutater.BrokerAPIConfig{ 540 BrokerName: "foobar", 541 APICallerName: "baz", 542 AgentName: "moon", 543 } 544 manifold := instancemutater.BrokerAPIManifold(config, func(broker environs.InstanceBroker, apiCaller base.APICaller, agent agent.Agent) (worker.Worker, error) { 545 c.Assert(broker, gc.Equals, s.broker) 546 c.Assert(apiCaller, gc.Equals, s.apiCaller) 547 c.Assert(agent, gc.Equals, s.agent) 548 549 return s.worker, nil 550 }) 551 result, err := manifold.Start(s.context) 552 c.Assert(err, gc.IsNil) 553 c.Assert(result, gc.Equals, s.worker) 554 } 555 556 func (s *brokerAPIManifoldSuite) TestMissingBrokerFromContext(c *gc.C) { 557 defer s.setup(c).Finish() 558 559 cExp := s.context.EXPECT() 560 cExp.Get("moon", gomock.Any()).SetArg(1, s.agent).Return(nil) 561 cExp.Get("foobar", gomock.Any()).Return(errors.New("missing")) 562 563 config := instancemutater.BrokerAPIConfig{ 564 BrokerName: "foobar", 565 APICallerName: "baz", 566 AgentName: "moon", 567 } 568 manifold := instancemutater.BrokerAPIManifold(config, func(environs.InstanceBroker, base.APICaller, agent.Agent) (worker.Worker, error) { 569 c.Fail() 570 return nil, nil 571 }) 572 _, err := manifold.Start(s.context) 573 c.Assert(err, gc.ErrorMatches, "missing") 574 } 575 576 func (s *brokerAPIManifoldSuite) TestMissingAPICallerFromContext(c *gc.C) { 577 defer s.setup(c).Finish() 578 579 cExp := s.context.EXPECT() 580 cExp.Get("moon", gomock.Any()).SetArg(1, s.agent).Return(nil) 581 cExp.Get("foobar", gomock.Any()).SetArg(1, s.broker).Return(nil) 582 cExp.Get("baz", gomock.Any()).Return(errors.New("missing")) 583 584 config := instancemutater.BrokerAPIConfig{ 585 BrokerName: "foobar", 586 APICallerName: "baz", 587 AgentName: "moon", 588 } 589 manifold := instancemutater.BrokerAPIManifold(config, func(environs.InstanceBroker, base.APICaller, agent.Agent) (worker.Worker, error) { 590 c.Fail() 591 return nil, nil 592 }) 593 _, err := manifold.Start(s.context) 594 c.Assert(err, gc.ErrorMatches, "missing") 595 } 596 597 type machineManifoldSuite struct { 598 testing.IsolationSuite 599 600 logger *mocks.MockLogger 601 context *mocks.MockContext 602 agent *mocks.MockAgent 603 agentConfig *mocks.MockConfig 604 broker brokerShim 605 apiCaller *mocks.MockAPICaller 606 worker *mocks.MockWorker 607 api *mocks.MockInstanceMutaterAPI 608 } 609 610 var _ = gc.Suite(&machineManifoldSuite{}) 611 612 func (s *machineManifoldSuite) setup(c *gc.C) *gomock.Controller { 613 ctrl := gomock.NewController(c) 614 615 s.logger = mocks.NewMockLogger(ctrl) 616 s.context = mocks.NewMockContext(ctrl) 617 s.agent = mocks.NewMockAgent(ctrl) 618 s.agentConfig = mocks.NewMockConfig(ctrl) 619 s.broker = brokerShim{ 620 MockInstanceBroker: mocks.NewMockInstanceBroker(ctrl), 621 MockLXDProfiler: mocks.NewMockLXDProfiler(ctrl), 622 } 623 s.apiCaller = mocks.NewMockAPICaller(ctrl) 624 s.worker = mocks.NewMockWorker(ctrl) 625 s.api = mocks.NewMockInstanceMutaterAPI(ctrl) 626 627 return ctrl 628 } 629 630 func (s *machineManifoldSuite) TestNewWorkerIsCalled(c *gc.C) { 631 defer s.setup(c).Finish() 632 633 s.behaviourContext() 634 s.behaviourAgent() 635 636 config := instancemutater.MachineManifoldConfig{ 637 BrokerName: "foobar", 638 APICallerName: "baz", 639 AgentName: "moon", 640 Logger: s.logger, 641 NewWorker: func(cfg instancemutater.Config) (worker.Worker, error) { 642 return s.worker, nil 643 }, 644 NewClient: func(base.APICaller) instancemutater.InstanceMutaterAPI { 645 return s.api 646 }, 647 } 648 manifold := instancemutater.MachineManifold(config) 649 result, err := manifold.Start(s.context) 650 c.Assert(err, gc.IsNil) 651 c.Assert(result, gc.Equals, s.worker) 652 } 653 654 func (s *machineManifoldSuite) TestNewWorkerIsRejectedForK8sController(c *gc.C) { 655 defer s.setup(c).Finish() 656 657 s.behaviourContext() 658 s.behaviorK8sController() 659 660 config := instancemutater.MachineManifoldConfig{ 661 BrokerName: "foobar", 662 APICallerName: "baz", 663 AgentName: "moon", 664 Logger: s.logger, 665 NewWorker: func(cfg instancemutater.Config) (worker.Worker, error) { 666 return s.worker, nil 667 }, 668 NewClient: func(base.APICaller) instancemutater.InstanceMutaterAPI { 669 return s.api 670 }, 671 } 672 manifold := instancemutater.MachineManifold(config) 673 result, err := manifold.Start(s.context) 674 c.Assert(err, gc.Equals, dependency.ErrUninstall) 675 c.Assert(result, gc.IsNil) 676 } 677 678 func (s *machineManifoldSuite) TestNewWorkerReturnsError(c *gc.C) { 679 defer s.setup(c).Finish() 680 681 s.behaviourContext() 682 s.behaviourAgent() 683 684 config := instancemutater.MachineManifoldConfig{ 685 BrokerName: "foobar", 686 APICallerName: "baz", 687 AgentName: "moon", 688 Logger: s.logger, 689 NewWorker: func(cfg instancemutater.Config) (worker.Worker, error) { 690 return nil, errors.New("errored") 691 }, 692 NewClient: func(base.APICaller) instancemutater.InstanceMutaterAPI { 693 return s.api 694 }, 695 } 696 manifold := instancemutater.MachineManifold(config) 697 _, err := manifold.Start(s.context) 698 c.Assert(err, gc.ErrorMatches, "cannot start machine instancemutater worker: errored") 699 } 700 701 func (s *machineManifoldSuite) TestConfigValidatesForMissingWorker(c *gc.C) { 702 defer s.setup(c).Finish() 703 704 s.behaviourContext() 705 706 config := instancemutater.MachineManifoldConfig{ 707 BrokerName: "foobar", 708 APICallerName: "baz", 709 AgentName: "moon", 710 Logger: s.logger, 711 } 712 manifold := instancemutater.MachineManifold(config) 713 _, err := manifold.Start(s.context) 714 c.Assert(err, gc.ErrorMatches, "nil NewWorker not valid") 715 } 716 717 func (s *machineManifoldSuite) TestConfigValidatesForMissingClient(c *gc.C) { 718 defer s.setup(c).Finish() 719 720 s.behaviourContext() 721 722 config := instancemutater.MachineManifoldConfig{ 723 BrokerName: "foobar", 724 APICallerName: "baz", 725 AgentName: "moon", 726 Logger: s.logger, 727 NewWorker: func(cfg instancemutater.Config) (worker.Worker, error) { 728 return s.worker, nil 729 }, 730 } 731 manifold := instancemutater.MachineManifold(config) 732 _, err := manifold.Start(s.context) 733 c.Assert(err, gc.ErrorMatches, "nil NewClient not valid") 734 } 735 736 func (s *machineManifoldSuite) behaviourContext() { 737 cExp := s.context.EXPECT() 738 cExp.Get("moon", gomock.Any()).SetArg(1, s.agent).Return(nil) 739 cExp.Get("foobar", gomock.Any()).SetArg(1, s.broker).Return(nil) 740 cExp.Get("baz", gomock.Any()).SetArg(1, s.apiCaller).Return(nil) 741 } 742 743 func (s *machineManifoldSuite) behaviourAgent() { 744 aExp := s.agent.EXPECT() 745 aExp.CurrentConfig().Return(s.agentConfig) 746 747 cExp := s.agentConfig.EXPECT() 748 cExp.Tag().Return(names.MachineTag{}) 749 } 750 751 func (s *machineManifoldSuite) behaviorK8sController() { 752 aExp := s.agent.EXPECT() 753 aExp.CurrentConfig().Return(s.agentConfig) 754 755 cExp := s.agentConfig.EXPECT() 756 cExp.Tag().Return(names.ControllerAgentTag{}) 757 758 lExp := s.logger.EXPECT() 759 lExp.Warningf(gomock.Any(), "controller") 760 } 761 762 type brokerShim struct { 763 *mocks.MockInstanceBroker 764 *mocks.MockLXDProfiler 765 }