github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/resource/api/helpers_test.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package api_test 5 6 import ( 7 "strings" 8 "time" 9 10 "github.com/juju/errors" 11 "github.com/juju/testing" 12 jc "github.com/juju/testing/checkers" 13 gc "gopkg.in/check.v1" 14 charmresource "gopkg.in/juju/charm.v6/resource" 15 "gopkg.in/juju/names.v2" 16 17 "github.com/juju/juju/apiserver/params" 18 "github.com/juju/juju/resource" 19 "github.com/juju/juju/resource/api" 20 "github.com/juju/juju/resource/resourcetesting" 21 ) 22 23 const fingerprint = "123456789012345678901234567890123456789012345678" 24 25 type HelpersSuite struct { 26 testing.IsolationSuite 27 } 28 29 var _ = gc.Suite(&HelpersSuite{}) 30 31 func (HelpersSuite) TestResource2API(c *gc.C) { 32 fp, err := charmresource.NewFingerprint([]byte(fingerprint)) 33 c.Assert(err, jc.ErrorIsNil) 34 now := time.Now() 35 res := resource.Resource{ 36 Resource: charmresource.Resource{ 37 Meta: charmresource.Meta{ 38 Name: "spam", 39 Type: charmresource.TypeFile, 40 Path: "spam.tgz", 41 Description: "you need it", 42 }, 43 Origin: charmresource.OriginUpload, 44 Revision: 1, 45 Fingerprint: fp, 46 Size: 10, 47 }, 48 ID: "a-application/spam", 49 PendingID: "some-unique-ID", 50 ApplicationID: "a-application", 51 Username: "a-user", 52 Timestamp: now, 53 } 54 err = res.Validate() 55 c.Assert(err, jc.ErrorIsNil) 56 apiRes := api.Resource2API(res) 57 58 c.Check(apiRes, jc.DeepEquals, params.Resource{ 59 CharmResource: params.CharmResource{ 60 Name: "spam", 61 Type: "file", 62 Path: "spam.tgz", 63 Description: "you need it", 64 Origin: "upload", 65 Revision: 1, 66 Fingerprint: []byte(fingerprint), 67 Size: 10, 68 }, 69 ID: "a-application/spam", 70 PendingID: "some-unique-ID", 71 ApplicationID: "a-application", 72 Username: "a-user", 73 Timestamp: now, 74 }) 75 } 76 77 func (HelpersSuite) TestAPIResult2ApplicationResourcesOkay(c *gc.C) { 78 fp, err := charmresource.NewFingerprint([]byte(fingerprint)) 79 c.Assert(err, jc.ErrorIsNil) 80 now := time.Now() 81 expected := resource.Resource{ 82 Resource: charmresource.Resource{ 83 Meta: charmresource.Meta{ 84 Name: "spam", 85 Type: charmresource.TypeFile, 86 Path: "spam.tgz", 87 Description: "you need it", 88 }, 89 Origin: charmresource.OriginUpload, 90 Revision: 1, 91 Fingerprint: fp, 92 Size: 10, 93 }, 94 ID: "a-application/spam", 95 PendingID: "some-unique-ID", 96 ApplicationID: "a-application", 97 Username: "a-user", 98 Timestamp: now, 99 } 100 err = expected.Validate() 101 c.Assert(err, jc.ErrorIsNil) 102 103 unitExpected := resource.Resource{ 104 Resource: charmresource.Resource{ 105 Meta: charmresource.Meta{ 106 Name: "unitspam", 107 Type: charmresource.TypeFile, 108 Path: "unitspam.tgz", 109 Description: "you need it", 110 }, 111 Origin: charmresource.OriginUpload, 112 Revision: 1, 113 Fingerprint: fp, 114 Size: 10, 115 }, 116 ID: "a-application/spam", 117 PendingID: "some-unique-ID", 118 ApplicationID: "a-application", 119 Username: "a-user", 120 Timestamp: now, 121 } 122 err = unitExpected.Validate() 123 c.Assert(err, jc.ErrorIsNil) 124 125 apiRes := params.Resource{ 126 CharmResource: params.CharmResource{ 127 Name: "spam", 128 Type: "file", 129 Path: "spam.tgz", 130 Description: "you need it", 131 Origin: "upload", 132 Revision: 1, 133 Fingerprint: []byte(fingerprint), 134 Size: 10, 135 }, 136 ID: "a-application/spam", 137 PendingID: "some-unique-ID", 138 ApplicationID: "a-application", 139 Username: "a-user", 140 Timestamp: now, 141 } 142 143 unitRes := params.Resource{ 144 CharmResource: params.CharmResource{ 145 Name: "unitspam", 146 Type: "file", 147 Path: "unitspam.tgz", 148 Description: "you need it", 149 Origin: "upload", 150 Revision: 1, 151 Fingerprint: []byte(fingerprint), 152 Size: 10, 153 }, 154 ID: "a-application/spam", 155 PendingID: "some-unique-ID", 156 ApplicationID: "a-application", 157 Username: "a-user", 158 Timestamp: now, 159 } 160 161 fp2, err := charmresource.GenerateFingerprint(strings.NewReader("boo!")) 162 c.Assert(err, jc.ErrorIsNil) 163 164 chRes := params.CharmResource{ 165 Name: "unitspam2", 166 Type: "file", 167 Path: "unitspam.tgz2", 168 Description: "you need it2", 169 Origin: "upload", 170 Revision: 2, 171 Fingerprint: fp2.Bytes(), 172 Size: 11, 173 } 174 175 chExpected := charmresource.Resource{ 176 Meta: charmresource.Meta{ 177 Name: "unitspam2", 178 Type: charmresource.TypeFile, 179 Path: "unitspam.tgz2", 180 Description: "you need it2", 181 }, 182 Origin: charmresource.OriginUpload, 183 Revision: 2, 184 Fingerprint: fp2, 185 Size: 11, 186 } 187 188 resources, err := api.APIResult2ApplicationResources(params.ResourcesResult{ 189 Resources: []params.Resource{ 190 apiRes, 191 }, 192 CharmStoreResources: []params.CharmResource{ 193 chRes, 194 }, 195 UnitResources: []params.UnitResources{ 196 { 197 Entity: params.Entity{ 198 Tag: "unit-foo-0", 199 }, 200 Resources: []params.Resource{ 201 unitRes, 202 }, 203 DownloadProgress: map[string]int64{ 204 unitRes.Name: 8, 205 }, 206 }, 207 }, 208 }) 209 c.Assert(err, jc.ErrorIsNil) 210 211 serviceResource := resource.ApplicationResources{ 212 Resources: []resource.Resource{ 213 expected, 214 }, 215 CharmStoreResources: []charmresource.Resource{ 216 chExpected, 217 }, 218 UnitResources: []resource.UnitResources{ 219 { 220 Tag: names.NewUnitTag("foo/0"), 221 Resources: []resource.Resource{ 222 unitExpected, 223 }, 224 DownloadProgress: map[string]int64{ 225 unitRes.Name: 8, 226 }, 227 }, 228 }, 229 } 230 231 c.Check(resources, jc.DeepEquals, serviceResource) 232 } 233 234 func (HelpersSuite) TestAPIResult2ApplicationResourcesBadUnitTag(c *gc.C) { 235 fp, err := charmresource.NewFingerprint([]byte(fingerprint)) 236 c.Assert(err, jc.ErrorIsNil) 237 now := time.Now() 238 expected := resource.Resource{ 239 Resource: charmresource.Resource{ 240 Meta: charmresource.Meta{ 241 Name: "spam", 242 Type: charmresource.TypeFile, 243 Path: "spam.tgz", 244 Description: "you need it", 245 }, 246 Origin: charmresource.OriginUpload, 247 Revision: 1, 248 Fingerprint: fp, 249 Size: 10, 250 }, 251 ID: "a-application/spam", 252 PendingID: "some-unique-ID", 253 ApplicationID: "a-application", 254 Username: "a-user", 255 Timestamp: now, 256 } 257 err = expected.Validate() 258 c.Assert(err, jc.ErrorIsNil) 259 260 unitExpected := resource.Resource{ 261 Resource: charmresource.Resource{ 262 Meta: charmresource.Meta{ 263 Name: "unitspam", 264 Type: charmresource.TypeFile, 265 Path: "unitspam.tgz", 266 Description: "you need it", 267 }, 268 Origin: charmresource.OriginUpload, 269 Revision: 1, 270 Fingerprint: fp, 271 Size: 10, 272 }, 273 ID: "a-application/spam", 274 PendingID: "some-unique-ID", 275 ApplicationID: "a-application", 276 Username: "a-user", 277 Timestamp: now, 278 } 279 err = unitExpected.Validate() 280 c.Assert(err, jc.ErrorIsNil) 281 282 apiRes := params.Resource{ 283 CharmResource: params.CharmResource{ 284 Name: "spam", 285 Type: "file", 286 Path: "spam.tgz", 287 Description: "you need it", 288 Origin: "upload", 289 Revision: 1, 290 Fingerprint: []byte(fingerprint), 291 Size: 10, 292 }, 293 ID: "a-application/spam", 294 PendingID: "some-unique-ID", 295 ApplicationID: "a-application", 296 Username: "a-user", 297 Timestamp: now, 298 } 299 300 unitRes := params.Resource{ 301 CharmResource: params.CharmResource{ 302 Name: "unitspam", 303 Type: "file", 304 Path: "unitspam.tgz", 305 Description: "you need it", 306 Origin: "upload", 307 Revision: 1, 308 Fingerprint: []byte(fingerprint), 309 Size: 10, 310 }, 311 ID: "a-application/spam", 312 PendingID: "some-unique-ID", 313 ApplicationID: "a-application", 314 Username: "a-user", 315 Timestamp: now, 316 } 317 318 _, err = api.APIResult2ApplicationResources(params.ResourcesResult{ 319 Resources: []params.Resource{ 320 apiRes, 321 }, 322 UnitResources: []params.UnitResources{ 323 { 324 Entity: params.Entity{ 325 Tag: "THIS IS NOT A GOOD UNIT TAG", 326 }, 327 Resources: []params.Resource{ 328 unitRes, 329 }, 330 }, 331 }, 332 }) 333 c.Assert(err, gc.ErrorMatches, ".*got bad data from server.*") 334 } 335 336 func (HelpersSuite) TestAPIResult2ApplicationResourcesFailure(c *gc.C) { 337 apiRes := params.Resource{ 338 CharmResource: params.CharmResource{ 339 Name: "spam", 340 Type: "file", 341 Path: "spam.tgz", 342 Origin: "upload", 343 Revision: 1, 344 Fingerprint: []byte(fingerprint), 345 Size: 10, 346 }, 347 ID: "a-application/spam", 348 ApplicationID: "a-application", 349 } 350 failure := errors.New("<failure>") 351 352 _, err := api.APIResult2ApplicationResources(params.ResourcesResult{ 353 ErrorResult: params.ErrorResult{ 354 Error: ¶ms.Error{ 355 Message: failure.Error(), 356 }, 357 }, 358 Resources: []params.Resource{ 359 apiRes, 360 }, 361 }) 362 363 c.Check(err, gc.ErrorMatches, "<failure>") 364 c.Check(errors.Cause(err), gc.Not(gc.Equals), failure) 365 } 366 367 func (HelpersSuite) TestAPIResult2ApplicationResourcesNotFound(c *gc.C) { 368 apiRes := params.Resource{ 369 CharmResource: params.CharmResource{ 370 Name: "spam", 371 Type: "file", 372 Path: "spam.tgz", 373 Origin: "upload", 374 Revision: 1, 375 Fingerprint: []byte(fingerprint), 376 Size: 10, 377 }, 378 ID: "a-application/spam", 379 ApplicationID: "a-application", 380 } 381 382 _, err := api.APIResult2ApplicationResources(params.ResourcesResult{ 383 ErrorResult: params.ErrorResult{ 384 Error: ¶ms.Error{ 385 Message: `application "a-application" not found`, 386 Code: params.CodeNotFound, 387 }, 388 }, 389 Resources: []params.Resource{ 390 apiRes, 391 }, 392 }) 393 394 c.Check(err, jc.Satisfies, errors.IsNotFound) 395 } 396 397 func (HelpersSuite) TestAPI2Resource(c *gc.C) { 398 now := time.Now() 399 res, err := api.API2Resource(params.Resource{ 400 CharmResource: params.CharmResource{ 401 Name: "spam", 402 Type: "file", 403 Path: "spam.tgz", 404 Description: "you need it", 405 Origin: "upload", 406 Revision: 1, 407 Fingerprint: []byte(fingerprint), 408 Size: 10, 409 }, 410 ID: "a-application/spam", 411 PendingID: "some-unique-ID", 412 ApplicationID: "a-application", 413 Username: "a-user", 414 Timestamp: now, 415 }) 416 c.Assert(err, jc.ErrorIsNil) 417 418 fp, err := charmresource.NewFingerprint([]byte(fingerprint)) 419 c.Assert(err, jc.ErrorIsNil) 420 expected := resource.Resource{ 421 Resource: charmresource.Resource{ 422 Meta: charmresource.Meta{ 423 Name: "spam", 424 Type: charmresource.TypeFile, 425 Path: "spam.tgz", 426 Description: "you need it", 427 }, 428 Origin: charmresource.OriginUpload, 429 Revision: 1, 430 Fingerprint: fp, 431 Size: 10, 432 }, 433 ID: "a-application/spam", 434 PendingID: "some-unique-ID", 435 ApplicationID: "a-application", 436 Username: "a-user", 437 Timestamp: now, 438 } 439 err = expected.Validate() 440 c.Assert(err, jc.ErrorIsNil) 441 442 c.Check(res, jc.DeepEquals, expected) 443 } 444 445 func (HelpersSuite) TestCharmResource2API(c *gc.C) { 446 fp, err := charmresource.NewFingerprint([]byte(fingerprint)) 447 c.Assert(err, jc.ErrorIsNil) 448 res := charmresource.Resource{ 449 Meta: charmresource.Meta{ 450 Name: "spam", 451 Type: charmresource.TypeFile, 452 Path: "spam.tgz", 453 Description: "you need it", 454 }, 455 Origin: charmresource.OriginUpload, 456 Revision: 1, 457 Fingerprint: fp, 458 Size: 10, 459 } 460 err = res.Validate() 461 c.Assert(err, jc.ErrorIsNil) 462 apiInfo := api.CharmResource2API(res) 463 464 c.Check(apiInfo, jc.DeepEquals, params.CharmResource{ 465 Name: "spam", 466 Type: "file", 467 Path: "spam.tgz", 468 Description: "you need it", 469 Origin: "upload", 470 Revision: 1, 471 Fingerprint: []byte(fingerprint), 472 Size: 10, 473 }) 474 } 475 476 func (HelpersSuite) TestAPI2CharmResource(c *gc.C) { 477 res, err := api.API2CharmResource(params.CharmResource{ 478 Name: "spam", 479 Type: "file", 480 Path: "spam.tgz", 481 Description: "you need it", 482 Origin: "upload", 483 Revision: 1, 484 Fingerprint: []byte(fingerprint), 485 Size: 10, 486 }) 487 c.Assert(err, jc.ErrorIsNil) 488 489 fp, err := charmresource.NewFingerprint([]byte(fingerprint)) 490 c.Assert(err, jc.ErrorIsNil) 491 expected := charmresource.Resource{ 492 Meta: charmresource.Meta{ 493 Name: "spam", 494 Type: charmresource.TypeFile, 495 Path: "spam.tgz", 496 Description: "you need it", 497 }, 498 Origin: charmresource.OriginUpload, 499 Revision: 1, 500 Fingerprint: fp, 501 Size: 10, 502 } 503 err = expected.Validate() 504 c.Assert(err, jc.ErrorIsNil) 505 506 c.Check(res, jc.DeepEquals, expected) 507 } 508 509 func (HelpersSuite) TestServiceResources2API(c *gc.C) { 510 res1 := resourcetesting.NewResource(c, nil, "res1", "a-application", "data").Resource 511 res2 := resourcetesting.NewResource(c, nil, "res2", "a-application", "data2").Resource 512 513 tag0 := names.NewUnitTag("a-application/0") 514 tag1 := names.NewUnitTag("a-application/1") 515 516 chres1 := res1.Resource 517 chres2 := res2.Resource 518 chres1.Revision++ 519 chres2.Revision++ 520 521 svcRes := resource.ApplicationResources{ 522 Resources: []resource.Resource{ 523 res1, 524 res2, 525 }, 526 UnitResources: []resource.UnitResources{ 527 { 528 Tag: tag0, 529 Resources: []resource.Resource{ 530 res1, 531 res2, 532 }, 533 DownloadProgress: map[string]int64{ 534 res2.Name: 2, 535 }, 536 }, 537 { 538 Tag: tag1, 539 }, 540 }, 541 CharmStoreResources: []charmresource.Resource{ 542 chres1, 543 chres2, 544 }, 545 } 546 547 result := api.ApplicationResources2APIResult(svcRes) 548 549 apiRes1 := api.Resource2API(res1) 550 apiRes2 := api.Resource2API(res2) 551 552 apiChRes1 := api.CharmResource2API(chres1) 553 apiChRes2 := api.CharmResource2API(chres2) 554 555 c.Check(result, jc.DeepEquals, params.ResourcesResult{ 556 Resources: []params.Resource{ 557 apiRes1, 558 apiRes2, 559 }, 560 UnitResources: []params.UnitResources{ 561 { 562 Entity: params.Entity{ 563 Tag: "unit-a-application-0", 564 }, 565 Resources: []params.Resource{ 566 apiRes1, 567 apiRes2, 568 }, 569 DownloadProgress: map[string]int64{ 570 res2.Name: 2, 571 }, 572 }, 573 { 574 // we should have a listing for every unit, even if they 575 // have no resources. 576 Entity: params.Entity{ 577 Tag: "unit-a-application-1", 578 }, 579 }, 580 }, 581 CharmStoreResources: []params.CharmResource{ 582 apiChRes1, 583 apiChRes2, 584 }, 585 }) 586 }