Merge lp:~prudhvikrishna/goamz/sqs into lp:~gophers/goamz/trunk

Proposed by Prudhvi Surapaneni
Status: Needs review
Proposed branch: lp:~prudhvikrishna/goamz/sqs
Merge into: lp:~gophers/goamz/trunk
Diff against target: 1304 lines (+1280/-0)
5 files modified
response_test.go (+238/-0)
sign.go (+35/-0)
sqs.go (+581/-0)
sqs_test.go (+306/-0)
suite_test.go (+120/-0)
To merge this branch: bzr merge lp:~prudhvikrishna/goamz/sqs
Reviewer Review Type Date Requested Status
The Go Language Gophers Pending
Review via email: mp+107309@code.launchpad.net
To post a comment you must log in.

Unmerged revisions

3. By Prudhvi Surapaneni

Fix Attribute Names

2. By Prudhvi Surapaneni

Use different Path's basing on access

1. By Prudhvi Surapaneni

Import SQS

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file 'response_test.go'
--- response_test.go 1970-01-01 00:00:00 +0000
+++ response_test.go 2012-05-25 00:21:19 +0000
@@ -0,0 +1,238 @@
1package sqs_test
2
3var TestCreateQueueXmlOK = `
4<CreateQueueResponse>
5 <CreateQueueResult>
6 <QueueUrl>http://sqs.us-east-1.amazonaws.com/123456789012/testQueue</QueueUrl>
7 </CreateQueueResult>
8 <ResponseMetadata>
9 <RequestId>7a62c49f-347e-4fc4-9331-6e8e7a96aa73</RequestId>
10 </ResponseMetadata>
11</CreateQueueResponse>
12`
13
14var TestListQueuesXmlOK = `
15<ListQueuesResponse>
16 <ListQueuesResult>
17 <QueueUrl>http://sqs.us-east-1.amazonaws.com/123456789012/testQueue</QueueUrl>
18 </ListQueuesResult>
19 <ResponseMetadata>
20 <RequestId>725275ae-0b9b-4762-b238-436d7c65a1ac</RequestId>
21 </ResponseMetadata>
22</ListQueuesResponse>
23`
24
25var TestGetQueueUrlXmlOK = `
26<GetQueueUrlResponse>
27 <GetQueueUrlResult>
28 <QueueUrl>http://sqs.us-east-1.amazonaws.com/123456789012/testQueue</QueueUrl>
29 </GetQueueUrlResult>
30 <ResponseMetadata>
31 <RequestId>470a6f13-2ed9-4181-ad8a-2fdea142988e</RequestId>
32 </ResponseMetadata>
33</GetQueueUrlResponse>
34`
35
36var TestChangeMessageVisibilityXmlOK = `
37<ChangeMessageVisibilityResponse>
38 <ResponseMetadata>
39 <RequestId>6a7a282a-d013-4a59-aba9-335b0fa48bed</RequestId>
40 </ResponseMetadata>
41</ChangeMessageVisibilityResponse>
42`
43
44var TestChangeMessaveVisibilityBatchXmlOK = `
45<ChangeMessageVisibilityBatchResponse>
46 <ChangeMessageVisibilityBatchResult>
47 <ChangeMessageVisibilityBatchResultEntry>
48 <Id>change_visibility_msg_2</Id>
49 </ChangeMessageVisibilityBatchResultEntry>
50 <ChangeMessageVisibilityBatchResultEntry>
51 <Id>change_visibility_msg_3</Id>
52 </ChangeMessageVisibilityBatchResultEntry>
53 </ChangeMessageVisibilityBatchResult>
54 <ResponseMetadata>
55 <RequestId>ca9668f7-ab1b-4f7a-8859-f15747ab17a7</RequestId>
56 </ResponseMetadata>
57</ChangeMessageVisibilityBatchResponse>
58`
59
60var TestReceiveMessageXmlOK = `
61<ReceiveMessageResponse>
62 <ReceiveMessageResult>
63 <Message>
64 <MessageId>5fea7756-0ea4-451a-a703-a558b933e274</MessageId>
65 <ReceiptHandle>MbZj6wDWli+JvwwJaBV+3dcjk2YW2vA3+STFFljTM8tJJg6HRG6PYSasuWXPJB+CwLj1FjgXUv1uSj1gUPAWV66FU/WeR4mq2OKpEGYWbnLmpRCJVAyeMjeU5ZBdtcQ+QEauMZc8ZRv37sIW2iJKq3M9MFx1YvV11A2x/KSbkJ0=</ReceiptHandle>
66 <MD5OfBody>fafb00f5732ab283681e124bf8747ed1</MD5OfBody>
67 <Body>This is a test message</Body>
68 <Attribute>
69 <Name>SenderId</Name>
70 <Value>195004372649</Value>
71 </Attribute>
72 <Attribute>
73 <Name>SentTimestamp</Name>
74 <Value>1238099229000</Value>
75 </Attribute>
76 <Attribute>
77 <Name>ApproximateReceiveCount</Name>
78 <Value>5</Value>
79 </Attribute>
80 <Attribute>
81 <Name>ApproximateFirstReceiveTimestamp</Name>
82 <Value>1250700979248</Value>
83 </Attribute>
84 </Message>
85 </ReceiveMessageResult>
86<ResponseMetadata>
87 <RequestId>b6633655-283d-45b4-aee4-4e84e0ae6afa</RequestId>
88</ResponseMetadata>
89</ReceiveMessageResponse>
90`
91
92var TestDeleteMessageXmlOK = `
93<DeleteQueueResponse>
94 <ResponseMetadata>
95 <RequestId>b5293cb5-d306-4a17-9048-b263635abe42</RequestId>
96 </ResponseMetadata>
97</DeleteQueueResponse>
98`
99
100var TestSendMessageXmlOK = `
101<SendMessageResponse>
102 <SendMessageResult>
103 <MD5OfMessageBody>fafb00f5732ab283681e124bf8747ed1</MD5OfMessageBody>
104 <MessageId>5fea7756-0ea4-451a-a703-a558b933e274</MessageId>
105 </SendMessageResult>
106 <ResponseMetadata>
107 <RequestId>27daac76-34dd-47df-bd01-1f6e873584a0</RequestId>
108 </ResponseMetadata>
109</SendMessageResponse>
110`
111
112var TestSendMessageBatchXmlOK = `
113<SendMessageBatchResponse>
114<SendMessageBatchResult>
115 <SendMessageBatchResultEntry>
116 <Id>test_msg_001</Id>
117 <MessageId>0a5231c7-8bff-4955-be2e-8dc7c50a25fa</MessageId>
118 <MD5OfMessageBody>0e024d309850c78cba5eabbeff7cae71</MD5OfMessageBody>
119 </SendMessageBatchResultEntry>
120 <SendMessageBatchResultEntry>
121 <Id>test_msg_002</Id>
122 <MessageId>15ee1ed3-87e7-40c1-bdaa-2e49968ea7e9</MessageId>
123 <MD5OfMessageBody>7fb8146a82f95e0af155278f406862c2</MD5OfMessageBody>
124 </SendMessageBatchResultEntry>
125</SendMessageBatchResult>
126<ResponseMetadata>
127 <RequestId>ca1ad5d0-8271-408b-8d0f-1351bf547e74</RequestId>
128</ResponseMetadata>
129</SendMessageBatchResponse>
130`
131
132var TestGetQueueAttributesAllXmlOK = `
133<GetQueueAttributesResponse>
134 <GetQueueAttributesResult>
135 <Attribute>
136 <Name>VisibilityTimeout</Name>
137 <Value>30</Value>
138 </Attribute>
139 <Attribute>
140 <Name>ApproximateNumberOfMessages</Name>
141 <Value>0</Value>
142 </Attribute>
143 <Attribute>
144 <Name>ApproximateNumberOfMessagesNotVisible</Name>
145 <Value>0</Value>
146 </Attribute>
147 <Attribute>
148 <Name>CreatedTimestamp</Name>
149 <Value>1286771522</Value>
150 </Attribute>
151 <Attribute>
152 <Name>LastModifiedTimestamp</Name>
153 <Value>1286771522</Value>
154 </Attribute>
155 <Attribute>
156 <Name>QueueArn</Name>
157 <Value>arn:aws:sqs:us-east-1:123456789012:qfoo</Value>
158 </Attribute>
159 <Attribute>
160 <Name>MaximumMessageSize</Name>
161 <Value>8192</Value>
162 </Attribute>
163 <Attribute>
164 <Name>MessageRetentionPeriod</Name>
165 <Value>345600</Value>
166 </Attribute>
167 </GetQueueAttributesResult>
168 <ResponseMetadata>
169 <RequestId>1ea71be5-b5a2-4f9d-b85a-945d8d08cd0b</RequestId>
170 </ResponseMetadata>
171</GetQueueAttributesResponse>
172`
173
174var TestGetQueueAttributesSelectiveXmlOK = `
175<GetQueueAttributesResponse>
176 <GetQueueAttributesResult>
177 <Attribute>
178 <Name>VisibilityTimeout</Name>
179 <Value>30</Value>
180 </Attribute>
181 <Attribute>
182 <Name>DelaySeconds</Name>
183 <Value>0</Value>
184 </Attribute>
185 </GetQueueAttributesResult>
186 <ResponseMetadata>
187 <RequestId>1ea71be5-b5a2-4f9d-b85a-945d8d08cd0b</RequestId>
188 </ResponseMetadata>
189</GetQueueAttributesResponse>
190`
191
192var TestDeleteMessageBatchXmlOK = `
193<DeleteMessageBatchResponse>
194 <DeleteMessageBatchResult>
195 <DeleteMessageBatchResultEntry>
196 <Id>msg1</Id>
197 </DeleteMessageBatchResultEntry>
198 <DeleteMessageBatchResultEntry>
199 <Id>msg2</Id>
200 </DeleteMessageBatchResultEntry>
201 </DeleteMessageBatchResult>
202 <ResponseMetadata>
203 <RequestId>d6f86b7a-74d1-4439-b43f-196a1e29cd85</RequestId>
204 </ResponseMetadata>
205</DeleteMessageBatchResponse>
206`
207
208var TestAddPermissionXmlOK = `
209<AddPermissionResponse>
210 <ResponseMetadata>
211 <RequestId>9a285199-c8d6-47c2-bdb2-314cb47d599d</RequestId>
212 </ResponseMetadata>
213</AddPermissionResponse>
214`
215
216var TestRemovePermissionXmlOK = `
217<RemovePermissionResponse>
218 <ResponseMetadata>
219 <RequestId>f8bdb362-6616-42c0-977a-ce9a8bcce3bb</RequestId>
220 </ResponseMetadata>
221</RemovePermissionResponse>
222`
223
224var TestDeleteQueueXmlOK = `
225<DeleteQueueResponse>
226 <ResponseMetadata>
227 <RequestId>6fde8d1e-52cd-4581-8cd9-c512f4c64223</RequestId>
228 </ResponseMetadata>
229</DeleteQueueResponse>
230`
231
232var TestSetQueueAttributesXmlOK = `
233<SetQueueAttributesResponse>
234 <ResponseMetadata>
235 <RequestId>e5cca473-4fc0-4198-a451-8abb94d02c75</RequestId>
236 </ResponseMetadata>
237</SetQueueAttributesResponse>
238`
0239
=== added file 'sign.go'
--- sign.go 1970-01-01 00:00:00 +0000
+++ sign.go 2012-05-25 00:21:19 +0000
@@ -0,0 +1,35 @@
1package sqs
2
3import (
4 "crypto/hmac"
5 "crypto/sha256"
6 "encoding/base64"
7 "launchpad.net/goamz/aws"
8 "sort"
9 "strings"
10)
11
12// ----------------------------------------------------------------------------
13// EC2 signing (http://goo.gl/fQmAN)
14
15var b64 = base64.StdEncoding
16
17func sign(auth aws.Auth, method, path string, params map[string]string, host string) {
18 params["AWSAccessKeyId"] = auth.AccessKey
19 params["SignatureVersion"] = "2"
20 params["SignatureMethod"] = "HmacSHA256"
21
22 var sarray []string
23 for k, v := range params {
24 sarray = append(sarray, aws.Encode(k)+"="+aws.Encode(v))
25 }
26 sort.StringSlice(sarray).Sort()
27 joined := strings.Join(sarray, "&")
28 payload := method + "\n" + host + "\n" + path + "\n" + joined
29 hash := hmac.New(sha256.New, []byte(auth.SecretKey))
30 hash.Write([]byte(payload))
31 signature := make([]byte, b64.EncodedLen(hash.Size()))
32 b64.Encode(signature, hash.Sum(nil))
33
34 params["Signature"] = string(signature)
35}
036
=== added file 'sqs.go'
--- sqs.go 1970-01-01 00:00:00 +0000
+++ sqs.go 2012-05-25 00:21:19 +0000
@@ -0,0 +1,581 @@
1//
2// goamz - Go packages to interact with the Amazon Web Services.
3//
4// https://wiki.ubuntu.com/goamz
5//
6// Copyright (c) 2012 Memeo Inc.
7//
8// Written by Prudhvi Krishna Surapaneni <me@prudhvi.net>
9//
10package sqs
11
12import (
13 "encoding/xml"
14 "fmt"
15 "launchpad.net/goamz/aws"
16 "log"
17 "net/http"
18 "net/http/httputil"
19 "net/url"
20 "strconv"
21 "time"
22)
23
24// The SQS type encapsulates operations with specific SQS region
25type SQS struct {
26 aws.Auth
27 aws.Region
28 private byte // Reserve the right of using private data.
29}
30
31const debug = false
32
33// New creates a new SQS handle
34func New(auth aws.Auth, region aws.Region) *SQS {
35 return &SQS{auth, region, 0}
36}
37
38// Queue type encapsulates operations on a SQS Queue
39type Queue struct {
40 *SQS
41 Url string
42}
43
44// Response to a CreateQueue request.
45//
46// See http://goo.gl/sVUjF for more details
47type CreateQueueResponse struct {
48 QueueUrl string `xml:"CreateQueueResult>QueueUrl"`
49 ResponseMetadata
50}
51
52// Response to a ListQueues request.
53//
54// See http://goo.gl/RPRWr for more details
55type ListQueuesResponse struct {
56 QueueUrl []string `xml:"ListQueuesResult>QueueUrl"`
57 ResponseMetadata
58}
59
60// Response to a GetQueueUrl request.
61//
62// See http://goo.gl/hk7Iu for more details
63type GetQueueUrlResponse struct {
64 QueueUrl string `xml:"GetQueueUrlResult>QueueUrl"`
65 ResponseMetadata
66}
67
68// Response to a ChangeMessageVisibility request.
69//
70// See http://goo.gl/EyJKF for more details
71type ChangeMessageVisibilityResponse struct {
72 ResponseMetadata
73}
74
75// See http://goo.gl/XTo0s for more details
76type ResponseMetadata struct {
77 RequestId string `xml:"ResponseMetadata>RequestId"`
78}
79
80// Error represents an error in an operation with SQS
81type Error struct {
82 StatusCode int // HTTP Status Code (200, 403, ... )
83 Code string // SQS Error Code
84 Message string // The human-oriented error message
85 RequestId string `xml:"RequestID"`
86}
87
88func (err *Error) Error() string {
89 if err.Code != "" {
90 return err.Message
91 }
92
93 return fmt.Sprintf("%s (%s)", err.Message, err.Code)
94}
95
96// For now a single error inst is being exposed. In the future it may be useful
97// to provide access to all of them, but rather than doing it as an array/slice,
98// use a *next pointer, so that it's backward compatible and it continues to be
99// easy to handle the first error, which is what most people will want.
100type xmlErrors struct {
101 RequestId string
102 Errors []Error `xml:"Errors>Error"`
103}
104
105// Attribute represents an instance of a SQS Queue Attribute.
106type Attribute struct {
107 Name string
108 Value string
109}
110
111// See http://goo.gl/pgffn for more details.
112type ChangeMessageVisibilityBatchEntry struct {
113 Id string
114 ReceiptHandle string
115 VisibilityTimeout int
116}
117
118// ReceiveMessageResponse holds the results of ReceiveMessage
119type ReceiveMessageResponse struct {
120 Messages []Message `xml:"ReceiveMessageResult>Message"`
121 ResponseMetadata
122}
123
124type DeleteMessageResponse struct {
125 ResponseMetadata
126}
127
128type SendMessageResponse struct {
129 SendMessageResult
130 ResponseMetadata
131}
132
133type SendMessageBatchResponse struct {
134 SendMessageBatchResult
135 ResponseMetadata
136}
137
138// SendMessageBatchResult holds the results of SendMessageBatch
139type SendMessageBatchResult struct {
140 Entries []SendMessageBatchResultEntry `xml:"SendMessageBatchResult>SendMessageBatchResultEntry"`
141}
142
143type SendMessageBatchResultEntry struct {
144 MD5OfMessageBody string `xml:"MD5OfMessageBody"`
145 MessageId string `xml:"MessageId"`
146 Id string `xml:"Id"`
147}
148
149type SendMessageBatchRequestEntry struct {
150 Id string
151 MessageBody string
152 DelaySeconds int
153}
154
155type SendMessageResult struct {
156 MD5OfMessageBody string `xml:"SendMessageResult>MD5OfMessageBody"`
157 MessageId string `xml:"SendMessageResult>MessageId"`
158}
159
160// Represents an instance of a SQS Message
161type Message struct {
162 MessageId string `xml:"MessageId"`
163 Body string `xml:"Body"`
164 MD5OfBody string `xml:"MD5OfBody"`
165 ReceiptHandle string `xml:"ReceiptHandle"`
166 Attribute []Attribute `xml:"Attribute"`
167}
168
169type ChangeMessageVisibilityBatchResponse struct {
170 Id []string `xml:"ChangeMessageVisibilityBatchResult>ChangeMessageVisibilityBatchResultEntry>Id"`
171 ResponseMetadata
172}
173
174type GetQueueAttributesResponse struct {
175 Attributes []Attribute `xml:"GetQueueAttributesResult>Attribute"`
176 ResponseMetadata
177}
178
179type DeleteMessageBatchResult struct {
180 Ids []string `xml:"DeleteMessageBatchResult>DeleteMessageBatchResultEntry>Id"`
181}
182
183type DeleteMessageBatchResponse struct {
184 DeleteMessageBatchResult `xml:"DeleteMessageBatchResponse>DeleteMessageBatchResult"`
185 ResponseMetadata
186}
187
188type DeleteMessageBatch struct {
189 Id string
190 ReceiptHandle string
191}
192
193type AccountPermission struct {
194 AWSAccountId string
195 ActionName string
196}
197
198type AddPermissionResponse struct {
199 ResponseMetadata
200}
201
202type RemovePermissionResponse struct {
203 ResponseMetadata
204}
205
206type SetQueueAttributesResponse struct {
207 ResponseMetadata
208}
209
210type DeleteQueueResponse struct {
211 ResponseMetadata
212}
213
214// CreateQueue action creates a new queue.
215//
216// See http://goo.gl/sVUjF for more details
217func (s *SQS) CreateQueue(name string, attributes []Attribute) (queue *Queue, err error) {
218 resp := &CreateQueueResponse{}
219 params := makeParams("CreateQueue")
220 queue = nil
221
222 for i, attribute := range attributes {
223 params["AttributeName."+strconv.Itoa(i+1)+".Name"] = attribute.Name
224 params["AttributeName."+strconv.Itoa(i+1)+".Value"] = attribute.Value
225 }
226
227 params["QueueName"] = name
228 err = s.query("", params, resp)
229 if err != nil {
230 return nil, err
231 }
232 queue = &Queue{s, resp.QueueUrl}
233 return queue, err
234}
235
236// AddPermission action adds a permission to a queue for a specific principal.
237//
238// See http://goo.gl/8WBp8 for more details
239func (q *Queue) AddPermission(label string, accountPermissions []AccountPermission) (resp *AddPermissionResponse, err error) {
240 resp = &AddPermissionResponse{}
241 params := makeParams("AddPermission")
242
243 params["Label"] = label
244 for i, accountPermission := range accountPermissions {
245 params["AWSAccountId."+strconv.Itoa(i+1)] = accountPermission.AWSAccountId
246 params["ActionName."+strconv.Itoa(i+1)] = accountPermission.ActionName
247 }
248
249 err = q.SQS.query(q.Url, params, resp)
250 return
251}
252
253// RemovePermission action revokes any permissions in the queue policy that matches the Label parameter.
254//
255// See http://goo.gl/YLOe8 for more details
256func (q *Queue) RemovePermission(label string) (resp *RemovePermissionResponse, err error) {
257 resp = &RemovePermissionResponse{}
258 params := makeParams("RemovePermission")
259
260 params["Label"] = label
261 err = q.SQS.query(q.Url, params, resp)
262 return
263}
264
265// GetQueueAttributes action returns one or all attributes of a queue.
266//
267// See http://goo.gl/WejDu for more details
268func (q *Queue) GetQueueAttributes(attributes []string) (resp *GetQueueAttributesResponse, err error) {
269 resp = &GetQueueAttributesResponse{}
270 params := makeParams("GetQueueAttributes")
271
272 for i, attribute := range attributes {
273 params["AttributeName."+strconv.Itoa(i+1)] = attribute
274 }
275
276 err = q.SQS.query(q.Url, params, resp)
277 return
278}
279
280// ChangeMessageVisibility action changes the visibility timeout of a specified message in a queue to a new value.
281//
282// See http://goo.gl/EyJKF for more details
283func (q *Queue) ChangeMessageVisibility(receiptHandle string, visibilityTimeout int) (resp *ChangeMessageVisibilityResponse, err error) {
284 resp = &ChangeMessageVisibilityResponse{}
285 params := makeParams("ChangeMessageVisibility")
286
287 params["VisibilityTimeout"] = strconv.Itoa(visibilityTimeout)
288 params["ReceiptHandle"] = receiptHandle
289
290 err = q.SQS.query(q.Url, params, resp)
291 return
292}
293
294// ChangeMessageVisibilityBatch action is a batch version of the ChangeMessageVisibility action.
295//
296// See http://goo.gl/pgffn for more details
297func (q *Queue) ChangeMessageVisibilityBatch(messageVisibilityBatch []ChangeMessageVisibilityBatchEntry) (resp *ChangeMessageVisibilityBatchResponse, err error) {
298 resp = &ChangeMessageVisibilityBatchResponse{}
299 params := makeParams("ChangeMessageVisibilityBatch")
300
301 for i, messageVisibility := range messageVisibilityBatch {
302 params["ChangeMessageVisibilityBatchRequestEntry."+strconv.Itoa(i+1)+".Id"] = messageVisibility.Id
303 params["ChangeMessageVisibilityBatchRequestEntry."+strconv.Itoa(i+1)+".ReceiptHandle"] = messageVisibility.ReceiptHandle
304 params["ChangeMessageVisibilityBatchRequestEntry."+strconv.Itoa(i+1)+".VisibilityTimeout"] = strconv.Itoa(messageVisibility.VisibilityTimeout)
305 }
306
307 err = q.SQS.query(q.Url, params, resp)
308 return
309}
310
311// ReceiveMessage action retrieves one or more messages from the specified queue.
312//
313// See http://goo.gl/ThPrF for more details
314func (q *Queue) ReceiveMessage(attributes []string, maxNumberOfMessages int, visibilityTimeout int) (resp *ReceiveMessageResponse, err error) {
315 resp = &ReceiveMessageResponse{}
316 params := makeParams("ReceiveMessage")
317
318 for i, attribute := range attributes {
319 params["AttributeName."+strconv.Itoa(i+1)] = attribute
320 }
321
322 params["MaxNumberOfMessages"] = strconv.Itoa(maxNumberOfMessages)
323 params["VisibilityTimeout"] = strconv.Itoa(visibilityTimeout)
324
325 err = q.SQS.query(q.Url, params, resp)
326 return
327}
328
329// DeleteMessage action deletes the specified message from the specified queue.
330//
331// See http://goo.gl/6XBv7 for more details
332func (q *Queue) DeleteMessage(receiptHandle string) (resp *DeleteMessageResponse, err error) {
333 resp = &DeleteMessageResponse{}
334 params := makeParams("DeleteMessage")
335
336 params["ReceiptHandle"] = receiptHandle
337
338 err = q.SQS.query(q.Url, params, resp)
339 return
340}
341
342// DeleteMessageBatch action is a batch version of the DeleteMessage action.
343//
344// See http://goo.gl/y1ehG for more details
345func (q *Queue) DeleteMessageBatch(deleteMessageBatch []DeleteMessageBatch) (resp *DeleteMessageBatchResponse, err error) {
346 resp = &DeleteMessageBatchResponse{}
347 params := makeParams("DeleteMessageBatch")
348
349 for i, deleteMessage := range deleteMessageBatch {
350 params["DeleteMessageBatchRequestEntry."+strconv.Itoa(i+1)+".Id"] = deleteMessage.Id
351 params["DeleteMessageBatchRequestEntry."+strconv.Itoa(i+1)+".ReceiptHandle"] = deleteMessage.ReceiptHandle
352 }
353
354 err = q.SQS.query(q.Url, params, resp)
355 return
356}
357
358// SendMessage action delivers a message to the specified queue.
359// The maximum allowed size is 64KB
360//
361// See http://goo.gl/7OnPb for more details
362func (q *Queue) SendMessage(messageBody string) (resp *SendMessageResponse, err error) {
363 resp = &SendMessageResponse{}
364 params := makeParams("SendMessage")
365
366 params["MessageBody"] = messageBody
367 err = q.SQS.query(q.Url, params, resp)
368 return
369}
370
371// SendMessageWithDelay is a helper function for SendMessage action which delivers a message to the specified queue
372// with a delay.
373//
374// See http://goo.gl/7OnPb for more details
375func (q *Queue) SendMessageWithDelay(messageBody string, delaySeconds int) (resp *SendMessageResponse, err error) {
376 resp = &SendMessageResponse{}
377 params := makeParams("SendMessage")
378
379 params["MessageBody"] = messageBody
380 params["DelaySeconds"] = strconv.Itoa(delaySeconds)
381 err = q.SQS.query(q.Url, params, resp)
382 return
383}
384
385// SendMessageBatch action delivers up to ten messages to the specified queue.
386//
387// See http://goo.gl/mNytv for more details
388func (q *Queue) SendMessageBatch(sendMessageBatchRequests []SendMessageBatchRequestEntry) (resp *SendMessageBatchResponse, err error) {
389 resp = &SendMessageBatchResponse{}
390 params := makeParams("SendMessageBatch")
391
392 for i, sendMessageBatchRequest := range sendMessageBatchRequests {
393 params["SendMessageBatchRequestEntry."+strconv.Itoa(i+1)+".Id"] = sendMessageBatchRequest.Id
394 params["SendMessageBatchRequestEntry."+strconv.Itoa(i+1)+".MessageBody"] = sendMessageBatchRequest.MessageBody
395 params["SendMessageBatchRequestEntry."+strconv.Itoa(i+1)+".DelaySeconds"] = strconv.Itoa(sendMessageBatchRequest.DelaySeconds)
396 }
397
398 err = q.SQS.query(q.Url, params, resp)
399 return
400}
401
402// Delete action deletes the queue specified by the queue URL, regardless of whether the queue is empty.
403//
404// See http://goo.gl/c3YCr for more details
405func (q *Queue) Delete() (resp *DeleteQueueResponse, err error) {
406 resp = &DeleteQueueResponse{}
407 params := makeParams("Delete")
408
409 err = q.SQS.query(q.Url, params, resp)
410 return
411}
412
413// SetQueueAttributes action sets one attribute of a queue per request.
414//
415// See http://goo.gl/LyZnj for more details
416func (q *Queue) SetQueueAttributes(attribute Attribute) (resp *SetQueueAttributesResponse, err error) {
417 resp = &SetQueueAttributesResponse{}
418 params := makeParams("SetQueueAttributes")
419
420 params["Attribute.Name"] = attribute.Name
421 params["Attribute.Value"] = attribute.Value
422
423 err = q.SQS.query(q.Url, params, resp)
424 return
425}
426
427// ListQueues action returns a list of your queues.
428//
429// See http://goo.gl/RPRWr for more details
430
431func (s *SQS) ListQueues() (resp *ListQueuesResponse, err error) {
432 resp = &ListQueuesResponse{}
433 params := makeParams("ListQueues")
434
435 err = s.query("", params, resp)
436 return
437}
438
439// ListQueuesWithPrefix action returns only a list of queues with a name beginning with the specified value are returned
440//
441// See http://goo.gl/RPRWr for more details
442func (s *SQS) ListQueuesWithPrefix(queueNamePrefix string) (resp *ListQueuesResponse, err error) {
443 resp = &ListQueuesResponse{}
444 params := makeParams("ListQueues")
445
446 if queueNamePrefix != "" {
447 params["QueueNamePrefix"] = queueNamePrefix
448 }
449
450 err = s.query("", params, resp)
451 return
452}
453
454// GetQueue is a helper function for GetQueueUrl action that returns an instance of a queue with specified name.
455//
456// See http://goo.gl/hk7Iu for more details
457func (s *SQS) GetQueue(queueName string) (queue *Queue, err error) {
458 resp, err := s.GetQueueUrl(queueName)
459 if err != nil {
460 return nil, err
461 }
462
463 queue = &Queue{s, resp.QueueUrl}
464 return
465}
466
467// GetQueueOfOwner is a helper function for GetQueueUrl action that returns an instance of a queue with specified name
468// and belongs to the specified AWS Account Id.
469//
470// See http://goo.gl/hk7Iu for more details
471func (s *SQS) GetQueueOfOwner(queueName, queueOwnerAWSAccountId string) (queue *Queue, err error) {
472 resp, err := s.GetQueueUrlOfOwner(queueName, queueOwnerAWSAccountId)
473 if err != nil {
474 return nil, err
475 }
476
477 queue = &Queue{s, resp.QueueUrl}
478 return
479
480}
481
482// GetQueueUrl action returns the Uniform Resource Locater (URL) of a queue.
483//
484// See http://goo.gl/hk7Iu for more details
485func (s *SQS) GetQueueUrl(queueName string) (resp *GetQueueUrlResponse, err error) {
486 resp = &GetQueueUrlResponse{}
487 params := makeParams("GetQueueUrl")
488
489 params["QueueName"] = queueName
490
491 err = s.query("", params, resp)
492 return
493}
494
495// GetQueueUrlOfOwner is a helper function for GetQueueUrl action that returns the URL of a queue with specified name
496// and belongs to the specified AWS Account Id.
497//
498// See http://goo.gl/hk7Iu for more details for more details
499func (s *SQS) GetQueueUrlOfOwner(queueName, queueOwnerAWSAccountId string) (resp *GetQueueUrlResponse, err error) {
500 resp = &GetQueueUrlResponse{}
501 params := makeParams("GetQueueUrl")
502
503 params["QueueName"] = queueName
504
505 if queueOwnerAWSAccountId != "" {
506 params["QueueOwnerAWSAccountId"] = queueOwnerAWSAccountId
507 }
508
509 err = s.query("", params, resp)
510 return
511}
512
513func (s *SQS) query(queueUrl string, params map[string]string, resp interface{}) error {
514 params["Version"] = "2011-10-01"
515 params["Timestamp"] = time.Now().In(time.UTC).Format(time.RFC3339)
516 var endpoint *url.URL
517 var path string
518 var err error
519 if queueUrl != "" {
520 endpoint, err = url.Parse(queueUrl)
521 path = queueUrl[len(s.Region.SQSEndpoint):]
522 } else {
523 endpoint, err = url.Parse(s.Region.SQSEndpoint)
524 path = "/"
525 }
526 if err != nil {
527 return err
528 }
529
530 sign(s.Auth, "GET", path, params, endpoint.Host)
531 endpoint.RawQuery = multimap(params).Encode()
532 if debug {
533 log.Printf("get { %v } -> {\n", endpoint.String())
534 }
535
536 r, err := http.Get(endpoint.String())
537 if err != nil {
538 return err
539 }
540 defer r.Body.Close()
541
542 if debug {
543 dump, _ := httputil.DumpResponse(r, true)
544 log.Printf("response:\n")
545 log.Printf("%v\n}\n", string(dump))
546 }
547 if r.StatusCode != 200 {
548 return buildError(r)
549 }
550 err = xml.NewDecoder(r.Body).Decode(resp)
551 return err
552}
553
554func multimap(p map[string]string) url.Values {
555 q := make(url.Values, len(p))
556 for k, v := range p {
557 q[k] = []string{v}
558 }
559 return q
560}
561
562func buildError(r *http.Response) error {
563 errors := xmlErrors{}
564 xml.NewDecoder(r.Body).Decode(&errors)
565 var err Error
566 if len(errors.Errors) > 0 {
567 err = errors.Errors[0]
568 }
569 err.RequestId = errors.RequestId
570 err.StatusCode = r.StatusCode
571 if err.Message == "" {
572 err.Message = r.Status
573 }
574 return &err
575}
576
577func makeParams(action string) map[string]string {
578 params := make(map[string]string)
579 params["Action"] = action
580 return params
581}
0582
=== added file 'sqs_test.go'
--- sqs_test.go 1970-01-01 00:00:00 +0000
+++ sqs_test.go 2012-05-25 00:21:19 +0000
@@ -0,0 +1,306 @@
1package sqs_test
2
3import (
4 "../sqs"
5 "launchpad.net/goamz/aws"
6 . "launchpad.net/gocheck"
7)
8
9var _ = Suite(&S{})
10
11type S struct {
12 //testServer.PrepareResponse(200, nil, TestChangeMessageVisibilityXmlOK)
13 HTTPSuite
14 sqs *sqs.SQS
15}
16
17func (s *S) SetUpSuite(c *C) {
18 s.HTTPSuite.SetUpSuite(c)
19 auth := aws.Auth{"abc", "123"}
20 s.sqs = sqs.New(auth, aws.Region{SQSEndpoint: testServer.URL})
21}
22
23func (s *S) TestCreateQueue(c *C) {
24 testServer.PrepareResponse(200, nil, TestCreateQueueXmlOK)
25
26 timeOutAttribute := sqs.Attribute{"VisibilityTimeout", "60"}
27 maxMessageSizeAttribute := sqs.Attribute{"MaximumMessageSize", "65536"}
28 messageRetentionAttribute := sqs.Attribute{"MessageRetentionPeriod", "345600"}
29 q, err := s.sqs.CreateQueue("testQueue", []sqs.Attribute{timeOutAttribute, maxMessageSizeAttribute, messageRetentionAttribute})
30 req := testServer.WaitRequest()
31
32 c.Assert(req.Method, Equals, "GET")
33 c.Assert(req.URL.Path, Equals, "/")
34 c.Assert(req.Header["Date"], Not(Equals), "")
35 c.Assert(q.Url, Equals, "http://sqs.us-east-1.amazonaws.com/123456789012/testQueue")
36 c.Assert(err, IsNil)
37}
38
39func (s *S) TestListQueues(c *C) {
40 testServer.PrepareResponse(200, nil, TestListQueuesXmlOK)
41
42 resp, err := s.sqs.ListQueues()
43 req := testServer.WaitRequest()
44
45 c.Assert(req.Method, Equals, "GET")
46 c.Assert(req.URL.Path, Equals, "/")
47 c.Assert(req.Header["Date"], Not(Equals), "")
48 c.Assert(len(resp.QueueUrl), Not(Equals), 0)
49 c.Assert(resp.QueueUrl[0], Equals, "http://sqs.us-east-1.amazonaws.com/123456789012/testQueue")
50 c.Assert(resp.ResponseMetadata.RequestId, Equals, "725275ae-0b9b-4762-b238-436d7c65a1ac")
51 c.Assert(err, IsNil)
52}
53
54func (s *S) TestGetQueueUrl(c *C) {
55 testServer.PrepareResponse(200, nil, TestGetQueueUrlXmlOK)
56
57 resp, err := s.sqs.GetQueueUrl("testQueue")
58 req := testServer.WaitRequest()
59
60 c.Assert(req.Method, Equals, "GET")
61 c.Assert(req.URL.Path, Equals, "/")
62 c.Assert(req.Header["Date"], Not(Equals), "")
63 c.Assert(resp.QueueUrl, Equals, "http://sqs.us-east-1.amazonaws.com/123456789012/testQueue")
64 c.Assert(resp.ResponseMetadata.RequestId, Equals, "470a6f13-2ed9-4181-ad8a-2fdea142988e")
65 c.Assert(err, IsNil)
66}
67
68func (s *S) TestChangeMessageVisibility(c *C) {
69 //testServer.PrepareResponse(200, nil, TestChangeMessageVisibilityXmlOK)
70 testServer.PrepareResponse(200, nil, TestCreateQueueXmlOK)
71
72 timeOutAttribute := sqs.Attribute{"VisibilityTimeout", "60"}
73 maxMessageSizeAttribute := sqs.Attribute{"MaximumMessageSize", "65536"}
74 messageRetentionAttribute := sqs.Attribute{"MessageRetentionPeriod", "345600"}
75 q, err := s.sqs.CreateQueue("testQueue", []sqs.Attribute{timeOutAttribute, maxMessageSizeAttribute, messageRetentionAttribute})
76 req := testServer.WaitRequest()
77
78 c.Assert(req.Method, Equals, "GET")
79 testServer.PrepareResponse(200, nil, TestChangeMessageVisibilityXmlOK)
80 resp, err := q.ChangeMessageVisibility("MbZj6wDWli%2BJvwwJaBV%2B3dcjk2YW2vA3%2BSTFFljT", 0)
81 testServer.WaitRequest()
82 c.Assert(err, IsNil)
83 c.Assert(resp.ResponseMetadata.RequestId, Equals, "6a7a282a-d013-4a59-aba9-335b0fa48bed")
84}
85
86func (s *S) TestChangeMessageVisibilityBatch(c *C) {
87 testServer.PrepareResponse(200, nil, TestCreateQueueXmlOK)
88
89 timeOutAttribute := sqs.Attribute{"VisibilityTimeout", "60"}
90 maxMessageSizeAttribute := sqs.Attribute{"MaximumMessageSize", "65536"}
91 messageRetentionAttribute := sqs.Attribute{"MessageRetentionPeriod", "345600"}
92 q, err := s.sqs.CreateQueue("testQueue", []sqs.Attribute{timeOutAttribute, maxMessageSizeAttribute, messageRetentionAttribute})
93 testServer.WaitRequest()
94
95 testServer.PrepareResponse(200, nil, TestChangeMessaveVisibilityBatchXmlOK)
96
97 messageVisibilityBatch := []sqs.ChangeMessageVisibilityBatchEntry{sqs.ChangeMessageVisibilityBatchEntry{"change_visibility_msg_2", "gfk0T0R0waama4fVFffkjKzmhMCymjQvfTFk2LxT33G4ms5subrE0deLKWSscPU1oD3J9zgeS4PQQ3U30qOumIE6AdAv3w%2F%2Fa1IXW6AqaWhGsEPaLm3Vf6IiWqdM8u5imB%2BNTwj3tQRzOWdTOePjOjPcTpRxBtXix%2BEvwJOZUma9wabv%2BSw6ZHjwmNcVDx8dZXJhVp16Bksiox%2FGrUvrVTCJRTWTLc59oHLLF8sEkKzRmGNzTDGTiV%2BYjHfQj60FD3rVaXmzTsoNxRhKJ72uIHVMGVQiAGgBX6HGv9LDmYhPXw4hy%2FNgIg%3D%3D", 45}, sqs.ChangeMessageVisibilityBatchEntry{"change_visibility_msg_3", "gfk0T0R0waama4fVFffkjKzmhMCymjQvfTFk2LxT33FUgBz3%2BnougdeLKWSscPU1%2FXgx%2BxcNnjnQQ3U30qOumIE6AdAv3w%2F%2Fa1IXW6AqaWhGsEPaLm3Vf6IiWqdM8u5imB%2BNTwj3tQRzOWdTOePjOsogjZM%2F7kzn4Ew27XLU9I%2FYaWYmKvDbq%2Fk3HKVB9HfB43kE49atP2aWrzNL4yunG41Q4cfRRtfJdcGQGNHQ2%2Byd0Usf5qR1dZr1iDo5xk946eQat83AxTRP%2BY4Qi0V7FAeSLH9su9xpX6HGv9LDmYhPXw4hy%2FNgIg%3D%3D", 45}}
98 resp, err := q.ChangeMessageVisibilityBatch(messageVisibilityBatch)
99 testServer.WaitRequest()
100 c.Assert(err, IsNil)
101 c.Assert(resp.ResponseMetadata.RequestId, Equals, "ca9668f7-ab1b-4f7a-8859-f15747ab17a7")
102 c.Assert(resp.Id[0], Equals, "change_visibility_msg_2")
103 c.Assert(resp.Id[1], Equals, "change_visibility_msg_3")
104}
105
106func (s *S) TestReceiveMessage(c *C) {
107 testServer.PrepareResponse(200, nil, TestGetQueueUrlXmlOK)
108
109 q, err := s.sqs.GetQueue("testQueue")
110 testServer.WaitRequest()
111
112 testServer.PrepareResponse(200, nil, TestReceiveMessageXmlOK)
113
114 resp, err := q.ReceiveMessage([]string{"All"}, 5, 15)
115 testServer.WaitRequest()
116 c.Assert(err, IsNil)
117 c.Assert(len(resp.Messages), Not(Equals), 0)
118}
119
120func (s *S) TestDeleteMessage(c *C) {
121 testServer.PrepareResponse(200, nil, TestGetQueueUrlXmlOK)
122
123 q, err := s.sqs.GetQueue("testQueue")
124 testServer.WaitRequest()
125
126 testServer.PrepareResponse(200, nil, TestDeleteMessageXmlOK)
127
128 resp, err := q.DeleteMessage("MbZj6wDWli%2BJvwwJaBV%2B3dcjk2YW2vA3%2BSTFFljTM8tJJg6HRG6PYSasuWXPJB%2BCwLj1FjgXUv1uSj1gUPAWV66FU/WeR4mq2OKpEGYWbnLmpRCJVAyeMjeU5ZBdtcQ%2BQEauMZc8ZRv37sIW2iJKq3M9MFx1YvV11A2x/KSbkJ0=")
129 testServer.WaitRequest()
130 c.Assert(err, IsNil)
131 c.Assert(resp.ResponseMetadata.RequestId, Equals, "b5293cb5-d306-4a17-9048-b263635abe42")
132}
133
134func (s *S) TestDeleteMessageBatch(c *C) {
135 testServer.PrepareResponse(200, nil, TestGetQueueUrlXmlOK)
136
137 q, err := s.sqs.GetQueue("testQueue")
138 testServer.WaitRequest()
139
140 testServer.PrepareResponse(200, nil, TestDeleteMessageBatchXmlOK)
141
142 deleteMessageBatch := []sqs.DeleteMessageBatch{sqs.DeleteMessageBatch{Id: "msg1", ReceiptHandle: "gfk0T0R0waama4fVFffkjPQrrvzMrOg0fTFk2LxT33EuB8wR0ZCFgKWyXGWFoqqpCIiprQUEhir%2F5LeGPpYTLzjqLQxyQYaQALeSNHb0us3uE84uujxpBhsDkZUQkjFFkNqBXn48xlMcVhTcI3YLH%2Bd%2BIqetIOHgBCZAPx6r%2B09dWaBXei6nbK5Ygih21DCDdAwFV68Jo8DXhb3ErEfoDqx7vyvC5nCpdwqv%2BJhU%2FTNGjNN8t51v5c%2FAXvQsAzyZVNapxUrHIt4NxRhKJ72uICcxruyE8eRXlxIVNgeNP8ZEDcw7zZU1Zw%3D%3D"}, sqs.DeleteMessageBatch{Id: "msg2", ReceiptHandle: "gfk0T0R0waama4fVFffkjKzmhMCymjQvfTFk2LxT33G4ms5subrE0deLKWSscPU1oD3J9zgeS4PQQ3U30qOumIE6AdAv3w%2F%2Fa1IXW6AqaWhGsEPaLm3Vf6IiWqdM8u5imB%2BNTwj3tQRzOWdTOePjOjPcTpRxBtXix%2BEvwJOZUma9wabv%2BSw6ZHjwmNcVDx8dZXJhVp16Bksiox%2FGrUvrVTCJRTWTLc59oHLLF8sEkKzRmGNzTDGTiV%2BYjHfQj60FD3rVaXmzTsoNxRhKJ72uIHVMGVQiAGgB%2BqAbSqfKHDQtVOmJJgkHug%3D%3D"}}
143 resp, err := q.DeleteMessageBatch(deleteMessageBatch)
144 testServer.WaitRequest()
145
146 c.Assert(err, IsNil)
147 c.Assert(len(resp.DeleteMessageBatchResult.Ids), Equals, 2)
148 c.Assert(resp.DeleteMessageBatchResult.Ids[0], Equals, "msg1")
149 c.Assert(resp.DeleteMessageBatchResult.Ids[1], Equals, "msg2")
150 c.Assert(resp.ResponseMetadata.RequestId, Equals, "d6f86b7a-74d1-4439-b43f-196a1e29cd85")
151}
152
153func (s *S) TestAddPermission(c *C) {
154 testServer.PrepareResponse(200, nil, TestGetQueueUrlXmlOK)
155
156 q, err := s.sqs.GetQueue("testQueue")
157 testServer.WaitRequest()
158
159 testServer.PrepareResponse(200, nil, TestAddPermissionXmlOK)
160 resp, err := q.AddPermission("testLabel", []sqs.AccountPermission{sqs.AccountPermission{"125074342641", "SendMessage"}, sqs.AccountPermission{"125074342642", "ReceiveMessage"}})
161 testServer.WaitRequest()
162
163 c.Assert(err, IsNil)
164 c.Assert(resp.ResponseMetadata.RequestId, Equals, "9a285199-c8d6-47c2-bdb2-314cb47d599d")
165}
166
167func (s *S) TestRemovePermission(c *C) {
168 testServer.PrepareResponse(200, nil, TestGetQueueUrlXmlOK)
169
170 q, err := s.sqs.GetQueue("testQueue")
171 testServer.WaitRequest()
172
173 testServer.PrepareResponse(200, nil, TestRemovePermissionXmlOK)
174 resp, err := q.RemovePermission("testLabel")
175 testServer.WaitRequest()
176
177 c.Assert(err, IsNil)
178 c.Assert(resp.ResponseMetadata.RequestId, Equals, "f8bdb362-6616-42c0-977a-ce9a8bcce3bb")
179}
180
181func (s *S) TestSendMessage(c *C) {
182 testServer.PrepareResponse(200, nil, TestGetQueueUrlXmlOK)
183
184 q, err := s.sqs.GetQueue("testQueue")
185 testServer.WaitRequest()
186
187 testServer.PrepareResponse(200, nil, TestSendMessageXmlOK)
188
189 resp, err := q.SendMessage("This is a Message")
190 testServer.WaitRequest()
191 c.Assert(err, IsNil)
192 c.Assert(resp.SendMessageResult.MD5OfMessageBody, Equals, "fafb00f5732ab283681e124bf8747ed1")
193 c.Assert(resp.SendMessageResult.MessageId, Equals, "5fea7756-0ea4-451a-a703-a558b933e274")
194 c.Assert(resp.ResponseMetadata.RequestId, Equals, "27daac76-34dd-47df-bd01-1f6e873584a0")
195}
196
197func (s *S) TestSendMessageWithDelay(c *C) {
198 testServer.PrepareResponse(200, nil, TestGetQueueUrlXmlOK)
199
200 q, err := s.sqs.GetQueue("testQueue")
201 testServer.WaitRequest()
202
203 testServer.PrepareResponse(200, nil, TestSendMessageXmlOK)
204
205 resp, err := q.SendMessageWithDelay("This is a Message", 60)
206 testServer.WaitRequest()
207 c.Assert(err, IsNil)
208 c.Assert(resp.SendMessageResult.MD5OfMessageBody, Equals, "fafb00f5732ab283681e124bf8747ed1")
209 c.Assert(resp.SendMessageResult.MessageId, Equals, "5fea7756-0ea4-451a-a703-a558b933e274")
210 c.Assert(resp.ResponseMetadata.RequestId, Equals, "27daac76-34dd-47df-bd01-1f6e873584a0")
211}
212
213func (s *S) TestSendMessageBatch(c *C) {
214 testServer.PrepareResponse(200, nil, TestGetQueueUrlXmlOK)
215
216 q, err := s.sqs.GetQueue("testQueue")
217 testServer.WaitRequest()
218
219 testServer.PrepareResponse(200, nil, TestSendMessageBatchXmlOK)
220
221 sendMessageBatchRequests := []sqs.SendMessageBatchRequestEntry{sqs.SendMessageBatchRequestEntry{Id: "test_msg_001", MessageBody: "test message body 1", DelaySeconds: 30}}
222 resp, err := q.SendMessageBatch(sendMessageBatchRequests)
223 testServer.WaitRequest()
224 c.Assert(err, IsNil)
225 c.Assert(len(resp.SendMessageBatchResult.Entries), Equals, 2)
226 c.Assert(resp.SendMessageBatchResult.Entries[0].Id, Equals, "test_msg_001")
227}
228
229func (s *S) TestGetQueueAttributes(c *C) {
230 testServer.PrepareResponse(200, nil, TestGetQueueUrlXmlOK)
231
232 q, err := s.sqs.GetQueue("testQueue")
233 testServer.WaitRequest()
234
235 testServer.PrepareResponse(200, nil, TestGetQueueAttributesAllXmlOK)
236
237 resp, err := q.GetQueueAttributes([]string{"ALL"})
238 testServer.WaitRequest()
239
240 c.Assert(err, IsNil)
241 c.Assert(len(resp.Attributes), Equals, 8)
242 c.Assert(resp.Attributes[0].Name, Equals, "VisibilityTimeout")
243 c.Assert(resp.Attributes[0].Value, Equals, "30")
244}
245
246func (s *S) TestGetQueueAttributesSelective(c *C) {
247 testServer.PrepareResponse(200, nil, TestGetQueueUrlXmlOK)
248
249 q, err := s.sqs.GetQueue("testQueue")
250 testServer.WaitRequest()
251
252 testServer.PrepareResponse(200, nil, TestGetQueueAttributesSelectiveXmlOK)
253
254 resp, err := q.GetQueueAttributes([]string{"VisibilityTimeout", "DelaySeconds"})
255 testServer.WaitRequest()
256
257 c.Assert(err, IsNil)
258 c.Assert(len(resp.Attributes), Equals, 2)
259 c.Assert(resp.Attributes[0].Name, Equals, "VisibilityTimeout")
260 c.Assert(resp.Attributes[0].Value, Equals, "30")
261 c.Assert(resp.Attributes[1].Name, Equals, "DelaySeconds")
262 c.Assert(resp.Attributes[1].Value, Equals, "0")
263}
264
265func (s *S) TestDeleteQueue(c *C) {
266 testServer.PrepareResponse(200, nil, TestGetQueueUrlXmlOK)
267
268 q, err := s.sqs.GetQueue("testQueue")
269 testServer.WaitRequest()
270
271 testServer.PrepareResponse(200, nil, TestDeleteQueueXmlOK)
272 resp, err := q.Delete()
273 testServer.WaitRequest()
274
275 c.Assert(err, IsNil)
276 c.Assert(resp.ResponseMetadata.RequestId, Equals, "6fde8d1e-52cd-4581-8cd9-c512f4c64223")
277}
278
279func (s *S) TestSetQueueAttributes(c *C) {
280 testServer.PrepareResponse(200, nil, TestGetQueueUrlXmlOK)
281
282 q, err := s.sqs.GetQueue("testQueue")
283 testServer.WaitRequest()
284
285 testServer.PrepareResponse(200, nil, TestSetQueueAttributesXmlOK)
286 var policyStr = `
287 {
288 "Version":"2008-10-17",
289 "Id":"/123456789012/testQueue/SQSDefaultPolicy",
290 "Statement": [
291 {
292 "Sid":"Queue1ReceiveMessage",
293 "Effect":"Allow",
294 "Principal":{"AWS":"*"},
295 "Action":"SQS:ReceiveMessage",
296 "Resource":"arn:aws:sqs:us-east-1:123456789012:testQueue"
297 }
298 ]
299 }
300 `
301 resp, err := q.SetQueueAttributes(sqs.Attribute{"Policy", policyStr})
302 testServer.WaitRequest()
303
304 c.Assert(err, IsNil)
305 c.Assert(resp.ResponseMetadata.RequestId, Equals, "e5cca473-4fc0-4198-a451-8abb94d02c75")
306}
0307
=== added file 'suite_test.go'
--- suite_test.go 1970-01-01 00:00:00 +0000
+++ suite_test.go 2012-05-25 00:21:19 +0000
@@ -0,0 +1,120 @@
1package sqs_test
2
3import (
4 "fmt"
5 . "launchpad.net/gocheck"
6 "net/http"
7 "net/url"
8 "os"
9 "testing"
10 "time"
11)
12
13func Test(t *testing.T) {
14 TestingT(t)
15}
16
17type HTTPSuite struct{}
18
19var testServer = NewTestHTTPServer("http://localhost:4444", 5*time.Second)
20
21func (s *HTTPSuite) SetUpSuite(c *C) {
22 testServer.Start()
23}
24
25func (s *HTTPSuite) TearDownTest(c *C) {
26 testServer.FlushRequests()
27}
28
29type TestHTTPServer struct {
30 URL string
31 Timeout time.Duration
32 started bool
33 request chan *http.Request
34 response chan *testResponse
35 pending chan bool
36}
37
38type testResponse struct {
39 Status int
40 Headers map[string]string
41 Body string
42}
43
44func NewTestHTTPServer(url string, timeout time.Duration) *TestHTTPServer {
45 return &TestHTTPServer{URL: url, Timeout: timeout}
46}
47
48func (s *TestHTTPServer) Start() {
49 if s.started {
50 return
51 }
52 s.started = true
53
54 s.request = make(chan *http.Request, 64)
55 s.response = make(chan *testResponse, 64)
56 s.pending = make(chan bool, 64)
57
58 url, _ := url.Parse(s.URL)
59 go http.ListenAndServe(url.Host, s)
60
61 s.PrepareResponse(202, nil, "Nothing.")
62 for {
63 // Wait for it to be up.
64 resp, err := http.Get(s.URL)
65 if err == nil && resp.StatusCode == 202 {
66 break
67 }
68 fmt.Fprintf(os.Stderr, "\nWaiting for fake server to be up... ")
69 time.Sleep(1e8)
70 }
71 fmt.Fprintf(os.Stderr, "done\n\n")
72 s.WaitRequest() // Consume dummy request
73}
74
75// FulshRequests discards requests which were not yet consumed by WaitRequest
76func (s *TestHTTPServer) FlushRequests() {
77 for {
78 select {
79 case <-s.request:
80 default:
81 return
82 }
83 }
84}
85
86func (s *TestHTTPServer) ServeHTTP(w http.ResponseWriter, req *http.Request) {
87 s.request <- req
88 var resp *testResponse
89 select {
90 case resp = <-s.response:
91 case <-time.After(s.Timeout):
92 fmt.Fprintf(os.Stderr, "ERROR: Timeout waiting for test to provide response\n")
93 resp = &testResponse{500, nil, ""}
94 }
95 if resp.Headers != nil {
96 h := w.Header()
97 for k, v := range resp.Headers {
98 h.Set(k, v)
99 }
100 }
101 if resp.Status != 0 {
102 w.WriteHeader(resp.Status)
103 }
104 w.Write([]byte(resp.Body))
105}
106
107func (s *TestHTTPServer) WaitRequest() *http.Request {
108 select {
109 case req := <-s.request:
110 req.ParseForm()
111 return req
112 case <-time.After(s.Timeout):
113 panic("Timeout waiting for goamz request")
114 }
115 panic("unreached")
116}
117
118func (s *TestHTTPServer) PrepareResponse(status int, headers map[string]string, body string) {
119 s.response <- &testResponse{status, headers, body}
120}

Subscribers

People subscribed via source and target branches