github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/cmd/juju/model/show_test.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for info. 3 4 package model_test 5 6 import ( 7 "time" 8 9 "github.com/juju/cmd" 10 "github.com/juju/cmd/cmdtesting" 11 "github.com/juju/errors" 12 gitjujutesting "github.com/juju/testing" 13 jc "github.com/juju/testing/checkers" 14 "github.com/juju/version" 15 gc "gopkg.in/check.v1" 16 "gopkg.in/juju/names.v2" 17 18 "github.com/juju/juju/apiserver/params" 19 "github.com/juju/juju/cmd/juju/model" 20 coremodel "github.com/juju/juju/core/model" 21 "github.com/juju/juju/core/status" 22 "github.com/juju/juju/jujuclient" 23 "github.com/juju/juju/testing" 24 ) 25 26 var _ = gc.Suite(&ShowCommandSuite{}) 27 var _ = gc.Suite(&showSLACommandSuite{}) 28 29 type ShowCommandSuite struct { 30 testing.FakeJujuXDGDataHomeSuite 31 fake fakeModelShowClient 32 store *jujuclient.MemStore 33 expectedOutput attrs 34 expectedDisplay string 35 } 36 37 func (s *ShowCommandSuite) SetUpTest(c *gc.C) { 38 s.FakeJujuXDGDataHomeSuite.SetUpTest(c) 39 lastConnection := time.Date(2015, 3, 20, 0, 0, 0, 0, time.UTC) 40 statusSince := time.Date(2016, 4, 5, 0, 0, 0, 0, time.UTC) 41 migrationStart := time.Date(2016, 4, 6, 0, 10, 0, 0, time.UTC) 42 migrationEnd := time.Date(2016, 4, 7, 0, 0, 15, 0, time.UTC) 43 44 users := []params.ModelUserInfo{{ 45 UserName: "admin", 46 LastConnection: &lastConnection, 47 Access: "write", 48 }, { 49 UserName: "bob", 50 DisplayName: "Bob", 51 Access: "read", 52 }} 53 54 s.fake = fakeModelShowClient{ 55 info: params.ModelInfo{ 56 Name: "mymodel", 57 UUID: testing.ModelTag.Id(), 58 Type: "iaas", 59 ControllerUUID: "1ca2293b-fdb9-4299-97d6-55583bb39364", 60 IsController: false, 61 OwnerTag: "user-admin", 62 CloudTag: "cloud-some-cloud", 63 CloudRegion: "some-region", 64 ProviderType: "openstack", 65 Life: params.Alive, 66 Status: params.EntityStatus{ 67 Status: status.Active, 68 Since: &statusSince, 69 }, 70 Users: users, 71 Migration: ¶ms.ModelMigrationStatus{ 72 Status: "obfuscating Quigley matrix", 73 Start: &migrationStart, 74 End: &migrationEnd, 75 }, 76 }, 77 } 78 79 s.expectedOutput = attrs{ 80 "mymodel": attrs{ 81 "name": "admin/mymodel", 82 "short-name": "mymodel", 83 "model-uuid": "deadbeef-0bad-400d-8000-4b1d0d06f00d", 84 "model-type": "iaas", 85 "controller-uuid": "1ca2293b-fdb9-4299-97d6-55583bb39364", 86 "controller-name": "testing", 87 "is-controller": false, 88 "owner": "admin", 89 "cloud": "some-cloud", 90 "region": "some-region", 91 "type": "openstack", 92 "life": "alive", 93 "status": attrs{ 94 "current": "active", 95 "since": "2016-04-05", 96 "migration": "obfuscating Quigley matrix", 97 "migration-start": "2016-04-06", 98 "migration-end": "2016-04-07", 99 }, 100 "users": attrs{ 101 "admin": attrs{ 102 "access": "write", 103 "last-connection": "2015-03-20", 104 }, 105 "bob": attrs{ 106 "display-name": "Bob", 107 "access": "read", 108 "last-connection": "never connected", 109 }, 110 }, 111 }, 112 } 113 114 s.store = jujuclient.NewMemStore() 115 s.store.CurrentControllerName = "testing" 116 s.store.Controllers["testing"] = jujuclient.ControllerDetails{} 117 s.store.Accounts["testing"] = jujuclient.AccountDetails{ 118 User: "admin", 119 } 120 err := s.store.UpdateModel("testing", "admin/mymodel", jujuclient.ModelDetails{ 121 ModelUUID: testing.ModelTag.Id(), 122 ModelType: coremodel.IAAS, 123 }) 124 c.Assert(err, jc.ErrorIsNil) 125 s.store.Models["testing"].CurrentModel = "admin/mymodel" 126 } 127 128 func (s *ShowCommandSuite) TestShow(c *gc.C) { 129 _, err := cmdtesting.RunCommand(c, s.newShowCommand()) 130 c.Assert(err, jc.ErrorIsNil) 131 s.fake.CheckCalls(c, []gitjujutesting.StubCall{ 132 {"ModelInfo", []interface{}{[]names.ModelTag{testing.ModelTag}}}, 133 {"Close", nil}, 134 }) 135 } 136 137 func (s *ShowCommandSuite) TestShowUnknownCallsRefresh(c *gc.C) { 138 called := false 139 refresh := func(jujuclient.ClientStore, string) error { 140 called = true 141 return nil 142 } 143 _, err := cmdtesting.RunCommand(c, model.NewShowCommandForTest(&s.fake, refresh, s.store), "unknown") 144 c.Check(called, jc.IsTrue) 145 c.Check(err, jc.Satisfies, errors.IsNotFound) 146 } 147 148 func (s *ShowCommandSuite) TestShowFormatYaml(c *gc.C) { 149 ctx, err := cmdtesting.RunCommand(c, s.newShowCommand(), "--format", "yaml") 150 c.Assert(err, jc.ErrorIsNil) 151 c.Assert(cmdtesting.Stdout(ctx), jc.YAMLEquals, s.expectedOutput) 152 } 153 154 func (s *ShowCommandSuite) addCredentialToTestData() { 155 s.fake.info.CloudCredentialTag = "cloudcred-some-cloud_some-owner_some-credential" 156 157 modelOutput := s.expectedOutput["mymodel"].(attrs) 158 modelOutput["credential"] = attrs{ 159 "name": "some-credential", 160 "owner": "some-owner", 161 "cloud": "some-cloud", 162 } 163 } 164 165 func (s *ShowCommandSuite) TestShowWithCredentialFormatYaml(c *gc.C) { 166 s.addCredentialToTestData() 167 ctx, err := cmdtesting.RunCommand(c, s.newShowCommand(), "--format", "yaml") 168 c.Assert(err, jc.ErrorIsNil) 169 c.Assert(cmdtesting.Stdout(ctx), jc.YAMLEquals, s.expectedOutput) 170 } 171 172 func (s *ShowCommandSuite) TestShowFormatJson(c *gc.C) { 173 ctx, err := cmdtesting.RunCommand(c, s.newShowCommand(), "--format", "json") 174 c.Assert(err, jc.ErrorIsNil) 175 c.Assert(cmdtesting.Stdout(ctx), jc.JSONEquals, s.expectedOutput) 176 } 177 178 func (s *ShowCommandSuite) TestShowWithCredentialFormatJson(c *gc.C) { 179 s.addCredentialToTestData() 180 ctx, err := cmdtesting.RunCommand(c, s.newShowCommand(), "--format", "json") 181 c.Assert(err, jc.ErrorIsNil) 182 c.Assert(cmdtesting.Stdout(ctx), jc.JSONEquals, s.expectedOutput) 183 } 184 185 func (s *ShowCommandSuite) TestUnrecognizedArg(c *gc.C) { 186 _, err := cmdtesting.RunCommand(c, s.newShowCommand(), "admin", "whoops") 187 c.Assert(err, gc.ErrorMatches, `unrecognized args: \["whoops"\]`) 188 } 189 190 func (s *ShowCommandSuite) TestShowBasicIncompleteModelsYaml(c *gc.C) { 191 s.fake.infos = []params.ModelInfoResult{ 192 {Result: createBasicModelInfo()}, 193 } 194 s.expectedDisplay = ` 195 basic-model: 196 name: owner/basic-model 197 short-name: basic-model 198 model-uuid: deadbeef-0bad-400d-8000-4b1d0d06f00d 199 model-type: iaas 200 controller-uuid: deadbeef-1bad-500d-9000-4b1d0d06f00d 201 controller-name: testing 202 is-controller: false 203 owner: owner 204 cloud: altostratus 205 region: mid-level 206 life: dead 207 `[1:] 208 s.assertShowOutput(c, "yaml") 209 } 210 211 func (s *ShowCommandSuite) TestShowBasicIncompleteModelsJson(c *gc.C) { 212 s.fake.infos = []params.ModelInfoResult{ 213 {Result: createBasicModelInfo()}, 214 } 215 s.expectedDisplay = "{\"basic-model\":" + 216 "{\"name\":\"owner/basic-model\"," + 217 "\"short-name\":\"basic-model\"," + 218 "\"model-uuid\":\"deadbeef-0bad-400d-8000-4b1d0d06f00d\"," + 219 "\"model-type\":\"iaas\"," + 220 "\"controller-uuid\":\"deadbeef-1bad-500d-9000-4b1d0d06f00d\"," + 221 "\"controller-name\":\"testing\"," + 222 "\"is-controller\":false," + 223 "\"owner\":\"owner\"," + 224 "\"cloud\":\"altostratus\"," + 225 "\"region\":\"mid-level\"," + 226 "\"life\":\"dead\"}}\n" 227 s.assertShowOutput(c, "json") 228 } 229 230 func (s *ShowCommandSuite) TestShowBasicWithStatusIncompleteModelsYaml(c *gc.C) { 231 s.fake.infos = []params.ModelInfoResult{ 232 {Result: createBasicModelInfoWithStatus()}, 233 } 234 s.expectedDisplay = ` 235 basic-model: 236 name: owner/basic-model 237 short-name: basic-model 238 model-uuid: deadbeef-0bad-400d-8000-4b1d0d06f00d 239 model-type: iaas 240 controller-uuid: deadbeef-1bad-500d-9000-4b1d0d06f00d 241 controller-name: testing 242 is-controller: false 243 owner: owner 244 cloud: altostratus 245 region: mid-level 246 life: dead 247 status: 248 current: busy 249 `[1:] 250 s.assertShowOutput(c, "yaml") 251 } 252 253 func (s *ShowCommandSuite) TestShowBasicWithStatusIncompleteModelsJson(c *gc.C) { 254 s.fake.infos = []params.ModelInfoResult{ 255 {Result: createBasicModelInfoWithStatus()}, 256 } 257 s.expectedDisplay = "{\"basic-model\":" + 258 "{\"name\":\"owner/basic-model\"," + 259 "\"short-name\":\"basic-model\"," + 260 "\"model-uuid\":\"deadbeef-0bad-400d-8000-4b1d0d06f00d\"," + 261 "\"model-type\":\"iaas\"," + 262 "\"controller-uuid\":\"deadbeef-1bad-500d-9000-4b1d0d06f00d\"," + 263 "\"controller-name\":\"testing\"," + 264 "\"is-controller\":false," + 265 "\"owner\":\"owner\"," + 266 "\"cloud\":\"altostratus\"," + 267 "\"region\":\"mid-level\"," + 268 "\"life\":\"dead\"," + 269 "\"status\":{\"current\":\"busy\"}}}\n" 270 271 s.assertShowOutput(c, "json") 272 } 273 274 func (s *ShowCommandSuite) TestShowBasicWithMigrationIncompleteModelsYaml(c *gc.C) { 275 basicAndMigrationStatusInfo := createBasicModelInfo() 276 addMigrationStatusStatus(basicAndMigrationStatusInfo) 277 s.fake.infos = []params.ModelInfoResult{ 278 {Result: basicAndMigrationStatusInfo}, 279 } 280 s.expectedDisplay = ` 281 basic-model: 282 name: owner/basic-model 283 short-name: basic-model 284 model-uuid: deadbeef-0bad-400d-8000-4b1d0d06f00d 285 model-type: iaas 286 controller-uuid: deadbeef-1bad-500d-9000-4b1d0d06f00d 287 controller-name: testing 288 is-controller: false 289 owner: owner 290 cloud: altostratus 291 region: mid-level 292 life: dead 293 status: 294 migration: importing 295 migration-start: just now 296 `[1:] 297 s.assertShowOutput(c, "yaml") 298 } 299 300 func (s *ShowCommandSuite) TestShowBasicWithMigrationIncompleteModelsJson(c *gc.C) { 301 basicAndMigrationStatusInfo := createBasicModelInfo() 302 addMigrationStatusStatus(basicAndMigrationStatusInfo) 303 s.fake.infos = []params.ModelInfoResult{ 304 {Result: basicAndMigrationStatusInfo}, 305 } 306 s.expectedDisplay = "{\"basic-model\":" + 307 "{\"name\":\"owner/basic-model\"," + 308 "\"short-name\":\"basic-model\"," + 309 "\"model-uuid\":\"deadbeef-0bad-400d-8000-4b1d0d06f00d\"," + 310 "\"model-type\":\"iaas\"," + 311 "\"controller-uuid\":\"deadbeef-1bad-500d-9000-4b1d0d06f00d\"," + 312 "\"controller-name\":\"testing\"," + 313 "\"is-controller\":false," + 314 "\"owner\":\"owner\"," + 315 "\"cloud\":\"altostratus\"," + 316 "\"region\":\"mid-level\"," + 317 "\"life\":\"dead\"," + 318 "\"status\":{\"migration\":\"importing\",\"migration-start\":\"just now\"}}}\n" 319 s.assertShowOutput(c, "json") 320 } 321 322 func (s *ShowCommandSuite) TestShowBasicWithStatusAndMigrationIncompleteModelsYaml(c *gc.C) { 323 basicAndStatusAndMigrationInfo := createBasicModelInfoWithStatus() 324 addMigrationStatusStatus(basicAndStatusAndMigrationInfo) 325 s.fake.infos = []params.ModelInfoResult{ 326 {Result: basicAndStatusAndMigrationInfo}, 327 } 328 s.expectedDisplay = ` 329 basic-model: 330 name: owner/basic-model 331 short-name: basic-model 332 model-uuid: deadbeef-0bad-400d-8000-4b1d0d06f00d 333 model-type: iaas 334 controller-uuid: deadbeef-1bad-500d-9000-4b1d0d06f00d 335 controller-name: testing 336 is-controller: false 337 owner: owner 338 cloud: altostratus 339 region: mid-level 340 life: dead 341 status: 342 current: busy 343 migration: importing 344 migration-start: just now 345 `[1:] 346 s.assertShowOutput(c, "yaml") 347 } 348 349 func (s *ShowCommandSuite) TestShowBasicWithStatusAndMigrationIncompleteModelsJson(c *gc.C) { 350 basicAndStatusAndMigrationInfo := createBasicModelInfoWithStatus() 351 addMigrationStatusStatus(basicAndStatusAndMigrationInfo) 352 s.fake.infos = []params.ModelInfoResult{ 353 {Result: basicAndStatusAndMigrationInfo}, 354 } 355 s.expectedDisplay = "{\"basic-model\":" + 356 "{\"name\":\"owner/basic-model\"," + 357 "\"short-name\":\"basic-model\"," + 358 "\"model-uuid\":\"deadbeef-0bad-400d-8000-4b1d0d06f00d\"," + 359 "\"model-type\":\"iaas\"," + 360 "\"controller-uuid\":\"deadbeef-1bad-500d-9000-4b1d0d06f00d\"," + 361 "\"controller-name\":\"testing\"," + 362 "\"is-controller\":false," + 363 "\"owner\":\"owner\"," + 364 "\"cloud\":\"altostratus\"," + 365 "\"region\":\"mid-level\"," + 366 "\"life\":\"dead\"," + 367 "\"status\":{\"current\":\"busy\",\"migration\":\"importing\",\"migration-start\":\"just now\"}}}\n" 368 369 s.assertShowOutput(c, "json") 370 } 371 372 func (s *ShowCommandSuite) TestShowBasicWithProviderIncompleteModelsYaml(c *gc.C) { 373 basicAndProviderTypeInfo := createBasicModelInfo() 374 basicAndProviderTypeInfo.ProviderType = "aws" 375 s.fake.infos = []params.ModelInfoResult{ 376 {Result: basicAndProviderTypeInfo}, 377 } 378 s.expectedDisplay = ` 379 basic-model: 380 name: owner/basic-model 381 short-name: basic-model 382 model-uuid: deadbeef-0bad-400d-8000-4b1d0d06f00d 383 model-type: iaas 384 controller-uuid: deadbeef-1bad-500d-9000-4b1d0d06f00d 385 controller-name: testing 386 is-controller: false 387 owner: owner 388 cloud: altostratus 389 region: mid-level 390 type: aws 391 life: dead 392 `[1:] 393 s.assertShowOutput(c, "yaml") 394 } 395 396 func (s *ShowCommandSuite) TestShowBasicWithProviderIncompleteModelsJson(c *gc.C) { 397 basicAndProviderTypeInfo := createBasicModelInfo() 398 basicAndProviderTypeInfo.ProviderType = "aws" 399 s.fake.infos = []params.ModelInfoResult{ 400 {Result: basicAndProviderTypeInfo}, 401 } 402 s.expectedDisplay = "{\"basic-model\":" + 403 "{\"name\":\"owner/basic-model\"," + 404 "\"short-name\":\"basic-model\"," + 405 "\"model-uuid\":\"deadbeef-0bad-400d-8000-4b1d0d06f00d\"," + 406 "\"model-type\":\"iaas\"," + 407 "\"controller-uuid\":\"deadbeef-1bad-500d-9000-4b1d0d06f00d\"," + 408 "\"controller-name\":\"testing\"," + 409 "\"is-controller\":false," + 410 "\"owner\":\"owner\"," + 411 "\"cloud\":\"altostratus\"," + 412 "\"region\":\"mid-level\"," + 413 "\"type\":\"aws\"," + 414 "\"life\":\"dead\"}}\n" 415 s.assertShowOutput(c, "json") 416 } 417 418 func (s *ShowCommandSuite) TestShowBasicWithUsersIncompleteModelsYaml(c *gc.C) { 419 basicAndUsersInfo := createBasicModelInfo() 420 basicAndUsersInfo.Users = []params.ModelUserInfo{ 421 {"admin", "display name", nil, params.UserAccessPermission("admin")}, 422 } 423 s.fake.infos = []params.ModelInfoResult{ 424 {Result: basicAndUsersInfo}, 425 } 426 s.expectedDisplay = ` 427 basic-model: 428 name: owner/basic-model 429 short-name: basic-model 430 model-uuid: deadbeef-0bad-400d-8000-4b1d0d06f00d 431 model-type: iaas 432 controller-uuid: deadbeef-1bad-500d-9000-4b1d0d06f00d 433 controller-name: testing 434 is-controller: false 435 owner: owner 436 cloud: altostratus 437 region: mid-level 438 life: dead 439 users: 440 admin: 441 display-name: display name 442 access: admin 443 last-connection: never connected 444 `[1:] 445 s.assertShowOutput(c, "yaml") 446 } 447 448 func (s *ShowCommandSuite) TestShowBasicWithUsersIncompleteModelsJson(c *gc.C) { 449 basicAndUsersInfo := createBasicModelInfo() 450 basicAndUsersInfo.Users = []params.ModelUserInfo{ 451 {"admin", "display name", nil, params.UserAccessPermission("admin")}, 452 } 453 454 s.fake.infos = []params.ModelInfoResult{ 455 {Result: basicAndUsersInfo}, 456 } 457 s.expectedDisplay = "{\"basic-model\":" + 458 "{\"name\":\"owner/basic-model\"," + 459 "\"short-name\":\"basic-model\"," + 460 "\"model-uuid\":\"deadbeef-0bad-400d-8000-4b1d0d06f00d\"," + 461 "\"model-type\":\"iaas\"," + 462 "\"controller-uuid\":\"deadbeef-1bad-500d-9000-4b1d0d06f00d\"," + 463 "\"controller-name\":\"testing\"," + 464 "\"is-controller\":false," + 465 "\"owner\":\"owner\"," + 466 "\"cloud\":\"altostratus\"," + 467 "\"region\":\"mid-level\"," + 468 "\"life\":\"dead\"," + 469 "\"users\":{\"admin\":{\"display-name\":\"display name\",\"access\":\"admin\",\"last-connection\":\"never connected\"}}}}\n" 470 s.assertShowOutput(c, "json") 471 } 472 473 func (s *ShowCommandSuite) TestShowBasicWithMachinesIncompleteModelsYaml(c *gc.C) { 474 basicAndMachinesInfo := createBasicModelInfo() 475 basicAndMachinesInfo.Machines = []params.ModelMachineInfo{ 476 {Id: "2"}, {Id: "12"}, 477 } 478 s.fake.infos = []params.ModelInfoResult{ 479 {Result: basicAndMachinesInfo}, 480 } 481 s.expectedDisplay = ` 482 basic-model: 483 name: owner/basic-model 484 short-name: basic-model 485 model-uuid: deadbeef-0bad-400d-8000-4b1d0d06f00d 486 model-type: iaas 487 controller-uuid: deadbeef-1bad-500d-9000-4b1d0d06f00d 488 controller-name: testing 489 is-controller: false 490 owner: owner 491 cloud: altostratus 492 region: mid-level 493 life: dead 494 machines: 495 "2": 496 cores: 0 497 "12": 498 cores: 0 499 `[1:] 500 s.assertShowOutput(c, "yaml") 501 } 502 503 func (s *ShowCommandSuite) TestShowBasicWithMachinesIncompleteModelsJson(c *gc.C) { 504 basicAndMachinesInfo := createBasicModelInfo() 505 basicAndMachinesInfo.Machines = []params.ModelMachineInfo{ 506 {Id: "2"}, {Id: "12"}, 507 } 508 s.fake.infos = []params.ModelInfoResult{ 509 {Result: basicAndMachinesInfo}, 510 } 511 s.expectedDisplay = "{\"basic-model\":" + 512 "{\"name\":\"owner/basic-model\"," + 513 "\"short-name\":\"basic-model\"," + 514 "\"model-uuid\":\"deadbeef-0bad-400d-8000-4b1d0d06f00d\"," + 515 "\"model-type\":\"iaas\"," + 516 "\"controller-uuid\":\"deadbeef-1bad-500d-9000-4b1d0d06f00d\"," + 517 "\"controller-name\":\"testing\"," + 518 "\"is-controller\":false," + 519 "\"owner\":\"owner\"," + 520 "\"cloud\":\"altostratus\"," + 521 "\"region\":\"mid-level\"," + 522 "\"life\":\"dead\"," + 523 "\"machines\":{\"12\":{\"cores\":0},\"2\":{\"cores\":0}}}}\n" 524 s.assertShowOutput(c, "json") 525 } 526 527 func (s *ShowCommandSuite) TestShowBasicWithSLAIncompleteModelsYaml(c *gc.C) { 528 basicAndSLAInfo := createBasicModelInfo() 529 basicAndSLAInfo.SLA = ¶ms.ModelSLAInfo{ 530 Owner: "owner", 531 Level: "level", 532 } 533 s.fake.infos = []params.ModelInfoResult{ 534 {Result: basicAndSLAInfo}, 535 } 536 s.expectedDisplay = ` 537 basic-model: 538 name: owner/basic-model 539 short-name: basic-model 540 model-uuid: deadbeef-0bad-400d-8000-4b1d0d06f00d 541 model-type: iaas 542 controller-uuid: deadbeef-1bad-500d-9000-4b1d0d06f00d 543 controller-name: testing 544 is-controller: false 545 owner: owner 546 cloud: altostratus 547 region: mid-level 548 life: dead 549 sla: level 550 sla-owner: owner 551 `[1:] 552 s.assertShowOutput(c, "yaml") 553 } 554 555 func (s *ShowCommandSuite) TestShowBasicWithSLAIncompleteModelsJson(c *gc.C) { 556 basicAndSLAInfo := createBasicModelInfo() 557 basicAndSLAInfo.SLA = ¶ms.ModelSLAInfo{ 558 Owner: "owner", 559 Level: "level", 560 } 561 s.fake.infos = []params.ModelInfoResult{ 562 {Result: basicAndSLAInfo}, 563 } 564 s.expectedDisplay = "{\"basic-model\":" + 565 "{\"name\":\"owner/basic-model\"," + 566 "\"short-name\":\"basic-model\"," + 567 "\"model-uuid\":\"deadbeef-0bad-400d-8000-4b1d0d06f00d\"," + 568 "\"model-type\":\"iaas\"," + 569 "\"controller-uuid\":\"deadbeef-1bad-500d-9000-4b1d0d06f00d\"," + 570 "\"controller-name\":\"testing\"," + 571 "\"is-controller\":false," + 572 "\"owner\":\"owner\"," + 573 "\"cloud\":\"altostratus\"," + 574 "\"region\":\"mid-level\"," + 575 "\"life\":\"dead\"," + 576 "\"sla\":\"level\"," + 577 "\"sla-owner\":\"owner\"}}\n" 578 s.assertShowOutput(c, "json") 579 } 580 581 func (s *ShowCommandSuite) TestShowModelWithAgentVersionInJson(c *gc.C) { 582 s.expectedDisplay = "{\"basic-model\":" + 583 "{\"name\":\"owner/basic-model\"," + 584 "\"short-name\":\"basic-model\"," + 585 "\"model-uuid\":\"deadbeef-0bad-400d-8000-4b1d0d06f00d\"," + 586 "\"model-type\":\"iaas\"," + 587 "\"controller-uuid\":\"deadbeef-1bad-500d-9000-4b1d0d06f00d\"," + 588 "\"controller-name\":\"testing\"," + 589 "\"is-controller\":false," + 590 "\"owner\":\"owner\"," + 591 "\"cloud\":\"altostratus\"," + 592 "\"region\":\"mid-level\"," + 593 "\"life\":\"dead\"," + 594 "\"agent-version\":\"2.55.5\"}}\n" 595 s.assertShowModelWithAgent(c, "json") 596 } 597 598 func (s *ShowCommandSuite) TestShowModelWithAgentVersionInYaml(c *gc.C) { 599 s.expectedDisplay = ` 600 basic-model: 601 name: owner/basic-model 602 short-name: basic-model 603 model-uuid: deadbeef-0bad-400d-8000-4b1d0d06f00d 604 model-type: iaas 605 controller-uuid: deadbeef-1bad-500d-9000-4b1d0d06f00d 606 controller-name: testing 607 is-controller: false 608 owner: owner 609 cloud: altostratus 610 region: mid-level 611 life: dead 612 agent-version: 2.55.5 613 `[1:] 614 s.assertShowModelWithAgent(c, "yaml") 615 } 616 617 func (s *ShowCommandSuite) assertShowModelWithAgent(c *gc.C, format string) { 618 // Since most of the tests in this suite already test model infos without 619 // agent version, all we need to do here is to test one with it. 620 agentVersion, err := version.Parse("2.55.5") 621 c.Assert(err, jc.ErrorIsNil) 622 basicTestInfo := createBasicModelInfo() 623 basicTestInfo.AgentVersion = &agentVersion 624 s.fake.infos = []params.ModelInfoResult{ 625 {Result: basicTestInfo}, 626 } 627 s.assertShowOutput(c, format) 628 } 629 630 func (s *ShowCommandSuite) newShowCommand() cmd.Command { 631 return model.NewShowCommandForTest(&s.fake, noOpRefresh, s.store) 632 } 633 634 func (s *ShowCommandSuite) assertShowOutput(c *gc.C, format string) { 635 ctx, err := cmdtesting.RunCommand(c, s.newShowCommand(), "--format", format) 636 c.Assert(err, jc.ErrorIsNil) 637 c.Assert(cmdtesting.Stdout(ctx), gc.Equals, s.expectedDisplay) 638 } 639 640 func createBasicModelInfo() *params.ModelInfo { 641 return ¶ms.ModelInfo{ 642 Name: "basic-model", 643 UUID: testing.ModelTag.Id(), 644 ControllerUUID: testing.ControllerTag.Id(), 645 IsController: false, 646 Type: "iaas", 647 OwnerTag: names.NewUserTag("owner").String(), 648 Life: params.Dead, 649 CloudTag: names.NewCloudTag("altostratus").String(), 650 CloudRegion: "mid-level", 651 } 652 } 653 654 func createBasicModelInfoWithStatus() *params.ModelInfo { 655 basicAndStatusInfo := createBasicModelInfo() 656 basicAndStatusInfo.Status = params.EntityStatus{ 657 Status: status.Busy, 658 } 659 return basicAndStatusInfo 660 } 661 662 func addMigrationStatusStatus(existingInfo *params.ModelInfo) { 663 now := time.Now() 664 existingInfo.Migration = ¶ms.ModelMigrationStatus{ 665 Status: "importing", 666 Start: &now, 667 } 668 } 669 670 type showSLACommandSuite struct { 671 ShowCommandSuite 672 } 673 674 func (s *showSLACommandSuite) SetUpTest(c *gc.C) { 675 s.ShowCommandSuite.SetUpTest(c) 676 677 s.fake.info.SLA = ¶ms.ModelSLAInfo{ 678 Level: "next", 679 Owner: "user", 680 } 681 slaOutput := s.expectedOutput["mymodel"].(attrs) 682 slaOutput["sla"] = "next" 683 slaOutput["sla-owner"] = "user" 684 } 685 686 func noOpRefresh(_ jujuclient.ClientStore, _ string) error { 687 return nil 688 } 689 690 type attrs map[string]interface{} 691 692 type fakeModelShowClient struct { 693 gitjujutesting.Stub 694 info params.ModelInfo 695 err *params.Error 696 infos []params.ModelInfoResult 697 } 698 699 func (f *fakeModelShowClient) Close() error { 700 f.MethodCall(f, "Close") 701 return f.NextErr() 702 } 703 704 func (f *fakeModelShowClient) ModelInfo(tags []names.ModelTag) ([]params.ModelInfoResult, error) { 705 f.MethodCall(f, "ModelInfo", tags) 706 if f.infos != nil { 707 return f.infos, nil 708 } 709 if len(tags) != 1 { 710 return nil, errors.Errorf("expected 1 tag, got %d", len(tags)) 711 } 712 if tags[0] != testing.ModelTag { 713 return nil, errors.Errorf("expected %s, got %s", testing.ModelTag.Id(), tags[0].Id()) 714 } 715 return []params.ModelInfoResult{{Result: &f.info, Error: f.err}}, f.NextErr() 716 }