func (s *BundleSuite) TestReadBundleBytes(c *C) { data, err := ioutil.ReadFile(s.bundlePath) c.Assert(err, IsNil) bundle, err := charm.ReadBundleBytes(data) c.Assert(err, IsNil) checkDummy(c, bundle, "") }
func (s *BundleSuite) TestBundleFileModes(c *C) { // Apply subtler mode differences than can be expressed in Bazaar. srcPath := testing.Charms.ClonedDirPath(c.MkDir(), "dummy") modes := []struct { path string mode os.FileMode }{ {"hooks/install", 0751}, {"empty", 0750}, {"src/hello.c", 0614}, } for _, m := range modes { err := os.Chmod(filepath.Join(srcPath, m.path), m.mode) c.Assert(err, IsNil) } var haveSymlinks = true if err := os.Symlink("../target", filepath.Join(srcPath, "hooks/symlink")); err != nil { haveSymlinks = false } // Bundle and extract the charm to a new directory. dir, err := charm.ReadDir(srcPath) c.Assert(err, IsNil) buf := new(bytes.Buffer) err = dir.BundleTo(buf) c.Assert(err, IsNil) bundle, err := charm.ReadBundleBytes(buf.Bytes()) c.Assert(err, IsNil) path := c.MkDir() err = bundle.ExpandTo(path) c.Assert(err, IsNil) // Check sensible file modes once round-tripped. info, err := os.Stat(filepath.Join(path, "src", "hello.c")) c.Assert(err, IsNil) c.Assert(info.Mode()&0777, Equals, os.FileMode(0644)) c.Assert(info.Mode()&os.ModeType, Equals, os.FileMode(0)) info, err = os.Stat(filepath.Join(path, "hooks", "install")) c.Assert(err, IsNil) c.Assert(info.Mode()&0777, Equals, os.FileMode(0755)) c.Assert(info.Mode()&os.ModeType, Equals, os.FileMode(0)) info, err = os.Stat(filepath.Join(path, "empty")) c.Assert(err, IsNil) c.Assert(info.Mode()&0777, Equals, os.FileMode(0755)) if haveSymlinks { target, err := os.Readlink(filepath.Join(path, "hooks", "symlink")) c.Assert(err, IsNil) c.Assert(target, Equals, "../target") } }
func (s *DirSuite) TestDirSetRevision(c *C) { dir := testing.Charms.ClonedDir(c.MkDir(), "dummy") c.Assert(dir.Revision(), Equals, 1) dir.SetRevision(42) c.Assert(dir.Revision(), Equals, 42) var b bytes.Buffer err := dir.BundleTo(&b) c.Assert(err, IsNil) bundle, err := charm.ReadBundleBytes(b.Bytes()) c.Assert(bundle.Revision(), Equals, 42) }
func copyCharmDir(dst string, dir *charm.Dir) { var b bytes.Buffer err := dir.BundleTo(&b) if err != nil { panic(err) } bundle, err := charm.ReadBundleBytes(b.Bytes()) if err != nil { panic(err) } err = bundle.ExpandTo(dst) if err != nil { panic(err) } }
func (s *StoreSuite) TestCharmPublisher(c *C) { urlA := charm.MustParseURL("cs:oneiric/wordpress-a") urlB := charm.MustParseURL("cs:oneiric/wordpress-b") urls := []*charm.URL{urlA, urlB} pub, err := s.store.CharmPublisher(urls, "some-digest") c.Assert(err, IsNil) c.Assert(pub.Revision(), Equals, 0) err = pub.Publish(testing.Charms.ClonedDir(c.MkDir(), "dummy")) c.Assert(err, IsNil) for _, url := range urls { info, rc, err := s.store.OpenCharm(url) c.Assert(err, IsNil) c.Assert(info.Revision(), Equals, 0) c.Assert(info.Digest(), Equals, "some-digest") data, err := ioutil.ReadAll(rc) c.Check(err, IsNil) err = rc.Close() c.Assert(err, IsNil) bundle, err := charm.ReadBundleBytes(data) c.Assert(err, IsNil) // The same information must be available by reading the // full charm data... c.Assert(bundle.Meta().Name, Equals, "dummy") c.Assert(bundle.Config().Options["title"].Default, Equals, "My Title") // ... and the queriable details. c.Assert(info.Meta().Name, Equals, "dummy") c.Assert(info.Config().Options["title"].Default, Equals, "My Title") info2, err := s.store.CharmInfo(url) c.Assert(err, IsNil) c.Assert(info2, DeepEquals, info) } }
func (s *StoreSuite) TestPublish(c *gc.C) { branch := s.dummyBranch(c, "") // Ensure that the streams are parsed separately by inserting // garbage on stderr. The wanted information is still there. plugin := fakePlugin{} plugin.install(c.MkDir(), `import sys; sys.stderr.write("STDERR STUFF FROM TEST\n")`) defer plugin.uninstall() err := store.PublishBazaarBranch(s.store, urls, branch.path(), "wrong-rev") c.Assert(err, gc.IsNil) for _, url := range urls { info, rc, err := s.store.OpenCharm(url) c.Assert(err, gc.IsNil) defer rc.Close() c.Assert(info.Revision(), gc.Equals, 0) c.Assert(info.Meta().Name, gc.Equals, "dummy") data, err := ioutil.ReadAll(rc) c.Assert(err, gc.IsNil) bundle, err := charm.ReadBundleBytes(data) c.Assert(err, gc.IsNil) c.Assert(bundle.Revision(), gc.Equals, 0) c.Assert(bundle.Meta().Name, gc.Equals, "dummy") } // Attempt to publish the same content again while providing the wrong // tip revision. It must pick the real revision from the branch and // note this was previously published. err = store.PublishBazaarBranch(s.store, urls, branch.path(), "wrong-rev") c.Assert(err, gc.Equals, store.ErrRedundantUpdate) // Bump the content revision and lie again about the known tip revision. // This time, though, pretend it's the same as the real branch revision // previously published. It must error and not publish the new revision // because it will use the revision provided as a parameter to check if // publishing was attempted before. This is the mechanism that enables // stopping fast without having to download every single branch. Real // revision is picked in the next scan. digest1 := branch.digest() branch.change() err = store.PublishBazaarBranch(s.store, urls, branch.path(), digest1) c.Assert(err, gc.Equals, store.ErrRedundantUpdate) // Now allow it to publish the new content by providing an unseen revision. err = store.PublishBazaarBranch(s.store, urls, branch.path(), "wrong-rev") c.Assert(err, gc.IsNil) digest2 := branch.digest() info, err := s.store.CharmInfo(urls[0]) c.Assert(err, gc.IsNil) c.Assert(info.Revision(), gc.Equals, 1) c.Assert(info.Meta().Name, gc.Equals, "dummy") // There are two events published, for each of the successful attempts. // The failures are ignored given that they are artifacts of the // publishing mechanism rather than actual problems. _, err = s.store.CharmEvent(urls[0], "wrong-rev") c.Assert(err, gc.Equals, store.ErrNotFound) for i, digest := range []string{digest1, digest2} { event, err := s.store.CharmEvent(urls[0], digest) c.Assert(err, gc.IsNil) c.Assert(event.Kind, gc.Equals, store.EventPublished) c.Assert(event.Revision, gc.Equals, i) c.Assert(event.Errors, gc.IsNil) c.Assert(event.Warnings, gc.IsNil) } }