github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/agent/agent_test.go (about) 1 // Copyright 2014 Canonical Ltd. 2 // Copyright 2014 Cloudbase Solutions SRL 3 // Licensed under the AGPLv3, see LICENCE file for details. 4 5 package agent_test 6 7 import ( 8 "fmt" 9 "path/filepath" 10 "reflect" 11 12 "github.com/juju/names" 13 jc "github.com/juju/testing/checkers" 14 "github.com/juju/version" 15 gc "gopkg.in/check.v1" 16 17 "github.com/juju/juju/agent" 18 "github.com/juju/juju/api" 19 "github.com/juju/juju/apiserver/params" 20 "github.com/juju/juju/mongo" 21 "github.com/juju/juju/network" 22 "github.com/juju/juju/state/multiwatcher" 23 "github.com/juju/juju/testing" 24 jujuversion "github.com/juju/juju/version" 25 ) 26 27 type suite struct { 28 testing.BaseSuite 29 } 30 31 var _ = gc.Suite(&suite{}) 32 33 var agentConfigTests = []struct { 34 about string 35 params agent.AgentConfigParams 36 checkErr string 37 inspectConfig func(*gc.C, agent.Config) 38 }{{ 39 about: "missing data directory", 40 checkErr: "data directory not found in configuration", 41 }, { 42 about: "missing tag", 43 params: agent.AgentConfigParams{ 44 Paths: agent.Paths{DataDir: "/data/dir"}, 45 }, 46 checkErr: "entity tag not found in configuration", 47 }, { 48 about: "missing upgraded to version", 49 params: agent.AgentConfigParams{ 50 Paths: agent.Paths{DataDir: "/data/dir"}, 51 Tag: names.NewMachineTag("1"), 52 }, 53 checkErr: "upgradedToVersion not found in configuration", 54 }, { 55 about: "missing password", 56 params: agent.AgentConfigParams{ 57 Paths: agent.Paths{DataDir: "/data/dir"}, 58 Tag: names.NewMachineTag("1"), 59 UpgradedToVersion: jujuversion.Current, 60 }, 61 checkErr: "password not found in configuration", 62 }, { 63 about: "missing model tag", 64 params: agent.AgentConfigParams{ 65 Paths: agent.Paths{DataDir: "/data/dir"}, 66 Tag: names.NewMachineTag("1"), 67 UpgradedToVersion: jujuversion.Current, 68 Password: "sekrit", 69 }, 70 checkErr: "model not found in configuration", 71 }, { 72 about: "invalid model tag", 73 params: agent.AgentConfigParams{ 74 Paths: agent.Paths{DataDir: "/data/dir"}, 75 Tag: names.NewMachineTag("1"), 76 UpgradedToVersion: jujuversion.Current, 77 Password: "sekrit", 78 Model: names.NewModelTag("uuid"), 79 }, 80 checkErr: `"uuid" is not a valid model uuid`, 81 }, { 82 about: "missing CA cert", 83 params: agent.AgentConfigParams{ 84 Paths: agent.Paths{DataDir: "/data/dir"}, 85 Tag: names.NewMachineTag("1"), 86 UpgradedToVersion: jujuversion.Current, 87 Password: "sekrit", 88 Model: testing.ModelTag, 89 }, 90 checkErr: "CA certificate not found in configuration", 91 }, { 92 about: "need either state or api addresses", 93 params: agent.AgentConfigParams{ 94 Paths: agent.Paths{DataDir: "/data/dir"}, 95 Tag: names.NewMachineTag("1"), 96 UpgradedToVersion: jujuversion.Current, 97 Password: "sekrit", 98 CACert: "ca cert", 99 Model: testing.ModelTag, 100 }, 101 checkErr: "state or API addresses not found in configuration", 102 }, { 103 about: "invalid state address", 104 params: agent.AgentConfigParams{ 105 Paths: agent.Paths{DataDir: "/data/dir"}, 106 Tag: names.NewMachineTag("1"), 107 UpgradedToVersion: jujuversion.Current, 108 Password: "sekrit", 109 CACert: "ca cert", 110 Model: testing.ModelTag, 111 StateAddresses: []string{"localhost:8080", "bad-address"}, 112 }, 113 checkErr: `invalid controller address "bad-address"`, 114 }, { 115 about: "invalid api address", 116 params: agent.AgentConfigParams{ 117 Paths: agent.Paths{DataDir: "/data/dir"}, 118 Tag: names.NewMachineTag("1"), 119 UpgradedToVersion: jujuversion.Current, 120 Password: "sekrit", 121 CACert: "ca cert", 122 Model: testing.ModelTag, 123 APIAddresses: []string{"localhost:8080", "bad-address"}, 124 }, 125 checkErr: `invalid API server address "bad-address"`, 126 }, { 127 about: "good state addresses", 128 params: agent.AgentConfigParams{ 129 Paths: agent.Paths{DataDir: "/data/dir"}, 130 Tag: names.NewMachineTag("1"), 131 UpgradedToVersion: jujuversion.Current, 132 Password: "sekrit", 133 CACert: "ca cert", 134 Model: testing.ModelTag, 135 StateAddresses: []string{"localhost:1234"}, 136 }, 137 }, { 138 about: "good api addresses", 139 params: agent.AgentConfigParams{ 140 Paths: agent.Paths{DataDir: "/data/dir"}, 141 Tag: names.NewMachineTag("1"), 142 UpgradedToVersion: jujuversion.Current, 143 Password: "sekrit", 144 CACert: "ca cert", 145 Model: testing.ModelTag, 146 APIAddresses: []string{"localhost:1234"}, 147 }, 148 }, { 149 about: "both state and api addresses", 150 params: agent.AgentConfigParams{ 151 Paths: agent.Paths{DataDir: "/data/dir"}, 152 Tag: names.NewMachineTag("1"), 153 UpgradedToVersion: jujuversion.Current, 154 Password: "sekrit", 155 CACert: "ca cert", 156 Model: testing.ModelTag, 157 StateAddresses: []string{"localhost:1234"}, 158 APIAddresses: []string{"localhost:1235"}, 159 }, 160 }, { 161 about: "everything...", 162 params: agent.AgentConfigParams{ 163 Paths: agent.Paths{DataDir: "/data/dir"}, 164 Tag: names.NewMachineTag("1"), 165 Password: "sekrit", 166 UpgradedToVersion: jujuversion.Current, 167 CACert: "ca cert", 168 Model: testing.ModelTag, 169 StateAddresses: []string{"localhost:1234"}, 170 APIAddresses: []string{"localhost:1235"}, 171 Nonce: "a nonce", 172 }, 173 }, { 174 about: "missing logDir sets default", 175 params: agent.AgentConfigParams{ 176 Paths: agent.Paths{DataDir: "/data/dir"}, 177 Tag: names.NewMachineTag("1"), 178 Password: "sekrit", 179 UpgradedToVersion: jujuversion.Current, 180 CACert: "ca cert", 181 Model: testing.ModelTag, 182 StateAddresses: []string{"localhost:1234"}, 183 APIAddresses: []string{"localhost:1235"}, 184 Nonce: "a nonce", 185 }, 186 inspectConfig: func(c *gc.C, cfg agent.Config) { 187 c.Check(cfg.LogDir(), gc.Equals, agent.DefaultPaths.LogDir) 188 }, 189 }, { 190 about: "missing metricsSpoolDir sets default", 191 params: agent.AgentConfigParams{ 192 Paths: agent.Paths{DataDir: "/data/dir"}, 193 Tag: names.NewMachineTag("1"), 194 Password: "sekrit", 195 UpgradedToVersion: jujuversion.Current, 196 CACert: "ca cert", 197 Model: testing.ModelTag, 198 StateAddresses: []string{"localhost:1234"}, 199 APIAddresses: []string{"localhost:1235"}, 200 Nonce: "a nonce", 201 }, 202 inspectConfig: func(c *gc.C, cfg agent.Config) { 203 c.Check(cfg.MetricsSpoolDir(), gc.Equals, agent.DefaultPaths.MetricsSpoolDir) 204 }, 205 }, { 206 about: "setting a custom metricsSpoolDir", 207 params: agent.AgentConfigParams{ 208 Paths: agent.Paths{ 209 DataDir: "/data/dir", 210 MetricsSpoolDir: "/tmp/nowhere", 211 }, 212 Tag: names.NewMachineTag("1"), 213 Password: "sekrit", 214 UpgradedToVersion: jujuversion.Current, 215 CACert: "ca cert", 216 Model: testing.ModelTag, 217 StateAddresses: []string{"localhost:1234"}, 218 APIAddresses: []string{"localhost:1235"}, 219 Nonce: "a nonce", 220 }, 221 inspectConfig: func(c *gc.C, cfg agent.Config) { 222 c.Check(cfg.MetricsSpoolDir(), gc.Equals, "/tmp/nowhere") 223 }, 224 }, { 225 about: "agentConfig must not be a User tag", 226 params: agent.AgentConfigParams{ 227 Paths: agent.Paths{DataDir: "/data/dir"}, 228 Tag: names.NewUserTag("admin"), // this is a joke, the admin user is nil. 229 UpgradedToVersion: jujuversion.Current, 230 Password: "sekrit", 231 }, 232 checkErr: "entity tag must be MachineTag or UnitTag, got names.UserTag", 233 }, { 234 about: "agentConfig accepts a Unit tag", 235 params: agent.AgentConfigParams{ 236 Paths: agent.Paths{DataDir: "/data/dir"}, 237 Tag: names.NewUnitTag("ubuntu/1"), 238 Password: "sekrit", 239 UpgradedToVersion: jujuversion.Current, 240 Model: testing.ModelTag, 241 CACert: "ca cert", 242 StateAddresses: []string{"localhost:1234"}, 243 APIAddresses: []string{"localhost:1235"}, 244 }, 245 inspectConfig: func(c *gc.C, cfg agent.Config) { 246 c.Check(cfg.Dir(), gc.Equals, "/data/dir/agents/unit-ubuntu-1") 247 }, 248 }, { 249 about: "prefer-ipv6 parsed when set", 250 params: agent.AgentConfigParams{ 251 Paths: agent.Paths{DataDir: "/data/dir"}, 252 Tag: names.NewMachineTag("1"), 253 Password: "sekrit", 254 UpgradedToVersion: jujuversion.Current, 255 CACert: "ca cert", 256 Model: testing.ModelTag, 257 StateAddresses: []string{"localhost:1234"}, 258 APIAddresses: []string{"localhost:1235"}, 259 Nonce: "a nonce", 260 PreferIPv6: true, 261 }, 262 inspectConfig: func(c *gc.C, cfg agent.Config) { 263 c.Check(cfg.PreferIPv6(), jc.IsTrue) 264 }, 265 }, { 266 about: "missing prefer-ipv6 defaults to false", 267 params: agent.AgentConfigParams{ 268 Paths: agent.Paths{DataDir: "/data/dir"}, 269 Tag: names.NewMachineTag("1"), 270 Password: "sekrit", 271 UpgradedToVersion: jujuversion.Current, 272 CACert: "ca cert", 273 Model: testing.ModelTag, 274 StateAddresses: []string{"localhost:1234"}, 275 APIAddresses: []string{"localhost:1235"}, 276 Nonce: "a nonce", 277 }, 278 inspectConfig: func(c *gc.C, cfg agent.Config) { 279 c.Check(cfg.PreferIPv6(), jc.IsFalse) 280 }, 281 }} 282 283 func (*suite) TestNewAgentConfig(c *gc.C) { 284 for i, test := range agentConfigTests { 285 c.Logf("%v: %s", i, test.about) 286 config, err := agent.NewAgentConfig(test.params) 287 if test.checkErr == "" { 288 c.Assert(err, jc.ErrorIsNil) 289 if test.inspectConfig != nil { 290 test.inspectConfig(c, config) 291 } 292 } else { 293 c.Assert(err, gc.ErrorMatches, test.checkErr) 294 } 295 } 296 } 297 298 func (*suite) TestMigrate(c *gc.C) { 299 initialParams := agent.AgentConfigParams{ 300 Paths: agent.Paths{ 301 DataDir: c.MkDir(), 302 LogDir: c.MkDir(), 303 }, 304 Tag: names.NewMachineTag("1"), 305 Nonce: "nonce", 306 Password: "secret", 307 UpgradedToVersion: version.MustParse("1.16.5"), 308 Jobs: []multiwatcher.MachineJob{ 309 multiwatcher.JobManageModel, 310 multiwatcher.JobHostUnits, 311 }, 312 CACert: "ca cert", 313 Model: testing.ModelTag, 314 StateAddresses: []string{"localhost:1234"}, 315 APIAddresses: []string{"localhost:4321"}, 316 Values: map[string]string{ 317 "key1": "value1", 318 "key2": "value2", 319 "key3": "value3", 320 }, 321 } 322 323 migrateTests := []struct { 324 comment string 325 fields []string 326 newParams agent.MigrateParams 327 expectValues map[string]string 328 expectErr string 329 }{{ 330 comment: "nothing to change", 331 fields: nil, 332 newParams: agent.MigrateParams{}, 333 }, { 334 fields: []string{"Paths"}, 335 newParams: agent.MigrateParams{ 336 Paths: agent.Paths{DataDir: c.MkDir()}, 337 }, 338 }, { 339 fields: []string{"Paths"}, 340 newParams: agent.MigrateParams{ 341 Paths: agent.Paths{ 342 DataDir: c.MkDir(), 343 LogDir: c.MkDir(), 344 }, 345 }, 346 }, { 347 fields: []string{"Jobs"}, 348 newParams: agent.MigrateParams{ 349 Jobs: []multiwatcher.MachineJob{multiwatcher.JobHostUnits}, 350 }, 351 }, { 352 comment: "invalid/immutable field specified", 353 fields: []string{"InvalidField"}, 354 newParams: agent.MigrateParams{}, 355 expectErr: `unknown field "InvalidField"`, 356 }, { 357 comment: "Values can be added, changed or removed", 358 fields: []string{"Values", "DeleteValues"}, 359 newParams: agent.MigrateParams{ 360 DeleteValues: []string{"key2", "key3"}, // delete 361 Values: map[string]string{ 362 "key1": "new value1", // change 363 "new key3": "value3", // add 364 "empty": "", // add empty val 365 }, 366 }, 367 expectValues: map[string]string{ 368 "key1": "new value1", 369 "new key3": "value3", 370 "empty": "", 371 }, 372 }} 373 for i, test := range migrateTests { 374 summary := "migrate fields" 375 if test.comment != "" { 376 summary += " (" + test.comment + ") " 377 } 378 c.Logf("test %d: %s %v", i, summary, test.fields) 379 380 initialConfig, err := agent.NewAgentConfig(initialParams) 381 c.Assert(err, jc.ErrorIsNil) 382 383 newConfig, err := agent.NewAgentConfig(initialParams) 384 c.Assert(err, jc.ErrorIsNil) 385 386 c.Assert(initialConfig.Write(), gc.IsNil) 387 c.Assert(agent.ConfigFileExists(initialConfig), jc.IsTrue) 388 389 err = newConfig.Migrate(test.newParams) 390 c.Assert(err, jc.ErrorIsNil) 391 err = newConfig.Write() 392 c.Assert(err, jc.ErrorIsNil) 393 c.Assert(agent.ConfigFileExists(newConfig), jc.IsTrue) 394 395 // Make sure we can read it back successfully and it 396 // matches what we wrote. 397 configPath := agent.ConfigPath(newConfig.DataDir(), newConfig.Tag()) 398 c.Logf("new config path: %v", configPath) 399 readConfig, err := agent.ReadConfig(configPath) 400 c.Check(err, jc.ErrorIsNil) 401 c.Check(newConfig, jc.DeepEquals, readConfig) 402 403 // Make sure only the specified fields were changed and 404 // the rest matches. 405 for _, field := range test.fields { 406 switch field { 407 case "Values": 408 err = agent.PatchConfig(initialConfig, field, test.expectValues) 409 c.Check(err, jc.ErrorIsNil) 410 case "DeleteValues": 411 err = agent.PatchConfig(initialConfig, field, test.newParams.DeleteValues) 412 c.Check(err, jc.ErrorIsNil) 413 default: 414 value := reflect.ValueOf(test.newParams).FieldByName(field) 415 if value.IsValid() && test.expectErr == "" { 416 err = agent.PatchConfig(initialConfig, field, value.Interface()) 417 c.Check(err, jc.ErrorIsNil) 418 } else { 419 err = agent.PatchConfig(initialConfig, field, value) 420 c.Check(err, gc.ErrorMatches, test.expectErr) 421 } 422 } 423 } 424 c.Check(newConfig, jc.DeepEquals, initialConfig) 425 } 426 } 427 428 func stateServingInfo() params.StateServingInfo { 429 return params.StateServingInfo{ 430 Cert: "cert", 431 PrivateKey: "key", 432 CAPrivateKey: "ca key", 433 StatePort: 69, 434 APIPort: 47, 435 SharedSecret: "shared", 436 SystemIdentity: "identity", 437 } 438 } 439 440 func (*suite) TestNewStateMachineConfig(c *gc.C) { 441 type testStruct struct { 442 about string 443 params agent.AgentConfigParams 444 servingInfo params.StateServingInfo 445 checkErr string 446 inspectConfig func(*gc.C, agent.Config) 447 } 448 var tests = []testStruct{{ 449 about: "missing controller cert", 450 checkErr: "controller cert not found in configuration", 451 }, { 452 about: "missing controller key", 453 servingInfo: params.StateServingInfo{ 454 Cert: "server cert", 455 }, 456 checkErr: "controller key not found in configuration", 457 }, { 458 about: "missing ca cert key", 459 servingInfo: params.StateServingInfo{ 460 Cert: "server cert", 461 PrivateKey: "server key", 462 }, 463 checkErr: "ca cert key not found in configuration", 464 }, { 465 about: "missing state port", 466 servingInfo: params.StateServingInfo{ 467 Cert: "server cert", 468 PrivateKey: "server key", 469 CAPrivateKey: "ca key", 470 }, 471 checkErr: "state port not found in configuration", 472 }, { 473 about: "params api port", 474 servingInfo: params.StateServingInfo{ 475 Cert: "server cert", 476 PrivateKey: "server key", 477 CAPrivateKey: "ca key", 478 StatePort: 69, 479 }, 480 checkErr: "api port not found in configuration", 481 }} 482 for _, test := range agentConfigTests { 483 tests = append(tests, testStruct{ 484 about: test.about, 485 params: test.params, 486 servingInfo: stateServingInfo(), 487 checkErr: test.checkErr, 488 }) 489 } 490 491 for i, test := range tests { 492 c.Logf("%v: %s", i, test.about) 493 cfg, err := agent.NewStateMachineConfig(test.params, test.servingInfo) 494 if test.checkErr == "" { 495 c.Assert(err, jc.ErrorIsNil) 496 if test.inspectConfig != nil { 497 test.inspectConfig(c, cfg) 498 } 499 } else { 500 c.Assert(err, gc.ErrorMatches, test.checkErr) 501 } 502 } 503 } 504 505 var attributeParams = agent.AgentConfigParams{ 506 Paths: agent.Paths{ 507 DataDir: "/data/dir", 508 }, 509 Tag: names.NewMachineTag("1"), 510 UpgradedToVersion: jujuversion.Current, 511 Password: "sekrit", 512 CACert: "ca cert", 513 StateAddresses: []string{"localhost:1234"}, 514 APIAddresses: []string{"localhost:1235"}, 515 Nonce: "a nonce", 516 Model: testing.ModelTag, 517 } 518 519 func (*suite) TestAttributes(c *gc.C) { 520 conf, err := agent.NewAgentConfig(attributeParams) 521 c.Assert(err, jc.ErrorIsNil) 522 c.Assert(conf.DataDir(), gc.Equals, "/data/dir") 523 compareSystemIdentityPath := filepath.FromSlash("/data/dir/system-identity") 524 systemIdentityPath := filepath.FromSlash(conf.SystemIdentityPath()) 525 c.Assert(systemIdentityPath, gc.Equals, compareSystemIdentityPath) 526 c.Assert(conf.Tag(), gc.Equals, names.NewMachineTag("1")) 527 c.Assert(conf.Dir(), gc.Equals, "/data/dir/agents/machine-1") 528 c.Assert(conf.Nonce(), gc.Equals, "a nonce") 529 c.Assert(conf.UpgradedToVersion(), jc.DeepEquals, jujuversion.Current) 530 } 531 532 func (*suite) TestStateServingInfo(c *gc.C) { 533 servingInfo := stateServingInfo() 534 conf, err := agent.NewStateMachineConfig(attributeParams, servingInfo) 535 c.Assert(err, jc.ErrorIsNil) 536 gotInfo, ok := conf.StateServingInfo() 537 c.Assert(ok, jc.IsTrue) 538 c.Assert(gotInfo, jc.DeepEquals, servingInfo) 539 newInfo := params.StateServingInfo{ 540 APIPort: 147, 541 StatePort: 169, 542 Cert: "new cert", 543 PrivateKey: "new key", 544 CAPrivateKey: "new ca key", 545 SharedSecret: "new shared", 546 SystemIdentity: "new identity", 547 } 548 conf.SetStateServingInfo(newInfo) 549 gotInfo, ok = conf.StateServingInfo() 550 c.Assert(ok, jc.IsTrue) 551 c.Assert(gotInfo, jc.DeepEquals, newInfo) 552 } 553 554 func (*suite) TestStateServingInfoNotAvailable(c *gc.C) { 555 conf, err := agent.NewAgentConfig(attributeParams) 556 c.Assert(err, jc.ErrorIsNil) 557 558 _, available := conf.StateServingInfo() 559 c.Assert(available, jc.IsFalse) 560 } 561 562 func (s *suite) TestAPIAddressesCannotWriteBack(c *gc.C) { 563 conf, err := agent.NewAgentConfig(attributeParams) 564 c.Assert(err, jc.ErrorIsNil) 565 value, err := conf.APIAddresses() 566 c.Assert(err, jc.ErrorIsNil) 567 c.Assert(value, jc.DeepEquals, []string{"localhost:1235"}) 568 value[0] = "invalidAdr" 569 //Check out change hasn't gone back into the internals 570 newValue, err := conf.APIAddresses() 571 c.Assert(err, jc.ErrorIsNil) 572 c.Assert(newValue, jc.DeepEquals, []string{"localhost:1235"}) 573 } 574 575 func (*suite) TestWriteAndRead(c *gc.C) { 576 testParams := attributeParams 577 testParams.Paths.DataDir = c.MkDir() 578 testParams.Paths.LogDir = c.MkDir() 579 conf, err := agent.NewAgentConfig(testParams) 580 c.Assert(err, jc.ErrorIsNil) 581 582 c.Assert(conf.Write(), gc.IsNil) 583 reread, err := agent.ReadConfig(agent.ConfigPath(conf.DataDir(), conf.Tag())) 584 c.Assert(err, jc.ErrorIsNil) 585 c.Assert(reread, jc.DeepEquals, conf) 586 } 587 588 func (*suite) TestAPIInfoMissingAddress(c *gc.C) { 589 conf := agent.EmptyConfig() 590 _, ok := conf.APIInfo() 591 c.Assert(ok, jc.IsFalse) 592 } 593 594 func (*suite) TestAPIInfoAddsLocalhostWhenServingInfoPresent(c *gc.C) { 595 attrParams := attributeParams 596 servingInfo := stateServingInfo() 597 conf, err := agent.NewStateMachineConfig(attrParams, servingInfo) 598 c.Assert(err, jc.ErrorIsNil) 599 apiinfo, ok := conf.APIInfo() 600 c.Assert(ok, jc.IsTrue) 601 c.Check(apiinfo.Addrs, gc.HasLen, len(attrParams.APIAddresses)+1) 602 localhostAddressFound := false 603 for _, eachApiAddress := range apiinfo.Addrs { 604 if eachApiAddress == "localhost:47" { 605 localhostAddressFound = true 606 break 607 } 608 } 609 c.Assert(localhostAddressFound, jc.IsTrue) 610 } 611 612 func (*suite) TestAPIInfoAddsLocalhostWhenServingInfoPresentAndPreferIPv6On(c *gc.C) { 613 attrParams := attributeParams 614 attrParams.PreferIPv6 = true 615 servingInfo := stateServingInfo() 616 conf, err := agent.NewStateMachineConfig(attrParams, servingInfo) 617 c.Assert(err, jc.ErrorIsNil) 618 apiinfo, ok := conf.APIInfo() 619 c.Assert(ok, jc.IsTrue) 620 c.Check(apiinfo.Addrs, gc.HasLen, len(attrParams.APIAddresses)+1) 621 localhostAddressFound := false 622 for _, eachApiAddress := range apiinfo.Addrs { 623 if eachApiAddress == "[::1]:47" { 624 localhostAddressFound = true 625 break 626 } 627 c.Check(eachApiAddress, gc.Not(gc.Equals), "localhost:47") 628 } 629 c.Assert(localhostAddressFound, jc.IsTrue) 630 } 631 632 func (*suite) TestMongoInfoHonorsPreferIPv6(c *gc.C) { 633 attrParams := attributeParams 634 attrParams.PreferIPv6 = true 635 servingInfo := stateServingInfo() 636 conf, err := agent.NewStateMachineConfig(attrParams, servingInfo) 637 c.Assert(err, jc.ErrorIsNil) 638 mongoInfo, ok := conf.MongoInfo() 639 c.Assert(ok, jc.IsTrue) 640 c.Check(mongoInfo.Info.Addrs, jc.DeepEquals, []string{"[::1]:69"}) 641 642 attrParams.PreferIPv6 = false 643 conf, err = agent.NewStateMachineConfig(attrParams, servingInfo) 644 c.Assert(err, jc.ErrorIsNil) 645 mongoInfo, ok = conf.MongoInfo() 646 c.Assert(ok, jc.IsTrue) 647 c.Check(mongoInfo.Info.Addrs, jc.DeepEquals, []string{"127.0.0.1:69"}) 648 } 649 650 func (*suite) TestAPIInfoDoesntAddLocalhostWhenNoServingInfoPreferIPv6Off(c *gc.C) { 651 attrParams := attributeParams 652 attrParams.PreferIPv6 = false 653 conf, err := agent.NewAgentConfig(attrParams) 654 c.Assert(err, jc.ErrorIsNil) 655 apiinfo, ok := conf.APIInfo() 656 c.Assert(ok, jc.IsTrue) 657 c.Assert(apiinfo.Addrs, gc.DeepEquals, attrParams.APIAddresses) 658 } 659 660 func (*suite) TestAPIInfoDoesntAddLocalhostWhenNoServingInfoPreferIPv6On(c *gc.C) { 661 attrParams := attributeParams 662 attrParams.PreferIPv6 = true 663 conf, err := agent.NewAgentConfig(attrParams) 664 c.Assert(err, jc.ErrorIsNil) 665 apiinfo, ok := conf.APIInfo() 666 c.Assert(ok, jc.IsTrue) 667 c.Assert(apiinfo.Addrs, gc.DeepEquals, attrParams.APIAddresses) 668 } 669 670 func (*suite) TestSetPassword(c *gc.C) { 671 attrParams := attributeParams 672 servingInfo := stateServingInfo() 673 servingInfo.APIPort = 1235 674 conf, err := agent.NewStateMachineConfig(attrParams, servingInfo) 675 c.Assert(err, jc.ErrorIsNil) 676 677 expectAPIInfo := &api.Info{ 678 Addrs: attrParams.APIAddresses, 679 CACert: attrParams.CACert, 680 Tag: attrParams.Tag, 681 Password: "", 682 Nonce: attrParams.Nonce, 683 ModelTag: attrParams.Model, 684 } 685 apiInfo, ok := conf.APIInfo() 686 c.Assert(ok, jc.IsTrue) 687 c.Assert(apiInfo, jc.DeepEquals, expectAPIInfo) 688 addr := fmt.Sprintf("127.0.0.1:%d", servingInfo.StatePort) 689 expectStateInfo := &mongo.MongoInfo{ 690 Info: mongo.Info{ 691 Addrs: []string{addr}, 692 CACert: attrParams.CACert, 693 }, 694 Tag: attrParams.Tag, 695 Password: "", 696 } 697 info, ok := conf.MongoInfo() 698 c.Assert(ok, jc.IsTrue) 699 c.Assert(info, jc.DeepEquals, expectStateInfo) 700 701 conf.SetPassword("newpassword") 702 703 expectAPIInfo.Password = "newpassword" 704 expectStateInfo.Password = "newpassword" 705 706 apiInfo, ok = conf.APIInfo() 707 c.Assert(ok, jc.IsTrue) 708 c.Assert(apiInfo, jc.DeepEquals, expectAPIInfo) 709 info, ok = conf.MongoInfo() 710 c.Assert(ok, jc.IsTrue) 711 c.Assert(info, jc.DeepEquals, expectStateInfo) 712 } 713 714 func (*suite) TestSetOldPassword(c *gc.C) { 715 conf, err := agent.NewAgentConfig(attributeParams) 716 c.Assert(err, jc.ErrorIsNil) 717 718 c.Assert(conf.OldPassword(), gc.Equals, attributeParams.Password) 719 conf.SetOldPassword("newoldpassword") 720 c.Assert(conf.OldPassword(), gc.Equals, "newoldpassword") 721 } 722 723 func (*suite) TestSetUpgradedToVersion(c *gc.C) { 724 conf, err := agent.NewAgentConfig(attributeParams) 725 c.Assert(err, jc.ErrorIsNil) 726 727 c.Assert(conf.UpgradedToVersion(), gc.Equals, jujuversion.Current) 728 729 expectVers := version.MustParse("3.4.5") 730 conf.SetUpgradedToVersion(expectVers) 731 c.Assert(conf.UpgradedToVersion(), gc.Equals, expectVers) 732 } 733 734 func (*suite) TestSetAPIHostPorts(c *gc.C) { 735 conf, err := agent.NewAgentConfig(attributeParams) 736 c.Assert(err, jc.ErrorIsNil) 737 738 addrs, err := conf.APIAddresses() 739 c.Assert(err, jc.ErrorIsNil) 740 c.Assert(addrs, gc.DeepEquals, attributeParams.APIAddresses) 741 742 // All the best candidate addresses for each server are 743 // used. Cloud-local addresses are preferred. Otherwise, public 744 // or unknown scope addresses are used. 745 // 746 // If a server has only machine-local addresses, or none 747 // at all, then it will be excluded. 748 server1 := network.NewAddresses("0.1.0.1", "0.1.0.2", "host.com") 749 server1[0].Scope = network.ScopeCloudLocal 750 server1[1].Scope = network.ScopeCloudLocal 751 server1[2].Scope = network.ScopePublic 752 753 server2 := network.NewAddresses("0.2.0.1", "0.2.0.2") 754 server2[0].Scope = network.ScopePublic 755 server2[1].Scope = network.ScopePublic 756 757 server3 := network.NewAddresses("127.0.0.1") 758 server3[0].Scope = network.ScopeMachineLocal 759 760 server4 := network.NewAddresses("0.4.0.1", "elsewhere.net") 761 server4[0].Scope = network.ScopeUnknown 762 server4[1].Scope = network.ScopeUnknown 763 764 conf.SetAPIHostPorts([][]network.HostPort{ 765 network.AddressesWithPort(server1, 1111), 766 network.AddressesWithPort(server2, 2222), 767 network.AddressesWithPort(server3, 3333), 768 network.AddressesWithPort(server4, 4444), 769 }) 770 addrs, err = conf.APIAddresses() 771 c.Assert(err, jc.ErrorIsNil) 772 c.Assert(addrs, gc.DeepEquals, []string{ 773 "0.1.0.1:1111", 774 "0.1.0.2:1111", 775 "host.com:1111", 776 "0.2.0.1:2222", 777 "0.2.0.2:2222", 778 "0.4.0.1:4444", 779 "elsewhere.net:4444", 780 }) 781 } 782 783 func (*suite) TestSetCACert(c *gc.C) { 784 conf, err := agent.NewAgentConfig(attributeParams) 785 c.Assert(err, jc.ErrorIsNil) 786 c.Assert(conf.CACert(), gc.Equals, "ca cert") 787 788 conf.SetCACert("new ca cert") 789 c.Assert(conf.CACert(), gc.Equals, "new ca cert") 790 }