~juju-qa/ubuntu/xenial/juju/xenial-2.0-beta3

« back to all changes in this revision

Viewing changes to src/gopkg.in/juju/charmstore.v5-unstable/internal/v4/common_test.go

  • Committer: Martin Packman
  • Date: 2016-03-30 19:31:08 UTC
  • mfrom: (1.1.41)
  • Revision ID: martin.packman@canonical.com-20160330193108-h9iz3ak334uk0z5r
Merge new upstream source 2.0~beta3

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
package v4_test // import "gopkg.in/juju/charmstore.v5-unstable/internal/v4"
2
2
 
3
3
import (
 
4
        "bytes"
4
5
        "encoding/json"
5
6
        "io"
6
7
        "net/http"
9
10
 
10
11
        "github.com/juju/loggo"
11
12
        jujutesting "github.com/juju/testing"
 
13
        "github.com/juju/testing/httptesting"
12
14
        "github.com/julienschmidt/httprouter"
13
15
        gc "gopkg.in/check.v1"
14
16
        "gopkg.in/errgo.v1"
 
17
        "gopkg.in/juju/charm.v6-unstable"
 
18
        "gopkg.in/juju/charmrepo.v2-unstable/csclient/params"
15
19
        "gopkg.in/macaroon-bakery.v1/bakery"
16
20
        "gopkg.in/macaroon-bakery.v1/bakery/checkers"
17
21
        "gopkg.in/macaroon-bakery.v1/bakerytest"
19
23
        "gopkg.in/mgo.v2"
20
24
 
21
25
        "gopkg.in/juju/charmstore.v5-unstable/internal/charmstore"
 
26
        "gopkg.in/juju/charmstore.v5-unstable/internal/router"
22
27
        "gopkg.in/juju/charmstore.v5-unstable/internal/storetesting"
23
28
        "gopkg.in/juju/charmstore.v5-unstable/internal/v4"
24
29
)
185
190
        s.store = s.srv.Pool().Store()
186
191
}
187
192
 
 
193
func (s *commonSuite) addPublicCharmFromRepo(c *gc.C, charmName string, rurl *router.ResolvedURL) (*router.ResolvedURL, charm.Charm) {
 
194
        return s.addPublicCharm(c, storetesting.Charms.CharmDir(charmName), rurl)
 
195
}
 
196
 
 
197
func (s *commonSuite) addPublicCharm(c *gc.C, ch charm.Charm, rurl *router.ResolvedURL) (*router.ResolvedURL, charm.Charm) {
 
198
        err := s.store.AddCharmWithArchive(rurl, ch)
 
199
        c.Assert(err, gc.IsNil)
 
200
        s.setPublic(c, rurl)
 
201
        return rurl, ch
 
202
}
 
203
 
 
204
func (s *commonSuite) setPublic(c *gc.C, rurl *router.ResolvedURL) {
 
205
        err := s.store.SetPerms(&rurl.URL, "stable.read", params.Everyone)
 
206
        c.Assert(err, gc.IsNil)
 
207
        err = s.store.Publish(rurl, params.StableChannel)
 
208
        c.Assert(err, gc.IsNil)
 
209
}
 
210
 
 
211
func (s *commonSuite) addPublicBundleFromRepo(c *gc.C, bundleName string, rurl *router.ResolvedURL, addRequiredCharms bool) (*router.ResolvedURL, charm.Bundle) {
 
212
        return s.addPublicBundle(c, storetesting.Charms.BundleDir(bundleName), rurl, addRequiredCharms)
 
213
}
 
214
 
 
215
func (s *commonSuite) addPublicBundle(c *gc.C, bundle charm.Bundle, rurl *router.ResolvedURL, addRequiredCharms bool) (*router.ResolvedURL, charm.Bundle) {
 
216
        if addRequiredCharms {
 
217
                s.addRequiredCharms(c, bundle)
 
218
        }
 
219
        err := s.store.AddBundleWithArchive(rurl, bundle)
 
220
        c.Assert(err, gc.IsNil)
 
221
        s.setPublic(c, rurl)
 
222
        return rurl, bundle
 
223
}
 
224
 
 
225
// addCharms adds all the given charms to s.store. The
 
226
// map key is the id of the charm.
 
227
func (s *commonSuite) addCharms(c *gc.C, charms map[string]charm.Charm) {
 
228
        for id, ch := range charms {
 
229
                s.addPublicCharm(c, storetesting.NewCharm(ch.Meta()), mustParseResolvedURL(id))
 
230
        }
 
231
}
 
232
 
 
233
// setPerms sets the stable channel read permissions of a set of
 
234
// entities. The map key is the is the id of each entity; its associated
 
235
// value is its read ACL.
 
236
func (s *commonSuite) setPerms(c *gc.C, readACLs map[string][]string) {
 
237
        for url, acl := range readACLs {
 
238
                err := s.store.SetPerms(charm.MustParseURL(url), "stable.read", acl...)
 
239
                c.Assert(err, gc.IsNil)
 
240
        }
 
241
}
 
242
 
188
243
// handler returns a request handler that can be
189
244
// used to invoke private methods. The caller
190
245
// is responsible for calling Put on the returned handler.
191
246
func (s *commonSuite) handler(c *gc.C) v4.ReqHandler {
192
 
        h := v4.New(s.store.Pool(), s.srvParams)
 
247
        h := v4.New(s.store.Pool(), s.srvParams, "")
193
248
        defer h.Close()
194
 
        rh, err := h.NewReqHandler()
 
249
        rh, err := h.NewReqHandler(new(http.Request))
195
250
        c.Assert(err, gc.IsNil)
196
251
        // It would be nice if we could call s.AddCleanup here
197
252
        // to call rh.Put when the test has completed, but
204
259
        return "/v4/" + path
205
260
}
206
261
 
 
262
// addRequiredCharms adds any charms required by the given
 
