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