func (s *MetaSuite) TestParseMetaRelations(c *C) { meta, err := charm.ReadMeta(repoMeta("mysql")) c.Assert(err, IsNil) c.Assert(meta.Provides["server"], Equals, charm.Relation{Interface: "mysql", Scope: charm.ScopeGlobal}) c.Assert(meta.Requires, IsNil) c.Assert(meta.Peers, IsNil) meta, err = charm.ReadMeta(repoMeta("riak")) c.Assert(err, IsNil) c.Assert(meta.Provides["endpoint"], Equals, charm.Relation{Interface: "http", Scope: charm.ScopeGlobal}) c.Assert(meta.Provides["admin"], Equals, charm.Relation{Interface: "http", Scope: charm.ScopeGlobal}) c.Assert(meta.Peers["ring"], Equals, charm.Relation{Interface: "riak", Limit: 1, Scope: charm.ScopeGlobal}) c.Assert(meta.Requires, IsNil) meta, err = charm.ReadMeta(repoMeta("terracotta")) c.Assert(err, IsNil) c.Assert(meta.Provides["dso"], Equals, charm.Relation{Interface: "terracotta", Optional: true, Scope: charm.ScopeGlobal}) c.Assert(meta.Peers["server-array"], Equals, charm.Relation{Interface: "terracotta-server", Limit: 1, Scope: charm.ScopeGlobal}) c.Assert(meta.Requires, IsNil) meta, err = charm.ReadMeta(repoMeta("wordpress")) c.Assert(err, IsNil) c.Assert(meta.Provides["url"], Equals, charm.Relation{Interface: "http", Scope: charm.ScopeGlobal}) c.Assert(meta.Requires["db"], Equals, charm.Relation{Interface: "mysql", Limit: 1, Scope: charm.ScopeGlobal}) c.Assert(meta.Requires["cache"], Equals, charm.Relation{Interface: "varnish", Limit: 2, Optional: true, Scope: charm.ScopeGlobal}) c.Assert(meta.Peers, IsNil) }
func renameRelation(c *C, charmPath, oldName, newName string) { path := filepath.Join(charmPath, "metadata.yaml") f, err := os.Open(path) c.Assert(err, IsNil) defer f.Close() meta, err := charm.ReadMeta(f) c.Assert(err, IsNil) replace := func(what map[string]charm.Relation) bool { for relName, relation := range what { if relName == oldName { what[newName] = relation delete(what, oldName) return true } } return false } replaced := replace(meta.Provides) || replace(meta.Requires) || replace(meta.Peers) c.Assert(replaced, Equals, true, Commentf("charm %q does not implement relation %q", charmPath, oldName)) newmeta, err := goyaml.Marshal(meta) c.Assert(err, IsNil) ioutil.WriteFile(path, newmeta, 0644) f, err = os.Open(path) c.Assert(err, IsNil) defer f.Close() meta, err = charm.ReadMeta(f) c.Assert(err, IsNil) }
func (s *MetaSuite) TestScopeConstraint(c *C) { meta, err := charm.ReadMeta(repoMeta("logging")) c.Assert(err, IsNil) c.Assert(meta.Provides["logging-client"].Scope, Equals, charm.ScopeGlobal) c.Assert(meta.Requires["logging-directory"].Scope, Equals, charm.ScopeContainer) c.Assert(meta.Subordinate, Equals, true) }
func (s *MetaSuite) TestSubordinateWithoutContainerRelation(c *C) { r := repoMeta("dummy") hackYaml := ReadYaml(r) hackYaml["subordinate"] = true _, err := charm.ReadMeta(hackYaml.Reader()) c.Assert(err, ErrorMatches, "subordinate charm \"dummy\" lacks requires relation with container scope") }
func (s *MetaSuite) TestRelationsConstraints(c *C) { check := func(s, e string) { meta, err := charm.ReadMeta(strings.NewReader(s)) if e != "" { c.Assert(err, ErrorMatches, e) c.Assert(meta, IsNil) } else { c.Assert(err, IsNil) c.Assert(meta, NotNil) } } prefix := "name: a\nsummary: b\ndescription: c\n" for i, t := range relationsConstraintsTests { c.Logf("test %d", i) check(prefix+t.rels, t.err) check(prefix+"subordinate: true\n"+t.rels, t.err) } // The juju-* namespace is accessible to container-scoped require // relations on subordinate charms. check(prefix+` subordinate: true requires: juju-info: interface: juju-info scope: container`, "") // The juju-* interfaces are allowed on any require relation. check(prefix+` requires: innocuous: juju-info`, "") }
func (s *MetaSuite) TestReadMetaVersion2(c *C) { meta, err := charm.ReadMeta(repoMeta("format2")) c.Assert(err, IsNil) c.Assert(meta.Name, Equals, "format2") c.Assert(meta.Format, Equals, 2) c.Assert(meta.Categories, HasLen, 0) }
func (s *MetaSuite) TestMetaHooks(c *C) { meta, err := charm.ReadMeta(repoMeta("wordpress")) c.Assert(err, IsNil) hooks := meta.Hooks() expectedHooks := map[string]bool{ "install": true, "start": true, "config-changed": true, "upgrade-charm": true, "stop": true, "cache-relation-joined": true, "cache-relation-changed": true, "cache-relation-departed": true, "cache-relation-broken": true, "db-relation-joined": true, "db-relation-changed": true, "db-relation-departed": true, "db-relation-broken": true, "logging-dir-relation-joined": true, "logging-dir-relation-changed": true, "logging-dir-relation-departed": true, "logging-dir-relation-broken": true, "monitoring-port-relation-joined": true, "monitoring-port-relation-changed": true, "monitoring-port-relation-departed": true, "monitoring-port-relation-broken": true, "url-relation-joined": true, "url-relation-changed": true, "url-relation-departed": true, "url-relation-broken": true, } c.Assert(hooks, DeepEquals, expectedHooks) }
func (s *MetaSuite) TestReadMetaVersion1(c *C) { meta, err := charm.ReadMeta(repoMeta("dummy")) c.Assert(err, IsNil) c.Assert(meta.Name, Equals, "dummy") c.Assert(meta.Summary, Equals, "That's a dummy charm.") c.Assert(meta.Description, Equals, "This is a longer description which\npotentially contains multiple lines.\n") c.Assert(meta.Format, Equals, 1) c.Assert(meta.OldRevision, Equals, 0) c.Assert(meta.Subordinate, Equals, false) }
func (s *CharmTestHelperSuite) TestMetaCharm(c *C) { forEachStandardCharm(c, func(name string) { chd := testing.Charms.Dir(name) config := chd.Config() metaYaml := "name: " + name + metaYamlSnippet meta, err := charm.ReadMeta(bytes.NewBuffer([]byte(metaYaml))) c.Assert(err, IsNil) ch := s.AddMetaCharm(c, name, metaYaml, 123) assertCustomCharm(c, ch, "series", meta, config, 123) }) }
func (s *MetaSuite) TestSubordinate(c *C) { meta, err := charm.ReadMeta(repoMeta("logging")) c.Assert(err, IsNil) c.Assert(meta.Subordinate, Equals, true) }
func (s *MetaSuite) TestReadCategory(c *C) { meta, err := charm.ReadMeta(repoMeta("category")) c.Assert(err, IsNil) c.Assert(meta.Categories, DeepEquals, []string{"database"}) }
func (s *DirSuite) TestBundleTo(c *C) { baseDir := c.MkDir() charmDir := testing.Charms.ClonedDirPath(baseDir, "dummy") var haveSymlinks = true if err := os.Symlink("../target", filepath.Join(charmDir, "hooks/symlink")); err != nil { haveSymlinks = false } dir, err := charm.ReadDir(charmDir) c.Assert(err, IsNil) path := filepath.Join(baseDir, "bundle.charm") file, err := os.Create(path) c.Assert(err, IsNil) err = dir.BundleTo(file) file.Close() c.Assert(err, IsNil) zipr, err := zip.OpenReader(path) c.Assert(err, IsNil) defer zipr.Close() var metaf, instf, emptyf, revf, symf *zip.File for _, f := range zipr.File { c.Logf("Bundled file: %s", f.Name) switch f.Name { case "revision": revf = f case "metadata.yaml": metaf = f case "hooks/install": instf = f case "hooks/symlink": symf = f case "empty/": emptyf = f case "build/ignored": c.Errorf("bundle includes build/*: %s", f.Name) case ".ignored", ".dir/ignored": c.Errorf("bundle includes .* entries: %s", f.Name) } } c.Assert(revf, NotNil) reader, err := revf.Open() c.Assert(err, IsNil) data, err := ioutil.ReadAll(reader) reader.Close() c.Assert(err, IsNil) c.Assert(string(data), Equals, "1") c.Assert(metaf, NotNil) reader, err = metaf.Open() c.Assert(err, IsNil) meta, err := charm.ReadMeta(reader) reader.Close() c.Assert(err, IsNil) c.Assert(meta.Name, Equals, "dummy") c.Assert(instf, NotNil) // Despite it being 0751, we pack and unpack it as 0755. c.Assert(instf.Mode()&0777, Equals, os.FileMode(0755)) if haveSymlinks { c.Assert(symf, NotNil) c.Assert(symf.Mode()&0777, Equals, os.FileMode(0777)) reader, err = symf.Open() c.Assert(err, IsNil) data, err = ioutil.ReadAll(reader) reader.Close() c.Assert(err, IsNil) c.Assert(string(data), Equals, "../target") } else { c.Assert(symf, IsNil) } c.Assert(emptyf, NotNil) c.Assert(emptyf.Mode()&os.ModeType, Equals, os.ModeDir) // Despite it being 0750, we pack and unpack it as 0755. c.Assert(emptyf.Mode()&0777, Equals, os.FileMode(0755)) }