1
// Copyright 2015 Canonical Ltd.
2
// Licensed under the AGPLv3, see LICENCE file for details.
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"
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"
23
const fingerprint = "123456789012345678901234567890123456789012345678"
25
func newFingerprint(c *gc.C, data string) charmresource.Fingerprint {
26
fp, err := charmresource.GenerateFingerprint(strings.NewReader(data))
27
c.Assert(err, jc.ErrorIsNil)
31
type HelpersSuite struct {
32
testing.IsolationSuite
35
var _ = gc.Suite(&HelpersSuite{})
37
func (HelpersSuite) TestResource2API(c *gc.C) {
38
fp, err := charmresource.NewFingerprint([]byte(fingerprint))
39
c.Assert(err, jc.ErrorIsNil)
41
res := resource.Resource{
42
Resource: charmresource.Resource{
43
Meta: charmresource.Meta{
45
Type: charmresource.TypeFile,
47
Description: "you need it",
49
Origin: charmresource.OriginUpload,
54
ID: "a-application/spam",
55
PendingID: "some-unique-ID",
56
ApplicationID: "a-application",
61
c.Assert(err, jc.ErrorIsNil)
62
apiRes := api.Resource2API(res)
64
c.Check(apiRes, jc.DeepEquals, api.Resource{
65
CharmResource: api.CharmResource{
69
Description: "you need it",
72
Fingerprint: []byte(fingerprint),
75
ID: "a-application/spam",
76
PendingID: "some-unique-ID",
77
ApplicationID: "a-application",
83
func (HelpersSuite) TestAPIResult2ServiceResourcesOkay(c *gc.C) {
84
fp, err := charmresource.NewFingerprint([]byte(fingerprint))
85
c.Assert(err, jc.ErrorIsNil)
87
expected := resource.Resource{
88
Resource: charmresource.Resource{
89
Meta: charmresource.Meta{
91
Type: charmresource.TypeFile,
93
Description: "you need it",
95
Origin: charmresource.OriginUpload,
100
ID: "a-application/spam",
101
PendingID: "some-unique-ID",
102
ApplicationID: "a-application",
106
err = expected.Validate()
107
c.Assert(err, jc.ErrorIsNil)
109
unitExpected := resource.Resource{
110
Resource: charmresource.Resource{
111
Meta: charmresource.Meta{
113
Type: charmresource.TypeFile,
114
Path: "unitspam.tgz",
115
Description: "you need it",
117
Origin: charmresource.OriginUpload,
122
ID: "a-application/spam",
123
PendingID: "some-unique-ID",
124
ApplicationID: "a-application",
128
err = unitExpected.Validate()
129
c.Assert(err, jc.ErrorIsNil)
131
apiRes := api.Resource{
132
CharmResource: api.CharmResource{
136
Description: "you need it",
139
Fingerprint: []byte(fingerprint),
142
ID: "a-application/spam",
143
PendingID: "some-unique-ID",
144
ApplicationID: "a-application",
149
unitRes := api.Resource{
150
CharmResource: api.CharmResource{
153
Path: "unitspam.tgz",
154
Description: "you need it",
157
Fingerprint: []byte(fingerprint),
160
ID: "a-application/spam",
161
PendingID: "some-unique-ID",
162
ApplicationID: "a-application",
167
fp2, err := charmresource.GenerateFingerprint(strings.NewReader("boo!"))
168
c.Assert(err, jc.ErrorIsNil)
170
chRes := api.CharmResource{
173
Path: "unitspam.tgz2",
174
Description: "you need it2",
177
Fingerprint: fp2.Bytes(),
181
chExpected := charmresource.Resource{
182
Meta: charmresource.Meta{
184
Type: charmresource.TypeFile,
185
Path: "unitspam.tgz2",
186
Description: "you need it2",
188
Origin: charmresource.OriginUpload,
194
resources, err := api.APIResult2ServiceResources(api.ResourcesResult{
195
Resources: []api.Resource{
198
CharmStoreResources: []api.CharmResource{
201
UnitResources: []api.UnitResources{
203
Entity: params.Entity{
206
Resources: []api.Resource{
209
DownloadProgress: map[string]int64{
215
c.Assert(err, jc.ErrorIsNil)
217
serviceResource := resource.ServiceResources{
218
Resources: []resource.Resource{
221
CharmStoreResources: []charmresource.Resource{
224
UnitResources: []resource.UnitResources{
226
Tag: names.NewUnitTag("foo/0"),
227
Resources: []resource.Resource{
230
DownloadProgress: map[string]int64{
237
c.Check(resources, jc.DeepEquals, serviceResource)
240
func (HelpersSuite) TestAPIResult2ServiceResourcesBadUnitTag(c *gc.C) {
241
fp, err := charmresource.NewFingerprint([]byte(fingerprint))
242
c.Assert(err, jc.ErrorIsNil)
244
expected := resource.Resource{
245
Resource: charmresource.Resource{
246
Meta: charmresource.Meta{
248
Type: charmresource.TypeFile,
250
Description: "you need it",
252
Origin: charmresource.OriginUpload,
257
ID: "a-application/spam",
258
PendingID: "some-unique-ID",
259
ApplicationID: "a-application",
263
err = expected.Validate()
264
c.Assert(err, jc.ErrorIsNil)
266
unitExpected := resource.Resource{
267
Resource: charmresource.Resource{
268
Meta: charmresource.Meta{
270
Type: charmresource.TypeFile,
271
Path: "unitspam.tgz",
272
Description: "you need it",
274
Origin: charmresource.OriginUpload,
279
ID: "a-application/spam",
280
PendingID: "some-unique-ID",
281
ApplicationID: "a-application",
285
err = unitExpected.Validate()
286
c.Assert(err, jc.ErrorIsNil)
288
apiRes := api.Resource{
289
CharmResource: api.CharmResource{
293
Description: "you need it",
296
Fingerprint: []byte(fingerprint),
299
ID: "a-application/spam",
300
PendingID: "some-unique-ID",
301
ApplicationID: "a-application",
306
unitRes := api.Resource{
307
CharmResource: api.CharmResource{
310
Path: "unitspam.tgz",
311
Description: "you need it",
314
Fingerprint: []byte(fingerprint),
317
ID: "a-application/spam",
318
PendingID: "some-unique-ID",
319
ApplicationID: "a-application",
324
_, err = api.APIResult2ServiceResources(api.ResourcesResult{
325
Resources: []api.Resource{
328
UnitResources: []api.UnitResources{
330
Entity: params.Entity{
331
Tag: "THIS IS NOT A GOOD UNIT TAG",
333
Resources: []api.Resource{
339
c.Assert(err, gc.ErrorMatches, ".*got bad data from server.*")
342
func (HelpersSuite) TestAPIResult2ServiceResourcesFailure(c *gc.C) {
343
apiRes := api.Resource{
344
CharmResource: api.CharmResource{
350
Fingerprint: []byte(fingerprint),
353
ID: "a-application/spam",
354
ApplicationID: "a-application",
356
failure := errors.New("<failure>")
358
_, err := api.APIResult2ServiceResources(api.ResourcesResult{
359
ErrorResult: params.ErrorResult{
360
Error: ¶ms.Error{
361
Message: failure.Error(),
364
Resources: []api.Resource{
369
c.Check(err, gc.ErrorMatches, "<failure>")
370
c.Check(errors.Cause(err), gc.Not(gc.Equals), failure)
373
func (HelpersSuite) TestAPIResult2ServiceResourcesNotFound(c *gc.C) {
374
apiRes := api.Resource{
375
CharmResource: api.CharmResource{
381
Fingerprint: []byte(fingerprint),
384
ID: "a-application/spam",
385
ApplicationID: "a-application",
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,
395
Resources: []api.Resource{
400
c.Check(err, jc.Satisfies, errors.IsNotFound)
403
func (HelpersSuite) TestAPI2Resource(c *gc.C) {
405
res, err := api.API2Resource(api.Resource{
406
CharmResource: api.CharmResource{
410
Description: "you need it",
413
Fingerprint: []byte(fingerprint),
416
ID: "a-application/spam",
417
PendingID: "some-unique-ID",
418
ApplicationID: "a-application",
422
c.Assert(err, jc.ErrorIsNil)
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{
430
Type: charmresource.TypeFile,
432
Description: "you need it",
434
Origin: charmresource.OriginUpload,
439
ID: "a-application/spam",
440
PendingID: "some-unique-ID",
441
ApplicationID: "a-application",
445
err = expected.Validate()
446
c.Assert(err, jc.ErrorIsNil)
448
c.Check(res, jc.DeepEquals, expected)
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{
457
Type: charmresource.TypeFile,
459
Description: "you need it",
461
Origin: charmresource.OriginUpload,
467
c.Assert(err, jc.ErrorIsNil)
468
apiInfo := api.CharmResource2API(res)
470
c.Check(apiInfo, jc.DeepEquals, api.CharmResource{
474
Description: "you need it",
477
Fingerprint: []byte(fingerprint),
482
func (HelpersSuite) TestAPI2CharmResource(c *gc.C) {
483
res, err := api.API2CharmResource(api.CharmResource{
487
Description: "you need it",
490
Fingerprint: []byte(fingerprint),
493
c.Assert(err, jc.ErrorIsNil)
495
fp, err := charmresource.NewFingerprint([]byte(fingerprint))
496
c.Assert(err, jc.ErrorIsNil)
497
expected := charmresource.Resource{
498
Meta: charmresource.Meta{
500
Type: charmresource.TypeFile,
502
Description: "you need it",
504
Origin: charmresource.OriginUpload,
509
err = expected.Validate()
510
c.Assert(err, jc.ErrorIsNil)
512
c.Check(res, jc.DeepEquals, expected)
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
519
tag0 := names.NewUnitTag("a-application/0")
520
tag1 := names.NewUnitTag("a-application/1")
522
chres1 := res1.Resource
523
chres2 := res2.Resource
527
svcRes := resource.ServiceResources{
528
Resources: []resource.Resource{
532
UnitResources: []resource.UnitResources{
535
Resources: []resource.Resource{
539
DownloadProgress: map[string]int64{
547
CharmStoreResources: []charmresource.Resource{
553
result := api.ServiceResources2APIResult(svcRes)
555
apiRes1 := api.Resource2API(res1)
556
apiRes2 := api.Resource2API(res2)
558
apiChRes1 := api.CharmResource2API(chres1)
559
apiChRes2 := api.CharmResource2API(chres2)
561
c.Check(result, jc.DeepEquals, api.ResourcesResult{
562
Resources: []api.Resource{
566
UnitResources: []api.UnitResources{
568
Entity: params.Entity{
569
Tag: "unit-a-application-0",
571
Resources: []api.Resource{
575
DownloadProgress: map[string]int64{
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",
587
CharmStoreResources: []api.CharmResource{