Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(198)

Side by Side Diff: store/http_test.go

Issue 5704056: store: add PublishCharmsDistro function
Patch Set: store: add PublishCharmsDistro function Created 12 years ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « store/branch_test.go ('k') | store/lpad.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 package store_test
2
3 import (
4 "bytes"
5 "fmt"
6 "io/ioutil"
7 . "launchpad.net/gocheck"
8 "net/http"
9 "net/url"
10 "os"
11 "time"
12 )
13
14 type HTTPSuite struct{}
15
16 var testServer = NewTestHTTPServer("http://localhost:4444", 5*time.Second)
17
18 func (s *HTTPSuite) SetUpSuite(c *C) {
19 testServer.Start()
20 }
21
22 func (s *HTTPSuite) TearDownTest(c *C) {
23 testServer.Flush()
24 }
25
26 type TestHTTPServer struct {
27 URL string
28 Timeout time.Duration
29 started bool
30 request chan *http.Request
31 response chan ResponseFunc
32 pending chan bool
33 }
34
35 func NewTestHTTPServer(url_ string, timeout time.Duration) *TestHTTPServer {
36 return &TestHTTPServer{URL: url_, Timeout: timeout}
37 }
38
39 type Response struct {
40 Status int
41 Headers map[string]string
42 Body string
43 }
44
45 type ResponseFunc func(path string) Response
46
47 func (s *TestHTTPServer) Start() {
48 if s.started {
49 return
50 }
51 s.started = true
52
53 s.request = make(chan *http.Request, 64)
54 s.response = make(chan ResponseFunc, 64)
55 s.pending = make(chan bool, 64)
56
57 url_, _ := url.Parse(s.URL)
58 go http.ListenAndServe(url_.Host, s)
59
60 s.Response(203, nil, "")
61 for {
62 // Wait for it to be up.
63 resp, err := http.Get(s.URL)
64 if err == nil && resp.StatusCode == 203 {
65 break
66 }
67 time.Sleep(1e8)
68 }
69 s.WaitRequest() // Consume dummy request.
70 }
71
72 // FlushRequests discards requests which were not yet consumed by WaitRequest.
73 func (s *TestHTTPServer) Flush() {
74 for {
75 select {
76 case <-s.request:
77 case <-s.response:
78 default:
79 return
80 }
81 }
82 }
83
84 func body(req *http.Request) string {
85 data, err := ioutil.ReadAll(req.Body)
86 if err != nil {
87 panic(err)
88 }
89 return string(data)
90 }
91
92 func (s *TestHTTPServer) ServeHTTP(w http.ResponseWriter, req *http.Request) {
93 req.ParseMultipartForm(1e6)
94 data, err := ioutil.ReadAll(req.Body)
95 if err != nil {
96 panic(err)
97 }
98 req.Body = ioutil.NopCloser(bytes.NewBuffer(data))
99 s.request <- req
100 var resp Response
101 select {
102 case respFunc := <-s.response:
103 resp = respFunc(req.URL.Path)
104 case <-time.After(s.Timeout):
105 const msg = "ERROR: Timeout waiting for test to prepare a respon se\n"
106 fmt.Fprintf(os.Stderr, msg)
107 resp = Response{500, nil, msg}
108 }
109 if resp.Headers != nil {
110 h := w.Header()
111 for k, v := range resp.Headers {
112 h.Set(k, v)
113 }
114 }
115 if resp.Status != 0 {
116 w.WriteHeader(resp.Status)
117 }
118 w.Write([]byte(resp.Body))
119 }
120
121 // WaitRequests returns the next n requests made to the http server from
122 // the queue. If not enough requests were previously made, it waits until
123 // the timeout value for them to be made.
124 func (s *TestHTTPServer) WaitRequests(n int) []*http.Request {
125 reqs := make([]*http.Request, 0, n)
126 for i := 0; i < n; i++ {
127 select {
128 case req := <-s.request:
129 reqs = append(reqs, req)
130 case <-time.After(s.Timeout):
131 panic("Timeout waiting for request")
132 }
133 }
134 return reqs
135 }
136
137 // WaitRequest returns the next request made to the http server from
138 // the queue. If no requests were previously made, it waits until the
139 // timeout value for one to be made.
140 func (s *TestHTTPServer) WaitRequest() *http.Request {
141 return s.WaitRequests(1)[0]
142 }
143
144 // ResponseFunc prepares the test server to respond the following n
145 // requests using f to build each response.
146 func (s *TestHTTPServer) ResponseFunc(n int, f ResponseFunc) {
147 for i := 0; i < n; i++ {
148 s.response <- f
149 }
150 }
151
152 // ResponseMap maps request paths to responses.
153 type ResponseMap map[string]Response
154
155 // ResponseMap prepares the test server to respond the following n
156 // requests using the m to obtain the responses.
157 func (s *TestHTTPServer) ResponseMap(n int, m ResponseMap) {
158 f := func(path string) Response {
159 for rpath, resp := range m {
160 if rpath == path {
161 return resp
162 }
163 }
164 return Response{Status: 500, Body: "Path not found in response m ap: " + path}
165 }
166 s.ResponseFunc(n, f)
167 }
168
169 // Responses prepares the test server to respond the following n requests
170 // using the provided response parameters.
171 func (s *TestHTTPServer) Responses(n int, status int, headers map[string]string, body string) {
172 f := func(path string) Response {
173 return Response{status, headers, body}
174 }
175 s.ResponseFunc(n, f)
176 }
177
178 // Response prepares the test server to respond the following request
179 // using the provided response parameters.
180 func (s *TestHTTPServer) Response(status int, headers map[string]string, body st ring) {
181 s.Responses(1, status, headers, body)
182 }
183
OLDNEW
« no previous file with comments | « store/branch_test.go ('k') | store/lpad.go » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b