// ListResources calls the ListResources API server method with // the given service names. func (c Client) ListResources(services []string) ([]resource.ServiceResources, error) { args, err := api.NewListResourcesArgs(services) if err != nil { return nil, errors.Trace(err) } var apiResults api.ResourcesResults if err := c.FacadeCall("ListResources", &args, &apiResults); err != nil { return nil, errors.Trace(err) } if len(apiResults.Results) != len(services) { // We don't bother returning the results we *did* get since // something bad happened on the server. return nil, errors.Errorf("got invalid data from server (expected %d results, got %d)", len(services), len(apiResults.Results)) } var errs []error results := make([]resource.ServiceResources, len(services)) for i := range services { apiResult := apiResults.Results[i] result, err := api.APIResult2ServiceResources(apiResult) if err != nil { errs = append(errs, errors.Trace(err)) } results[i] = result } if err := resolveErrors(errs); err != nil { return nil, errors.Trace(err) } return results, nil }
func (helpersSuite) TestAPIResult2ServiceResourcesNotFound(c *gc.C) { apiRes := api.Resource{ CharmResource: api.CharmResource{ Name: "spam", Type: "file", Path: "spam.tgz", Origin: "upload", Revision: 1, Fingerprint: []byte(fingerprint), Size: 10, }, ID: "a-service/spam", ServiceID: "a-service", } _, err := api.APIResult2ServiceResources(api.ResourcesResult{ ErrorResult: params.ErrorResult{ Error: ¶ms.Error{ Message: `service "a-service" not found`, Code: params.CodeNotFound, }, }, Resources: []api.Resource{ apiRes, }, }) c.Check(err, jc.Satisfies, errors.IsNotFound) }
func (helpersSuite) TestAPIResult2ServiceResourcesFailure(c *gc.C) { apiRes := api.Resource{ CharmResource: api.CharmResource{ Name: "spam", Type: "file", Path: "spam.tgz", Origin: "upload", Revision: 1, Fingerprint: []byte(fingerprint), Size: 10, }, ID: "a-service/spam", ServiceID: "a-service", } failure := errors.New("<failure>") _, err := api.APIResult2ServiceResources(api.ResourcesResult{ ErrorResult: params.ErrorResult{ Error: ¶ms.Error{ Message: failure.Error(), }, }, Resources: []api.Resource{ apiRes, }, }) c.Check(err, gc.ErrorMatches, "<failure>") c.Check(errors.Cause(err), gc.Not(gc.Equals), failure) }
func (helpersSuite) TestAPIResult2ServiceResourcesOkay(c *gc.C) { fp, err := charmresource.NewFingerprint([]byte(fingerprint)) c.Assert(err, jc.ErrorIsNil) now := time.Now() expected := resource.Resource{ Resource: charmresource.Resource{ Meta: charmresource.Meta{ Name: "spam", Type: charmresource.TypeFile, Path: "spam.tgz", Description: "you need it", }, Origin: charmresource.OriginUpload, Revision: 1, Fingerprint: fp, Size: 10, }, ID: "a-service/spam", PendingID: "some-unique-ID", ServiceID: "a-service", Username: "******", Timestamp: now, } err = expected.Validate() c.Assert(err, jc.ErrorIsNil) unitExpected := resource.Resource{ Resource: charmresource.Resource{ Meta: charmresource.Meta{ Name: "unitspam", Type: charmresource.TypeFile, Path: "unitspam.tgz", Description: "you need it", }, Origin: charmresource.OriginUpload, Revision: 1, Fingerprint: fp, Size: 10, }, ID: "a-service/spam", PendingID: "some-unique-ID", ServiceID: "a-service", Username: "******", Timestamp: now, } err = unitExpected.Validate() c.Assert(err, jc.ErrorIsNil) apiRes := api.Resource{ CharmResource: api.CharmResource{ Name: "spam", Type: "file", Path: "spam.tgz", Description: "you need it", Origin: "upload", Revision: 1, Fingerprint: []byte(fingerprint), Size: 10, }, ID: "a-service/spam", PendingID: "some-unique-ID", ServiceID: "a-service", Username: "******", Timestamp: now, } unitRes := api.Resource{ CharmResource: api.CharmResource{ Name: "unitspam", Type: "file", Path: "unitspam.tgz", Description: "you need it", Origin: "upload", Revision: 1, Fingerprint: []byte(fingerprint), Size: 10, }, ID: "a-service/spam", PendingID: "some-unique-ID", ServiceID: "a-service", Username: "******", Timestamp: now, } resources, err := api.APIResult2ServiceResources(api.ResourcesResult{ Resources: []api.Resource{ apiRes, }, UnitResources: []api.UnitResources{ { Entity: params.Entity{ Tag: "unit-foo-0", }, Resources: []api.Resource{ unitRes, }, }, }, }) c.Assert(err, jc.ErrorIsNil) serviceResource := resource.ServiceResources{ Resources: []resource.Resource{ expected, }, UnitResources: []resource.UnitResources{ { Tag: names.NewUnitTag("foo/0"), Resources: []resource.Resource{ unitExpected, }, }, }, } c.Check(resources, jc.DeepEquals, serviceResource) }
func (helpersSuite) TestAPIResult2ServiceResourcesBadUnitTag(c *gc.C) { fp, err := charmresource.NewFingerprint([]byte(fingerprint)) c.Assert(err, jc.ErrorIsNil) now := time.Now() expected := resource.Resource{ Resource: charmresource.Resource{ Meta: charmresource.Meta{ Name: "spam", Type: charmresource.TypeFile, Path: "spam.tgz", Description: "you need it", }, Origin: charmresource.OriginUpload, Revision: 1, Fingerprint: fp, Size: 10, }, ID: "a-service/spam", PendingID: "some-unique-ID", ServiceID: "a-service", Username: "******", Timestamp: now, } err = expected.Validate() c.Assert(err, jc.ErrorIsNil) unitExpected := resource.Resource{ Resource: charmresource.Resource{ Meta: charmresource.Meta{ Name: "unitspam", Type: charmresource.TypeFile, Path: "unitspam.tgz", Description: "you need it", }, Origin: charmresource.OriginUpload, Revision: 1, Fingerprint: fp, Size: 10, }, ID: "a-service/spam", PendingID: "some-unique-ID", ServiceID: "a-service", Username: "******", Timestamp: now, } err = unitExpected.Validate() c.Assert(err, jc.ErrorIsNil) apiRes := api.Resource{ CharmResource: api.CharmResource{ Name: "spam", Type: "file", Path: "spam.tgz", Description: "you need it", Origin: "upload", Revision: 1, Fingerprint: []byte(fingerprint), Size: 10, }, ID: "a-service/spam", PendingID: "some-unique-ID", ServiceID: "a-service", Username: "******", Timestamp: now, } unitRes := api.Resource{ CharmResource: api.CharmResource{ Name: "unitspam", Type: "file", Path: "unitspam.tgz", Description: "you need it", Origin: "upload", Revision: 1, Fingerprint: []byte(fingerprint), Size: 10, }, ID: "a-service/spam", PendingID: "some-unique-ID", ServiceID: "a-service", Username: "******", Timestamp: now, } _, err = api.APIResult2ServiceResources(api.ResourcesResult{ Resources: []api.Resource{ apiRes, }, UnitResources: []api.UnitResources{ { Entity: params.Entity{ Tag: "THIS IS NOT A GOOD UNIT TAG", }, Resources: []api.Resource{ unitRes, }, }, }, }) c.Assert(err, gc.ErrorMatches, ".*got bad data from server.*") }
func (HelpersSuite) TestAPIResult2ServiceResourcesOkay(c *gc.C) { fp, err := charmresource.NewFingerprint([]byte(fingerprint)) c.Assert(err, jc.ErrorIsNil) now := time.Now() expected := resource.Resource{ Resource: charmresource.Resource{ Meta: charmresource.Meta{ Name: "spam", Type: charmresource.TypeFile, Path: "spam.tgz", Description: "you need it", }, Origin: charmresource.OriginUpload, Revision: 1, Fingerprint: fp, Size: 10, }, ID: "a-application/spam", PendingID: "some-unique-ID", ApplicationID: "a-application", Username: "******", Timestamp: now, } err = expected.Validate() c.Assert(err, jc.ErrorIsNil) unitExpected := resource.Resource{ Resource: charmresource.Resource{ Meta: charmresource.Meta{ Name: "unitspam", Type: charmresource.TypeFile, Path: "unitspam.tgz", Description: "you need it", }, Origin: charmresource.OriginUpload, Revision: 1, Fingerprint: fp, Size: 10, }, ID: "a-application/spam", PendingID: "some-unique-ID", ApplicationID: "a-application", Username: "******", Timestamp: now, } err = unitExpected.Validate() c.Assert(err, jc.ErrorIsNil) apiRes := api.Resource{ CharmResource: api.CharmResource{ Name: "spam", Type: "file", Path: "spam.tgz", Description: "you need it", Origin: "upload", Revision: 1, Fingerprint: []byte(fingerprint), Size: 10, }, ID: "a-application/spam", PendingID: "some-unique-ID", ApplicationID: "a-application", Username: "******", Timestamp: now, } unitRes := api.Resource{ CharmResource: api.CharmResource{ Name: "unitspam", Type: "file", Path: "unitspam.tgz", Description: "you need it", Origin: "upload", Revision: 1, Fingerprint: []byte(fingerprint), Size: 10, }, ID: "a-application/spam", PendingID: "some-unique-ID", ApplicationID: "a-application", Username: "******", Timestamp: now, } fp2, err := charmresource.GenerateFingerprint(strings.NewReader("boo!")) c.Assert(err, jc.ErrorIsNil) chRes := api.CharmResource{ Name: "unitspam2", Type: "file", Path: "unitspam.tgz2", Description: "you need it2", Origin: "upload", Revision: 2, Fingerprint: fp2.Bytes(), Size: 11, } chExpected := charmresource.Resource{ Meta: charmresource.Meta{ Name: "unitspam2", Type: charmresource.TypeFile, Path: "unitspam.tgz2", Description: "you need it2", }, Origin: charmresource.OriginUpload, Revision: 2, Fingerprint: fp2, Size: 11, } resources, err := api.APIResult2ServiceResources(api.ResourcesResult{ Resources: []api.Resource{ apiRes, }, CharmStoreResources: []api.CharmResource{ chRes, }, UnitResources: []api.UnitResources{ { Entity: params.Entity{ Tag: "unit-foo-0", }, Resources: []api.Resource{ unitRes, }, DownloadProgress: map[string]int64{ unitRes.Name: 8, }, }, }, }) c.Assert(err, jc.ErrorIsNil) serviceResource := resource.ServiceResources{ Resources: []resource.Resource{ expected, }, CharmStoreResources: []charmresource.Resource{ chExpected, }, UnitResources: []resource.UnitResources{ { Tag: names.NewUnitTag("foo/0"), Resources: []resource.Resource{ unitExpected, }, DownloadProgress: map[string]int64{ unitRes.Name: 8, }, }, }, } c.Check(resources, jc.DeepEquals, serviceResource) }