263
// bundle that are not already in the store.
 
264
func (s *commonSuite) addRequiredCharms(c *gc.C, bundle charm.Bundle) {
 
265
        for _, svc := range bundle.Data().Services {
 
266
                u := charm.MustParseURL(svc.Charm)
 
267
                if _, err := s.store.FindBestEntity(u, params.StableChannel, nil); err == nil {
 
268
                        continue
 
269
                }
 
270
                if u.Revision == -1 {
 
271
                        u.Revision = 0
 
272
                }
 
273
                var rurl router.ResolvedURL
 
274
                rurl.URL = *u
 
275
                chDir, err := charm.ReadCharmDir(storetesting.Charms.CharmDirPath(u.Name))
 
276
                ch := charm.Charm(chDir)
 
277
                if err != nil {
 
278
                        // The charm doesn't exist in the local charm repo; make one up.
 
279
                        ch = storetesting.NewCharm(nil)
 
280
                }
 
281
                if len(ch.Meta().Series) == 0 && u.Series == "" {
 
282
                        rurl.URL.Series = "trusty"
 
283
                }
 
284
                if u.User == "" {
 
285
                        rurl.URL.User = "charmers"
 
286
                        rurl.PromulgatedRevision = rurl.URL.Revision
 
287
                } else {
 
288
                        rurl.PromulgatedRevision = -1
 
289
                }
 
290
                c.Logf("adding charm %v %d required by bundle to fulfil %v", &rurl.URL, rurl.PromulgatedRevision, svc.Charm)
 
291
                s.addPublicCharm(c, ch, &rurl)
 
292
        }
 
293
}
 
294
 
 
295
func (s *commonSuite) assertPut(c *gc.C, url string, val interface{}) {
 
296
        s.assertPut0(c, url, val, false)
 
297
}
 
298
 
 
299
func (s *commonSuite) assertPutAsAdmin(c *gc.C, url string, val interface{}) {
 
300
        s.assertPut0(c, url, val, true)
 
301
}
 
302
 
 
303
func (s *commonSuite) assertPut0(c *gc.C, url string, val interface{}, asAdmin bool) {
 
304
        body, err := json.Marshal(val)
 
305
        c.Assert(err, gc.IsNil)
 
306
        p := httptesting.JSONCallParams{
 
307
                Handler: s.srv,
 
308
                URL:     storeURL(url),
 
309
                Method:  "PUT",
 
310
                Do:      bakeryDo(nil),
 
311
                Header: http.Header{
 
312
                        "Content-Type": {"application/json"},
 
313
                },
 
314
                Body: bytes.NewReader(body),
 
315
        }
 
316
        if asAdmin {
 
317
                p.Username = testUsername
 
318
                p.Password = testPassword
 
319
        }
 
320
        httptesting.AssertJSONCall(c, p)
 
321
}
 
322
 
 
323
func (s *commonSuite) assertGet(c *gc.C, url string, expectVal interface{}) {
 
324
        httptesting.AssertJSONCall(c, httptesting.JSONCallParams{
 
325
                Handler:    s.srv,
 
326
                Do:         bakeryDo(nil),
 
327
                URL:        storeURL(url),
 
328
                ExpectBody: expectVal,
 
329
        })
 
330
}
 
331
 
 
332
// assertGetIsUnauthorized asserts that a GET to the given URL results
 
333
// in an ErrUnauthorized response with the given error message.
 
334
func (s *commonSuite) assertGetIsUnauthorized(c *gc.C, url, expectMessage string) {
 
335
        httptesting.AssertJSONCall(c, httptesting.JSONCallParams{
 
336
                Handler:      s.srv,
 
337
                Do:           bakeryDo(nil),
 
338
                Method:       "GET",
 
339
                URL:          storeURL(url),
 
340
                ExpectStatus: http.StatusUnauthorized,
 
341
                ExpectBody: params.Error{
 
342
                        Code:    params.ErrUnauthorized,
 
343
                        Message: expectMessage,
 
344
                },
 
345
        })
 
346
}
 
347
 
 
348
// assertGetIsUnauthorized asserts that a PUT to the given URL with the
 
349
// given body value results in an ErrUnauthorized response with the given
 
350
// error message.
 
351
func (s *commonSuite) assertPutIsUnauthorized(c *gc.C, url string, val interface{}, expectMessage string) {
 
352
        body, err := json.Marshal(val)
 
353
        c.Assert(err, gc.IsNil)
 
354
        httptesting.AssertJSONCall(c, httptesting.JSONCallParams{
 
355
                Handler: s.srv,
 
356
                URL:     storeURL(url),
 
357
                Method:  "PUT",
 
358
                Do:      bakeryDo(nil),
 
359
                Header: http.Header{
 
360
                        "Content-Type": {"application/json"},
 
361
                },
 
362
                Body:         bytes.NewReader(body),
 
363
                ExpectStatus: http.StatusUnauthorized,
 
364
                ExpectBody: params.Error{
 
365
                        Code:    params.ErrUnauthorized,
 
366
                        Message: expectMessage,
 
367
                },
 
368
        })
 
369
}
 
370
 
 
371
// doAsUser calls the given function, discharging any authorization
 
372
// request as the given user name.
 
373
func (s *commonSuite) doAsUser(user string, f func()) {
 
374
        old := s.discharge
 
375
        s.discharge = dischargeForUser(user)
 
376
        defer func() {
 
377
                s.discharge = old
 
378
        }()
 
379
        f()
 
380
}
 
381
 
207
382
func bakeryDo(client *http.Client) func(*http.Request) (*http.Response, error) {
208
383
        if client == nil {
209
384
                client = httpbakery.NewHTTPClient()