Merge lp:~niemeyer/goamz/testing-cleanup into lp:~gophers/goamz/trunk
- testing-cleanup
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 27 |
Proposed branch: | lp:~niemeyer/goamz/testing-cleanup |
Merge into: | lp:~gophers/goamz/trunk |
Diff against target: |
2514 lines (+427/-1143) 27 files modified
aws/aws_test.go (+5/-0) aws/suite_test.go (+0/-139) ec2/ec2.go (+17/-17) ec2/ec2_test.go (+38/-27) ec2/ec2i_test.go (+2/-4) ec2/ec2t_test.go (+5/-8) ec2/ec2test/filter.go (+2/-2) ec2/ec2test/server.go (+12/-12) ec2/sign.go (+4/-4) ec2/suite_test.go (+0/-118) exp/mturk/mturk.go (+5/-5) exp/mturk/mturk_test.go (+15/-4) exp/mturk/suite_test.go (+0/-120) exp/sdb/sdb.go (+3/-3) exp/sdb/sdb_test.go (+21/-10) exp/sdb/suite_test.go (+0/-139) exp/sns/sns_test.go (+13/-2) exp/sns/suite_test.go (+0/-200) iam/iam_test.go (+18/-7) iam/iami_test.go (+2/-4) iam/suite_test.go (+0/-128) s3/s3.go (+18/-13) s3/s3_test.go (+25/-14) s3/s3i_test.go (+18/-24) s3/suite_test.go (+0/-139) testutil/http.go (+174/-0) testutil/suite.go (+30/-0) |
To merge this branch: | bzr merge lp:~niemeyer/goamz/testing-cleanup |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
The Go Language Gophers | Pending | ||
Review via email: mp+145878@code.launchpad.net |
Commit message
Description of the change
testutil: new package for test clean up
Killed all the repetition in suite_test files, and improved the
implementation of the test HTTP server.
A few test bugs were also fixed on the way.
Gustavo Niemeyer (niemeyer) wrote : | # |
Roger Peppe (rogpeppe) wrote : | # |
LGTM except for the query about the default security group test.
nice to see all that code factored out.
https:/
File ec2/ec2_test.go (right):
https:/
ec2/ec2_test.go:24: testServer.Start()
that makes much more sense, given we're using the global below.
https:/
File ec2/ec2t_test.go (right):
https:/
ec2/ec2t_
s.ec2.SecurityG
why commented out? this was testing specific ec2test functionality.
have you tried these tests live? i seem to remember that
i needed to add the "default" group because it was
being returned for some of the filtering requests.
https:/
File ec2/ec2test/
https:/
ec2/ec2test/
later
align?
(and below)
https:/
File ec2/sign.go (right):
https:/
ec2/sign.go:23: // be in natural order of the keys. This is distinct
from the
s/in natural/in the natural/
?
https:/
File exp/mturk/
https:/
exp/mturk/
great to see all this duplication go away.
https:/
File s3/s3.go (right):
https:/
s3/s3.go:231: // into different groupings of keys, similar to how
folders would work.
s/would// ?
Gustavo Niemeyer (niemeyer) wrote : | # |
https:/
File ec2/ec2t_test.go (right):
https:/
ec2/ec2t_
s.ec2.SecurityG
On 2013/01/31 15:42:43, rog wrote:
> why commented out? this was testing specific ec2test functionality.
Sorry, it shouldn't be commented out. It should be removed. There's
nothing special about the default group, and the test is broken because
it trusts the system to only have a single group named default, which is
not a given.
> have you tried these tests live? i seem to remember that
> i needed to add the "default" group because it was
> being returned for some of the filtering requests.
Yeah, it was testing it live that forced me to fix it.
Roger Peppe (rogpeppe) wrote : | # |
On 31 January 2013 15:58, <email address hidden> wrote:
>
> https:/
> File ec2/ec2t_test.go (right):
>
> https:/
> ec2/ec2t_
> s.ec2.SecurityG
> On 2013/01/31 15:42:43, rog wrote:
>>
>> why commented out? this was testing specific ec2test functionality.
>
>
> Sorry, it shouldn't be commented out. It should be removed. There's
> nothing special about the default group, and the test is broken because
> it trusts the system to only have a single group named default, which is
> not a given.
The default is created by automatically, can't be removed, and has
default permissions
set up for tcp and udp (which means that it gets selected by some of
the filters)
if you try to create another group called "default", you get a
"The security group 'default' is reserved" error.
That seems fairly special to me - I *think* we're always guaranteed
a single group named default... but maybe that's only true of us-east.
How did the test fail for you? I'd definitely like to understand more about
the problem before changing those tests.
Gustavo Niemeyer (niemeyer) wrote : | # |
On 2013/01/31 17:01:29, rog wrote:
> The default is created by automatically, can't be removed, and has
> default permissions set up for tcp and udp (which means that it
> gets selected by some of the filters)
None of that seems relevant for filtering.
> if you try to create another group called "default", you get a
> "The security group 'default' is reserved" error.
I have two groups named "default" in my account, and that's breaking the
test case. One of them comes from VPC. Amazon created it.
> That seems fairly special to me - I *think* we're always guaranteed
> a single group named default... but maybe that's only true of us-east.
I'm not lying, promise.
- 28. By Gustavo Niemeyer
-
Review by Roger.
Gustavo Niemeyer (niemeyer) wrote : | # |
Please take a look.
https:/
File ec2/ec2test/
https:/
ec2/ec2test/
later
On 2013/01/31 15:42:43, rog wrote:
> align?
> (and below)
Done.
https:/
File ec2/sign.go (right):
https:/
ec2/sign.go:23: // be in natural order of the keys. This is distinct
from the
On 2013/01/31 15:42:43, rog wrote:
> s/in natural/in the natural/
> ?
Done.
https:/
File s3/s3.go (right):
https:/
s3/s3.go:231: // into different groupings of keys, similar to how
folders would work.
On 2013/01/31 15:42:43, rog wrote:
> s/would// ?
That's how they would work if S3 used the concept of folders. It
doesn't, so it doesn't work quite that way.
Gustavo Niemeyer (niemeyer) wrote : | # |
*** Submitted:
testutil: new package for test clean up
Killed all the repetition in suite_test files, and improved the
implementation of the test HTTP server.
A few test bugs were also fixed on the way.
R=rog
CC=
https:/
Preview Diff
1 | === modified file 'aws/aws_test.go' |
2 | --- aws/aws_test.go 2012-07-02 23:36:49 +0000 |
3 | +++ aws/aws_test.go 2013-01-31 17:09:20 +0000 |
4 | @@ -5,8 +5,13 @@ |
5 | . "launchpad.net/gocheck" |
6 | "os" |
7 | "strings" |
8 | + "testing" |
9 | ) |
10 | |
11 | +func Test(t *testing.T) { |
12 | + TestingT(t) |
13 | +} |
14 | + |
15 | var _ = Suite(&S{}) |
16 | |
17 | type S struct { |
18 | |
19 | === removed file 'aws/suite_test.go' |
20 | --- aws/suite_test.go 2012-05-03 17:12:28 +0000 |
21 | +++ aws/suite_test.go 1970-01-01 00:00:00 +0000 |
22 | @@ -1,139 +0,0 @@ |
23 | -package aws_test |
24 | - |
25 | -import ( |
26 | - "flag" |
27 | - "fmt" |
28 | - "launchpad.net/goamz/aws" |
29 | - . "launchpad.net/gocheck" |
30 | - "net/http" |
31 | - "net/url" |
32 | - "os" |
33 | - "testing" |
34 | - "time" |
35 | -) |
36 | - |
37 | -func Test(t *testing.T) { |
38 | - TestingT(t) |
39 | -} |
40 | - |
41 | -var integration = flag.Bool("i", false, "Enable integration tests") |
42 | - |
43 | -type SuiteI struct { |
44 | - auth aws.Auth |
45 | -} |
46 | - |
47 | -func (s *SuiteI) SetUpSuite(c *C) { |
48 | - if !*integration { |
49 | - c.Skip("Integration tests not enabled (-int flag)") |
50 | - } |
51 | - auth, err := aws.EnvAuth() |
52 | - if err != nil { |
53 | - c.Fatal(err) |
54 | - } |
55 | - s.auth = auth |
56 | -} |
57 | - |
58 | -type HTTPSuite struct{} |
59 | - |
60 | -var testServer = NewTestHTTPServer("http://localhost:4444", 5*time.Second) |
61 | - |
62 | -func (s *HTTPSuite) SetUpSuite(c *C) { |
63 | - testServer.Start() |
64 | -} |
65 | - |
66 | -func (s *HTTPSuite) TearDownTest(c *C) { |
67 | - testServer.FlushRequests() |
68 | -} |
69 | - |
70 | -type TestHTTPServer struct { |
71 | - URL string |
72 | - Timeout time.Duration |
73 | - started bool |
74 | - request chan *http.Request |
75 | - response chan *testResponse |
76 | - pending chan bool |
77 | -} |
78 | - |
79 | -type testResponse struct { |
80 | - Status int |
81 | - Headers map[string]string |
82 | - Body string |
83 | -} |
84 | - |
85 | -func NewTestHTTPServer(url_ string, timeout time.Duration) *TestHTTPServer { |
86 | - return &TestHTTPServer{URL: url_, Timeout: timeout} |
87 | -} |
88 | - |
89 | -func (s *TestHTTPServer) Start() { |
90 | - if s.started { |
91 | - return |
92 | - } |
93 | - s.started = true |
94 | - |
95 | - s.request = make(chan *http.Request, 64) |
96 | - s.response = make(chan *testResponse, 64) |
97 | - s.pending = make(chan bool, 64) |
98 | - |
99 | - url, _ := url.Parse(s.URL) |
100 | - go http.ListenAndServe(url.Host, s) |
101 | - |
102 | - s.PrepareResponse(123, nil, "") |
103 | - for { |
104 | - // Wait for it to be up. |
105 | - resp, err := http.Get(s.URL) |
106 | - if err == nil && resp.StatusCode == 123 { |
107 | - break |
108 | - } |
109 | - fmt.Fprintf(os.Stderr, "\nWaiting for fake server to be up... ") |
110 | - time.Sleep(1e8) |
111 | - } |
112 | - fmt.Fprintf(os.Stderr, "done\n\n") |
113 | - s.WaitRequest() // Consume dummy request. |
114 | -} |
115 | - |
116 | -// FlushRequests discards requests which were not yet consumed by WaitRequest. |
117 | -func (s *TestHTTPServer) FlushRequests() { |
118 | - for { |
119 | - select { |
120 | - case <-s.request: |
121 | - default: |
122 | - return |
123 | - } |
124 | - } |
125 | -} |
126 | - |
127 | -func (s *TestHTTPServer) ServeHTTP(w http.ResponseWriter, req *http.Request) { |
128 | - s.request <- req |
129 | - var resp *testResponse |
130 | - select { |
131 | - case resp = <-s.response: |
132 | - case <-time.After(s.Timeout): |
133 | - fmt.Fprintf(os.Stderr, "ERROR: Timeout waiting for test to provide response\n") |
134 | - resp = &testResponse{500, nil, ""} |
135 | - } |
136 | - h := w.Header() |
137 | - if resp.Headers != nil { |
138 | - for k, v := range resp.Headers { |
139 | - h.Set(k, v) |
140 | - } |
141 | - } |
142 | - if resp.Status != 0 { |
143 | - w.WriteHeader(resp.Status) |
144 | - } |
145 | - w.Write([]byte(resp.Body)) |
146 | -} |
147 | - |
148 | -func (s *TestHTTPServer) WaitRequest() *http.Request { |
149 | - select { |
150 | - case req := <-s.request: |
151 | - req.ParseForm() |
152 | - return req |
153 | - case <-time.After(s.Timeout): |
154 | - panic("Timeout waiting for goamz request") |
155 | - } |
156 | - panic("unreached") |
157 | -} |
158 | - |
159 | -func (s *TestHTTPServer) PrepareResponse(status int, headers map[string]string, body string) { |
160 | - s.response <- &testResponse{status, headers, body} |
161 | -} |
162 | |
163 | === modified file 'ec2/ec2.go' |
164 | --- ec2/ec2.go 2012-10-28 16:05:46 +0000 |
165 | +++ ec2/ec2.go 2013-01-31 17:09:20 +0000 |
166 | @@ -86,7 +86,7 @@ |
167 | // ---------------------------------------------------------------------------- |
168 | // Request dispatching logic. |
169 | |
170 | -// Error encapsulates an error returned by EC2. |
171 | +// Error encapsulates an error returned by EC2. |
172 | // |
173 | // See http://goo.gl/VZGuC for more details. |
174 | type Error struct { |
175 | @@ -425,15 +425,15 @@ |
176 | // |
177 | // See http://goo.gl/wnDBf for more details. |
178 | type BlockDeviceMapping struct { |
179 | - DeviceName string `xml:"deviceName"` |
180 | - VirtualName string `xml:"virtualName"` |
181 | - SnapshotId string `xml:"ebs>snapshotId"` |
182 | - VolumeType string `xml:"ebs>volumeType"` |
183 | - VolumeSize int64 `xml:"ebs>volumeSize"` |
184 | - DeleteOnTermination bool `xml:"ebs>deleteOnTermination"` |
185 | + DeviceName string `xml:"deviceName"` |
186 | + VirtualName string `xml:"virtualName"` |
187 | + SnapshotId string `xml:"ebs>snapshotId"` |
188 | + VolumeType string `xml:"ebs>volumeType"` |
189 | + VolumeSize int64 `xml:"ebs>volumeSize"` |
190 | + DeleteOnTermination bool `xml:"ebs>deleteOnTermination"` |
191 | |
192 | // The number of I/O operations per second (IOPS) that the volume supports. |
193 | - IOPS int64 `xml:"ebs>iops"` |
194 | + IOPS int64 `xml:"ebs>iops"` |
195 | } |
196 | |
197 | // Image represents details about an image. |
198 | @@ -467,7 +467,7 @@ |
199 | // For example, to get all the private images associated with this account set |
200 | // the boolean filter "is-private" to true. |
201 | // |
202 | -// Note: calling this function with nil ids and filter parameters will result in |
203 | +// Note: calling this function with nil ids and filter parameters will result in |
204 | // a very large number of images being returned. |
205 | // |
206 | // See http://goo.gl/SRBhW for more details. |
207 | @@ -512,11 +512,11 @@ |
208 | |
209 | // DeleteSnapshots deletes the volume snapshots with the given ids. |
210 | // |
211 | -// Note: If you make periodic snapshots of a volume, the snapshots are |
212 | -// incremental so that only the blocks on the device that have changed |
213 | -// since your last snapshot are incrementally saved in the new snapshot. |
214 | -// Even though snapshots are saved incrementally, the snapshot deletion |
215 | -// process is designed so that you need to retain only the most recent |
216 | +// Note: If you make periodic snapshots of a volume, the snapshots are |
217 | +// incremental so that only the blocks on the device that have changed |
218 | +// since your last snapshot are incrementally saved in the new snapshot. |
219 | +// Even though snapshots are saved incrementally, the snapshot deletion |
220 | +// process is designed so that you need to retain only the most recent |
221 | // snapshot in order to restore the volume. |
222 | // |
223 | // See http://goo.gl/vwU1y for more details. |
224 | @@ -558,7 +558,7 @@ |
225 | Tags []Tag `xml:"tagSet>item"` |
226 | } |
227 | |
228 | -// Snapshots returns details about volume snapshots available to the user. |
229 | +// Snapshots returns details about volume snapshots available to the user. |
230 | // The ids and filter parameters, if provided, limit the snapshots returned. |
231 | // |
232 | // See http://goo.gl/ogJL4 for more details. |
233 | @@ -620,7 +620,7 @@ |
234 | Groups []SecurityGroupInfo `xml:"securityGroupInfo>item"` |
235 | } |
236 | |
237 | -// SecurityGroup encapsulates details for a security group in EC2. |
238 | +// SecurityGroup encapsulates details for a security group in EC2. |
239 | // |
240 | // See http://goo.gl/CIdyP for more details. |
241 | type SecurityGroupInfo struct { |
242 | @@ -785,7 +785,7 @@ |
243 | } |
244 | |
245 | // CreateTags adds or overwrites one or more tags for the specified instance ids. |
246 | -// |
247 | +// |
248 | // See http://goo.gl/Vmkqc for more details |
249 | func (ec2 *EC2) CreateTags(instIds []string, tags []Tag) (resp *SimpleResp, err error) { |
250 | params := makeParams("CreateTags") |
251 | |
252 | === modified file 'ec2/ec2_test.go' |
253 | --- ec2/ec2_test.go 2012-10-18 18:56:09 +0000 |
254 | +++ ec2/ec2_test.go 2013-01-31 17:09:20 +0000 |
255 | @@ -3,24 +3,35 @@ |
256 | import ( |
257 | "launchpad.net/goamz/aws" |
258 | "launchpad.net/goamz/ec2" |
259 | + "launchpad.net/goamz/testutil" |
260 | . "launchpad.net/gocheck" |
261 | + "testing" |
262 | ) |
263 | |
264 | +func Test(t *testing.T) { |
265 | + TestingT(t) |
266 | +} |
267 | + |
268 | var _ = Suite(&S{}) |
269 | |
270 | type S struct { |
271 | - HTTPSuite |
272 | ec2 *ec2.EC2 |
273 | } |
274 | |
275 | +var testServer = testutil.NewHTTPServer() |
276 | + |
277 | func (s *S) SetUpSuite(c *C) { |
278 | - s.HTTPSuite.SetUpSuite(c) |
279 | + testServer.Start() |
280 | auth := aws.Auth{"abc", "123"} |
281 | s.ec2 = ec2.New(auth, aws.Region{EC2Endpoint: testServer.URL}) |
282 | } |
283 | |
284 | +func (s *S) TearDownTest(c *C) { |
285 | + testServer.Flush() |
286 | +} |
287 | + |
288 | func (s *S) TestRunInstancesErrorDump(c *C) { |
289 | - testServer.PrepareResponse(400, nil, ErrorDump) |
290 | + testServer.Response(400, nil, ErrorDump) |
291 | |
292 | options := ec2.RunInstances{ |
293 | ImageId: "ami-a6f504cf", // Ubuntu Maverick, i386, instance store |
294 | @@ -45,7 +56,7 @@ |
295 | } |
296 | |
297 | func (s *S) TestRunInstancesErrorWithoutXML(c *C) { |
298 | - testServer.PrepareResponse(500, nil, "") |
299 | + testServer.Response(500, nil, "") |
300 | options := ec2.RunInstances{ImageId: "image-id"} |
301 | |
302 | resp, err := s.ec2.RunInstances(&options) |
303 | @@ -64,7 +75,7 @@ |
304 | } |
305 | |
306 | func (s *S) TestRunInstancesExample(c *C) { |
307 | - testServer.PrepareResponse(200, nil, RunInstancesExample) |
308 | + testServer.Response(200, nil, RunInstancesExample) |
309 | |
310 | options := ec2.RunInstances{ |
311 | KeyName: "my-keys", |
312 | @@ -145,7 +156,7 @@ |
313 | } |
314 | |
315 | func (s *S) TestTerminateInstancesExample(c *C) { |
316 | - testServer.PrepareResponse(200, nil, TerminateInstancesExample) |
317 | + testServer.Response(200, nil, TerminateInstancesExample) |
318 | |
319 | resp, err := s.ec2.TerminateInstances([]string{"i-1", "i-2"}) |
320 | |
321 | @@ -175,7 +186,7 @@ |
322 | } |
323 | |
324 | func (s *S) TestDescribeInstancesExample1(c *C) { |
325 | - testServer.PrepareResponse(200, nil, DescribeInstancesExample1) |
326 | + testServer.Response(200, nil, DescribeInstancesExample1) |
327 | |
328 | filter := ec2.NewFilter() |
329 | filter.Add("key1", "value1") |
330 | @@ -207,7 +218,7 @@ |
331 | } |
332 | |
333 | func (s *S) TestDescribeInstancesExample2(c *C) { |
334 | - testServer.PrepareResponse(200, nil, DescribeInstancesExample2) |
335 | + testServer.Response(200, nil, DescribeInstancesExample2) |
336 | |
337 | filter := ec2.NewFilter() |
338 | filter.Add("key1", "value1") |
339 | @@ -244,7 +255,7 @@ |
340 | } |
341 | |
342 | func (s *S) TestDescribeImagesExample(c *C) { |
343 | - testServer.PrepareResponse(200, nil, DescribeImagesExample) |
344 | + testServer.Response(200, nil, DescribeImagesExample) |
345 | |
346 | filter := ec2.NewFilter() |
347 | filter.Add("key1", "value1") |
348 | @@ -292,7 +303,7 @@ |
349 | } |
350 | |
351 | func (s *S) TestCreateSnapshotExample(c *C) { |
352 | - testServer.PrepareResponse(200, nil, CreateSnapshotExample) |
353 | + testServer.Response(200, nil, CreateSnapshotExample) |
354 | |
355 | resp, err := s.ec2.CreateSnapshot("vol-4d826724", "Daily Backup") |
356 | |
357 | @@ -314,7 +325,7 @@ |
358 | } |
359 | |
360 | func (s *S) TestDeleteSnapshotsExample(c *C) { |
361 | - testServer.PrepareResponse(200, nil, DeleteSnapshotExample) |
362 | + testServer.Response(200, nil, DeleteSnapshotExample) |
363 | |
364 | resp, err := s.ec2.DeleteSnapshots([]string{"snap-78a54011"}) |
365 | |
366 | @@ -327,7 +338,7 @@ |
367 | } |
368 | |
369 | func (s *S) TestDescribeSnapshotsExample(c *C) { |
370 | - testServer.PrepareResponse(200, nil, DescribeSnapshotsExample) |
371 | + testServer.Response(200, nil, DescribeSnapshotsExample) |
372 | |
373 | filter := ec2.NewFilter() |
374 | filter.Add("key1", "value1") |
375 | @@ -366,7 +377,7 @@ |
376 | } |
377 | |
378 | func (s *S) TestCreateSecurityGroupExample(c *C) { |
379 | - testServer.PrepareResponse(200, nil, CreateSecurityGroupExample) |
380 | + testServer.Response(200, nil, CreateSecurityGroupExample) |
381 | |
382 | resp, err := s.ec2.CreateSecurityGroup("websrv", "Web Servers") |
383 | |
384 | @@ -382,7 +393,7 @@ |
385 | } |
386 | |
387 | func (s *S) TestDescribeSecurityGroupsExample(c *C) { |
388 | - testServer.PrepareResponse(200, nil, DescribeSecurityGroupsExample) |
389 | + testServer.Response(200, nil, DescribeSecurityGroupsExample) |
390 | |
391 | resp, err := s.ec2.SecurityGroups([]ec2.SecurityGroup{{Name: "WebServers"}, {Name: "RangedPortsBySource"}}, nil) |
392 | |
393 | @@ -423,7 +434,7 @@ |
394 | } |
395 | |
396 | func (s *S) TestDescribeSecurityGroupsExampleWithFilter(c *C) { |
397 | - testServer.PrepareResponse(200, nil, DescribeSecurityGroupsExample) |
398 | + testServer.Response(200, nil, DescribeSecurityGroupsExample) |
399 | |
400 | filter := ec2.NewFilter() |
401 | filter.Add("ip-permission.protocol", "tcp") |
402 | @@ -449,7 +460,7 @@ |
403 | } |
404 | |
405 | func (s *S) TestDescribeSecurityGroupsDumpWithGroup(c *C) { |
406 | - testServer.PrepareResponse(200, nil, DescribeSecurityGroupsDump) |
407 | + testServer.Response(200, nil, DescribeSecurityGroupsDump) |
408 | |
409 | resp, err := s.ec2.SecurityGroups(nil, nil) |
410 | |
411 | @@ -477,7 +488,7 @@ |
412 | } |
413 | |
414 | func (s *S) TestDeleteSecurityGroupExample(c *C) { |
415 | - testServer.PrepareResponse(200, nil, DeleteSecurityGroupExample) |
416 | + testServer.Response(200, nil, DeleteSecurityGroupExample) |
417 | |
418 | resp, err := s.ec2.DeleteSecurityGroup(ec2.SecurityGroup{Name: "websrv"}) |
419 | req := testServer.WaitRequest() |
420 | @@ -490,7 +501,7 @@ |
421 | } |
422 | |
423 | func (s *S) TestDeleteSecurityGroupExampleWithId(c *C) { |
424 | - testServer.PrepareResponse(200, nil, DeleteSecurityGroupExample) |
425 | + testServer.Response(200, nil, DeleteSecurityGroupExample) |
426 | |
427 | // ignore return and error - we're only want to check the parameter handling. |
428 | s.ec2.DeleteSecurityGroup(ec2.SecurityGroup{Id: "sg-67ad940e", Name: "ignored"}) |
429 | @@ -501,7 +512,7 @@ |
430 | } |
431 | |
432 | func (s *S) TestAuthorizeSecurityGroupExample1(c *C) { |
433 | - testServer.PrepareResponse(200, nil, AuthorizeSecurityGroupIngressExample) |
434 | + testServer.Response(200, nil, AuthorizeSecurityGroupIngressExample) |
435 | |
436 | perms := []ec2.IPPerm{{ |
437 | Protocol: "tcp", |
438 | @@ -526,7 +537,7 @@ |
439 | } |
440 | |
441 | func (s *S) TestAuthorizeSecurityGroupExample1WithId(c *C) { |
442 | - testServer.PrepareResponse(200, nil, AuthorizeSecurityGroupIngressExample) |
443 | + testServer.Response(200, nil, AuthorizeSecurityGroupIngressExample) |
444 | |
445 | perms := []ec2.IPPerm{{ |
446 | Protocol: "tcp", |
447 | @@ -544,7 +555,7 @@ |
448 | } |
449 | |
450 | func (s *S) TestAuthorizeSecurityGroupExample2(c *C) { |
451 | - testServer.PrepareResponse(200, nil, AuthorizeSecurityGroupIngressExample) |
452 | + testServer.Response(200, nil, AuthorizeSecurityGroupIngressExample) |
453 | |
454 | perms := []ec2.IPPerm{{ |
455 | Protocol: "tcp", |
456 | @@ -577,7 +588,7 @@ |
457 | func (s *S) TestRevokeSecurityGroupExample(c *C) { |
458 | // RevokeSecurityGroup is implemented by the same code as AuthorizeSecurityGroup |
459 | // so there's no need to duplicate all the tests. |
460 | - testServer.PrepareResponse(200, nil, RevokeSecurityGroupIngressExample) |
461 | + testServer.Response(200, nil, RevokeSecurityGroupIngressExample) |
462 | |
463 | resp, err := s.ec2.RevokeSecurityGroup(ec2.SecurityGroup{Name: "websrv"}, nil) |
464 | |
465 | @@ -590,7 +601,7 @@ |
466 | } |
467 | |
468 | func (s *S) TestCreateTags(c *C) { |
469 | - testServer.PrepareResponse(200, nil, CreateTagsExample) |
470 | + testServer.Response(200, nil, CreateTagsExample) |
471 | |
472 | resp, err := s.ec2.CreateTags([]string{"ami-1a2b3c4d", "i-7f4d3a2b"}, []ec2.Tag{{"webserver", ""}, {"stack", "Production"}}) |
473 | |
474 | @@ -607,7 +618,7 @@ |
475 | } |
476 | |
477 | func (s *S) TestStartInstances(c *C) { |
478 | - testServer.PrepareResponse(200, nil, StartInstancesExample) |
479 | + testServer.Response(200, nil, StartInstancesExample) |
480 | |
481 | resp, err := s.ec2.StartInstances("i-10a64379") |
482 | req := testServer.WaitRequest() |
483 | @@ -627,7 +638,7 @@ |
484 | } |
485 | |
486 | func (s *S) TestStopInstances(c *C) { |
487 | - testServer.PrepareResponse(200, nil, StopInstancesExample) |
488 | + testServer.Response(200, nil, StopInstancesExample) |
489 | |
490 | resp, err := s.ec2.StopInstances("i-10a64379") |
491 | req := testServer.WaitRequest() |
492 | @@ -647,7 +658,7 @@ |
493 | } |
494 | |
495 | func (s *S) TestRebootInstances(c *C) { |
496 | - testServer.PrepareResponse(200, nil, RebootInstancesExample) |
497 | + testServer.Response(200, nil, RebootInstancesExample) |
498 | |
499 | resp, err := s.ec2.RebootInstances("i-10a64379") |
500 | req := testServer.WaitRequest() |
501 | @@ -663,7 +674,7 @@ |
502 | ec2.FakeTime(true) |
503 | defer ec2.FakeTime(false) |
504 | |
505 | - testServer.PrepareResponse(200, nil, RebootInstancesExample) |
506 | + testServer.Response(200, nil, RebootInstancesExample) |
507 | |
508 | // https://bugs.launchpad.net/goamz/+bug/1022749 |
509 | ec2 := ec2.New(s.ec2.Auth, aws.Region{EC2Endpoint: testServer.URL + "/services/Cloud"}) |
510 | |
511 | === modified file 'ec2/ec2i_test.go' |
512 | --- ec2/ec2i_test.go 2012-10-28 16:05:46 +0000 |
513 | +++ ec2/ec2i_test.go 2013-01-31 17:09:20 +0000 |
514 | @@ -2,15 +2,13 @@ |
515 | |
516 | import ( |
517 | "crypto/rand" |
518 | - "flag" |
519 | "fmt" |
520 | "launchpad.net/goamz/aws" |
521 | "launchpad.net/goamz/ec2" |
522 | + "launchpad.net/goamz/testutil" |
523 | . "launchpad.net/gocheck" |
524 | ) |
525 | |
526 | -var amazon = flag.Bool("amazon", false, "Enable tests against amazon server") |
527 | - |
528 | // AmazonServer represents an Amazon EC2 server. |
529 | type AmazonServer struct { |
530 | auth aws.Auth |
531 | @@ -34,7 +32,7 @@ |
532 | } |
533 | |
534 | func (s *AmazonClientSuite) SetUpSuite(c *C) { |
535 | - if !*amazon { |
536 | + if !testutil.Amazon { |
537 | c.Skip("AmazonClientSuite tests not enabled") |
538 | } |
539 | s.srv.SetUp(c) |
540 | |
541 | === modified file 'ec2/ec2t_test.go' |
542 | --- ec2/ec2t_test.go 2012-10-28 16:05:46 +0000 |
543 | +++ ec2/ec2t_test.go 2013-01-31 17:09:20 +0000 |
544 | @@ -5,6 +5,7 @@ |
545 | "launchpad.net/goamz/aws" |
546 | "launchpad.net/goamz/ec2" |
547 | "launchpad.net/goamz/ec2/ec2test" |
548 | + "launchpad.net/goamz/testutil" |
549 | . "launchpad.net/gocheck" |
550 | "regexp" |
551 | "sort" |
552 | @@ -88,7 +89,7 @@ |
553 | var _ = Suite(&AmazonServerSuite{}) |
554 | |
555 | func (s *AmazonServerSuite) SetUpSuite(c *C) { |
556 | - if !*amazon { |
557 | + if !testutil.Amazon { |
558 | c.Skip("AmazonServerSuite tests not enabled") |
559 | } |
560 | s.srv.SetUp(c) |
561 | @@ -435,17 +436,13 @@ |
562 | |
563 | func (s *ServerTests) TestGroupFiltering(c *C) { |
564 | g := make([]ec2.SecurityGroup, 4) |
565 | - for i := range g[0:3] { |
566 | + for i := range g { |
567 | resp, err := s.ec2.CreateSecurityGroup(sessionName(fmt.Sprintf("testgroup%d", i)), fmt.Sprintf("testdescription%d", i)) |
568 | c.Assert(err, IsNil) |
569 | g[i] = resp.SecurityGroup |
570 | c.Logf("group %d: %v", i, g[i]) |
571 | defer s.ec2.DeleteSecurityGroup(g[i]) |
572 | } |
573 | - // Get the default group. |
574 | - resp, err := s.ec2.SecurityGroups([]ec2.SecurityGroup{{Name: "default"}}, nil) |
575 | - c.Assert(err, IsNil) |
576 | - g[3] = resp.Groups[0].SecurityGroup |
577 | |
578 | perms := [][]ec2.IPPerm{ |
579 | {{ |
580 | @@ -536,7 +533,7 @@ |
581 | filterCheck("group-name", g[2].Name, groups(2)), |
582 | filterCheck("ip-permission.cidr", "1.2.3.4/32", groups(0)), |
583 | filterCheck("ip-permission.group-name", g[1].Name, groups(1, 2)), |
584 | - filterCheck("ip-permission.protocol", "udp", groups(2, 3)), |
585 | + filterCheck("ip-permission.protocol", "udp", groups(2)), |
586 | filterCheck("ip-permission.from-port", "200", groups(1, 2)), |
587 | filterCheck("ip-permission.to-port", "200", groups(0)), |
588 | // TODO owner-id |
589 | @@ -568,7 +565,7 @@ |
590 | if t.allowExtra { |
591 | namePat := regexp.MustCompile(sessionName("testgroup[0-9]")) |
592 | for id, g := range groups { |
593 | - if g.Name != "default" && !namePat.MatchString(g.Name) { |
594 | + if !namePat.MatchString(g.Name) { |
595 | delete(groups, id) |
596 | } |
597 | } |
598 | |
599 | === modified file 'ec2/ec2test/filter.go' |
600 | --- ec2/ec2test/filter.go 2012-03-09 14:02:34 +0000 |
601 | +++ ec2/ec2test/filter.go 2013-01-31 17:09:20 +0000 |
602 | @@ -13,13 +13,13 @@ |
603 | type filter map[string][]string |
604 | |
605 | // newFilter creates a new filter from the Filter fields in the url form. |
606 | -// |
607 | +// |
608 | // The filtering is specified through a map of name=>values, where the |
609 | // name is a well-defined key identifying the data to be matched, |
610 | // and the list of values holds the possible values the filtered |
611 | // item can take for the key to be included in the |
612 | // result set. For example: |
613 | -// |
614 | +// |
615 | // Filter.1.Name=instance-type |
616 | // Filter.1.Value.1=m1.small |
617 | // Filter.1.Value.2=m1.large |
618 | |
619 | === modified file 'ec2/ec2test/server.go' |
620 | --- ec2/ec2test/server.go 2012-09-11 14:10:43 +0000 |
621 | +++ ec2/ec2test/server.go 2013-01-31 17:09:20 +0000 |
622 | @@ -417,18 +417,18 @@ |
623 | } |
624 | |
625 | // TODO attributes still to consider: |
626 | - // ImageId: accept anything, we can verify later |
627 | - // KeyName ? |
628 | - // InstanceType ? |
629 | - // KernelId ? |
630 | - // RamdiskId ? |
631 | - // AvailZone ? |
632 | - // GroupName tag |
633 | - // Monitoring ignore? |
634 | - // SubnetId ? |
635 | - // DisableAPITermination bool |
636 | - // ShutdownBehavior string |
637 | - // PrivateIPAddress string |
638 | + // ImageId: accept anything, we can verify later |
639 | + // KeyName ? |
640 | + // InstanceType ? |
641 | + // KernelId ? |
642 | + // RamdiskId ? |
643 | + // AvailZone ? |
644 | + // GroupName tag |
645 | + // Monitoring ignore? |
646 | + // SubnetId ? |
647 | + // DisableAPITermination bool |
648 | + // ShutdownBehavior string |
649 | + // PrivateIPAddress string |
650 | |
651 | srv.mu.Lock() |
652 | defer srv.mu.Unlock() |
653 | |
654 | === modified file 'ec2/sign.go' |
655 | --- ec2/sign.go 2012-10-28 16:04:45 +0000 |
656 | +++ ec2/sign.go 2013-01-31 17:09:20 +0000 |
657 | @@ -19,10 +19,10 @@ |
658 | params["SignatureVersion"] = "2" |
659 | params["SignatureMethod"] = "HmacSHA256" |
660 | |
661 | - // AWS specifies that the parameters in a signed request must |
662 | - // be in natural order of the keys. This is distinct from the |
663 | - // natural order of the encoded value of key=value. Basically |
664 | - // percent and equals affect the sorting order. |
665 | + // AWS specifies that the parameters in a signed request must |
666 | + // be provided in the natural order of the keys. This is distinct |
667 | + // from the natural order of the encoded value of key=value. |
668 | + // Percent and equals affect the sorting order. |
669 | var keys, sarray []string |
670 | for k, _ := range params { |
671 | keys = append(keys, k) |
672 | |
673 | === removed file 'ec2/suite_test.go' |
674 | --- ec2/suite_test.go 2012-08-31 08:11:21 +0000 |
675 | +++ ec2/suite_test.go 1970-01-01 00:00:00 +0000 |
676 | @@ -1,118 +0,0 @@ |
677 | -package ec2_test |
678 | - |
679 | -import ( |
680 | - "fmt" |
681 | - . "launchpad.net/gocheck" |
682 | - "net/http" |
683 | - "net/url" |
684 | - "os" |
685 | - "testing" |
686 | - "time" |
687 | -) |
688 | - |
689 | -func Test(t *testing.T) { |
690 | - TestingT(t) |
691 | -} |
692 | - |
693 | -type HTTPSuite struct{} |
694 | - |
695 | -var testServer = NewTestHTTPServer("http://localhost:4444", 5*time.Second) |
696 | - |
697 | -func (s *HTTPSuite) SetUpSuite(c *C) { |
698 | - testServer.Start() |
699 | -} |
700 | - |
701 | -func (s *HTTPSuite) TearDownTest(c *C) { |
702 | - testServer.FlushRequests() |
703 | -} |
704 | - |
705 | -type TestHTTPServer struct { |
706 | - URL string |
707 | - Timeout time.Duration |
708 | - started bool |
709 | - request chan *http.Request |
710 | - response chan *testResponse |
711 | - pending chan bool |
712 | -} |
713 | - |
714 | -type testResponse struct { |
715 | - Status int |
716 | - Headers map[string]string |
717 | - Body string |
718 | -} |
719 | - |
720 | -func NewTestHTTPServer(url string, timeout time.Duration) *TestHTTPServer { |
721 | - return &TestHTTPServer{URL: url, Timeout: timeout} |
722 | -} |
723 | - |
724 | -func (s *TestHTTPServer) Start() { |
725 | - if s.started { |
726 | - return |
727 | - } |
728 | - s.started = true |
729 | - |
730 | - s.request = make(chan *http.Request, 64) |
731 | - s.response = make(chan *testResponse, 64) |
732 | - s.pending = make(chan bool, 64) |
733 | - |
734 | - url, _ := url.Parse(s.URL) |
735 | - go http.ListenAndServe(url.Host, s) |
736 | - |
737 | - s.PrepareResponse(202, nil, "Nothing.") |
738 | - for { |
739 | - // Wait for it to be up. |
740 | - resp, err := http.Get(s.URL) |
741 | - if err == nil && resp.StatusCode == 202 { |
742 | - break |
743 | - } |
744 | - time.Sleep(1e8) |
745 | - } |
746 | - s.WaitRequest() // Consume dummy request. |
747 | -} |
748 | - |
749 | -// FlushRequests discards requests which were not yet consumed by WaitRequest. |
750 | -func (s *TestHTTPServer) FlushRequests() { |
751 | - for { |
752 | - select { |
753 | - case <-s.request: |
754 | - default: |
755 | - return |
756 | - } |
757 | - } |
758 | -} |
759 | - |
760 | -func (s *TestHTTPServer) ServeHTTP(w http.ResponseWriter, req *http.Request) { |
761 | - s.request <- req |
762 | - var resp *testResponse |
763 | - select { |
764 | - case resp = <-s.response: |
765 | - case <-time.After(s.Timeout): |
766 | - fmt.Fprintf(os.Stderr, "ERROR: Timeout waiting for test to provide response\n") |
767 | - resp = &testResponse{500, nil, ""} |
768 | - } |
769 | - if resp.Headers != nil { |
770 | - h := w.Header() |
771 | - for k, v := range resp.Headers { |
772 | - h.Set(k, v) |
773 | - } |
774 | - } |
775 | - if resp.Status != 0 { |
776 | - w.WriteHeader(resp.Status) |
777 | - } |
778 | - w.Write([]byte(resp.Body)) |
779 | -} |
780 | - |
781 | -func (s *TestHTTPServer) WaitRequest() *http.Request { |
782 | - select { |
783 | - case req := <-s.request: |
784 | - req.ParseForm() |
785 | - return req |
786 | - case <-time.After(s.Timeout): |
787 | - panic("Timeout waiting for goamz request") |
788 | - } |
789 | - panic("unreached") |
790 | -} |
791 | - |
792 | -func (s *TestHTTPServer) PrepareResponse(status int, headers map[string]string, body string) { |
793 | - s.response <- &testResponse{status, headers, body} |
794 | -} |
795 | |
796 | === modified file 'exp/mturk/mturk.go' |
797 | --- exp/mturk/mturk.go 2012-05-03 17:12:28 +0000 |
798 | +++ exp/mturk/mturk.go 2013-01-31 17:09:20 +0000 |
799 | @@ -43,7 +43,7 @@ |
800 | // ---------------------------------------------------------------------------- |
801 | // Request dispatching logic. |
802 | |
803 | -// Error encapsulates an error returned by MTurk. |
804 | +// Error encapsulates an error returned by MTurk. |
805 | type Error struct { |
806 | StatusCode int // HTTP status code (200, 403, ...) |
807 | Code string // EC2 error code ("UnsupportedOperation", ...) |
808 | @@ -150,7 +150,7 @@ |
809 | // Corresponds to the "CreateHIT" operation of the Mechanical Turk |
810 | // API. http://goo.gl/cDBRc Currently only supports "external" |
811 | // questions (see "HIT" struct above). If "keywords", "maxAssignments", |
812 | -// "qualificationRequirement" or "requesterAnnotation" are the zero |
813 | +// "qualificationRequirement" or "requesterAnnotation" are the zero |
814 | // value for their types, they will not be included in the request. |
815 | func (mt *MTurk) CreateHIT(title, description string, question ExternalQuestion, reward Price, assignmentDurationInSeconds, lifetimeInSeconds uint, keywords string, maxAssignments uint, qualificationRequirement *QualificationRequirement, requesterAnnotation string) (h *HIT, err error) { |
816 | params := make(map[string]string) |
817 | @@ -191,8 +191,8 @@ |
818 | |
819 | // Corresponds to the "CreateHIT" operation of the Mechanical Turk |
820 | // API, using an existing "hit type". http://goo.gl/cDBRc Currently only |
821 | -// supports "external" questions (see "HIT" struct above). If |
822 | -// "maxAssignments" or "requesterAnnotation" are the zero value for |
823 | +// supports "external" questions (see "HIT" struct above). If |
824 | +// "maxAssignments" or "requesterAnnotation" are the zero value for |
825 | // their types, they will not be included in the request. |
826 | func (mt *MTurk) CreateHITOfType(hitTypeId string, q ExternalQuestion, lifetimeInSeconds uint, maxAssignments uint, requesterAnnotation string) (h *HIT, err error) { |
827 | params := make(map[string]string) |
828 | @@ -217,7 +217,7 @@ |
829 | return |
830 | } |
831 | |
832 | -// Corresponds to "SearchHITs" operation of Mechanical Turk. http://goo.gl/PskcX |
833 | +// Corresponds to "SearchHITs" operation of Mechanical Turk. http://goo.gl/PskcX |
834 | // Currenlty supports none of the optional parameters. |
835 | func (mt *MTurk) SearchHITs() (s *SearchHITsResult, err error) { |
836 | params := make(map[string]string) |
837 | |
838 | === modified file 'exp/mturk/mturk_test.go' |
839 | --- exp/mturk/mturk_test.go 2012-05-03 17:12:28 +0000 |
840 | +++ exp/mturk/mturk_test.go 2013-01-31 17:09:20 +0000 |
841 | @@ -3,19 +3,26 @@ |
842 | import ( |
843 | "launchpad.net/goamz/aws" |
844 | "launchpad.net/goamz/exp/mturk" |
845 | + "launchpad.net/goamz/testutil" |
846 | . "launchpad.net/gocheck" |
847 | "net/url" |
848 | + "testing" |
849 | ) |
850 | |
851 | +func Test(t *testing.T) { |
852 | + TestingT(t) |
853 | +} |
854 | + |
855 | var _ = Suite(&S{}) |
856 | |
857 | type S struct { |
858 | - HTTPSuite |
859 | mturk *mturk.MTurk |
860 | } |
861 | |
862 | +var testServer = testutil.NewHTTPServer() |
863 | + |
864 | func (s *S) SetUpSuite(c *C) { |
865 | - s.HTTPSuite.SetUpSuite(c) |
866 | + testServer.Start() |
867 | auth := aws.Auth{"abc", "123"} |
868 | u, err := url.Parse(testServer.URL) |
869 | if err != nil { |
870 | @@ -28,8 +35,12 @@ |
871 | } |
872 | } |
873 | |
874 | +func (s *S) TearDownTest(c *C) { |
875 | + testServer.Flush() |
876 | +} |
877 | + |
878 | func (s *S) TestCreateHIT(c *C) { |
879 | - testServer.PrepareResponse(200, nil, BasicHitResponse) |
880 | + testServer.Response(200, nil, BasicHitResponse) |
881 | |
882 | question := mturk.ExternalQuestion{ |
883 | ExternalURL: "http://www.amazon.com", |
884 | @@ -51,7 +62,7 @@ |
885 | } |
886 | |
887 | func (s *S) TestSearchHITs(c *C) { |
888 | - testServer.PrepareResponse(200, nil, SearchHITResponse) |
889 | + testServer.Response(200, nil, SearchHITResponse) |
890 | |
891 | hitResult, err := s.mturk.SearchHITs() |
892 | |
893 | |
894 | === removed file 'exp/mturk/suite_test.go' |
895 | --- exp/mturk/suite_test.go 2012-03-09 15:34:56 +0000 |
896 | +++ exp/mturk/suite_test.go 1970-01-01 00:00:00 +0000 |
897 | @@ -1,120 +0,0 @@ |
898 | -package mturk_test |
899 | - |
900 | -import ( |
901 | - "fmt" |
902 | - . "launchpad.net/gocheck" |
903 | - "net/http" |
904 | - "net/url" |
905 | - "os" |
906 | - "testing" |
907 | - "time" |
908 | -) |
909 | - |
910 | -func Test(t *testing.T) { |
911 | - TestingT(t) |
912 | -} |
913 | - |
914 | -type HTTPSuite struct{} |
915 | - |
916 | -var testServer = NewTestHTTPServer("http://localhost:4444", 5*time.Second) |
917 | - |
918 | -func (s *HTTPSuite) SetUpSuite(c *C) { |
919 | - testServer.Start() |
920 | -} |
921 | - |
922 | -func (s *HTTPSuite) TearDownTest(c *C) { |
923 | - testServer.FlushRequests() |
924 | -} |
925 | - |
926 | -type TestHTTPServer struct { |
927 | - URL string |
928 | - Timeout time.Duration |
929 | - started bool |
930 | - request chan *http.Request |
931 | - response chan *testResponse |
932 | - pending chan bool |
933 | -} |
934 | - |
935 | -type testResponse struct { |
936 | - Status int |
937 | - Headers map[string]string |
938 | - Body string |
939 | -} |
940 | - |
941 | -func NewTestHTTPServer(url string, timeout time.Duration) *TestHTTPServer { |
942 | - return &TestHTTPServer{URL: url, Timeout: timeout} |
943 | -} |
944 | - |
945 | -func (s *TestHTTPServer) Start() { |
946 | - if s.started { |
947 | - return |
948 | - } |
949 | - s.started = true |
950 | - |
951 | - s.request = make(chan *http.Request, 64) |
952 | - s.response = make(chan *testResponse, 64) |
953 | - s.pending = make(chan bool, 64) |
954 | - |
955 | - url, _ := url.Parse(s.URL) |
956 | - go http.ListenAndServe(url.Host, s) |
957 | - |
958 | - s.PrepareResponse(202, nil, "Nothing.") |
959 | - for { |
960 | - // Wait for it to be up. |
961 | - resp, err := http.Get(s.URL) |
962 | - if err == nil && resp.StatusCode == 202 { |
963 | - break |
964 | - } |
965 | - fmt.Fprintf(os.Stderr, "\nWaiting for fake server to be up... ") |
966 | - time.Sleep(1e8) |
967 | - } |
968 | - fmt.Fprintf(os.Stderr, "done\n\n") |
969 | - s.WaitRequest() // Consume dummy request. |
970 | -} |
971 | - |
972 | -// FlushRequests discards requests which were not yet consumed by WaitRequest. |
973 | -func (s *TestHTTPServer) FlushRequests() { |
974 | - for { |
975 | - select { |
976 | - case <-s.request: |
977 | - default: |
978 | - return |
979 | - } |
980 | - } |
981 | -} |
982 | - |
983 | -func (s *TestHTTPServer) ServeHTTP(w http.ResponseWriter, req *http.Request) { |
984 | - s.request <- req |
985 | - var resp *testResponse |
986 | - select { |
987 | - case resp = <-s.response: |
988 | - case <-time.After(s.Timeout): |
989 | - fmt.Fprintf(os.Stderr, "ERROR: Timeout waiting for test to provide response\n") |
990 | - resp = &testResponse{500, nil, ""} |
991 | - } |
992 | - if resp.Headers != nil { |
993 | - h := w.Header() |
994 | - for k, v := range resp.Headers { |
995 | - h.Set(k, v) |
996 | - } |
997 | - } |
998 | - if resp.Status != 0 { |
999 | - w.WriteHeader(resp.Status) |
1000 | - } |
1001 | - w.Write([]byte(resp.Body)) |
1002 | -} |
1003 | - |
1004 | -func (s *TestHTTPServer) WaitRequest() *http.Request { |
1005 | - select { |
1006 | - case req := <-s.request: |
1007 | - req.ParseForm() |
1008 | - return req |
1009 | - case <-time.After(s.Timeout): |
1010 | - panic("Timeout waiting for goamz request") |
1011 | - } |
1012 | - panic("unreached") |
1013 | -} |
1014 | - |
1015 | -func (s *TestHTTPServer) PrepareResponse(status int, headers map[string]string, body string) { |
1016 | - s.response <- &testResponse{status, headers, body} |
1017 | -} |
1018 | |
1019 | === modified file 'exp/sdb/sdb.go' |
1020 | --- exp/sdb/sdb.go 2012-03-09 15:34:56 +0000 |
1021 | +++ exp/sdb/sdb.go 2013-01-31 17:09:20 +0000 |
1022 | @@ -18,7 +18,7 @@ |
1023 | |
1024 | // BUG: SelectResp isn't properly organized. It must change. |
1025 | |
1026 | -// |
1027 | +// |
1028 | |
1029 | import ( |
1030 | "encoding/xml" |
1031 | @@ -129,7 +129,7 @@ |
1032 | |
1033 | // Select returns a set of items and attributes that match expr. |
1034 | // Select is similar to the standard SQL SELECT statement. |
1035 | -// |
1036 | +// |
1037 | // See http://goo.gl/GTsSZ for more details. |
1038 | func (sdb *SDB) Select(expr string, consistent bool) (resp *SelectResp, err error) { |
1039 | resp = &SelectResp{} |
1040 | @@ -206,7 +206,7 @@ |
1041 | pa.missing[name] = true |
1042 | } |
1043 | |
1044 | -// PutAttrs adds attrs to item. |
1045 | +// PutAttrs adds attrs to item. |
1046 | // |
1047 | // See http://goo.gl/yTAV4 for more details. |
1048 | func (item *Item) PutAttrs(attrs *PutAttrs) (resp *SimpleResp, err error) { |
1049 | |
1050 | === modified file 'exp/sdb/sdb_test.go' |
1051 | --- exp/sdb/sdb_test.go 2012-03-09 15:34:56 +0000 |
1052 | +++ exp/sdb/sdb_test.go 2013-01-31 17:09:20 +0000 |
1053 | @@ -3,24 +3,35 @@ |
1054 | import ( |
1055 | "launchpad.net/goamz/aws" |
1056 | "launchpad.net/goamz/exp/sdb" |
1057 | + "launchpad.net/goamz/testutil" |
1058 | . "launchpad.net/gocheck" |
1059 | + "testing" |
1060 | ) |
1061 | |
1062 | +func Test(t *testing.T) { |
1063 | + TestingT(t) |
1064 | +} |
1065 | + |
1066 | var _ = Suite(&S{}) |
1067 | |
1068 | type S struct { |
1069 | - HTTPSuite |
1070 | sdb *sdb.SDB |
1071 | } |
1072 | |
1073 | +var testServer = testutil.NewHTTPServer() |
1074 | + |
1075 | func (s *S) SetUpSuite(c *C) { |
1076 | - s.HTTPSuite.SetUpSuite(c) |
1077 | + testServer.Start() |
1078 | auth := aws.Auth{"abc", "123"} |
1079 | s.sdb = sdb.New(auth, aws.Region{SDBEndpoint: testServer.URL}) |
1080 | } |
1081 | |
1082 | +func (s *S) TearDownTest(c *C) { |
1083 | + testServer.Flush() |
1084 | +} |
1085 | + |
1086 | func (s *S) TestCreateDomainOK(c *C) { |
1087 | - testServer.PrepareResponse(200, nil, TestCreateDomainXmlOK) |
1088 | + testServer.Response(200, nil, TestCreateDomainXmlOK) |
1089 | |
1090 | domain := s.sdb.Domain("domain") |
1091 | resp, err := domain.CreateDomain() |
1092 | @@ -37,7 +48,7 @@ |
1093 | } |
1094 | |
1095 | func (s *S) TestListDomainsOK(c *C) { |
1096 | - testServer.PrepareResponse(200, nil, TestListDomainsXmlOK) |
1097 | + testServer.Response(200, nil, TestListDomainsXmlOK) |
1098 | |
1099 | resp, err := s.sdb.ListDomains() |
1100 | req := testServer.WaitRequest() |
1101 | @@ -54,7 +65,7 @@ |
1102 | } |
1103 | |
1104 | func (s *S) TestListDomainsWithNextTokenXmlOK(c *C) { |
1105 | - testServer.PrepareResponse(200, nil, TestListDomainsWithNextTokenXmlOK) |
1106 | + testServer.Response(200, nil, TestListDomainsWithNextTokenXmlOK) |
1107 | |
1108 | resp, err := s.sdb.ListDomains() |
1109 | req := testServer.WaitRequest() |
1110 | @@ -72,7 +83,7 @@ |
1111 | } |
1112 | |
1113 | func (s *S) TestDeleteDomainOK(c *C) { |
1114 | - testServer.PrepareResponse(200, nil, TestDeleteDomainXmlOK) |
1115 | + testServer.Response(200, nil, TestDeleteDomainXmlOK) |
1116 | |
1117 | domain := s.sdb.Domain("domain") |
1118 | resp, err := domain.DeleteDomain() |
1119 | @@ -89,7 +100,7 @@ |
1120 | } |
1121 | |
1122 | func (s *S) TestPutAttrsOK(c *C) { |
1123 | - testServer.PrepareResponse(200, nil, TestPutAttrsXmlOK) |
1124 | + testServer.Response(200, nil, TestPutAttrsXmlOK) |
1125 | |
1126 | domain := s.sdb.Domain("MyDomain") |
1127 | item := domain.Item("Item123") |
1128 | @@ -128,7 +139,7 @@ |
1129 | } |
1130 | |
1131 | func (s *S) TestAttrsOK(c *C) { |
1132 | - testServer.PrepareResponse(200, nil, TestAttrsXmlOK) |
1133 | + testServer.Response(200, nil, TestAttrsXmlOK) |
1134 | |
1135 | domain := s.sdb.Domain("MyDomain") |
1136 | item := domain.Item("Item123") |
1137 | @@ -155,7 +166,7 @@ |
1138 | } |
1139 | |
1140 | func (s *S) TestAttrsSelectOK(c *C) { |
1141 | - testServer.PrepareResponse(200, nil, TestAttrsXmlOK) |
1142 | + testServer.Response(200, nil, TestAttrsXmlOK) |
1143 | |
1144 | domain := s.sdb.Domain("MyDomain") |
1145 | item := domain.Item("Item123") |
1146 | @@ -184,7 +195,7 @@ |
1147 | } |
1148 | |
1149 | func (s *S) TestSelectOK(c *C) { |
1150 | - testServer.PrepareResponse(200, nil, TestSelectXmlOK) |
1151 | + testServer.Response(200, nil, TestSelectXmlOK) |
1152 | |
1153 | resp, err := s.sdb.Select("select Color from MyDomain where Color like 'Blue%'", true) |
1154 | req := testServer.WaitRequest() |
1155 | |
1156 | === removed file 'exp/sdb/suite_test.go' |
1157 | --- exp/sdb/suite_test.go 2012-03-09 15:34:56 +0000 |
1158 | +++ exp/sdb/suite_test.go 1970-01-01 00:00:00 +0000 |
1159 | @@ -1,139 +0,0 @@ |
1160 | -package sdb_test |
1161 | - |
1162 | -import ( |
1163 | - "flag" |
1164 | - "fmt" |
1165 | - "launchpad.net/goamz/aws" |
1166 | - "launchpad.net/gocheck" |
1167 | - "net/http" |
1168 | - "net/url" |
1169 | - "os" |
1170 | - "testing" |
1171 | - "time" |
1172 | -) |
1173 | - |
1174 | -func Test(t *testing.T) { |
1175 | - gocheck.TestingT(t) |
1176 | -} |
1177 | - |
1178 | -var integration = flag.Bool("i", false, "Enable integration tests") |
1179 | - |
1180 | -type SuiteI struct { |
1181 | - auth aws.Auth |
1182 | -} |
1183 | - |
1184 | -func (s *SuiteI) SetUpSuite(c *gocheck.C) { |
1185 | - if !*integration { |
1186 | - c.Skip("Integration tests not enabled (-int flag)") |
1187 | - } |
1188 | - auth, err := aws.EnvAuth() |
1189 | - if err != nil { |
1190 | - c.Fatal(err) |
1191 | - } |
1192 | - s.auth = auth |
1193 | -} |
1194 | - |
1195 | -type HTTPSuite struct{} |
1196 | - |
1197 | -var testServer = NewTestHTTPServer("http://localhost:4444", 5*time.Second) |
1198 | - |
1199 | -func (s *HTTPSuite) SetUpSuite(c *gocheck.C) { |
1200 | - testServer.Start() |
1201 | -} |
1202 | - |
1203 | -func (s *HTTPSuite) TearDownTest(c *gocheck.C) { |
1204 | - testServer.FlushRequests() |
1205 | -} |
1206 | - |
1207 | -type TestHTTPServer struct { |
1208 | - URL string |
1209 | - Timeout time.Duration |
1210 | - started bool |
1211 | - request chan *http.Request |
1212 | - response chan *testResponse |
1213 | - pending chan bool |
1214 | -} |
1215 | - |
1216 | -type testResponse struct { |
1217 | - Status int |
1218 | - Headers map[string]string |
1219 | - Body string |
1220 | -} |
1221 | - |
1222 | -func NewTestHTTPServer(url_ string, timeout time.Duration) *TestHTTPServer { |
1223 | - return &TestHTTPServer{URL: url_, Timeout: timeout} |
1224 | -} |
1225 | - |
1226 | -func (s *TestHTTPServer) Start() { |
1227 | - if s.started { |
1228 | - return |
1229 | - } |
1230 | - s.started = true |
1231 | - |
1232 | - s.request = make(chan *http.Request, 64) |
1233 | - s.response = make(chan *testResponse, 64) |
1234 | - s.pending = make(chan bool, 64) |
1235 | - |
1236 | - url_, _ := url.Parse(s.URL) |
1237 | - go http.ListenAndServe(url_.Host, s) |
1238 | - |
1239 | - s.PrepareResponse(202, nil, "Nothing.") |
1240 | - for { |
1241 | - // Wait for it to be up. |
1242 | - resp, err := http.Get(s.URL) |
1243 | - if err == nil && resp.StatusCode == 202 { |
1244 | - break |
1245 | - } |
1246 | - fmt.Fprintf(os.Stderr, "\nWaiting for fake server to be up... ") |
1247 | - time.Sleep(1e8) |
1248 | - } |
1249 | - fmt.Fprintf(os.Stderr, "done\n\n") |
1250 | - s.WaitRequest() // Consume dummy request. |
1251 | -} |
1252 | - |
1253 | -// FlushRequests discards requests which were not yet consumed by WaitRequest. |
1254 | -func (s *TestHTTPServer) FlushRequests() { |
1255 | - for { |
1256 | - select { |
1257 | - case <-s.request: |
1258 | - default: |
1259 | - return |
1260 | - } |
1261 | - } |
1262 | -} |
1263 | - |
1264 | -func (s *TestHTTPServer) ServeHTTP(w http.ResponseWriter, req *http.Request) { |
1265 | - s.request <- req |
1266 | - var resp *testResponse |
1267 | - select { |
1268 | - case resp = <-s.response: |
1269 | - case <-time.After(s.Timeout): |
1270 | - fmt.Fprintf(os.Stderr, "ERROR: Timeout waiting for test to provide response\n") |
1271 | - resp = &testResponse{500, nil, ""} |
1272 | - } |
1273 | - if resp.Headers != nil { |
1274 | - h := w.Header() |
1275 | - for k, v := range resp.Headers { |
1276 | - h.Set(k, v) |
1277 | - } |
1278 | - } |
1279 | - if resp.Status != 0 { |
1280 | - w.WriteHeader(resp.Status) |
1281 | - } |
1282 | - w.Write([]byte(resp.Body)) |
1283 | -} |
1284 | - |
1285 | -func (s *TestHTTPServer) WaitRequest() *http.Request { |
1286 | - select { |
1287 | - case req := <-s.request: |
1288 | - req.ParseForm() |
1289 | - return req |
1290 | - case <-time.After(s.Timeout): |
1291 | - panic("Timeout waiting for goamz request") |
1292 | - } |
1293 | - panic("unreached") |
1294 | -} |
1295 | - |
1296 | -func (s *TestHTTPServer) PrepareResponse(status int, headers map[string]string, body string) { |
1297 | - s.response <- &testResponse{status, headers, body} |
1298 | -} |
1299 | |
1300 | === modified file 'exp/sns/sns_test.go' |
1301 | --- exp/sns/sns_test.go 2012-05-03 17:12:28 +0000 |
1302 | +++ exp/sns/sns_test.go 2013-01-31 17:09:20 +0000 |
1303 | @@ -3,22 +3,33 @@ |
1304 | import ( |
1305 | "launchpad.net/goamz/aws" |
1306 | "launchpad.net/goamz/exp/sns" |
1307 | + "launchpad.net/goamz/testutil" |
1308 | . "launchpad.net/gocheck" |
1309 | + "testing" |
1310 | ) |
1311 | |
1312 | +func Test(t *testing.T) { |
1313 | + TestingT(t) |
1314 | +} |
1315 | + |
1316 | var _ = Suite(&S{}) |
1317 | |
1318 | type S struct { |
1319 | - HTTPSuite |
1320 | sns *sns.SNS |
1321 | } |
1322 | |
1323 | +var testServer = testutil.NewHTTPServer() |
1324 | + |
1325 | func (s *S) SetUpSuite(c *C) { |
1326 | - s.HTTPSuite.SetUpSuite(c) |
1327 | + testServer.Start() |
1328 | auth := aws.Auth{"abc", "123"} |
1329 | s.sns = sns.New(auth, aws.Region{SNSEndpoint: testServer.URL}) |
1330 | } |
1331 | |
1332 | +func (s *S) TearDownTest(c *C) { |
1333 | + testServer.Flush() |
1334 | +} |
1335 | + |
1336 | func (s *S) TestListTopicsOK(c *C) { |
1337 | testServer.Response(200, nil, TestListTopicsXmlOK) |
1338 | |
1339 | |
1340 | === removed file 'exp/sns/suite_test.go' |
1341 | --- exp/sns/suite_test.go 2012-03-09 15:34:56 +0000 |
1342 | +++ exp/sns/suite_test.go 1970-01-01 00:00:00 +0000 |
1343 | @@ -1,200 +0,0 @@ |
1344 | -package sns_test |
1345 | - |
1346 | -import ( |
1347 | - "bytes" |
1348 | - "flag" |
1349 | - "fmt" |
1350 | - "io/ioutil" |
1351 | - . "launchpad.net/gocheck" |
1352 | - "net/http" |
1353 | - "net/url" |
1354 | - "os" |
1355 | - "testing" |
1356 | - "time" |
1357 | -) |
1358 | - |
1359 | -func Test(t *testing.T) { |
1360 | - TestingT(t) |
1361 | -} |
1362 | - |
1363 | -var integration = flag.Bool("i", false, "Enable integration tests") |
1364 | - |
1365 | -type SuiteI struct{} |
1366 | - |
1367 | -func (s *SuiteI) SetUpSuite(c *C) { |
1368 | - if !*integration { |
1369 | - c.Skip("Integration tests not enabled (-i flag)") |
1370 | - } |
1371 | -} |
1372 | - |
1373 | -type HTTPSuite struct{} |
1374 | - |
1375 | -var testServer = NewTestHTTPServer("http://localhost:4444", 5*time.Second) |
1376 | - |
1377 | -func (s *HTTPSuite) SetUpSuite(c *C) { |
1378 | - testServer.Start() |
1379 | -} |
1380 | - |
1381 | -func (s *HTTPSuite) TearDownTest(c *C) { |
1382 | - testServer.Flush() |
1383 | -} |
1384 | - |
1385 | -type TestHTTPServer struct { |
1386 | - URL string |
1387 | - Timeout time.Duration |
1388 | - started bool |
1389 | - request chan *http.Request |
1390 | - response chan ResponseFunc |
1391 | - pending chan bool |
1392 | -} |
1393 | - |
1394 | -func NewTestHTTPServer(url_ string, timeout time.Duration) *TestHTTPServer { |
1395 | - return &TestHTTPServer{URL: url_, Timeout: timeout} |
1396 | -} |
1397 | - |
1398 | -type Response struct { |
1399 | - Status int |
1400 | - Headers map[string]string |
1401 | - Body string |
1402 | -} |
1403 | - |
1404 | -type ResponseFunc func(path string) Response |
1405 | - |
1406 | -func (s *TestHTTPServer) Start() { |
1407 | - if s.started { |
1408 | - return |
1409 | - } |
1410 | - s.started = true |
1411 | - |
1412 | - s.request = make(chan *http.Request, 64) |
1413 | - s.response = make(chan ResponseFunc, 64) |
1414 | - s.pending = make(chan bool, 64) |
1415 | - |
1416 | - url_, _ := url.Parse(s.URL) |
1417 | - go http.ListenAndServe(url_.Host, s) |
1418 | - |
1419 | - s.Response(203, nil, "") |
1420 | - for { |
1421 | - // Wait for it to be up. |
1422 | - resp, err := http.Get(s.URL) |
1423 | - if err == nil && resp.StatusCode == 203 { |
1424 | - break |
1425 | - } |
1426 | - fmt.Fprintf(os.Stderr, "\nWaiting for fake server to be up... ") |
1427 | - time.Sleep(1e8) |
1428 | - } |
1429 | - fmt.Fprintf(os.Stderr, "done\n\n") |
1430 | - s.WaitRequest() // Consume dummy request. |
1431 | -} |
1432 | - |
1433 | -// FlushRequests discards requests which were not yet consumed by WaitRequest. |
1434 | -func (s *TestHTTPServer) Flush() { |
1435 | - for { |
1436 | - select { |
1437 | - case <-s.request: |
1438 | - case <-s.response: |
1439 | - default: |
1440 | - return |
1441 | - } |
1442 | - } |
1443 | -} |
1444 | - |
1445 | -func body(req *http.Request) string { |
1446 | - data, err := ioutil.ReadAll(req.Body) |
1447 | - if err != nil { |
1448 | - panic(err) |
1449 | - } |
1450 | - return string(data) |
1451 | -} |
1452 | - |
1453 | -func (s *TestHTTPServer) ServeHTTP(w http.ResponseWriter, req *http.Request) { |
1454 | - req.ParseMultipartForm(1e6) |
1455 | - data, err := ioutil.ReadAll(req.Body) |
1456 | - if err != nil { |
1457 | - panic(err) |
1458 | - } |
1459 | - req.Body = ioutil.NopCloser(bytes.NewBuffer(data)) |
1460 | - s.request <- req |
1461 | - var resp Response |
1462 | - select { |
1463 | - case respFunc := <-s.response: |
1464 | - resp = respFunc(req.URL.Path) |
1465 | - case <-time.After(s.Timeout): |
1466 | - const msg = "ERROR: Timeout waiting for test to prepare a response\n" |
1467 | - fmt.Fprintf(os.Stderr, msg) |
1468 | - resp = Response{500, nil, msg} |
1469 | - } |
1470 | - if resp.Headers != nil { |
1471 | - h := w.Header() |
1472 | - for k, v := range resp.Headers { |
1473 | - h.Set(k, v) |
1474 | - } |
1475 | - } |
1476 | - if resp.Status != 0 { |
1477 | - w.WriteHeader(resp.Status) |
1478 | - } |
1479 | - w.Write([]byte(resp.Body)) |
1480 | -} |
1481 | - |
1482 | -// WaitRequests returns the next n requests made to the http server from |
1483 | -// the queue. If not enough requests were previously made, it waits until |
1484 | -// the timeout value for them to be made. |
1485 | -func (s *TestHTTPServer) WaitRequests(n int) []*http.Request { |
1486 | - reqs := make([]*http.Request, 0, n) |
1487 | - for i := 0; i < n; i++ { |
1488 | - select { |
1489 | - case req := <-s.request: |
1490 | - reqs = append(reqs, req) |
1491 | - case <-time.After(s.Timeout): |
1492 | - panic("Timeout waiting for request") |
1493 | - } |
1494 | - } |
1495 | - return reqs |
1496 | -} |
1497 | - |
1498 | -// WaitRequest returns the next request made to the http server from |
1499 | -// the queue. If no requests were previously made, it waits until the |
1500 | -// timeout value for one to be made. |
1501 | -func (s *TestHTTPServer) WaitRequest() *http.Request { |
1502 | - return s.WaitRequests(1)[0] |
1503 | -} |
1504 | - |
1505 | -// ResponseFunc prepares the test server to respond the following n |
1506 | -// requests using f to build each response. |
1507 | -func (s *TestHTTPServer) ResponseFunc(n int, f ResponseFunc) { |
1508 | - for i := 0; i < n; i++ { |
1509 | - s.response <- f |
1510 | - } |
1511 | -} |
1512 | - |
1513 | -// ResponseMap maps request paths to responses. |
1514 | -type ResponseMap map[string]Response |
1515 | - |
1516 | -// ResponseMap prepares the test server to respond the following n |
1517 | -// requests using the m to obtain the responses. |
1518 | -func (s *TestHTTPServer) ResponseMap(n int, m ResponseMap) { |
1519 | - f := func(path string) Response { |
1520 | - for rpath, resp := range m { |
1521 | - if rpath == path { |
1522 | - return resp |
1523 | - } |
1524 | - } |
1525 | - return Response{Status: 500, Body: "Path not found in response map: " + path} |
1526 | - } |
1527 | - s.ResponseFunc(n, f) |
1528 | -} |
1529 | - |
1530 | -// Responses prepares the test server to respond the following n requests |
1531 | -// using the provided response parameters. |
1532 | -func (s *TestHTTPServer) Responses(n int, status int, headers map[string]string, body string) { |
1533 | - f := func(path string) Response { |
1534 | - return Response{status, headers, body} |
1535 | - } |
1536 | - s.ResponseFunc(n, f) |
1537 | -} |
1538 | - |
1539 | -// Response prepares the test server to respond the following request |
1540 | -// using the provided response parameters. |
1541 | -func (s *TestHTTPServer) Response(status int, headers map[string]string, body string) { |
1542 | - s.Responses(1, status, headers, body) |
1543 | -} |
1544 | |
1545 | === modified file 'iam/iam_test.go' |
1546 | --- iam/iam_test.go 2012-10-10 20:16:54 +0000 |
1547 | +++ iam/iam_test.go 2013-01-31 17:09:20 +0000 |
1548 | @@ -3,24 +3,35 @@ |
1549 | import ( |
1550 | "launchpad.net/goamz/aws" |
1551 | "launchpad.net/goamz/iam" |
1552 | + "launchpad.net/goamz/testutil" |
1553 | . "launchpad.net/gocheck" |
1554 | + "testing" |
1555 | ) |
1556 | |
1557 | +func Test(t *testing.T) { |
1558 | + TestingT(t) |
1559 | +} |
1560 | + |
1561 | type S struct { |
1562 | - HTTPSuite |
1563 | iam *iam.IAM |
1564 | } |
1565 | |
1566 | var _ = Suite(&S{}) |
1567 | |
1568 | +var testServer = testutil.NewHTTPServer() |
1569 | + |
1570 | func (s *S) SetUpSuite(c *C) { |
1571 | - s.HTTPSuite.SetUpSuite(c) |
1572 | + testServer.Start() |
1573 | auth := aws.Auth{"abc", "123"} |
1574 | s.iam = iam.New(auth, aws.Region{IAMEndpoint: testServer.URL}) |
1575 | } |
1576 | |
1577 | +func (s *S) TearDownTest(c *C) { |
1578 | + testServer.Flush() |
1579 | +} |
1580 | + |
1581 | func (s *S) TestCreateUser(c *C) { |
1582 | - testServer.PrepareResponse(200, nil, CreateUserExample) |
1583 | + testServer.Response(200, nil, CreateUserExample) |
1584 | resp, err := s.iam.CreateUser("Bob", "/division_abc/subdivision_xyz/") |
1585 | values := testServer.WaitRequest().URL.Query() |
1586 | c.Assert(values.Get("Action"), Equals, "CreateUser") |
1587 | @@ -38,7 +49,7 @@ |
1588 | } |
1589 | |
1590 | func (s *S) TestCreateUserConflict(c *C) { |
1591 | - testServer.PrepareResponse(409, nil, DuplicateUserExample) |
1592 | + testServer.Response(409, nil, DuplicateUserExample) |
1593 | resp, err := s.iam.CreateUser("Bob", "/division_abc/subdivision_xyz/") |
1594 | testServer.WaitRequest() |
1595 | c.Assert(resp, IsNil) |
1596 | @@ -50,7 +61,7 @@ |
1597 | } |
1598 | |
1599 | func (s *S) TestGetUser(c *C) { |
1600 | - testServer.PrepareResponse(200, nil, GetUserExample) |
1601 | + testServer.Response(200, nil, GetUserExample) |
1602 | resp, err := s.iam.GetUser("Bob") |
1603 | values := testServer.WaitRequest().URL.Query() |
1604 | c.Assert(values.Get("Action"), Equals, "GetUser") |
1605 | @@ -67,7 +78,7 @@ |
1606 | } |
1607 | |
1608 | func (s *S) TestDeleteUser(c *C) { |
1609 | - testServer.PrepareResponse(200, nil, RequestIdExample) |
1610 | + testServer.Response(200, nil, RequestIdExample) |
1611 | resp, err := s.iam.DeleteUser("Bob") |
1612 | values := testServer.WaitRequest().URL.Query() |
1613 | c.Assert(values.Get("Action"), Equals, "DeleteUser") |
1614 | @@ -77,7 +88,7 @@ |
1615 | } |
1616 | |
1617 | func (s *S) TestCreateAccessKey(c *C) { |
1618 | - testServer.PrepareResponse(200, nil, CreateAccessKeyExample) |
1619 | + testServer.Response(200, nil, CreateAccessKeyExample) |
1620 | resp, err := s.iam.CreateAccessKey("Bob") |
1621 | values := testServer.WaitRequest().URL.Query() |
1622 | c.Assert(values.Get("Action"), Equals, "CreateAccessKey") |
1623 | |
1624 | === modified file 'iam/iami_test.go' |
1625 | --- iam/iami_test.go 2012-10-10 20:21:55 +0000 |
1626 | +++ iam/iami_test.go 2013-01-31 17:09:20 +0000 |
1627 | @@ -1,14 +1,12 @@ |
1628 | package iam_test |
1629 | |
1630 | import ( |
1631 | - "flag" |
1632 | "launchpad.net/goamz/aws" |
1633 | "launchpad.net/goamz/iam" |
1634 | + "launchpad.net/goamz/testutil" |
1635 | . "launchpad.net/gocheck" |
1636 | ) |
1637 | |
1638 | -var amazon = flag.Bool("amazon", false, "Enable tests against amazon server") |
1639 | - |
1640 | // AmazonServer represents an Amazon AWS server. |
1641 | type AmazonServer struct { |
1642 | auth aws.Auth |
1643 | @@ -31,7 +29,7 @@ |
1644 | } |
1645 | |
1646 | func (s *AmazonClientSuite) SetUpSuite(c *C) { |
1647 | - if !*amazon { |
1648 | + if !testutil.Amazon { |
1649 | c.Skip("AmazonClientSuite tests not enabled") |
1650 | } |
1651 | s.srv.SetUp(c) |
1652 | |
1653 | === removed file 'iam/suite_test.go' |
1654 | --- iam/suite_test.go 2012-10-05 22:45:47 +0000 |
1655 | +++ iam/suite_test.go 1970-01-01 00:00:00 +0000 |
1656 | @@ -1,128 +0,0 @@ |
1657 | -package iam_test |
1658 | - |
1659 | -import ( |
1660 | - "bytes" |
1661 | - "fmt" |
1662 | - "io/ioutil" |
1663 | - . "launchpad.net/gocheck" |
1664 | - "net/http" |
1665 | - "net/url" |
1666 | - "os" |
1667 | - "testing" |
1668 | - "time" |
1669 | -) |
1670 | - |
1671 | -func Test(t *testing.T) { |
1672 | - TestingT(t) |
1673 | -} |
1674 | - |
1675 | -type HTTPSuite struct{} |
1676 | - |
1677 | -var testServer = NewTestHTTPServer("http://localhost:4444", 5*time.Second) |
1678 | - |
1679 | -func (s *HTTPSuite) SetUpSuite(c *C) { |
1680 | - testServer.Start() |
1681 | -} |
1682 | - |
1683 | -func (s *HTTPSuite) TearDownTest(c *C) { |
1684 | - testServer.FlushRequests() |
1685 | -} |
1686 | - |
1687 | -type TestHTTPServer struct { |
1688 | - URL string |
1689 | - Timeout time.Duration |
1690 | - started bool |
1691 | - body chan []byte |
1692 | - request chan *http.Request |
1693 | - response chan *testResponse |
1694 | - pending chan bool |
1695 | -} |
1696 | - |
1697 | -type testResponse struct { |
1698 | - Status int |
1699 | - Headers map[string]string |
1700 | - Body string |
1701 | -} |
1702 | - |
1703 | -func NewTestHTTPServer(url string, timeout time.Duration) *TestHTTPServer { |
1704 | - return &TestHTTPServer{URL: url, Timeout: timeout} |
1705 | -} |
1706 | - |
1707 | -func (s *TestHTTPServer) Start() { |
1708 | - if s.started { |
1709 | - return |
1710 | - } |
1711 | - s.started = true |
1712 | - |
1713 | - s.body = make(chan []byte, 64) |
1714 | - s.request = make(chan *http.Request, 64) |
1715 | - s.response = make(chan *testResponse, 64) |
1716 | - s.pending = make(chan bool, 64) |
1717 | - |
1718 | - url, _ := url.Parse(s.URL) |
1719 | - go http.ListenAndServe(url.Host, s) |
1720 | - |
1721 | - s.PrepareResponse(202, nil, "Nothing.") |
1722 | - for { |
1723 | - // Wait for it to be up. |
1724 | - resp, err := http.Get(s.URL) |
1725 | - if err == nil && resp.StatusCode == 202 { |
1726 | - break |
1727 | - } |
1728 | - fmt.Fprintf(os.Stderr, "\nWaiting for fake server to be up... ") |
1729 | - time.Sleep(1e8) |
1730 | - } |
1731 | - fmt.Fprintf(os.Stderr, "done\n\n") |
1732 | - s.WaitRequest() // Consume dummy request. |
1733 | -} |
1734 | - |
1735 | -// FlushRequests discards requests which were not yet consumed by WaitRequest. |
1736 | -func (s *TestHTTPServer) FlushRequests() { |
1737 | - for { |
1738 | - select { |
1739 | - case <-s.request: |
1740 | - default: |
1741 | - return |
1742 | - } |
1743 | - } |
1744 | -} |
1745 | - |
1746 | -func (s *TestHTTPServer) ServeHTTP(w http.ResponseWriter, req *http.Request) { |
1747 | - b, _ := ioutil.ReadAll(req.Body) |
1748 | - s.body <- b |
1749 | - s.request <- req |
1750 | - var resp *testResponse |
1751 | - select { |
1752 | - case resp = <-s.response: |
1753 | - case <-time.After(s.Timeout): |
1754 | - fmt.Fprintf(os.Stderr, "ERROR: Timeout waiting for test to provide response\n") |
1755 | - resp = &testResponse{500, nil, ""} |
1756 | - } |
1757 | - if resp.Headers != nil { |
1758 | - h := w.Header() |
1759 | - for k, v := range resp.Headers { |
1760 | - h.Set(k, v) |
1761 | - } |
1762 | - } |
1763 | - if resp.Status != 0 { |
1764 | - w.WriteHeader(resp.Status) |
1765 | - } |
1766 | - w.Write([]byte(resp.Body)) |
1767 | -} |
1768 | - |
1769 | -func (s *TestHTTPServer) WaitRequest() *http.Request { |
1770 | - select { |
1771 | - case req := <-s.request: |
1772 | - body := <-s.body |
1773 | - req.Body = ioutil.NopCloser(bytes.NewReader(body)) |
1774 | - req.ParseForm() |
1775 | - return req |
1776 | - case <-time.After(s.Timeout): |
1777 | - panic("Timeout waiting for goamz request") |
1778 | - } |
1779 | - panic("unreached") |
1780 | -} |
1781 | - |
1782 | -func (s *TestHTTPServer) PrepareResponse(status int, headers map[string]string, body string) { |
1783 | - s.response <- &testResponse{status, headers, body} |
1784 | -} |
1785 | |
1786 | === modified file 's3/s3.go' |
1787 | --- s3/s3.go 2012-12-10 05:30:05 +0000 |
1788 | +++ s3/s3.go 2013-01-31 17:09:20 +0000 |
1789 | @@ -67,7 +67,7 @@ |
1790 | // locationConstraint returns an io.Reader specifying a LocationConstraint if |
1791 | // required for the region. |
1792 | // |
1793 | -// See http://goo.gl/bh9Kq for more details. |
1794 | +// See http://goo.gl/bh9Kq for details. |
1795 | func (s3 *S3) locationConstraint() io.Reader { |
1796 | constraint := "" |
1797 | if s3.Region.S3LocationConstraint { |
1798 | @@ -89,7 +89,7 @@ |
1799 | |
1800 | // PutBucket creates a new bucket. |
1801 | // |
1802 | -// See http://goo.gl/ndjnR for more details. |
1803 | +// See http://goo.gl/ndjnR for details. |
1804 | func (b *Bucket) PutBucket(perm ACL) error { |
1805 | headers := map[string][]string{ |
1806 | "x-amz-acl": {string(perm)}, |
1807 | @@ -107,7 +107,7 @@ |
1808 | // DelBucket removes an existing S3 bucket. All objects in the bucket must |
1809 | // be removed before the bucket itself can be removed. |
1810 | // |
1811 | -// See http://goo.gl/GoBrY for more details. |
1812 | +// See http://goo.gl/GoBrY for details. |
1813 | func (b *Bucket) DelBucket() error { |
1814 | req := &request{ |
1815 | method: "DELETE", |
1816 | @@ -117,9 +117,14 @@ |
1817 | return b.S3.query(req, nil) |
1818 | } |
1819 | |
1820 | +func hasCode(err error, code string) bool { |
1821 | + s3err, ok := err.(*Error) |
1822 | + return ok && s3err.Code == code |
1823 | +} |
1824 | + |
1825 | // Get retrieves an object from an S3 bucket. |
1826 | // |
1827 | -// See http://goo.gl/isCO7 for more details. |
1828 | +// See http://goo.gl/isCO7 for details. |
1829 | func (b *Bucket) Get(path string) (data []byte, err error) { |
1830 | body, err := b.GetReader(path) |
1831 | if err != nil { |
1832 | @@ -151,7 +156,7 @@ |
1833 | |
1834 | // Put inserts an object into the S3 bucket. |
1835 | // |
1836 | -// See http://goo.gl/FEBPD for more details. |
1837 | +// See http://goo.gl/FEBPD for details. |
1838 | func (b *Bucket) Put(path string, data []byte, contType string, perm ACL) error { |
1839 | body := bytes.NewBuffer(data) |
1840 | return b.PutReader(path, body, int64(len(data)), contType, perm) |
1841 | @@ -177,7 +182,7 @@ |
1842 | |
1843 | // Del removes an object from the S3 bucket. |
1844 | // |
1845 | -// See http://goo.gl/APeTt for more details. |
1846 | +// See http://goo.gl/APeTt for details. |
1847 | func (b *Bucket) Del(path string) error { |
1848 | req := &request{ |
1849 | method: "DELETE", |
1850 | @@ -215,15 +220,15 @@ |
1851 | Owner Owner |
1852 | } |
1853 | |
1854 | -// List returns a information about objects in an S3 bucket. |
1855 | +// List returns information about objects in an S3 bucket. |
1856 | // |
1857 | // The prefix parameter limits the response to keys that begin with the |
1858 | -// specified prefix. You can use prefixes to separate a bucket into different |
1859 | -// groupings of keys (e.g. to get a feeling of folders). |
1860 | +// specified prefix. |
1861 | // |
1862 | -// The delimited parameter causes the response to group all of the keys that |
1863 | -// share a common prefix up to the next delimiter to be grouped in a single |
1864 | -// entry within the CommonPrefixes field. |
1865 | +// The delim parameter causes the response to group all of the keys that |
1866 | +// share a common prefix up to the next delimiter in a single entry within |
1867 | +// the CommonPrefixes field. You can use delimiters to separate a bucket |
1868 | +// into different groupings of keys, similar to how folders would work. |
1869 | // |
1870 | // The marker parameter specifies the key to start with when listing objects |
1871 | // in a bucket. Amazon S3 lists objects in alphabetical order and |
1872 | @@ -270,7 +275,7 @@ |
1873 | // }, |
1874 | // } |
1875 | // |
1876 | -// See http://goo.gl/YjQTc for more details. |
1877 | +// See http://goo.gl/YjQTc for details. |
1878 | func (b *Bucket) List(prefix, delim, marker string, max int) (result *ListResp, err error) { |
1879 | params := map[string][]string{ |
1880 | "prefix": {prefix}, |
1881 | |
1882 | === modified file 's3/s3_test.go' |
1883 | --- s3/s3_test.go 2012-07-05 05:47:52 +0000 |
1884 | +++ s3/s3_test.go 2013-01-31 17:09:20 +0000 |
1885 | @@ -4,29 +4,40 @@ |
1886 | "bytes" |
1887 | "io/ioutil" |
1888 | "net/http" |
1889 | + "testing" |
1890 | |
1891 | "launchpad.net/goamz/aws" |
1892 | "launchpad.net/goamz/s3" |
1893 | + "launchpad.net/goamz/testutil" |
1894 | . "launchpad.net/gocheck" |
1895 | ) |
1896 | |
1897 | -var _ = Suite(&S{}) |
1898 | +func Test(t *testing.T) { |
1899 | + TestingT(t) |
1900 | +} |
1901 | |
1902 | type S struct { |
1903 | - HTTPSuite |
1904 | s3 *s3.S3 |
1905 | } |
1906 | |
1907 | +var _ = Suite(&S{}) |
1908 | + |
1909 | +var testServer = testutil.NewHTTPServer() |
1910 | + |
1911 | func (s *S) SetUpSuite(c *C) { |
1912 | - s.HTTPSuite.SetUpSuite(c) |
1913 | + testServer.Start() |
1914 | auth := aws.Auth{"abc", "123"} |
1915 | s.s3 = s3.New(auth, aws.Region{Name: "faux-region-1", S3Endpoint: testServer.URL}) |
1916 | } |
1917 | |
1918 | +func (s *S) TearDownTest(c *C) { |
1919 | + testServer.Flush() |
1920 | +} |
1921 | + |
1922 | // PutBucket docs: http://goo.gl/kBTCu |
1923 | |
1924 | func (s *S) TestPutBucket(c *C) { |
1925 | - testServer.PrepareResponse(200, nil, "") |
1926 | + testServer.Response(200, nil, "") |
1927 | |
1928 | b := s.s3.Bucket("bucket") |
1929 | err := b.PutBucket(s3.Private) |
1930 | @@ -41,7 +52,7 @@ |
1931 | // DeleteBucket docs: http://goo.gl/GoBrY |
1932 | |
1933 | func (s *S) TestDelBucket(c *C) { |
1934 | - testServer.PrepareResponse(204, nil, "") |
1935 | + testServer.Response(204, nil, "") |
1936 | |
1937 | b := s.s3.Bucket("bucket") |
1938 | err := b.DelBucket() |
1939 | @@ -56,7 +67,7 @@ |
1940 | // GetObject docs: http://goo.gl/isCO7 |
1941 | |
1942 | func (s *S) TestGet(c *C) { |
1943 | - testServer.PrepareResponse(200, nil, "content") |
1944 | + testServer.Response(200, nil, "content") |
1945 | |
1946 | b := s.s3.Bucket("bucket") |
1947 | data, err := b.Get("name") |
1948 | @@ -71,7 +82,7 @@ |
1949 | } |
1950 | |
1951 | func (s *S) TestURL(c *C) { |
1952 | - testServer.PrepareResponse(200, nil, "content") |
1953 | + testServer.Response(200, nil, "content") |
1954 | |
1955 | b := s.s3.Bucket("bucket") |
1956 | url := b.URL("name") |
1957 | @@ -88,7 +99,7 @@ |
1958 | } |
1959 | |
1960 | func (s *S) TestGetReader(c *C) { |
1961 | - testServer.PrepareResponse(200, nil, "content") |
1962 | + testServer.Response(200, nil, "content") |
1963 | |
1964 | b := s.s3.Bucket("bucket") |
1965 | rc, err := b.GetReader("name") |
1966 | @@ -105,7 +116,7 @@ |
1967 | } |
1968 | |
1969 | func (s *S) TestGetNotFound(c *C) { |
1970 | - testServer.PrepareResponse(404, nil, GetObjectErrorDump) |
1971 | + testServer.Response(404, nil, GetObjectErrorDump) |
1972 | |
1973 | b := s.s3.Bucket("non-existent-bucket") |
1974 | data, err := b.Get("non-existent") |
1975 | @@ -130,7 +141,7 @@ |
1976 | // PutObject docs: http://goo.gl/FEBPD |
1977 | |
1978 | func (s *S) TestPutObject(c *C) { |
1979 | - testServer.PrepareResponse(200, nil, "") |
1980 | + testServer.Response(200, nil, "") |
1981 | |
1982 | b := s.s3.Bucket("bucket") |
1983 | err := b.Put("name", []byte("content"), "content-type", s3.Private) |
1984 | @@ -147,7 +158,7 @@ |
1985 | } |
1986 | |
1987 | func (s *S) TestPutReader(c *C) { |
1988 | - testServer.PrepareResponse(200, nil, "") |
1989 | + testServer.Response(200, nil, "") |
1990 | |
1991 | b := s.s3.Bucket("bucket") |
1992 | buf := bytes.NewBufferString("content") |
1993 | @@ -167,7 +178,7 @@ |
1994 | // DelObject docs: http://goo.gl/APeTt |
1995 | |
1996 | func (s *S) TestDelObject(c *C) { |
1997 | - testServer.PrepareResponse(200, nil, "") |
1998 | + testServer.Response(200, nil, "") |
1999 | |
2000 | b := s.s3.Bucket("bucket") |
2001 | err := b.Del("name") |
2002 | @@ -182,7 +193,7 @@ |
2003 | // Bucket List Objects docs: http://goo.gl/YjQTc |
2004 | |
2005 | func (s *S) TestList(c *C) { |
2006 | - testServer.PrepareResponse(200, nil, GetListResultDump1) |
2007 | + testServer.Response(200, nil, GetListResultDump1) |
2008 | |
2009 | b := s.s3.Bucket("quotes") |
2010 | |
2011 | @@ -221,7 +232,7 @@ |
2012 | } |
2013 | |
2014 | func (s *S) TestListWithDelimiter(c *C) { |
2015 | - testServer.PrepareResponse(200, nil, GetListResultDump2) |
2016 | + testServer.Response(200, nil, GetListResultDump2) |
2017 | |
2018 | b := s.s3.Bucket("quotes") |
2019 | |
2020 | |
2021 | === modified file 's3/s3i_test.go' |
2022 | --- s3/s3i_test.go 2013-01-28 13:30:10 +0000 |
2023 | +++ s3/s3i_test.go 2013-01-31 17:09:20 +0000 |
2024 | @@ -10,6 +10,7 @@ |
2025 | |
2026 | "launchpad.net/goamz/aws" |
2027 | "launchpad.net/goamz/s3" |
2028 | + "launchpad.net/goamz/testutil" |
2029 | . "launchpad.net/gocheck" |
2030 | "time" |
2031 | ) |
2032 | @@ -45,7 +46,7 @@ |
2033 | } |
2034 | |
2035 | func (s *AmazonClientSuite) SetUpSuite(c *C) { |
2036 | - if !*amazon { |
2037 | + if !testutil.Amazon { |
2038 | c.Skip("live tests against AWS disabled (no -amazon)") |
2039 | } |
2040 | s.srv.SetUp(c) |
2041 | @@ -62,7 +63,7 @@ |
2042 | } |
2043 | |
2044 | func (s *AmazonDomainClientSuite) SetUpSuite(c *C) { |
2045 | - if !*amazon { |
2046 | + if !testutil.Amazon { |
2047 | c.Skip("live tests against AWS disabled (no -amazon)") |
2048 | } |
2049 | s.srv.SetUp(c) |
2050 | @@ -102,12 +103,15 @@ |
2051 | |
2052 | func (s *ClientTests) TestBasicFunctionality(c *C) { |
2053 | b := s.Bucket(testBucket) |
2054 | + b.DelBucket() |
2055 | + |
2056 | err := b.PutBucket(s3.PublicRead) |
2057 | c.Assert(err, IsNil) |
2058 | defer b.DelBucket() |
2059 | |
2060 | err = b.Put("name", []byte("yo!"), "text/plain", s3.PublicRead) |
2061 | c.Assert(err, IsNil) |
2062 | + defer b.Del("name") |
2063 | |
2064 | data, err := b.Get("name") |
2065 | c.Assert(err, IsNil) |
2066 | @@ -120,6 +124,7 @@ |
2067 | buf := bytes.NewBufferString("hey!") |
2068 | err = b.PutReader("name2", buf, int64(buf.Len()), "text/plain", s3.Private) |
2069 | c.Assert(err, IsNil) |
2070 | + defer b.Del("name2") |
2071 | |
2072 | rc, err := b.GetReader("name2") |
2073 | c.Assert(err, IsNil) |
2074 | @@ -225,16 +230,13 @@ |
2075 | // normal list. |
2076 | { |
2077 | Contents: keys(objectNames...), |
2078 | - }, |
2079 | - { |
2080 | + }, { |
2081 | Marker: objectNames[0], |
2082 | Contents: keys(objectNames[1:]...), |
2083 | - }, |
2084 | - { |
2085 | + }, { |
2086 | Marker: objectNames[0] + "a", |
2087 | Contents: keys(objectNames[1:]...), |
2088 | - }, |
2089 | - { |
2090 | + }, { |
2091 | Marker: "z", |
2092 | }, |
2093 | |
2094 | @@ -243,14 +245,12 @@ |
2095 | MaxKeys: 2, |
2096 | Contents: keys(objectNames[0:2]...), |
2097 | IsTruncated: true, |
2098 | - }, |
2099 | - { |
2100 | + }, { |
2101 | MaxKeys: 2, |
2102 | Marker: objectNames[0], |
2103 | Contents: keys(objectNames[1:3]...), |
2104 | IsTruncated: true, |
2105 | - }, |
2106 | - { |
2107 | + }, { |
2108 | MaxKeys: 2, |
2109 | Marker: objectNames[len(objectNames)-2], |
2110 | Contents: keys(objectNames[len(objectNames)-1:]...), |
2111 | @@ -261,38 +261,32 @@ |
2112 | Delimiter: "/", |
2113 | CommonPrefixes: []string{"photos/", "test/"}, |
2114 | Contents: keys("index.html", "index2.html"), |
2115 | - }, |
2116 | - { |
2117 | + }, { |
2118 | Delimiter: "/", |
2119 | Prefix: "photos/2006/", |
2120 | CommonPrefixes: []string{"photos/2006/February/", "photos/2006/January/"}, |
2121 | - }, |
2122 | - { |
2123 | + }, { |
2124 | Delimiter: "/", |
2125 | Prefix: "t", |
2126 | CommonPrefixes: []string{"test/"}, |
2127 | - }, |
2128 | - { |
2129 | + }, { |
2130 | Delimiter: "/", |
2131 | MaxKeys: 1, |
2132 | Contents: keys("index.html"), |
2133 | IsTruncated: true, |
2134 | - }, |
2135 | - { |
2136 | + }, { |
2137 | Delimiter: "/", |
2138 | MaxKeys: 1, |
2139 | Marker: "index2.html", |
2140 | CommonPrefixes: []string{"photos/"}, |
2141 | IsTruncated: true, |
2142 | - }, |
2143 | - { |
2144 | + }, { |
2145 | Delimiter: "/", |
2146 | MaxKeys: 1, |
2147 | Marker: "photos/", |
2148 | CommonPrefixes: []string{"test/"}, |
2149 | IsTruncated: false, |
2150 | - }, |
2151 | - { |
2152 | + }, { |
2153 | Delimiter: "Feb", |
2154 | CommonPrefixes: []string{"photos/2006/Feb"}, |
2155 | Contents: keys("index.html", "index2.html", "photos/2006/January/sample.jpg", "test/bar", "test/foo"), |
2156 | |
2157 | === removed file 's3/suite_test.go' |
2158 | --- s3/suite_test.go 2012-05-02 15:22:53 +0000 |
2159 | +++ s3/suite_test.go 1970-01-01 00:00:00 +0000 |
2160 | @@ -1,139 +0,0 @@ |
2161 | -package s3_test |
2162 | - |
2163 | -import ( |
2164 | - "flag" |
2165 | - "fmt" |
2166 | - "launchpad.net/goamz/aws" |
2167 | - . "launchpad.net/gocheck" |
2168 | - "net/http" |
2169 | - "net/url" |
2170 | - "os" |
2171 | - "testing" |
2172 | - "time" |
2173 | -) |
2174 | - |
2175 | -func Test(t *testing.T) { |
2176 | - TestingT(t) |
2177 | -} |
2178 | - |
2179 | -var amazon = flag.Bool("amazon", false, "Enable tests against amazon server") |
2180 | - |
2181 | -type SuiteI struct { |
2182 | - auth aws.Auth |
2183 | -} |
2184 | - |
2185 | -func (s *SuiteI) SetUpSuite(c *C) { |
2186 | - if !*amazon { |
2187 | - c.Skip("amazon tests not enabled (-amazon flag)") |
2188 | - } |
2189 | - auth, err := aws.EnvAuth() |
2190 | - if err != nil { |
2191 | - c.Fatal(err.Error()) |
2192 | - } |
2193 | - s.auth = auth |
2194 | -} |
2195 | - |
2196 | -type HTTPSuite struct{} |
2197 | - |
2198 | -var testServer = NewTestHTTPServer("http://localhost:4444", 5*time.Second) |
2199 | - |
2200 | -func (s *HTTPSuite) SetUpSuite(c *C) { |
2201 | - testServer.Start() |
2202 | -} |
2203 | - |
2204 | -func (s *HTTPSuite) TearDownTest(c *C) { |
2205 | - testServer.FlushRequests() |
2206 | -} |
2207 | - |
2208 | -type TestHTTPServer struct { |
2209 | - URL string |
2210 | - Timeout time.Duration |
2211 | - started bool |
2212 | - request chan *http.Request |
2213 | - response chan *testResponse |
2214 | - pending chan bool |
2215 | -} |
2216 | - |
2217 | -type testResponse struct { |
2218 | - Status int |
2219 | - Headers map[string]string |
2220 | - Body string |
2221 | -} |
2222 | - |
2223 | -func NewTestHTTPServer(url string, timeout time.Duration) *TestHTTPServer { |
2224 | - return &TestHTTPServer{URL: url, Timeout: timeout} |
2225 | -} |
2226 | - |
2227 | -func (s *TestHTTPServer) Start() { |
2228 | - if s.started { |
2229 | - return |
2230 | - } |
2231 | - s.started = true |
2232 | - |
2233 | - s.request = make(chan *http.Request, 64) |
2234 | - s.response = make(chan *testResponse, 64) |
2235 | - s.pending = make(chan bool, 64) |
2236 | - |
2237 | - url, _ := url.Parse(s.URL) |
2238 | - go http.ListenAndServe(url.Host, s) |
2239 | - |
2240 | - s.PrepareResponse(202, nil, "Nothing.") |
2241 | - for { |
2242 | - // Wait for it to be up. |
2243 | - resp, err := http.Get(s.URL) |
2244 | - if err == nil && resp.StatusCode == 202 { |
2245 | - break |
2246 | - } |
2247 | - fmt.Fprintf(os.Stderr, "\nWaiting for fake server to be up... ") |
2248 | - time.Sleep(1e8) |
2249 | - } |
2250 | - fmt.Fprintf(os.Stderr, "done\n\n") |
2251 | - s.WaitRequest() // Consume dummy request. |
2252 | -} |
2253 | - |
2254 | -// FlushRequests discards requests which were not yet consumed by WaitRequest. |
2255 | -func (s *TestHTTPServer) FlushRequests() { |
2256 | - for { |
2257 | - select { |
2258 | - case <-s.request: |
2259 | - default: |
2260 | - return |
2261 | - } |
2262 | - } |
2263 | -} |
2264 | - |
2265 | -func (s *TestHTTPServer) ServeHTTP(w http.ResponseWriter, req *http.Request) { |
2266 | - s.request <- req |
2267 | - var resp *testResponse |
2268 | - select { |
2269 | - case resp = <-s.response: |
2270 | - case <-time.After(s.Timeout): |
2271 | - fmt.Fprintf(os.Stderr, "ERROR: Timeout waiting for test to provide response\n") |
2272 | - resp = &testResponse{500, nil, ""} |
2273 | - } |
2274 | - if resp.Headers != nil { |
2275 | - h := w.Header() |
2276 | - for k, v := range resp.Headers { |
2277 | - h.Set(k, v) |
2278 | - } |
2279 | - } |
2280 | - if resp.Status != 0 { |
2281 | - w.WriteHeader(resp.Status) |
2282 | - } |
2283 | - w.Write([]byte(resp.Body)) |
2284 | -} |
2285 | - |
2286 | -func (s *TestHTTPServer) WaitRequest() *http.Request { |
2287 | - select { |
2288 | - case req := <-s.request: |
2289 | - req.ParseForm() |
2290 | - return req |
2291 | - case <-time.After(s.Timeout): |
2292 | - panic("Timeout waiting for goamz request") |
2293 | - } |
2294 | - panic("unreached") |
2295 | -} |
2296 | - |
2297 | -func (s *TestHTTPServer) PrepareResponse(status int, headers map[string]string, body string) { |
2298 | - s.response <- &testResponse{status, headers, body} |
2299 | -} |
2300 | |
2301 | === added directory 'testutil' |
2302 | === added file 'testutil/http.go' |
2303 | --- testutil/http.go 1970-01-01 00:00:00 +0000 |
2304 | +++ testutil/http.go 2013-01-31 17:09:20 +0000 |
2305 | @@ -0,0 +1,174 @@ |
2306 | +package testutil |
2307 | + |
2308 | +import ( |
2309 | + "bytes" |
2310 | + "fmt" |
2311 | + "io/ioutil" |
2312 | + "net" |
2313 | + "net/http" |
2314 | + "net/url" |
2315 | + "os" |
2316 | + "time" |
2317 | +) |
2318 | + |
2319 | +type HTTPServer struct { |
2320 | + URL string |
2321 | + Timeout time.Duration |
2322 | + started bool |
2323 | + request chan *http.Request |
2324 | + response chan ResponseFunc |
2325 | +} |
2326 | + |
2327 | +type Response struct { |
2328 | + Status int |
2329 | + Headers map[string]string |
2330 | + Body string |
2331 | +} |
2332 | + |
2333 | +func NewHTTPServer() *HTTPServer { |
2334 | + return &HTTPServer{URL: "http://localhost:4444", Timeout: 5 * time.Second} |
2335 | +} |
2336 | + |
2337 | +type ResponseFunc func(path string) Response |
2338 | + |
2339 | +func (s *HTTPServer) Start() { |
2340 | + if s.started { |
2341 | + return |
2342 | + } |
2343 | + s.started = true |
2344 | + s.request = make(chan *http.Request, 64) |
2345 | + s.response = make(chan ResponseFunc, 64) |
2346 | + u, err := url.Parse(s.URL) |
2347 | + if err != nil { |
2348 | + panic(err) |
2349 | + } |
2350 | + l, err := net.Listen("tcp", u.Host) |
2351 | + if err != nil { |
2352 | + panic(err) |
2353 | + } |
2354 | + go http.Serve(l, s) |
2355 | + |
2356 | + s.Response(203, nil, "") |
2357 | + for { |
2358 | + // Wait for it to be up. |
2359 | + resp, err := http.Get(s.URL) |
2360 | + if err == nil && resp.StatusCode == 203 { |
2361 | + break |
2362 | + } |
2363 | + time.Sleep(1e8) |
2364 | + } |
2365 | + s.WaitRequest() // Consume dummy request. |
2366 | +} |
2367 | + |
2368 | +// Flush discards all pending requests and responses. |
2369 | +func (s *HTTPServer) Flush() { |
2370 | + for { |
2371 | + select { |
2372 | + case <-s.request: |
2373 | + case <-s.response: |
2374 | + default: |
2375 | + return |
2376 | + } |
2377 | + } |
2378 | +} |
2379 | + |
2380 | +func body(req *http.Request) string { |
2381 | + data, err := ioutil.ReadAll(req.Body) |
2382 | + if err != nil { |
2383 | + panic(err) |
2384 | + } |
2385 | + return string(data) |
2386 | +} |
2387 | + |
2388 | +func (s *HTTPServer) ServeHTTP(w http.ResponseWriter, req *http.Request) { |
2389 | + req.ParseMultipartForm(1e6) |
2390 | + data, err := ioutil.ReadAll(req.Body) |
2391 | + if err != nil { |
2392 | + panic(err) |
2393 | + } |
2394 | + req.Body = ioutil.NopCloser(bytes.NewBuffer(data)) |
2395 | + s.request <- req |
2396 | + var resp Response |
2397 | + select { |
2398 | + case respFunc := <-s.response: |
2399 | + resp = respFunc(req.URL.Path) |
2400 | + case <-time.After(s.Timeout): |
2401 | + const msg = "ERROR: Timeout waiting for test to prepare a response\n" |
2402 | + fmt.Fprintf(os.Stderr, msg) |
2403 | + resp = Response{500, nil, msg} |
2404 | + } |
2405 | + if resp.Headers != nil { |
2406 | + h := w.Header() |
2407 | + for k, v := range resp.Headers { |
2408 | + h.Set(k, v) |
2409 | + } |
2410 | + } |
2411 | + if resp.Status != 0 { |
2412 | + w.WriteHeader(resp.Status) |
2413 | + } |
2414 | + w.Write([]byte(resp.Body)) |
2415 | +} |
2416 | + |
2417 | +// WaitRequests returns the next n requests made to the http server from |
2418 | +// the queue. If not enough requests were previously made, it waits until |
2419 | +// the timeout value for them to be made. |
2420 | +func (s *HTTPServer) WaitRequests(n int) []*http.Request { |
2421 | + reqs := make([]*http.Request, 0, n) |
2422 | + for i := 0; i < n; i++ { |
2423 | + select { |
2424 | + case req := <-s.request: |
2425 | + reqs = append(reqs, req) |
2426 | + case <-time.After(s.Timeout): |
2427 | + panic("Timeout waiting for request") |
2428 | + } |
2429 | + } |
2430 | + return reqs |
2431 | +} |
2432 | + |
2433 | +// WaitRequest returns the next request made to the http server from |
2434 | +// the queue. If no requests were previously made, it waits until the |
2435 | +// timeout value for one to be made. |
2436 | +func (s *HTTPServer) WaitRequest() *http.Request { |
2437 | + return s.WaitRequests(1)[0] |
2438 | +} |
2439 | + |
2440 | +// ResponseFunc prepares the test server to respond the following n |
2441 | +// requests using f to build each response. |
2442 | +func (s *HTTPServer) ResponseFunc(n int, f ResponseFunc) { |
2443 | + for i := 0; i < n; i++ { |
2444 | + s.response <- f |
2445 | + } |
2446 | +} |
2447 | + |
2448 | +// ResponseMap maps request paths to responses. |
2449 | +type ResponseMap map[string]Response |
2450 | + |
2451 | +// ResponseMap prepares the test server to respond the following n |
2452 | +// requests using the m to obtain the responses. |
2453 | +func (s *HTTPServer) ResponseMap(n int, m ResponseMap) { |
2454 | + f := func(path string) Response { |
2455 | + for rpath, resp := range m { |
2456 | + if rpath == path { |
2457 | + return resp |
2458 | + } |
2459 | + } |
2460 | + body := "Path not found in response map: " + path |
2461 | + return Response{Status: 500, Body: body} |
2462 | + } |
2463 | + s.ResponseFunc(n, f) |
2464 | +} |
2465 | + |
2466 | +// Responses prepares the test server to respond the following n requests |
2467 | +// using the provided response parameters. |
2468 | +func (s *HTTPServer) Responses(n int, status int, headers map[string]string, body string) { |
2469 | + f := func(path string) Response { |
2470 | + return Response{status, headers, body} |
2471 | + } |
2472 | + s.ResponseFunc(n, f) |
2473 | +} |
2474 | + |
2475 | +// Response prepares the test server to respond the following request |
2476 | +// using the provided response parameters. |
2477 | +func (s *HTTPServer) Response(status int, headers map[string]string, body string) { |
2478 | + s.Responses(1, status, headers, body) |
2479 | +} |
2480 | |
2481 | === added file 'testutil/suite.go' |
2482 | --- testutil/suite.go 1970-01-01 00:00:00 +0000 |
2483 | +++ testutil/suite.go 2013-01-31 17:09:20 +0000 |
2484 | @@ -0,0 +1,30 @@ |
2485 | +package testutil |
2486 | + |
2487 | +import ( |
2488 | + "flag" |
2489 | + "launchpad.net/goamz/aws" |
2490 | + . "launchpad.net/gocheck" |
2491 | +) |
2492 | + |
2493 | +// Amazon must be used by all tested packages to determine whether to |
2494 | +// run functional tests against the real AWS servers. |
2495 | +var Amazon bool |
2496 | + |
2497 | +func init() { |
2498 | + flag.BoolVar(&Amazon, "amazon", false, "Enable tests against amazon server") |
2499 | +} |
2500 | + |
2501 | +type LiveSuite struct { |
2502 | + auth aws.Auth |
2503 | +} |
2504 | + |
2505 | +func (s *LiveSuite) SetUpSuite(c *C) { |
2506 | + if !Amazon { |
2507 | + c.Skip("amazon tests not enabled (-amazon flag)") |
2508 | + } |
2509 | + auth, err := aws.EnvAuth() |
2510 | + if err != nil { |
2511 | + c.Fatal(err.Error()) |
2512 | + } |
2513 | + s.auth = auth |
2514 | +} |
Reviewers: mp+145878_ code.launchpad. net,
Message:
Please take a look.
Description:
testutil: new package for test clean up
Killed all the repetition in suite_test files, and improved the
implementation of the test HTTP server.
A few test bugs were also fixed on the way.
https:/ /code.launchpad .net/~niemeyer/ goamz/testing- cleanup/ +merge/ 145878
(do not edit description out of merge proposal)
Please review this at https:/ /codereview. appspot. com/7232065/
Affected files: filter. go server. go mturk_test. go suite_test. go suite_test. go suite_test. go
A [revision details]
M aws/aws_test.go
D aws/suite_test.go
M ec2/ec2.go
M ec2/ec2_test.go
M ec2/ec2i_test.go
M ec2/ec2t_test.go
M ec2/ec2test/
M ec2/ec2test/
M ec2/sign.go
D ec2/suite_test.go
M exp/mturk/mturk.go
M exp/mturk/
D exp/mturk/
M exp/sdb/sdb.go
M exp/sdb/sdb_test.go
D exp/sdb/
M exp/sns/sns_test.go
D exp/sns/
M iam/iam_test.go
M iam/iami_test.go
D iam/suite_test.go
M s3/s3.go
M s3/s3_test.go
M s3/s3i_test.go
D s3/suite_test.go
A testutil/http.go
A testutil/suite.go