Example #1
0
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, "")
}
Example #2
0
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")
	}
}
Example #3
0
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)
}
Example #4
0
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)
	}
}
Example #5
0
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)
	}
}
Example #6
0
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)
	}
}