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

« back to all changes in this revision

Viewing changes to src/github.com/juju/juju/resource/api/server/unithandler_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
// Copyright 2016 Canonical Ltd.
 
2
// Licensed under the AGPLv3, see LICENCE file for details.
 
3
 
 
4
package server_test
 
5
 
 
6
import (
 
7
        "bytes"
 
8
        "fmt"
 
9
        "io"
 
10
        "net/http"
 
11
        "net/url"
 
12
 
 
13
        "github.com/juju/errors"
 
14
        "github.com/juju/testing"
 
15
        jc "github.com/juju/testing/checkers"
 
16
        "github.com/juju/testing/filetesting"
 
17
        gc "gopkg.in/check.v1"
 
18
 
 
19
        "github.com/juju/juju/resource"
 
20
        "github.com/juju/juju/resource/api"
 
21
        "github.com/juju/juju/resource/api/server"
 
22
        "github.com/juju/juju/resource/resourcetesting"
 
23
)
 
24
 
 
25
var _ = gc.Suite(&UnitResourceHandlerSuite{})
 
26
 
 
27
type UnitResourceHandlerSuite struct {
 
28
        testing.IsolationSuite
 
29
 
 
30
        stub   *testing.Stub
 
31
        opener *stubResourceOpener
 
32
        deps   *stubUnitResourceHandlerDeps
 
33
        resp   *stubResponseWriter
 
34
}
 
35
 
 
36
func (s *UnitResourceHandlerSuite) SetUpTest(c *gc.C) {
 
37
        s.IsolationSuite.SetUpTest(c)
 
38
 
 
39
        s.stub = &testing.Stub{}
 
40
        s.opener = &stubResourceOpener{Stub: s.stub}
 
41
        s.deps = &stubUnitResourceHandlerDeps{Stub: s.stub}
 
42
        s.resp = newStubResponseWriter(s.stub)
 
43
}
 
44
 
 
45
func (s *UnitResourceHandlerSuite) TestIntegration(c *gc.C) {
 
46
        opened := resourcetesting.NewResource(c, s.stub, "spam", "a-service", "some data")
 
47
        s.opener.ReturnOpenResource = opened
 
48
        s.deps.ReturnNewResourceOpener = s.opener
 
49
        deps := server.NewUnitResourceHandlerDeps(s.deps)
 
50
        h := server.NewUnitResourceHandler(deps)
 
51
        req, err := api.NewHTTPDownloadRequest("spam")
 
52
        c.Assert(err, jc.ErrorIsNil)
 
53
        req.URL, err = url.ParseRequestURI("https://api:17018/units/eggs/1/resources/spam?:resource=spam")
 
54
        c.Assert(err, jc.ErrorIsNil)
 
55
        resp := &fakeResponseWriter{
 
56
                stubResponseWriter: s.resp,
 
57
        }
 
58
 
 
59
        c.Logf("%#v", opened.ReadCloser)
 
60
        h.ServeHTTP(resp, req)
 
61
 
 
62
        resp.checkWritten(c, "some data", http.Header{
 
63
                "Content-Type":   []string{api.ContentTypeRaw},
 
64
                "Content-Length": []string{"9"}, // len("some data")
 
65
                "Content-Sha384": []string{opened.Fingerprint.String()},
 
66
        })
 
67
}
 
68
 
 
69
func (s *UnitResourceHandlerSuite) TestNewUnitResourceHandler(c *gc.C) {
 
70
        h := server.NewUnitResourceHandler(s.deps)
 
71
 
 
72
        s.stub.CheckNoCalls(c)
 
73
        c.Check(h, gc.NotNil)
 
74
}
 
75
 
 
76
func (s *UnitResourceHandlerSuite) TestServeHTTPDownloadOkay(c *gc.C) {
 
77
        s.deps.ReturnNewResourceOpener = s.opener
 
78
        opened := resourcetesting.NewResource(c, s.stub, "spam", "a-service", "some data")
 
79
        s.deps.ReturnHandleDownload = opened
 
80
        h := &server.UnitResourceHandler{
 
81
                UnitResourceHandlerDeps: s.deps,
 
82
        }
 
83
        req, err := http.NewRequest("GET", "...", nil)
 
84
        c.Assert(err, jc.ErrorIsNil)
 
85
 
 
86
        h.ServeHTTP(s.resp, req)
 
87
 
 
88
        s.stub.CheckCallNames(c,
 
89
                "NewResourceOpener",
 
90
                "HandleDownload",
 
91
                "UpdateDownloadResponse",
 
92
                "WriteHeader",
 
93
                "Copy",
 
94
                "Close",
 
95
        )
 
96
        s.stub.CheckCall(c, 0, "NewResourceOpener", req)
 
97
        s.stub.CheckCall(c, 1, "HandleDownload", s.opener, req)
 
98
        s.stub.CheckCall(c, 2, "UpdateDownloadResponse", s.resp, opened.Resource)
 
99
        s.stub.CheckCall(c, 3, "WriteHeader", http.StatusOK)
 
100
        s.stub.CheckCall(c, 4, "Copy", s.resp, opened)
 
101
}
 
