Ejemplo n.º 1
0
func (s *MockStore) serveInfo(w http.ResponseWriter, r *http.Request) {
	if metadata := r.Header.Get("Juju-Metadata"); metadata != "" {
		s.Metadata = append(s.Metadata, metadata)
		logger.Infof("Juju metadata: " + metadata)
	}

	r.ParseForm()
	if r.Form.Get("stats") == "0" {
		s.InfoRequestCountNoStats += 1
	} else {
		s.InfoRequestCount += 1
	}

	response := map[string]*charm.InfoResponse{}
	for _, url := range r.Form["charms"] {
		cr := &charm.InfoResponse{}
		response[url] = cr
		charmURL, err := charm.ParseURL(url)
		if err == charm.ErrUnresolvedUrl {
			ref, _, err := charm.ParseReference(url)
			if err != nil {
				panic(err)
			}
			if s.DefaultSeries == "" {
				panic(fmt.Errorf("mock store lacks a default series cannot resolve charm URL: %q", url))
			}
			charmURL = &charm.URL{Reference: ref, Series: s.DefaultSeries}
		}
		switch charmURL.Name {
		case "borken":
			cr.Errors = append(cr.Errors, "badness")
		case "terracotta":
			cr.Errors = append(cr.Errors, "cannot get revision")
		case "unwise":
			cr.Warnings = append(cr.Warnings, "foolishness")
			fallthrough
		default:
			if rev, ok := s.charms[charmURL.WithRevision(-1).String()]; ok {
				if charmURL.Revision == -1 {
					cr.Revision = rev
				} else {
					cr.Revision = charmURL.Revision
				}
				cr.Sha256 = s.bundleSha256
				cr.CanonicalURL = charmURL.String()
			} else {
				cr.Errors = append(cr.Errors, "entry not found")
			}
		}
	}
	data, err := json.Marshal(response)
	if err != nil {
		panic(err)
	}
	w.Header().Set("Content-Type", "application/json")
	_, err = w.Write(data)
	if err != nil {
		panic(err)
	}
}
Ejemplo n.º 2
0
func (s *StoreSuite) TestSeriesSolver(c *gc.C) {
	for _, t := range seriesSolverCharms {
		url := charm.MustParseURL(fmt.Sprintf("cs:%s/%s", t.series, t.name))
		urls := []*charm.URL{url}

		pub, err := s.store.CharmPublisher(urls, fmt.Sprintf("some-%s-%s-digest", t.series, t.name))
		c.Assert(err, gc.IsNil)
		c.Assert(pub.Revision(), gc.Equals, 0)

		err = pub.Publish(&FakeCharmDir{})
		c.Assert(err, gc.IsNil)
	}

	// LTS, then non-LTS, reverse alphabetical order
	ref, _, err := charm.ParseReference("cs:wordpress")
	c.Assert(err, gc.IsNil)
	series, err := s.store.Series(ref)
	c.Assert(err, gc.IsNil)
	c.Assert(series, gc.HasLen, 5)
	c.Check(series[0], gc.Equals, "trusty")
	c.Check(series[1], gc.Equals, "precise")
	c.Check(series[2], gc.Equals, "volumetric")
	c.Check(series[3], gc.Equals, "quantal")
	c.Check(series[4], gc.Equals, "oneiric")

	// Ensure that the full charm name matches, not just prefix
	ref, _, err = charm.ParseReference("cs:mysql")
	c.Assert(err, gc.IsNil)
	series, err = s.store.Series(ref)
	c.Assert(err, gc.IsNil)
	c.Assert(series, gc.HasLen, 1)
	c.Check(series[0], gc.Equals, "precise")

	// No LTS, reverse alphabetical order
	ref, _, err = charm.ParseReference("cs:zebra")
	c.Assert(err, gc.IsNil)
	series, err = s.store.Series(ref)
	c.Assert(err, gc.IsNil)
	c.Assert(series, gc.HasLen, 2)
	c.Check(series[0], gc.Equals, "zef")
	c.Check(series[1], gc.Equals, "def")
}
Ejemplo n.º 3
0
func (s *URLSuite) TestParseUnresolved(c *gc.C) {
	for _, t := range inferNoDefaultSeriesTests {
		if t.resolved {
			url, err := charm.ParseURL(t.vague)
			c.Assert(err, gc.IsNil)
			c.Assert(url.Series, gc.Not(gc.Equals), "")
		} else {
			_, series, err := charm.ParseReference(t.vague)
			c.Assert(err, gc.IsNil)
			c.Assert(series, gc.Equals, "")
			_, err = charm.ParseURL(t.vague)
			c.Assert(err, gc.NotNil)
			c.Assert(err, gc.Equals, charm.ErrUnresolvedUrl)
		}
	}
}
Ejemplo n.º 4
0
func (s *Server) resolveURL(url string) (*charm.URL, error) {
	ref, series, err := charm.ParseReference(url)
	if err != nil {
		return nil, err
	}
	if series == "" {
		prefSeries, err := s.store.Series(ref)
		if err != nil {
			return nil, err
		}
		if len(prefSeries) == 0 {
			return nil, ErrNotFound
		}
		return &charm.URL{Reference: ref, Series: prefSeries[0]}, nil
	}
	return &charm.URL{Reference: ref, Series: series}, nil
}
Ejemplo n.º 5
0
func (s *URLSuite) TestReferenceJSON(c *gc.C) {
	ref, _, err := charm.ParseReference("cs:series/name")
	c.Assert(err, gc.IsNil)
	data, err := json.Marshal(&ref)
	c.Assert(err, gc.IsNil)
	c.Check(string(data), gc.Equals, `"cs:name"`)

	var parsed charm.Reference
	err = json.Unmarshal(data, &parsed)
	c.Assert(err, gc.IsNil)
	c.Check(parsed, gc.DeepEquals, ref)

	// unmarshalling json gibberish and invalid charm reference strings
	for _, value := range []string{":{", `"cs:{}+<"`, `"cs:~_~/f00^^&^/baaaar$%-?"`} {
		err = json.Unmarshal([]byte(value), &parsed)
		c.Check(err, gc.NotNil)
	}
}
Ejemplo n.º 6
0
// resolveCharmURL returns a resolved charm URL, given a charm location string.
// If the series is not resolved, the environment default-series is used, or if
// not set, the series is resolved with the state server.
func resolveCharmURL(url string, client *api.Client, conf *config.Config) (*charm.URL, error) {
	ref, series, err := charm.ParseReference(url)
	if err != nil {
		return nil, err
	}
	// If series is not set, use configured default series
	if series == "" {
		if defaultSeries, ok := conf.DefaultSeries(); ok {
			series = defaultSeries
		}
	}
	// Otherwise, look up the best supported series for this charm
	if series == "" {
		if ref.Schema == "local" {
			possibleUrl := &charm.URL{Reference: ref, Series: "precise"}
			logger.Errorf(`The series is not specified in the environment (default-series) or with the charm. Did you mean:
	%s`, possibleUrl.String())
			return nil, fmt.Errorf("cannot resolve series for charm: %q", ref)
		}
		return client.ResolveCharm(ref)
	}
	return &charm.URL{Reference: ref, Series: series}, nil
}
Ejemplo n.º 7
0
func (s *StoreSuite) TestMysqlSeriesSolver(c *gc.C) {
	for _, t := range mysqlSeriesCharms {
		var urls []*charm.URL
		for _, url := range t.urls {
			urls = append(urls, charm.MustParseURL(url))
		}

		pub, err := s.store.CharmPublisher(urls, t.fakeDigest)
		c.Assert(err, gc.IsNil)
		c.Assert(pub.Revision(), gc.Equals, 0)

		err = pub.Publish(&FakeCharmDir{})
		c.Assert(err, gc.IsNil)
	}

	ref, _, err := charm.ParseReference("cs:mysql")
	c.Assert(err, gc.IsNil)
	series, err := s.store.Series(ref)
	c.Assert(err, gc.IsNil)
	c.Assert(series, gc.HasLen, 2)
	c.Check(series[0], gc.Equals, "precise")
	c.Check(series[1], gc.Equals, "oneiric")
}
Ejemplo n.º 8
0
func (s *URLSuite) TestParseURL(c *gc.C) {
	for i, t := range urlTests {
		c.Logf("test %d", i)
		url, uerr := charm.ParseURL(t.s)
		ref, series, rerr := charm.ParseReference(t.s)
		comment := gc.Commentf("ParseURL(%q)", t.s)
		if t.url != nil && t.url.Series == "" {
			if t.err != "" {
				// Expected error should match
				c.Assert(rerr, gc.NotNil, comment)
				c.Check(rerr.Error(), gc.Matches, t.err, comment)
			} else {
				// Expected charm reference should match
				c.Check(ref, gc.DeepEquals, t.url.Reference, comment)
				c.Check(t.url.Reference.String(), gc.Equals, t.s)
			}
			if rerr != nil {
				// If ParseReference has an error, ParseURL should share it
				c.Check(uerr.Error(), gc.Equals, rerr.Error(), comment)
			} else {
				// Otherwise, ParseURL with an empty series should error unresolved.
				c.Check(uerr.Error(), gc.Equals, charm.ErrUnresolvedUrl.Error(), comment)
			}
		} else {
			if t.err != "" {
				c.Assert(uerr, gc.NotNil, comment)
				c.Check(uerr.Error(), gc.Matches, t.err, comment)
				c.Check(uerr.Error(), gc.Equals, rerr.Error(), comment)
			} else {
				c.Check(url.Series, gc.Equals, series, comment)
				c.Check(url, gc.DeepEquals, t.url, comment)
				c.Check(t.url.String(), gc.Equals, t.s)
			}
		}
	}
}