~ubuntu-branches/ubuntu/vivid/juju-core/vivid-updates

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): Curtis C. Hovey
  • Date: 2015-09-29 19:43:29 UTC
  • mfrom: (47.1.4 wily-proposed)
  • Revision ID: package-import@ubuntu.com-20150929194329-9y496tbic30hc7vp
Tags: 1.24.6-0ubuntu1~15.04.1
Backport of 1.24.6 from wily. (LP: #1500916, #1497087)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package v4_test
 
2
 
 
3
import (
 
4
        "encoding/json"
 
5
        "io"
 
6
        "net/http"
 
7
        "net/http/httptest"
 
8
 
 
9
        gc "gopkg.in/check.v1"
 
10
 
 
11
        "github.com/julienschmidt/httprouter"
 
12
        "gopkg.in/errgo.v1"
 
13
        "gopkg.in/macaroon-bakery.v0/bakery"
 
14
        "gopkg.in/macaroon-bakery.v0/bakery/checkers"
 
15
        "gopkg.in/macaroon-bakery.v0/bakerytest"
 
16
        "gopkg.in/macaroon-bakery.v0/httpbakery"
 
17
 
 
18
        "gopkg.in/juju/charmstore.v4/internal/charmstore"
 
19
        "gopkg.in/juju/charmstore.v4/internal/storetesting"
 
20
        "gopkg.in/juju/charmstore.v4/internal/v4"
 
21
)
 
22
 
 
23
type commonSuite struct {
 
24
        storetesting.IsolatedMgoSuite
 
25
 
 
26
        // srv holds the store HTTP handler.
 
27
        srv http.Handler
 
28
 
 
29
        // srvParams holds the parameters that the
 
30
        // srv handler was started with
 
31
        srvParams charmstore.ServerParams
 
32
 
 
33
        // noMacaroonSrv holds the store HTTP handler
 
34
        // for an instance of the store without identity
 
35
        // enabled. If enableIdentity is false, this is
 
36
        // the same as srv.
 
37
        noMacaroonSrv http.Handler
 
38
 
 
39
        // noMacaroonSrvParams holds the parameters that the
 
40
        // noMacaroonSrv handler was started with
 
41
        noMacaroonSrvParams charmstore.ServerParams
 
42
 
 
43
        // store holds an instance of *charm.Store
 
44
        // that can be used to access the charmstore database
 
45
        // directly.
 
46
        store *charmstore.Store
 
47
 
 
48
        // esSuite is set only when enableES is set to true.
 
49
        esSuite *storetesting.ElasticSearchSuite
 
50
 
 
51
        // discharge holds the function that will be used
 
52
        // to check third party caveats by the mock
 
53
        // discharger. This will be ignored if enableIdentity was
 
54
        // not true before commonSuite.SetUpTest is invoked.
 
55
        //
 
56
        // It may be set by tests to influence the behavior of the
 
57
        // discharger.
 
58
        discharge func(cav, arg string) ([]checkers.Caveat, error)
 
59
 
 
60
        discharger *bakerytest.Discharger
 
61
        idM        *idM
 
62
        idMServer  *httptest.Server
 
63
 
 
64
        // The following fields may be set before
 
65
        // SetUpSuite is invoked on commonSuite
 
66
        // and influences how the suite sets itself up.
 
67
 
 
68
        // enableIdentity holds whether the charmstore server
 
69
        // will be started with a configured identity service.
 
70
        enableIdentity bool
 
71
 
 
72
        // enableES holds whether the charmstore server will be
 
73
        // started with Elastic Search enabled.
 
74
        enableES bool
 
75
}
 
76
 
 
77
func (s *commonSuite) SetUpSuite(c *gc.C) {
 
78
        s.IsolatedMgoSuite.SetUpSuite(c)
 
79
        if s.enableES {
 
80
                s.esSuite = new(storetesting.ElasticSearchSuite)
 
81
                s.esSuite.SetUpSuite(c)
 
82
        }
 
83
}
 
84
 
 
85
func (s *commonSuite) TearDownSuite(c *gc.C) {
 
86
        if s.esSuite != nil {
 
87
                s.esSuite.TearDownSuite(c)
 
88
        }
 
89
}
 
90
 
 
91
func (s *commonSuite) SetUpTest(c *gc.C) {
 
92
        s.IsolatedMgoSuite.SetUpTest(c)
 
93
        if s.esSuite != nil {
 
94
                s.esSuite.SetUpTest(c)
 
95
        }
 
96
        if s.enableIdentity {
 
97
                s.idM = newIdM()
 
98
                s.idMServer = httptest.NewServer(s.idM)
 
99
        }
 
100
        s.startServer(c)
 
101
}
 
102
 
 
103
func (s *commonSuite) TearDownTest(c *gc.C) {
 
104
        s.store.Close()
 
105
        if s.esSuite != nil {
 
106
                s.esSuite.TearDownTest(c)
 
107
        }
 
108
        if s.discharger != nil {
 
109
                s.discharger.Close()
 
110
                s.idMServer.Close()
 
111
        }
 
112
        s.IsolatedMgoSuite.TearDownTest(c)
 
113
}
 
114
 
 
115
// startServer creates a new charmstore server.
 
116
func (s *commonSuite) startServer(c *gc.C) {
 
117
        config := charmstore.ServerParams{
 
118
                AuthUsername: testUsername,
 
119
                AuthPassword: testPassword,
 
120
        }
 
121
        if s.enableIdentity {
 
122
                s.discharge = func(_, _ string) ([]checkers.Caveat, error) {
 
123
                        return nil, errgo.New("no discharge")
 
124
                }
 
125
                discharger := bakerytest.NewDischarger(nil, func(_ *http.Request, cond string, arg string) ([]checkers.Caveat, error) {
 
126
                        return s.discharge(cond, arg)
 
127
                })
 
128
                config.IdentityLocation = discharger.Location()
 
129
                config.PublicKeyLocator = discharger
 
130
                config.IdentityAPIURL = s.idMServer.URL
 
131
        }
 
132
        var si *charmstore.SearchIndex
 
133
        if s.enableES {
 
134
                si = &charmstore.SearchIndex{
 
135
                        Database: s.esSuite.ES,
 
136
                        Index:    s.esSuite.TestIndex,
 
137
                }
 
138
        }
 
139
        db := s.Session.DB("charmstore")
 
140
        var err error
 
141
        s.srv, err = charmstore.NewServer(db, si, config, map[string]charmstore.NewAPIHandlerFunc{"v4": v4.NewAPIHandler})
 
142
        c.Assert(err, gc.IsNil)
 
143
        s.srvParams = config
 
144
 
 
145
        if s.enableIdentity {
 
146
                config.IdentityLocation = ""
 
147
                config.PublicKeyLocator = nil
 
148
                config.IdentityAPIURL = ""
 
149
                s.noMacaroonSrv, err = charmstore.NewServer(db, si, config, map[string]charmstore.NewAPIHandlerFunc{"v4": v4.NewAPIHandler})
 
150
                c.Assert(err, gc.IsNil)
 
151
        } else {
 
152
                s.noMacaroonSrv = s.srv
 
153
        }
 
154
        s.noMacaroonSrvParams = config
 
155
 
 
156
        pool, err := charmstore.NewPool(db, si, &bakery.NewServiceParams{})
 
157
        c.Assert(err, gc.IsNil)
 
158
        s.store = pool.Store()
 
159
}
 
160
 
 
161
func storeURL(path string) string {
 
162
        return "/v4/" + path
 
163
}
 
164
 
 
165
func bakeryDo(client *http.Client) func(*http.Request) (*http.Response, error) {
 
166
        if client == nil {
 
167
                client = httpbakery.NewHTTPClient()
 
168
        }
 
169
        return func(req *http.Request) (*http.Response, error) {
 
170
                if req.Body != nil {
 
171
                        return httpbakery.DoWithBody(client, req, httpbakery.SeekerBody(req.Body.(io.ReadSeeker)), noInteraction)
 
172
                }
 
173
                return httpbakery.Do(client, req, noInteraction)
 
174
        }
 
175
}
 
176
 
 
177
type idM struct {
 
178
        // groups may be set to determine the mapping
 
179
        // from user to groups for that user.
 
180
        groups map[string][]string
 
181
 
 
182
        // body may be set to cause serveGroups to return
 
183
        // an arbitrary HTTP response body.
 
184
        body string
 
185
 
 
186
        // status may be set to indicate the HTTP status code
 
187
        // when body is not nil.
 
188
        status int
 
189
 
 
190
        router *httprouter.Router
 
191
}
 
192
 
 
193
func newIdM() *idM {
 
194
        idM := &idM{
 
195
                groups: make(map[string][]string),
 
196
                router: httprouter.New(),
 
197
        }
 
198
        idM.router.GET("/v1/u/:user/idpgroups", idM.serveGroups)
 
199
        return idM
 
200
}
 
201
 
 
202
func (idM *idM) ServeHTTP(w http.ResponseWriter, req *http.Request) {
 
203
        idM.router.ServeHTTP(w, req)
 
204
}
 
205
 
 
206
func (idM *idM) serveGroups(w http.ResponseWriter, req *http.Request, p httprouter.Params) {
 
207
        if idM.body != "" {
 
208
                if idM.status != 0 {
 
209
                        w.WriteHeader(idM.status)
 
210
                }
 
211
                w.Write([]byte(idM.body))
 
212
                return
 
213
        }
 
214
        u := p.ByName("user")
 
215
        if u == "" {
 
216
                panic("no user")
 
217
        }
 
218
        enc := json.NewEncoder(w)
 
219
        if err := enc.Encode(idM.groups[u]); err != nil {
 
220
                panic(err)
 
221
        }
 
222
}