102
 
 
103
func (s *UnitResourceHandlerSuite) TestServeHTTPDownloadHandlerFailed(c *gc.C) {
 
104
        h := &server.UnitResourceHandler{
 
105
                UnitResourceHandlerDeps: s.deps,
 
106
        }
 
107
        failure := errors.New("<failure>")
 
108
        s.stub.SetErrors(nil, failure)
 
109
        req, err := http.NewRequest("GET", "...", nil)
 
110
        c.Assert(err, jc.ErrorIsNil)
 
111
 
 
112
        h.ServeHTTP(s.resp, req)
 
113
 
 
114
        s.stub.CheckCallNames(c,
 
115
                "NewResourceOpener",
 
116
                "HandleDownload",
 
117
                "SendHTTPError",
 
118
        )
 
119
        s.stub.CheckCall(c, 2, "SendHTTPError", s.resp, failure)
 
120
}
 
121
 
 
122
func (s *UnitResourceHandlerSuite) TestServeHTTPDownloadCopyFailed(c *gc.C) {
 
123
        s.deps.ReturnHandleDownload = resourcetesting.NewResource(c, s.stub, "spam", "a-service", "some data")
 
124
        h := &server.UnitResourceHandler{
 
125
                UnitResourceHandlerDeps: s.deps,
 
126
        }
 
127
        failure := errors.New("<failure>")
 
128
        s.stub.SetErrors(nil, nil, failure)
 
129
        req, err := http.NewRequest("GET", "...", nil)
 
130
        c.Assert(err, jc.ErrorIsNil)
 
131
 
 
132
        h.ServeHTTP(s.resp, req)
 
133
 
 
134
        s.stub.CheckCallNames(c,
 
135
                "NewResourceOpener",
 
136
                "HandleDownload",
 
137
                "UpdateDownloadResponse",
 
138
                "WriteHeader",
 
139
                "Copy",
 
140
                "Close",
 
141
        )
 
142
}
 
143
 
 
144
func (s *UnitResourceHandlerSuite) TestServeHTTPConnectFailed(c *gc.C) {
 
145
        h := &server.UnitResourceHandler{
 
146
                UnitResourceHandlerDeps: s.deps,
 
147
        }
 
148
        failure := errors.New("<failure>")
 
149
        s.stub.SetErrors(failure)
 
150
        req, err := http.NewRequest("GET", "...", nil)
 
151
        c.Assert(err, jc.ErrorIsNil)
 
152
 
 
153
        h.ServeHTTP(s.resp, req)
 
154
 
 
155
        s.stub.CheckCallNames(c,
 
156
                "NewResourceOpener",
 
157
                "SendHTTPError",
 
158
        )
 
159
        s.stub.CheckCall(c, 1, "SendHTTPError", s.resp, failure)
 
160
}
 
161
 
 
162
func (s *UnitResourceHandlerSuite) TestServeHTTPUnsupportedMethod(c *gc.C) {
 
163
        h := &server.UnitResourceHandler{
 
164
                UnitResourceHandlerDeps: s.deps,
 
165
        }
 
166
        req, err := http.NewRequest("HEAD", "...", nil)
 
167
        c.Assert(err, jc.ErrorIsNil)
 
168
 
 
169
        h.ServeHTTP(s.resp, req)
 
170
 
 
171
        s.stub.CheckCallNames(c,
 
172
                "NewResourceOpener",
 
173
                "SendHTTPError",
 
174
        )
 
175
}
 
176
 
 
177
type stubUnitResourceHandlerDeps struct {
 
178
        *testing.Stub
 
179
 
 
180
        ReturnNewResourceOpener resource.Opener
 
181
        ReturnHandleDownload    resource.Opened
 
182
}
 
183
 
 
184
func (s *stubUnitResourceHandlerDeps) NewResourceOpener(req *http.Request) (resource.Opener, error) {
 
185
        s.AddCall("NewResourceOpener", req)
 
186
        if err := s.NextErr(); err != nil {
 
187
                return nil, err
 
188
        }
 
189
 
 
190
        return s.ReturnNewResourceOpener, nil
 
191
}
 
