~jtv/gwacl/storage-tool-command-line

19.1.1 by Jeroen Vermeulen
Refactor a bit, add POST support, test GET and POST. The latter test is still failing.
1
package gwacl
2
3
import (
174.1.2 by Gavin Panella
Check request body of x509 requests. This has highlighted a problem with PUT requests.
4
    "io/ioutil"
19.1.2 by Jeroen Vermeulen
Reformat.
5
    . "launchpad.net/gocheck"
6
    "net/http"
7
    "net/http/httptest"
216.1.1 by Raphael Badin
Add utility to retry requests when responses have specific http status codes.
8
    "time"
19.1.1 by Jeroen Vermeulen
Refactor a bit, add POST support, test GET and POST. The latter test is still failing.
9
)
10
64.1.1 by Jeroen Vermeulen
Unexport remaining test suites.
11
type x509DispatcherSuite struct{}
19.1.1 by Jeroen Vermeulen
Refactor a bit, add POST support, test GET and POST. The latter test is still failing.
12
64.1.1 by Jeroen Vermeulen
Unexport remaining test suites.
13
var _ = Suite(&x509DispatcherSuite{})
19.1.1 by Jeroen Vermeulen
Refactor a bit, add POST support, test GET and POST. The latter test is still failing.
14
174.1.2 by Gavin Panella
Check request body of x509 requests. This has highlighted a problem with PUT requests.
15
type Request struct {
16
    *http.Request
17
    BodyContent []byte
18
}
19
19.1.1 by Jeroen Vermeulen
Refactor a bit, add POST support, test GET and POST. The latter test is still failing.
20
// makeRecordingHTTPServer creates an http server (don't forget to Close() it when done)
21
// that serves at the given base URL, copies incoming requests into the given
22
// channel, and finally returns the given status code.  If body is not nil, it
23
// will be returned as the request body.
174.1.2 by Gavin Panella
Check request body of x509 requests. This has highlighted a problem with PUT requests.
24
func makeRecordingHTTPServer(requests chan *Request, status int, body []byte, headers http.Header) *httptest.Server {
19.1.2 by Jeroen Vermeulen
Reformat.
25
    returnRequest := func(w http.ResponseWriter, r *http.Request) {
174.1.2 by Gavin Panella
Check request body of x509 requests. This has highlighted a problem with PUT requests.
26
        // Capture all the request body content for later inspection.
27
        requestBody, err := ioutil.ReadAll(r.Body)
28
        if err != nil {
29
            panic(err)
30
        }
31
        requests <- &Request{r, requestBody}
32
147.2.2 by Raphael Badin
Review fixes.
33
        for header, values := range headers {
34
            for _, value := range values {
35
                w.Header().Set(header, value)
36
            }
147.2.1 by Raphael Badin
Follow redirections.
37
        }
19.1.3 by Jeroen Vermeulen
Get POST, and handling of request/response bodies, working.
38
        w.WriteHeader(status)
19.1.2 by Jeroen Vermeulen
Reformat.
39
        if body != nil {
40
            w.Write(body)
41
        }
42
    }
43
    serveMux := http.NewServeMux()
44
    serveMux.HandleFunc("/", returnRequest)
45
    return httptest.NewServer(serveMux)
19.1.1 by Jeroen Vermeulen
Refactor a bit, add POST support, test GET and POST. The latter test is still failing.
46
}
47
64.1.1 by Jeroen Vermeulen
Unexport remaining test suites.
48
func (*x509DispatcherSuite) TestGetRequestDoesHTTPGET(c *C) {
174.1.2 by Gavin Panella
Check request body of x509 requests. This has highlighted a problem with PUT requests.
49
    httpRequests := make(chan *Request, 1)
147.2.1 by Raphael Badin
Follow redirections.
50
    server := makeRecordingHTTPServer(httpRequests, http.StatusOK, nil, nil)
19.1.2 by Jeroen Vermeulen
Reformat.
51
    defer server.Close()
52
    // No real certificate needed since we're testing on http, not https.
216.1.1 by Raphael Badin
Add utility to retry requests when responses have specific http status codes.
53
    session, err := newX509Session("subscriptionid", "", "West US", NoRetryPolicy)
19.1.2 by Jeroen Vermeulen
Reformat.
54
    c.Assert(err, IsNil)
55
    path := "/foo/bar"
178.1.4 by Julian Edwards
Fix dispatcher etc tests
56
    version := "test-version"
180.1.1 by Gavin Panella
Format.
57
    request := newX509RequestGET(server.URL+path, version)
19.1.2 by Jeroen Vermeulen
Reformat.
58
193.3.1 by jtv at canonical
Try replacing curl with the standard http package. Still crashing weirdly deep in Go's runtime system though.
59
    response, err := performX509Request(session, request)
19.1.2 by Jeroen Vermeulen
Reformat.
60
    c.Assert(err, IsNil)
61
    c.Assert(response.StatusCode, Equals, http.StatusOK)
62
63
    httpRequest := <-httpRequests
64
    c.Check(httpRequest.Method, Equals, "GET")
178.1.5 by Julian Edwards
add more checks to ensure APIVersion is in the request headers as x-ms-version
65
    c.Check(httpRequest.Header[http.CanonicalHeaderKey("X-Ms-Version")], DeepEquals, []string{version})
19.1.2 by Jeroen Vermeulen
Reformat.
66
    c.Check(httpRequest.URL.String(), Equals, path)
174.1.2 by Gavin Panella
Check request body of x509 requests. This has highlighted a problem with PUT requests.
67
    c.Check(httpRequest.BodyContent, HasLen, 0)
19.1.1 by Jeroen Vermeulen
Refactor a bit, add POST support, test GET and POST. The latter test is still failing.
68
}
69
216.1.1 by Raphael Badin
Add utility to retry requests when responses have specific http status codes.
70
func (*x509DispatcherSuite) TestRetryPolicyCausesRequestsToBeRetried(c *C) {
71
    nbRetries := 2
72
    nbRequests := nbRetries + 1
73
    httpRequests := make(chan *Request, nbRequests)
74
    server := makeRecordingHTTPServer(httpRequests, http.StatusConflict, nil, nil)
75
    defer server.Close()
76
    // No real certificate needed since we're testing on http, not https.
216.1.4 by Raphael Badin
Export variables so this can be used from outside the library.
77
    retryPolicy := RetryPolicy{NbRetries: nbRetries, HttpStatusCodes: []int{http.StatusConflict}, Delay: time.Nanosecond}
216.1.1 by Raphael Badin
Add utility to retry requests when responses have specific http status codes.
78
    session, err := newX509Session("subscriptionid", "", "West US", retryPolicy)
79
    c.Assert(err, IsNil)
80
    path := "/foo/bar"
81
    version := "test-version"
82
    request := newX509RequestGET(server.URL+path, version)
83
84
    response, err := performX509Request(session, request)
85
    c.Assert(err, IsNil)
86
    c.Assert(response.StatusCode, Equals, http.StatusConflict)
87
88
    // nbRequests request were performed.
89
    c.Check(httpRequests, HasLen, nbRequests)
90
}
91
64.1.1 by Jeroen Vermeulen
Unexport remaining test suites.
92
func (*x509DispatcherSuite) TestPostRequestDoesHTTPPOST(c *C) {
174.1.2 by Gavin Panella
Check request body of x509 requests. This has highlighted a problem with PUT requests.
93
    httpRequests := make(chan *Request, 1)
19.1.2 by Jeroen Vermeulen
Reformat.
94
    requestBody := []byte{1, 2, 3}
95
    responseBody := []byte{4, 5, 6}
28.1.1 by Raphael Badin
Add method to create hosted service.
96
    requestContentType := "bogusContentType"
147.2.1 by Raphael Badin
Follow redirections.
97
    server := makeRecordingHTTPServer(httpRequests, http.StatusOK, responseBody, nil)
19.1.2 by Jeroen Vermeulen
Reformat.
98
    defer server.Close()
99
    // No real certificate needed since we're testing on http, not https.
216.1.1 by Raphael Badin
Add utility to retry requests when responses have specific http status codes.
100
    session, err := newX509Session("subscriptionid", "", "West US", NoRetryPolicy)
19.1.2 by Jeroen Vermeulen
Reformat.
101
    c.Assert(err, IsNil)
102
    path := "/foo/bar"
178.1.4 by Julian Edwards
Fix dispatcher etc tests
103
    version := "test-version"
104
    request := newX509RequestPOST(server.URL+path, version, requestBody, requestContentType)
19.1.2 by Jeroen Vermeulen
Reformat.
105
193.3.1 by jtv at canonical
Try replacing curl with the standard http package. Still crashing weirdly deep in Go's runtime system though.
106
    response, err := performX509Request(session, request)
19.1.2 by Jeroen Vermeulen
Reformat.
107
    c.Assert(err, IsNil)
108
    c.Assert(response.StatusCode, Equals, http.StatusOK)
174.1.2 by Gavin Panella
Check request body of x509 requests. This has highlighted a problem with PUT requests.
109
    c.Check(response.Body, DeepEquals, responseBody)
19.1.2 by Jeroen Vermeulen
Reformat.
110
111
    httpRequest := <-httpRequests
28.1.1 by Raphael Badin
Add method to create hosted service.
112
    c.Check(httpRequest.Header[http.CanonicalHeaderKey("Content-Type")], DeepEquals, []string{requestContentType})
113
    c.Check(httpRequest.Header[http.CanonicalHeaderKey("X-Ms-Version")], DeepEquals, []string{request.APIVersion})
19.1.2 by Jeroen Vermeulen
Reformat.
114
    c.Check(httpRequest.Method, Equals, "POST")
115
    c.Check(httpRequest.URL.String(), Equals, path)
174.1.2 by Gavin Panella
Check request body of x509 requests. This has highlighted a problem with PUT requests.
116
    c.Check(httpRequest.BodyContent, DeepEquals, requestBody)
19.1.1 by Jeroen Vermeulen
Refactor a bit, add POST support, test GET and POST. The latter test is still failing.
117
}
30.2.1 by Jeroen Vermeulen
Tests and skeleton: DELETE support. Tests: 1 panic.
118
64.1.1 by Jeroen Vermeulen
Unexport remaining test suites.
119
func (*x509DispatcherSuite) TestDeleteRequestDoesHTTPDELETE(c *C) {
174.1.2 by Gavin Panella
Check request body of x509 requests. This has highlighted a problem with PUT requests.
120
    httpRequests := make(chan *Request, 1)
147.2.1 by Raphael Badin
Follow redirections.
121
    server := makeRecordingHTTPServer(httpRequests, http.StatusOK, nil, nil)
30.2.1 by Jeroen Vermeulen
Tests and skeleton: DELETE support. Tests: 1 panic.
122
    defer server.Close()
123
    // No real certificate needed since we're testing on http, not https.
216.1.1 by Raphael Badin
Add utility to retry requests when responses have specific http status codes.
124
    session, err := newX509Session("subscriptionid", "", "West US", NoRetryPolicy)
30.2.1 by Jeroen Vermeulen
Tests and skeleton: DELETE support. Tests: 1 panic.
125
    c.Assert(err, IsNil)
126
    path := "/foo/bar"
178.1.4 by Julian Edwards
Fix dispatcher etc tests
127
    version := "test-version"
180.1.1 by Gavin Panella
Format.
128
    request := newX509RequestDELETE(server.URL+path, version)
30.2.1 by Jeroen Vermeulen
Tests and skeleton: DELETE support. Tests: 1 panic.
129
193.3.1 by jtv at canonical
Try replacing curl with the standard http package. Still crashing weirdly deep in Go's runtime system though.
130
    response, err := performX509Request(session, request)
30.2.1 by Jeroen Vermeulen
Tests and skeleton: DELETE support. Tests: 1 panic.
131
    c.Assert(err, IsNil)
132
    c.Assert(response.StatusCode, Equals, http.StatusOK)
133
134
    httpRequest := <-httpRequests
135
    c.Check(httpRequest.Method, Equals, "DELETE")
178.1.6 by Julian Edwards
add more checks to ensure APIVersion is in the request headers as x-ms-version
136
    c.Check(httpRequest.Header[http.CanonicalHeaderKey("X-Ms-Version")], DeepEquals, []string{version})
30.2.1 by Jeroen Vermeulen
Tests and skeleton: DELETE support. Tests: 1 panic.
137
    c.Check(httpRequest.URL.String(), Equals, path)
174.1.2 by Gavin Panella
Check request body of x509 requests. This has highlighted a problem with PUT requests.
138
    c.Check(httpRequest.BodyContent, HasLen, 0)
30.2.1 by Jeroen Vermeulen
Tests and skeleton: DELETE support. Tests: 1 panic.
139
}
32.1.1 by Jeroen Vermeulen
Support PUT.
140
64.1.1 by Jeroen Vermeulen
Unexport remaining test suites.
141
func (*x509DispatcherSuite) TestPutRequestDoesHTTPPUT(c *C) {
174.1.2 by Gavin Panella
Check request body of x509 requests. This has highlighted a problem with PUT requests.
142
    httpRequests := make(chan *Request, 1)
32.1.1 by Jeroen Vermeulen
Support PUT.
143
    requestBody := []byte{1, 2, 3}
144
    responseBody := []byte{4, 5, 6}
147.2.1 by Raphael Badin
Follow redirections.
145
    server := makeRecordingHTTPServer(httpRequests, http.StatusOK, responseBody, nil)
32.1.1 by Jeroen Vermeulen
Support PUT.
146
    defer server.Close()
147
    // No real certificate needed since we're testing on http, not https.
216.1.1 by Raphael Badin
Add utility to retry requests when responses have specific http status codes.
148
    session, err := newX509Session("subscriptionid", "", "West US", NoRetryPolicy)
32.1.1 by Jeroen Vermeulen
Support PUT.
149
    c.Assert(err, IsNil)
150
    path := "/foo/bar"
178.1.4 by Julian Edwards
Fix dispatcher etc tests
151
    version := "test-version"
152
    request := newX509RequestPUT(server.URL+path, version, requestBody, "application/octet-stream")
32.1.1 by Jeroen Vermeulen
Support PUT.
153
193.3.1 by jtv at canonical
Try replacing curl with the standard http package. Still crashing weirdly deep in Go's runtime system though.
154
    response, err := performX509Request(session, request)
32.1.1 by Jeroen Vermeulen
Support PUT.
155
    c.Assert(err, IsNil)
156
    c.Assert(response.StatusCode, Equals, http.StatusOK)
174.1.2 by Gavin Panella
Check request body of x509 requests. This has highlighted a problem with PUT requests.
157
    c.Check(response.Body, DeepEquals, responseBody)
32.1.1 by Jeroen Vermeulen
Support PUT.
158
159
    httpRequest := <-httpRequests
160
    c.Check(httpRequest.Method, Equals, "PUT")
178.1.6 by Julian Edwards
add more checks to ensure APIVersion is in the request headers as x-ms-version
161
    c.Check(httpRequest.Header[http.CanonicalHeaderKey("X-Ms-Version")], DeepEquals, []string{version})
32.1.1 by Jeroen Vermeulen
Support PUT.
162
    c.Check(httpRequest.URL.String(), Equals, path)
174.1.2 by Gavin Panella
Check request body of x509 requests. This has highlighted a problem with PUT requests.
163
    c.Check(httpRequest.BodyContent, DeepEquals, requestBody)
32.1.1 by Jeroen Vermeulen
Support PUT.
164
}
45.2.1 by Jeroen Vermeulen
Test and skeleton: get header from x509 response. Tests: 1 failure.
165
64.1.1 by Jeroen Vermeulen
Unexport remaining test suites.
166
func (*x509DispatcherSuite) TestRequestRegistersHeader(c *C) {
45.2.1 by Jeroen Vermeulen
Test and skeleton: get header from x509 response. Tests: 1 failure.
167
    customHeader := http.CanonicalHeaderKey("x-gwacl-test")
168
    customValue := []string{"present"}
169
    returnRequest := func(w http.ResponseWriter, r *http.Request) {
170
        w.Header()[customHeader] = customValue
171
        w.WriteHeader(http.StatusOK)
172
    }
173
    serveMux := http.NewServeMux()
174
    serveMux.HandleFunc("/", returnRequest)
175
    server := httptest.NewServer(serveMux)
176
    defer server.Close()
216.1.1 by Raphael Badin
Add utility to retry requests when responses have specific http status codes.
177
    session, err := newX509Session("subscriptionid", "", "West US", NoRetryPolicy)
45.2.1 by Jeroen Vermeulen
Test and skeleton: get header from x509 response. Tests: 1 failure.
178
    c.Assert(err, IsNil)
179
    path := "/foo/bar"
180.1.1 by Gavin Panella
Format.
180
    request := newX509RequestGET(server.URL+path, "testversion")
45.2.1 by Jeroen Vermeulen
Test and skeleton: get header from x509 response. Tests: 1 failure.
181
193.3.1 by jtv at canonical
Try replacing curl with the standard http package. Still crashing weirdly deep in Go's runtime system though.
182
    response, err := performX509Request(session, request)
45.2.1 by Jeroen Vermeulen
Test and skeleton: get header from x509 response. Tests: 1 failure.
183
    c.Assert(err, IsNil)
184
185
    c.Check(response.Header[customHeader], DeepEquals, customValue)
186
}