func (s *DetailFormatterSuite) TestFormatDetail(c *gc.C) { fp, err := charmresource.GenerateFingerprint(strings.NewReader("something")) c.Assert(err, jc.ErrorIsNil) svc := resource.Resource{ Resource: charmresource.Resource{ Meta: charmresource.Meta{ Name: "website", Description: "your website data", Type: charmresource.TypeFile, Path: "foobar", }, Revision: 5, Origin: charmresource.OriginStore, Fingerprint: fp, Size: 10, }, Username: "******", Timestamp: time.Now().Add(-1 * time.Hour * 24 * 365), ID: "a-service/website", ServiceID: "a-service", } fp2, err := charmresource.GenerateFingerprint(strings.NewReader("other")) c.Assert(err, jc.ErrorIsNil) unit := resource.Resource{ Resource: charmresource.Resource{ Meta: charmresource.Meta{ Name: "website", Description: "your website data", Type: charmresource.TypeFile, Path: "foobar", }, Revision: 7, Origin: charmresource.OriginStore, Fingerprint: fp2, Size: 15, }, Username: "******", Timestamp: time.Now(), ID: "a-service/website", ServiceID: "a-service", } tag := names.NewUnitTag("a-service/55") d, err := FormatDetailResource(tag, svc, unit, 8) c.Assert(err, jc.ErrorIsNil) c.Assert(d, gc.Equals, FormattedDetailResource{ unitNumber: 55, UnitID: "a-service/55", Expected: FormatSvcResource(svc), Progress: 8, progress: "80%", revProgress: "5 (fetching: 80%)", Unit: FormatSvcResource(unit), }, ) }
func (s *ClientSuite) TestResourceInfo(c *gc.C) { fp, err := resource.GenerateFingerprint(strings.NewReader("data")) c.Assert(err, jc.ErrorIsNil) apiRes := params.Resource{ Name: "name", Type: "file", Path: "foo.zip", Description: "something", Origin: "store", Revision: 5, Fingerprint: fp.Bytes(), Size: 4, } s.wrapper.ReturnResourceMeta = apiRes client, err := newCachingClient(s.cache, nil, s.wrapper.makeWrapper) c.Assert(err, jc.ErrorIsNil) req := ResourceRequest{ Charm: charm.MustParseURL("cs:mysql"), Channel: params.StableChannel, Name: "name", Revision: 5, } res, err := client.ResourceInfo(req) c.Assert(err, jc.ErrorIsNil) expected, err := params.API2Resource(apiRes) c.Assert(err, jc.ErrorIsNil) c.Check(res, gc.DeepEquals, expected) // call #0 is a call to makeWrapper s.wrapper.stub.CheckCall(c, 1, "ResourceMeta", params.StableChannel, req.Charm, req.Name, req.Revision) }
func (s *UploadSuite) TestPendingOkay(c *gc.C) { res, apiResult := newResourceResult(c, "a-service", "spam") uuid, err := utils.NewUUID() c.Assert(err, jc.ErrorIsNil) expected := uuid.String() s.response.Resource = apiResult.Resources[0] data := "<data>" fp, err := charmresource.GenerateFingerprint(strings.NewReader(data)) c.Assert(err, jc.ErrorIsNil) req, err := http.NewRequest("PUT", "/services/a-service/resources/spam", nil) c.Assert(err, jc.ErrorIsNil) req.Header.Set("Content-Type", "application/octet-stream") req.Header.Set("Content-SHA384", fp.String()) req.Header.Set("Content-Length", fmt.Sprint(len(data))) req.ContentLength = int64(len(data)) req.URL.RawQuery = "pendingid=" + expected reader := &stubFile{stub: s.stub} reader.returnRead = strings.NewReader(data) s.facade.pendingIDs = []string{expected} cl := client.NewClient(s.facade, s, s.facade) uploadID, err := cl.AddPendingResource("a-service", res[0].Resource, reader) c.Assert(err, jc.ErrorIsNil) s.stub.CheckCallNames(c, "FacadeCall", "Read", "Read", "Seek", "Do", ) s.stub.CheckCall(c, 4, "Do", req, reader, s.response) c.Check(uploadID, gc.Equals, expected) }
func resourceHash(content string) charmresource.Fingerprint { fp, err := charmresource.GenerateFingerprint(strings.NewReader(content)) if err != nil { panic(err) } return fp }
func (s *UtilsSuite) newReader(c *gc.C, content string) (io.ReadCloser, charmresource.Fingerprint) { r := filetesting.NewStubFile(s.stub, bytes.NewBufferString(content)) tmpReader := strings.NewReader(content) fp, err := charmresource.GenerateFingerprint(tmpReader) c.Assert(err, jc.ErrorIsNil) return r, fp }
func (s *InternalClientSuite) TestListResources(c *gc.C) { fp, err := resource.GenerateFingerprint(strings.NewReader("data")) c.Assert(err, jc.ErrorIsNil) stable := params.Resource{ Name: "name", Type: "file", Path: "foo.zip", Description: "something", Origin: "store", Revision: 5, Fingerprint: fp.Bytes(), Size: 4, } dev := params.Resource{ Name: "name2", Type: "file", Path: "bar.zip", Description: "something", Origin: "store", Revision: 7, Fingerprint: fp.Bytes(), Size: 4, } s.lowLevel.ReturnListResourcesStable = map[string][]params.Resource{ "cs:quantal/foo-1": []params.Resource{stable}, } s.lowLevel.ReturnListResourcesDev = map[string][]params.Resource{ "cs:quantal/bar-1": []params.Resource{dev}, } client := Client{lowLevel: s.lowLevel} foo := charm.MustParseURL("cs:quantal/foo-1") bar := charm.MustParseURL("cs:quantal/bar-1") ret, err := client.ListResources([]CharmID{{ URL: foo, Channel: "stable", }, { URL: bar, Channel: "development", }}) c.Assert(err, jc.ErrorIsNil) stableOut, err := params.API2Resource(stable) c.Assert(err, jc.ErrorIsNil) devOut, err := params.API2Resource(dev) c.Assert(err, jc.ErrorIsNil) c.Assert(ret, gc.DeepEquals, [][]resource.Resource{ {stableOut}, {devOut}, }) s.lowLevel.stableStub.CheckCall(c, 0, "ListResources", params.StableChannel, []*charm.URL{foo}) s.lowLevel.devStub.CheckCall(c, 0, "ListResources", params.DevelopmentChannel, []*charm.URL{bar}) }
func (s *SerializationSuite) TestDeserializeFingerprintOkay(c *gc.C) { content := "some data\n..." expected, err := charmresource.GenerateFingerprint(strings.NewReader(content)) c.Assert(err, jc.ErrorIsNil) fp, err := resource.DeserializeFingerprint(expected.Bytes()) c.Assert(err, jc.ErrorIsNil) c.Check(fp, jc.DeepEquals, expected) }
func (s *ResourcesMongoSuite) TestResource2DocCharmstoreFull(c *gc.C) { content := "some data\n..." fp, err := charmresource.GenerateFingerprint(strings.NewReader(content)) c.Assert(err, jc.ErrorIsNil) now := time.Now().UTC() applicationID := "a-application" docID := applicationResourceID("spam") res := resource.Resource{ Resource: charmresource.Resource{ Meta: charmresource.Meta{ Name: "spam", Type: charmresource.TypeFile, Path: "spam.tgz", Description: "you need this!", }, Origin: charmresource.OriginStore, Revision: 5, Fingerprint: fp, Size: int64(len(content)), }, ID: "a-application/spam", PendingID: "some-unique-ID", ApplicationID: applicationID, Username: "******", Timestamp: now, } doc := resource2doc(docID, storedResource{ Resource: res, storagePath: "application-a-application/resources/spam", }) c.Check(doc, jc.DeepEquals, &resourceDoc{ DocID: docID, ID: res.ID, PendingID: "some-unique-ID", ApplicationID: applicationID, Name: "spam", Type: "file", Path: "spam.tgz", Description: "you need this!", Origin: "store", Revision: 5, Fingerprint: fp.Bytes(), Size: int64(len(content)), Username: "******", Timestamp: now, StoragePath: "application-a-application/resources/spam", }) }
func (s *ListCharmSuite) TestChannelFlag(c *gc.C) { fp1, err := charmresource.GenerateFingerprint(strings.NewReader("abc")) c.Assert(err, jc.ErrorIsNil) fp2, err := charmresource.GenerateFingerprint(strings.NewReader("xyz")) c.Assert(err, jc.ErrorIsNil) resources := []charmresource.Resource{ charmRes(c, "website", ".tgz", ".tgz of your website", string(fp1.Bytes())), charmRes(c, "music", ".mp3", "mp3 of your backing vocals", string(fp2.Bytes())), } s.client.ReturnListResources = [][]charmresource.Resource{resources} command := NewListCharmResourcesCommand(s.client) code, _, stderr := runCmd(c, command, "--channel", "development", "cs:a-charm", ) c.Check(code, gc.Equals, 0) c.Check(stderr, gc.Equals, "") c.Check(command.channel, gc.Equals, "development") }
func (s *ResourcesMongoSuite) TestDoc2BasicResourceCharmstoreFull(c *gc.C) { serviceID := "a-service" docID := serviceResourceID("spam") content := "some data\n..." fp, err := charmresource.GenerateFingerprint(strings.NewReader(content)) c.Assert(err, jc.ErrorIsNil) now := time.Now().UTC() res, err := doc2basicResource(resourceDoc{ DocID: docID, ID: "a-service/spam", PendingID: "some-unique-ID", ServiceID: serviceID, Name: "spam", Type: "file", Path: "spam.tgz", Description: "you need this!", Origin: "store", Revision: 5, Fingerprint: fp.Bytes(), Size: int64(len(content)), Username: "******", Timestamp: now, StoragePath: "service-a-service/resources/spam", }) c.Assert(err, jc.ErrorIsNil) c.Check(res, jc.DeepEquals, resource.Resource{ Resource: charmresource.Resource{ Meta: charmresource.Meta{ Name: "spam", Type: charmresource.TypeFile, Path: "spam.tgz", Description: "you need this!", }, Origin: charmresource.OriginStore, Revision: 5, Fingerprint: fp, Size: int64(len(content)), }, ID: "a-service/spam", PendingID: "some-unique-ID", ServiceID: serviceID, Username: "******", Timestamp: now, }) }
func (s *ResourcesMongoSuite) TestDoc2BasicResourceUploadFull(c *gc.C) { applicationID := "a-application" docID := pendingResourceID("spam", "some-unique-ID-001") content := "some data\n..." fp, err := charmresource.GenerateFingerprint(strings.NewReader(content)) c.Assert(err, jc.ErrorIsNil) now := time.Now().UTC() res, err := doc2basicResource(resourceDoc{ DocID: docID, ID: "a-application/spam", ApplicationID: applicationID, PendingID: "some-unique-ID-001", Name: "spam", Type: "file", Path: "spam.tgz", Description: "you need this!", Origin: "upload", Revision: 0, Fingerprint: fp.Bytes(), Size: int64(len(content)), Username: "******", Timestamp: now, StoragePath: "application-a-application/resources/spam", }) c.Assert(err, jc.ErrorIsNil) c.Check(res, jc.DeepEquals, resource.Resource{ Resource: charmresource.Resource{ Meta: charmresource.Meta{ Name: "spam", Type: charmresource.TypeFile, Path: "spam.tgz", Description: "you need this!", }, Origin: charmresource.OriginUpload, Revision: 0, Fingerprint: fp, Size: int64(len(content)), }, ID: "a-application/spam", PendingID: "some-unique-ID-001", ApplicationID: applicationID, Username: "******", Timestamp: now, }) }
func (s *ResourcesMongoSuite) TestResource2DocUploadPending(c *gc.C) { content := "some data\n..." fp, err := charmresource.GenerateFingerprint(strings.NewReader(content)) c.Assert(err, jc.ErrorIsNil) now := coretesting.ZeroTime() applicationID := "a-application" docID := pendingResourceID("spam", "some-unique-ID-001") res := resource.Resource{ Resource: charmresource.Resource{ Meta: charmresource.Meta{ Name: "spam", Type: charmresource.TypeFile, Path: "spam.tgz", }, Origin: charmresource.OriginUpload, Fingerprint: fp, Size: int64(len(content)), }, ID: applicationID + "/spam", PendingID: "some-unique-ID-001", ApplicationID: applicationID, Username: "******", Timestamp: now, } doc := resource2doc(docID, storedResource{ Resource: res, storagePath: "application-a-application/resources/spam", }) c.Check(doc, jc.DeepEquals, &resourceDoc{ DocID: docID, ID: res.ID, PendingID: "some-unique-ID-001", ApplicationID: applicationID, Name: "spam", Type: "file", Path: "spam.tgz", Origin: "upload", Fingerprint: fp.Bytes(), Size: int64(len(content)), Username: "******", Timestamp: now, StoragePath: "application-a-application/resources/spam", }) }
func (s *ResourcesMongoSuite) TestDoc2Resource(c *gc.C) { serviceID := "a-service" docID := pendingResourceID("spam", "some-unique-ID-001") content := "some data\n..." fp, err := charmresource.GenerateFingerprint(strings.NewReader(content)) c.Assert(err, jc.ErrorIsNil) now := time.Now().UTC() res, err := doc2resource(resourceDoc{ DocID: docID, ID: "a-service/spam", PendingID: "some-unique-ID-001", ServiceID: serviceID, Name: "spam", Type: "file", Path: "spam.tgz", Origin: "upload", Fingerprint: fp.Bytes(), Size: int64(len(content)), Username: "******", Timestamp: now, StoragePath: "service-a-service/resources/spam-some-unique-ID-001", }) c.Assert(err, jc.ErrorIsNil) c.Check(res, jc.DeepEquals, storedResource{ Resource: resource.Resource{ Resource: charmresource.Resource{ Meta: charmresource.Meta{ Name: "spam", Type: charmresource.TypeFile, Path: "spam.tgz", }, Origin: charmresource.OriginUpload, Fingerprint: fp, Size: int64(len(content)), }, ID: "a-service/spam", PendingID: "some-unique-ID-001", ServiceID: serviceID, Username: "******", Timestamp: now, }, storagePath: "service-a-service/resources/spam-some-unique-ID-001", }) }
func fakeParamsResource(name string, data []byte) params.Resource { fp, err := resource.GenerateFingerprint(bytes.NewReader(data)) if err != nil { panic(err) } return params.Resource{ Name: name, Type: "file", Path: name + ".tgz", Description: "something about " + name, Revision: len(name), Fingerprint: fp.Bytes(), Size: int64(len(data)), } }
func (s *ResourcesMongoSuite) TestResource2DocUploadBasic(c *gc.C) { content := "some data\n..." fp, err := charmresource.GenerateFingerprint(strings.NewReader(content)) c.Assert(err, jc.ErrorIsNil) now := time.Now().UTC() serviceID := "a-service" docID := serviceResourceID("spam") res := resource.Resource{ Resource: charmresource.Resource{ Meta: charmresource.Meta{ Name: "spam", Type: charmresource.TypeFile, Path: "spam.tgz", }, Origin: charmresource.OriginUpload, Fingerprint: fp, Size: int64(len(content)), }, ID: serviceID + "/spam", ServiceID: serviceID, Username: "******", Timestamp: now, } doc := resource2doc(docID, storedResource{ Resource: res, storagePath: "service-a-service/resources/spam", }) c.Check(doc, jc.DeepEquals, &resourceDoc{ DocID: docID, ID: res.ID, ServiceID: serviceID, Name: "spam", Type: "file", Path: "spam.tgz", Origin: "upload", Fingerprint: fp.Bytes(), Size: int64(len(content)), Username: "******", Timestamp: now, StoragePath: "service-a-service/resources/spam", }) }
func (s *ResourcesMongoSuite) TestCharmStoreResource2DocFull(c *gc.C) { content := "some data\n..." fp, err := charmresource.GenerateFingerprint(strings.NewReader(content)) c.Assert(err, jc.ErrorIsNil) now := time.Now().UTC() applicationID := "a-application" id := applicationID + "/spam" docID := applicationResourceID("spam") + "#charmstore" res := charmresource.Resource{ Meta: charmresource.Meta{ Name: "spam", Type: charmresource.TypeFile, Path: "spam.tgz", Description: "you need this!", }, Origin: charmresource.OriginStore, Revision: 3, Fingerprint: fp, Size: int64(len(content)), } doc := charmStoreResource2Doc(docID, charmStoreResource{ Resource: res, id: id, applicationID: applicationID, lastPolled: now, }) c.Check(doc, jc.DeepEquals, &resourceDoc{ DocID: docID, ID: id, ApplicationID: applicationID, Name: "spam", Type: "file", Path: "spam.tgz", Description: "you need this!", Origin: "store", Revision: 3, Fingerprint: fp.Bytes(), Size: int64(len(content)), LastPolled: now, }) }
func (s *UpgradeCharmResourceSuite) TestUpgradeWithResources(c *gc.C) { myriakPath := testcharms.Repo.ClonedDir(c.MkDir(), "riak") err := ioutil.WriteFile(path.Join(myriakPath.Path, "metadata.yaml"), riakResourceMeta, 0644) c.Assert(err, jc.ErrorIsNil) data := []byte("some-data") fp, err := charmresource.GenerateFingerprint(bytes.NewReader(data)) c.Assert(err, jc.ErrorIsNil) resourceFile := path.Join(c.MkDir(), "data.lib") err = ioutil.WriteFile(resourceFile, data, 0644) c.Assert(err, jc.ErrorIsNil) _, err = testing.RunCommand(c, application.NewUpgradeCharmCommand(), "riak", "--path="+myriakPath.Path, "--resource", "data="+resourceFile) c.Assert(err, jc.ErrorIsNil) resources, err := s.State.Resources() c.Assert(err, jc.ErrorIsNil) sr, err := resources.ListResources("riak") c.Assert(err, jc.ErrorIsNil) c.Check(sr.Resources, gc.HasLen, 1) c.Check(sr.Resources[0].ApplicationID, gc.Equals, "riak") // Most of this is just a sanity check... this is all tested elsewhere. c.Check(sr.Resources[0].PendingID, gc.Equals, "") c.Check(sr.Resources[0].Username, gc.Not(gc.Equals), "") c.Check(sr.Resources[0].ID, gc.Not(gc.Equals), "") c.Check(sr.Resources[0].Timestamp.IsZero(), jc.IsFalse) // Ensure we get the data we passed in from the metadata.yaml. c.Check(sr.Resources[0].Resource, gc.DeepEquals, charmresource.Resource{ Meta: charmresource.Meta{ Name: "data", Type: charmresource.TypeFile, Path: "foo.lib", Description: "some comment", }, Origin: charmresource.OriginUpload, Fingerprint: fp, Size: int64(len(data)), }) }
func (s *ResourcesMongoSuite) TestDoc2BasicResourceUploadBasic(c *gc.C) { applicationID := "a-application" docID := applicationResourceID("spam") content := "some data\n..." fp, err := charmresource.GenerateFingerprint(strings.NewReader(content)) c.Assert(err, jc.ErrorIsNil) now := coretesting.NonZeroTime() res, err := doc2basicResource(resourceDoc{ DocID: docID, ID: "a-application/spam", ApplicationID: applicationID, Name: "spam", Type: "file", Path: "spam.tgz", Origin: "upload", Fingerprint: fp.Bytes(), Size: int64(len(content)), Username: "******", Timestamp: now, StoragePath: "application-a-application/resources/spam", }) c.Assert(err, jc.ErrorIsNil) c.Check(res, jc.DeepEquals, resource.Resource{ Resource: charmresource.Resource{ Meta: charmresource.Meta{ Name: "spam", Type: charmresource.TypeFile, Path: "spam.tgz", }, Origin: charmresource.OriginUpload, Fingerprint: fp, Size: int64(len(content)), }, ID: "a-application/spam", ApplicationID: applicationID, Username: "******", Timestamp: now, }) }
func newUploadRequest(c *gc.C, name, service, content string) (*http.Request, io.Reader) { fp, err := charmresource.GenerateFingerprint(strings.NewReader(content)) c.Assert(err, jc.ErrorIsNil) method := "PUT" urlStr := "https://api:17017/services/%s/resources/%s" urlStr += "?:service=%s&:resource=%s" // ...added by the mux. urlStr = fmt.Sprintf(urlStr, service, name, service, name) body := strings.NewReader(content) req, err := http.NewRequest(method, urlStr, body) c.Assert(err, jc.ErrorIsNil) req.Header.Set("Content-Type", "application/octet-stream") req.Header.Set("Content-Length", fmt.Sprint(len(content))) req.Header.Set("Content-SHA384", fp.String()) return req, body }
// GenerateContent returns a new Content for the given data stream. func GenerateContent(reader io.ReadSeeker) (Content, error) { var sizer utils.SizeTracker sizingReader := io.TeeReader(reader, &sizer) fp, err := charmresource.GenerateFingerprint(sizingReader) if err != nil { return Content{}, errors.Trace(err) } if _, err := reader.Seek(0, os.SEEK_SET); err != nil { return Content{}, errors.Trace(err) } size := sizer.Size() content := Content{ Data: reader, Size: size, Fingerprint: fp, } return content, nil }
// NewCharmResource produces basic resource info for the given name // and content. The origin is set set to "upload". func NewCharmResource(c *gc.C, name, content string) charmresource.Resource { fp, err := charmresource.GenerateFingerprint(strings.NewReader(content)) c.Assert(err, jc.ErrorIsNil) res := charmresource.Resource{ Meta: charmresource.Meta{ Name: name, Type: charmresource.TypeFile, Path: name + ".tgz", }, Origin: charmresource.OriginUpload, Revision: 0, Fingerprint: fp, Size: int64(len(content)), } err = res.Validate() c.Assert(err, jc.ErrorIsNil) return res }
func (s *SvcFormatterSuite) TestFormatSvcResource(c *gc.C) { fp, err := charmresource.GenerateFingerprint(strings.NewReader("something")) c.Assert(err, jc.ErrorIsNil) r := resource.Resource{ Resource: charmresource.Resource{ Meta: charmresource.Meta{ Name: "website", Description: "your website data", Type: charmresource.TypeFile, Path: "foobar", }, Revision: 5, Origin: charmresource.OriginStore, Fingerprint: fp, Size: 10, }, Username: "******", Timestamp: time.Now().Add(-1 * time.Hour * 24 * 365), ID: "a-service/website", ServiceID: "a-service", } f := FormatSvcResource(r) c.Assert(f, gc.Equals, FormattedSvcResource{ ID: "a-service/website", ServiceID: "a-service", Name: r.Name, Type: "file", Path: r.Path, Used: true, Revision: r.Revision, Origin: "store", Fingerprint: fp.String(), Size: 10, Description: r.Description, Timestamp: r.Timestamp, Username: r.Username, combinedRevision: "5", usedYesNo: "yes", combinedOrigin: "charmstore", }) }
func (s *UploadSuite) TestOkay(c *gc.C) { data := "<data>" _, s.response.Resource = newResource(c, "spam", "a-user", data) fp, err := charmresource.GenerateFingerprint(strings.NewReader(data)) c.Assert(err, jc.ErrorIsNil) req, err := http.NewRequest("PUT", "/services/a-service/resources/spam", nil) c.Assert(err, jc.ErrorIsNil) req.Header.Set("Content-Type", "application/octet-stream") req.Header.Set("Content-SHA384", fp.String()) req.Header.Set("Content-Length", fmt.Sprint(len(data))) req.ContentLength = int64(len(data)) reader := &stubFile{stub: s.stub} reader.returnRead = strings.NewReader(data) cl := client.NewClient(s.facade, s, s.facade) err = cl.Upload("a-service", "spam", reader) c.Assert(err, jc.ErrorIsNil) s.stub.CheckCallNames(c, "Read", "Read", "Seek", "Do") s.stub.CheckCall(c, 3, "Do", req, reader, s.response) }
func (s *ClientSuite) TestGetResource(c *gc.C) { fp, err := resource.GenerateFingerprint(strings.NewReader("data")) c.Assert(err, jc.ErrorIsNil) rc := ioutil.NopCloser(strings.NewReader("data")) s.wrapper.ReturnGetResource = csclient.ResourceData{ ReadCloser: rc, Hash: fp.String(), Size: 4, } apiRes := params.Resource{ Name: "name", Type: "file", Path: "foo.zip", Description: "something", Origin: "store", Revision: 5, Fingerprint: fp.Bytes(), Size: 4, } s.wrapper.ReturnResourceMeta = apiRes client, err := newCachingClient(s.cache, nil, s.wrapper.makeWrapper) c.Assert(err, jc.ErrorIsNil) req := ResourceRequest{ Charm: charm.MustParseURL("cs:mysql"), Channel: params.DevelopmentChannel, Name: "name", Revision: 5, } data, err := client.GetResource(req) c.Assert(err, jc.ErrorIsNil) expected, err := params.API2Resource(apiRes) c.Assert(err, jc.ErrorIsNil) c.Check(data.Resource, gc.DeepEquals, expected) c.Check(data.ReadCloser, gc.DeepEquals, rc) // call #0 is a call to makeWrapper s.wrapper.stub.CheckCall(c, 1, "ResourceMeta", params.DevelopmentChannel, req.Charm, req.Name, req.Revision) s.wrapper.stub.CheckCall(c, 2, "GetResource", params.DevelopmentChannel, req.Charm, req.Name, req.Revision) }
func charmRes(c *gc.C, name, suffix, description, content string) charmresource.Resource { if content == "" { content = name } fp, err := charmresource.GenerateFingerprint(strings.NewReader(content)) c.Assert(err, jc.ErrorIsNil) res := charmresource.Resource{ Meta: charmresource.Meta{ Name: name, Type: charmresource.TypeFile, Path: name + suffix, Description: description, }, Origin: charmresource.OriginStore, Revision: 1, Fingerprint: fp, Size: int64(len(content)), } err = res.Validate() c.Assert(err, jc.ErrorIsNil) return res }
func newFingerprint(c *gc.C, data string) charmresource.Fingerprint { fp, err := charmresource.GenerateFingerprint(strings.NewReader(data)) c.Assert(err, jc.ErrorIsNil) return fp }
func (s *ClientSuite) TestListResources(c *gc.C) { fp, err := resource.GenerateFingerprint(strings.NewReader("data")) c.Assert(err, jc.ErrorIsNil) stable := params.Resource{ Name: "name", Type: "file", Path: "foo.zip", Description: "something", Origin: "store", Revision: 5, Fingerprint: fp.Bytes(), Size: 4, } dev := params.Resource{ Name: "name2", Type: "file", Path: "bar.zip", Description: "something", Origin: "store", Revision: 7, Fingerprint: fp.Bytes(), Size: 4, } dev2 := params.Resource{ Name: "name3", Type: "file", Path: "bar.zip", Description: "something", Origin: "store", Revision: 8, Fingerprint: fp.Bytes(), Size: 4, } s.wrapper.ReturnListResourcesStable = []resourceResult{oneResourceResult(stable), resourceResult{err: params.ErrNotFound}} s.wrapper.ReturnListResourcesDev = []resourceResult{oneResourceResult(dev), oneResourceResult(dev2)} client, err := newCachingClient(s.cache, nil, s.wrapper.makeWrapper) c.Assert(err, jc.ErrorIsNil) foo := charm.MustParseURL("cs:quantal/foo-1") bar := charm.MustParseURL("cs:quantal/bar-1") baz := charm.MustParseURL("cs:quantal/baz-1") ret, err := client.ListResources([]CharmID{{ URL: foo, Channel: params.StableChannel, }, { URL: bar, Channel: params.DevelopmentChannel, }, { URL: baz, Channel: params.DevelopmentChannel, }}) c.Assert(err, jc.ErrorIsNil) stableOut, err := params.API2Resource(stable) c.Assert(err, jc.ErrorIsNil) devOut, err := params.API2Resource(dev) c.Assert(err, jc.ErrorIsNil) dev2Out, err := params.API2Resource(dev2) c.Assert(err, jc.ErrorIsNil) c.Assert(ret, gc.DeepEquals, [][]resource.Resource{ {stableOut}, {devOut}, {dev2Out}, }) s.wrapper.stableStub.CheckCall(c, 0, "ListResources", params.StableChannel, foo) s.wrapper.devStub.CheckCall(c, 0, "ListResources", params.DevelopmentChannel, bar) s.wrapper.devStub.CheckCall(c, 1, "ListResources", params.DevelopmentChannel, baz) }
func (s *ListCharmSuite) TestOutputFormats(c *gc.C) { fp1, err := charmresource.GenerateFingerprint(strings.NewReader("abc")) c.Assert(err, jc.ErrorIsNil) fp2, err := charmresource.GenerateFingerprint(strings.NewReader("xyz")) c.Assert(err, jc.ErrorIsNil) resources := []charmresource.Resource{ charmRes(c, "website", ".tgz", ".tgz of your website", string(fp1.Bytes())), charmRes(c, "music", ".mp3", "mp3 of your backing vocals", string(fp2.Bytes())), } s.client.ReturnListResources = [][]charmresource.Resource{resources} formats := map[string]string{ "tabular": ` RESOURCE REVISION website 1 music 1 `[1:], "yaml": ` - name: website type: file path: website.tgz description: .tgz of your website revision: 1 fingerprint: 73100f01cf258766906c34a30f9a486f07259c627ea0696d97c4582560447f59a6df4a7cf960708271a30324b1481ef4 size: 48 origin: store - name: music type: file path: music.mp3 description: mp3 of your backing vocals revision: 1 fingerprint: b0ea2a0f90267a8bd32848c65d7a61569a136f4e421b56127b6374b10a576d29e09294e620b4dcdee40f602115104bd5 size: 48 origin: store `[1:], "json": strings.Replace(""+ "["+ " {"+ ` "name":"website",`+ ` "type":"file",`+ ` "path":"website.tgz",`+ ` "description":".tgz of your website",`+ ` "revision":1,`+ ` "fingerprint":"73100f01cf258766906c34a30f9a486f07259c627ea0696d97c4582560447f59a6df4a7cf960708271a30324b1481ef4",`+ ` "size":48,`+ ` "origin":"store"`+ " },{"+ ` "name":"music",`+ ` "type":"file",`+ ` "path":"music.mp3",`+ ` "description":"mp3 of your backing vocals",`+ ` "revision":1,`+ ` "fingerprint":"b0ea2a0f90267a8bd32848c65d7a61569a136f4e421b56127b6374b10a576d29e09294e620b4dcdee40f602115104bd5",`+ ` "size":48,`+ ` "origin":"store"`+ " }"+ "]\n", " ", "", -1), } for format, expected := range formats { c.Logf("checking format %q", format) command := NewListCharmResourcesCommand() command.ResourceLister = s.client args := []string{ "--format", format, "cs:a-charm", } code, stdout, stderr := runCmd(c, command, args...) c.Check(code, gc.Equals, 0) c.Check(stdout, gc.Equals, expected) c.Check(stderr, gc.Equals, "") } }
func (s *UpgradeCharmStoreResourceSuite) TestDeployStarsaySuccess(c *gc.C) { testcharms.UploadCharm(c, s.client, "trusty/starsay-1", "starsay") // let's make a fake resource file to upload data := []byte("some-data") fp, err := charmresource.GenerateFingerprint(bytes.NewReader(data)) c.Assert(err, jc.ErrorIsNil) resourceFile := path.Join(c.MkDir(), "data.xml") err = ioutil.WriteFile(resourceFile, data, 0644) c.Assert(err, jc.ErrorIsNil) ctx, err := testing.RunCommand(c, service.NewDeployCommand(), "trusty/starsay", "--resource", "upload-resource="+resourceFile) c.Assert(err, jc.ErrorIsNil) output := testing.Stderr(ctx) expectedOutput := `Added charm "cs:trusty/starsay-1" to the model. Deploying charm "cs:trusty/starsay-1" with the charm series "trusty". ` c.Assert(output, gc.Equals, expectedOutput) s.assertCharmsUploaded(c, "cs:trusty/starsay-1") s.assertServicesDeployed(c, map[string]serviceInfo{ "starsay": {charm: "cs:trusty/starsay-1"}, }) _, err = s.State.Unit("starsay/0") c.Assert(err, jc.ErrorIsNil) res, err := s.State.Resources() c.Assert(err, jc.ErrorIsNil) svcres, err := res.ListResources("starsay") c.Assert(err, jc.ErrorIsNil) sort.Sort(byname(svcres.Resources)) c.Assert(svcres.Resources, gc.HasLen, 3) c.Check(svcres.Resources[2].Timestamp, gc.Not(gc.Equals), time.Time{}) svcres.Resources[2].Timestamp = time.Time{} expectedResources := []resource.Resource{ { Resource: charmresource.Resource{ Meta: charmresource.Meta{ Name: "install-resource", Type: charmresource.TypeFile, Path: "gotta-have-it.txt", Description: "get things started", }, Origin: charmresource.OriginStore, Revision: -1, }, ID: "starsay/install-resource", ServiceID: "starsay", }, { Resource: charmresource.Resource{ Meta: charmresource.Meta{ Name: "store-resource", Type: charmresource.TypeFile, Path: "filename.tgz", Description: "One line that is useful when operators need to push it.", }, Origin: charmresource.OriginStore, Revision: -1, }, ID: "starsay/store-resource", ServiceID: "starsay", }, { Resource: charmresource.Resource{ Meta: charmresource.Meta{ Name: "upload-resource", Type: charmresource.TypeFile, Path: "somename.xml", Description: "Who uses xml anymore?", }, Origin: charmresource.OriginUpload, Revision: 0, Fingerprint: fp, Size: int64(len(data)), }, ID: "starsay/upload-resource", ServiceID: "starsay", Username: "******", // Timestamp is checked above }, } c.Check(svcres.Resources, jc.DeepEquals, expectedResources) oldCharmStoreResources := make([]charmresource.Resource, len(svcres.CharmStoreResources)) copy(oldCharmStoreResources, svcres.CharmStoreResources) sort.Sort(csbyname(oldCharmStoreResources)) testcharms.UploadCharm(c, s.client, "trusty/starsay-2", "starsay") _, err = testing.RunCommand(c, service.NewUpgradeCharmCommand(), "starsay") c.Assert(err, jc.ErrorIsNil) s.assertServicesDeployed(c, map[string]serviceInfo{ "starsay": {charm: "cs:trusty/starsay-2"}, }) res, err = s.State.Resources() c.Assert(err, jc.ErrorIsNil) svcres, err = res.ListResources("starsay") c.Assert(err, jc.ErrorIsNil) sort.Sort(byname(svcres.Resources)) c.Assert(svcres.Resources, gc.HasLen, 3) c.Check(svcres.Resources[2].Timestamp, gc.Not(gc.Equals), time.Time{}) svcres.Resources[2].Timestamp = time.Time{} // ensure that we haven't overridden the previously uploaded resource. c.Check(svcres.Resources, jc.DeepEquals, expectedResources) sort.Sort(csbyname(svcres.CharmStoreResources)) c.Check(oldCharmStoreResources, gc.DeepEquals, svcres.CharmStoreResources) }
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, } 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) }