192
 
 
193
func (s *stubUnitResourceHandlerDeps) SendHTTPError(resp http.ResponseWriter, err error) {
 
194
        s.AddCall("SendHTTPError", resp, err)
 
195
        s.NextErr() // Pop one off.
 
196
}
 
197
 
 
198
func (s *stubUnitResourceHandlerDeps) UpdateDownloadResponse(resp http.ResponseWriter, info resource.Resource) {
 
199
        s.AddCall("UpdateDownloadResponse", resp, info)
 
200
        s.NextErr() // Pop one off.
 
201
}
 
202
 
 
203
func (s *stubUnitResourceHandlerDeps) HandleDownload(opener resource.Opener, req *http.Request) (resource.Opened, error) {
 
204
        s.AddCall("HandleDownload", opener, req)
 
205
        if err := s.NextErr(); err != nil {
 
206
                return resource.Opened{}, err
 
207
        }
 
208
 
 
209
        return s.ReturnHandleDownload, nil
 
210
}
 
211
 
 
212
type stubResourceOpener struct {
 
213
        *testing.Stub
 
214
 
 
215
        ReturnOpenResource resource.Opened
 
216
}
 
217
 
 
218
func (s *stubResourceOpener) OpenResource(name string) (resource.Opened, error) {
 
219
        s.AddCall("OpenResource", name)
 
220
        if err := s.NextErr(); err != nil {
 
221
                return resource.Opened{}, err
 
222
        }
 
223
 
 
224
        return s.ReturnOpenResource, nil
 
225
}
 
226
 
 
227
func (s *stubUnitResourceHandlerDeps) Copy(w io.Writer, r io.Reader) error {
 
228
        s.AddCall("Copy", w, r)
 
229
        if err := s.NextErr(); err != nil {
 
230
                return err
 
231
        }
 
232
 
 
233
        return nil
 
234
}
 
235
 
 
236
type stubResponseWriter struct {
 
237
        *testing.Stub
 
238
        io.Writer
 
239
        buf *bytes.Buffer
 
240
 
 
241
        ReturnHeader http.Header
 
242
}
 
243
 
 
244
func newStubResponseWriter(stub *testing.Stub) *stubResponseWriter {
 
245
        writer, buf := filetesting.NewStubWriter(stub)
 
246
        return &stubResponseWriter{
 
247
                Stub:   stub,
 
248
                Writer: writer,
 
249
                buf:    buf,
 
250
 
 
251
                ReturnHeader: make(http.Header),
 
252
        }
 
253
}
 
254
 
 
255
func (s *stubResponseWriter) Header() http.Header {
 
256
        s.AddCall("Header")
 
257
        s.NextErr() // Pop one off.
 
258
 
 
259
        return s.ReturnHeader
 
260
}
 
261
 
 
262
func (s *stubResponseWriter) WriteHeader(code int) {
 
263
        s.AddCall("WriteHeader", code)
 
264
        s.NextErr() // Pop one off.
 
265
}
 
266
 
 
267
type fakeResponseWriter struct {
 
268
        *stubResponseWriter
 
269
 
 
270
        writeCalled   bool
 
271
        writtenHeader http.Header
 
272
}
 
273
 
 
274
func (f *fakeResponseWriter) checkWritten(c *gc.C, body string, header http.Header) {
 
275
        if !c.Check(f.writeCalled, jc.IsTrue) {
 
276
                return
 
277
        }
 
278
        c.Check(f.buf.String(), gc.Equals, body)
 
279
        c.Check(f.writtenHeader, jc.DeepEquals, header)
 
280
        c.Check(f.writtenHeader.Get("Content-Length"), gc.Equals, fmt.Sprint(len(body)))
 
281
}
 
282
 
 
283
func (f *fakeResponseWriter) WriteHeader(code int) {
 
284
        f.stubResponseWriter.WriteHeader(code)
 
285
 
 
286
        // See http.Header.clone() in the stdlib (net/http/header.go).
 
287
        header := make(http.Header)
 
288
        for k, vv := range f.ReturnHeader {
 
289
                vv2 := make([]string, len(vv))
 
290
                copy(vv2, vv)
 
291
                header[k] = vv2
 
292
        }
 
293
        f.writtenHeader = header
 
294
}
 
295
 
 
296
func (f *fakeResponseWriter) Write(data []byte) (int, error) {
 
297
        f.writeCalled = true
 
298
        if f.writtenHeader == nil {
 
299
                f.WriteHeader(http.StatusOK)
 
300
        }
 
301
        return f.stubResponseWriter.Write(data)
 
302
}