You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

415 lines
14 KiB

  1. package sqs
  2. import (
  3. "crypto/md5"
  4. "encoding/binary"
  5. "fmt"
  6. "hash"
  7. "github.com/goamz/goamz/aws"
  8. . "gopkg.in/check.v1"
  9. )
  10. var _ = Suite(&S{})
  11. type S struct {
  12. HTTPSuite
  13. sqs *SQS
  14. }
  15. func (s *S) SetUpSuite(c *C) {
  16. s.HTTPSuite.SetUpSuite(c)
  17. auth := aws.Auth{AccessKey: "abc", SecretKey: "123"}
  18. s.sqs = New(auth, aws.Region{SQSEndpoint: testServer.URL})
  19. }
  20. func (s *S) TestCreateQueue(c *C) {
  21. testServer.PrepareResponse(200, nil, TestCreateQueueXmlOK)
  22. resp, err := s.sqs.CreateQueue("testQueue")
  23. req := testServer.WaitRequest()
  24. c.Assert(req.Method, Equals, "GET")
  25. c.Assert(req.URL.Path, Equals, "/")
  26. c.Assert(req.Header["Date"], Not(Equals), "")
  27. fmt.Printf("%+v\n", req)
  28. c.Assert(req.Form["Action"], DeepEquals, []string{"CreateQueue"})
  29. c.Assert(req.Form["Attribute.1.Name"], DeepEquals, []string{"VisibilityTimeout"})
  30. c.Assert(req.Form["Attribute.1.Value"], DeepEquals, []string{"30"})
  31. c.Assert(resp.Url, Equals, "http://sqs.us-east-1.amazonaws.com/123456789012/testQueue")
  32. c.Assert(err, IsNil)
  33. }
  34. func (s *S) TestCreateQueueWithTimeout(c *C) {
  35. testServer.PrepareResponse(200, nil, TestCreateQueueXmlOK)
  36. s.sqs.CreateQueueWithTimeout("testQueue", 180)
  37. req := testServer.WaitRequest()
  38. // TestCreateQueue() tests the core functionality, just check the timeout in this test
  39. c.Assert(req.Form["Attribute.1.Name"], DeepEquals, []string{"VisibilityTimeout"})
  40. c.Assert(req.Form["Attribute.1.Value"], DeepEquals, []string{"180"})
  41. }
  42. func (s *S) TestCreateQueueWithAttributes(c *C) {
  43. testServer.PrepareResponse(200, nil, TestCreateQueueXmlOK)
  44. s.sqs.CreateQueueWithAttributes("testQueue", map[string]string{
  45. "ReceiveMessageWaitTimeSeconds": "20",
  46. "VisibilityTimeout": "240",
  47. })
  48. req := testServer.WaitRequest()
  49. // TestCreateQueue() tests the core functionality, just check the timeout in this test
  50. var receiveMessageWaitSet bool
  51. var visibilityTimeoutSet bool
  52. for i := 1; i <= 2; i++ {
  53. prefix := fmt.Sprintf("Attribute.%d.", i)
  54. attr := req.FormValue(prefix + "Name")
  55. value := req.FormValue(prefix + "Value")
  56. switch attr {
  57. case "ReceiveMessageWaitTimeSeconds":
  58. c.Assert(value, DeepEquals, "20")
  59. receiveMessageWaitSet = true
  60. case "VisibilityTimeout":
  61. c.Assert(value, DeepEquals, "240")
  62. visibilityTimeoutSet = true
  63. }
  64. }
  65. c.Assert(receiveMessageWaitSet, Equals, true)
  66. c.Assert(visibilityTimeoutSet, Equals, true)
  67. }
  68. func (s *S) TestListQueues(c *C) {
  69. testServer.PrepareResponse(200, nil, TestListQueuesXmlOK)
  70. resp, err := s.sqs.ListQueues("")
  71. req := testServer.WaitRequest()
  72. c.Assert(req.Method, Equals, "GET")
  73. c.Assert(req.URL.Path, Equals, "/")
  74. c.Assert(req.Header["Date"], Not(Equals), "")
  75. c.Assert(len(resp.QueueUrl), Not(Equals), 0)
  76. c.Assert(resp.QueueUrl[0], Equals, "http://sqs.us-east-1.amazonaws.com/123456789012/testQueue")
  77. c.Assert(resp.ResponseMetadata.RequestId, Equals, "725275ae-0b9b-4762-b238-436d7c65a1ac")
  78. c.Assert(err, IsNil)
  79. }
  80. func (s *S) TestDeleteQueue(c *C) {
  81. testServer.PrepareResponse(200, nil, TestDeleteQueueXmlOK)
  82. q := &Queue{s.sqs, testServer.URL + "/123456789012/testQueue/"}
  83. resp, err := q.Delete()
  84. req := testServer.WaitRequest()
  85. c.Assert(req.Method, Equals, "GET")
  86. c.Assert(req.URL.Path, Equals, "/123456789012/testQueue/")
  87. c.Assert(req.Header["Date"], Not(Equals), "")
  88. c.Assert(resp.ResponseMetadata.RequestId, Equals, "6fde8d1e-52cd-4581-8cd9-c512f4c64223")
  89. c.Assert(err, IsNil)
  90. }
  91. func (s *S) TestPurgeQueue(c *C) {
  92. testServer.PrepareResponse(200, nil, TestPurgeQueueXmlOK)
  93. q := &Queue{s.sqs, testServer.URL + "/123456789012/testQueue/"}
  94. resp, err := q.Purge()
  95. req := testServer.WaitRequest()
  96. c.Assert(req.Method, Equals, "GET")
  97. c.Assert(req.URL.Path, Equals, "/123456789012/testQueue/")
  98. c.Assert(req.Header["Date"], Not(Equals), "")
  99. c.Assert(resp.ResponseMetadata.RequestId, Equals, "6fde8d1e-52cd-4581-8cd9-c512f4c64223")
  100. c.Assert(err, IsNil)
  101. }
  102. func (s *S) TestSendMessage(c *C) {
  103. testServer.PrepareResponse(200, nil, TestSendMessageXmlOK)
  104. q := &Queue{s.sqs, testServer.URL + "/123456789012/testQueue/"}
  105. resp, err := q.SendMessage("This is a test message")
  106. req := testServer.WaitRequest()
  107. c.Assert(req.Method, Equals, "GET")
  108. c.Assert(req.URL.Path, Equals, "/123456789012/testQueue/")
  109. c.Assert(req.Header["Date"], Not(Equals), "")
  110. msg := "This is a test message"
  111. var h hash.Hash = md5.New()
  112. h.Write([]byte(msg))
  113. c.Assert(resp.MD5, Equals, fmt.Sprintf("%x", h.Sum(nil)))
  114. c.Assert(resp.Id, Equals, "5fea7756-0ea4-451a-a703-a558b933e274")
  115. c.Assert(err, IsNil)
  116. }
  117. func (s *S) TestSendMessageRelativePath(c *C) {
  118. testServer.PrepareResponse(200, nil, TestSendMessageXmlOK)
  119. q := &Queue{s.sqs, "/123456789012/testQueue/"}
  120. resp, err := q.SendMessage("This is a test message")
  121. req := testServer.WaitRequest()
  122. c.Assert(req.Method, Equals, "GET")
  123. c.Assert(req.URL.Path, Equals, "/123456789012/testQueue/")
  124. c.Assert(req.Header["Date"], Not(Equals), "")
  125. msg := "This is a test message"
  126. var h hash.Hash = md5.New()
  127. h.Write([]byte(msg))
  128. c.Assert(resp.MD5, Equals, fmt.Sprintf("%x", h.Sum(nil)))
  129. c.Assert(resp.Id, Equals, "5fea7756-0ea4-451a-a703-a558b933e274")
  130. c.Assert(err, IsNil)
  131. }
  132. func encodeMessageAttribute(str string) []byte {
  133. bstr := []byte(str)
  134. bs := make([]byte, 4+len(bstr))
  135. binary.BigEndian.PutUint32(bs, uint32(len(bstr)))
  136. copy(bs[4:len(bs)], bstr)
  137. return bs
  138. }
  139. func (s *S) TestSendMessageWithAttributes(c *C) {
  140. testServer.PrepareResponse(200, nil, TestSendMessageXmlOK)
  141. q := &Queue{s.sqs, testServer.URL + "/123456789012/testQueue/"}
  142. attrs := map[string]string{
  143. "test_attribute_name_1": "test_attribute_value_1",
  144. }
  145. resp, err := q.SendMessageWithAttributes("This is a test message", attrs)
  146. req := testServer.WaitRequest()
  147. c.Assert(req.Method, Equals, "GET")
  148. c.Assert(req.URL.Path, Equals, "/123456789012/testQueue/")
  149. c.Assert(req.Header["Date"], Not(Equals), "")
  150. var attrsHash = md5.New()
  151. attrsHash.Write(encodeMessageAttribute("test_attribute_name_1"))
  152. attrsHash.Write(encodeMessageAttribute("String"))
  153. attrsHash.Write([]byte{1})
  154. attrsHash.Write(encodeMessageAttribute("test_attribute_value_1"))
  155. c.Assert(resp.MD5OfMessageAttributes, Equals, fmt.Sprintf("%x", attrsHash.Sum(nil)))
  156. msg := "This is a test message"
  157. var h hash.Hash = md5.New()
  158. h.Write([]byte(msg))
  159. c.Assert(resp.MD5, Equals, fmt.Sprintf("%x", h.Sum(nil)))
  160. c.Assert(resp.Id, Equals, "5fea7756-0ea4-451a-a703-a558b933e274")
  161. c.Assert(err, IsNil)
  162. }
  163. func (s *S) TestSendMessageBatch(c *C) {
  164. testServer.PrepareResponse(200, nil, TestSendMessageBatchXmlOk)
  165. q := &Queue{s.sqs, testServer.URL + "/123456789012/testQueue/"}
  166. msgList := []string{"test message body 1", "test message body 2"}
  167. resp, err := q.SendMessageBatchString(msgList)
  168. req := testServer.WaitRequest()
  169. c.Assert(req.Method, Equals, "GET")
  170. c.Assert(req.URL.Path, Equals, "/123456789012/testQueue/")
  171. c.Assert(req.Header["Date"], Not(Equals), "")
  172. for idx, msg := range msgList {
  173. var h hash.Hash = md5.New()
  174. h.Write([]byte(msg))
  175. c.Assert(resp.SendMessageBatchResult[idx].MD5OfMessageBody, Equals, fmt.Sprintf("%x", h.Sum(nil)))
  176. c.Assert(err, IsNil)
  177. }
  178. }
  179. func (s *S) TestDeleteMessageBatch(c *C) {
  180. testServer.PrepareResponse(200, nil, TestDeleteMessageBatchXmlOK)
  181. q := &Queue{s.sqs, testServer.URL + "/123456789012/testQueue/"}
  182. msgList := []Message{*(&Message{ReceiptHandle: "gfk0T0R0waama4fVFffkjPQrrvzMrOg0fTFk2LxT33EuB8wR0ZCFgKWyXGWFoqqpCIiprQUEhir%2F5LeGPpYTLzjqLQxyQYaQALeSNHb0us3uE84uujxpBhsDkZUQkjFFkNqBXn48xlMcVhTcI3YLH%2Bd%2BIqetIOHgBCZAPx6r%2B09dWaBXei6nbK5Ygih21DCDdAwFV68Jo8DXhb3ErEfoDqx7vyvC5nCpdwqv%2BJhU%2FTNGjNN8t51v5c%2FAXvQsAzyZVNapxUrHIt4NxRhKJ72uICcxruyE8eRXlxIVNgeNP8ZEDcw7zZU1Zw%3D%3D"}),
  183. *(&Message{ReceiptHandle: "gfk0T0R0waama4fVFffkjKzmhMCymjQvfTFk2LxT33G4ms5subrE0deLKWSscPU1oD3J9zgeS4PQQ3U30qOumIE6AdAv3w%2F%2Fa1IXW6AqaWhGsEPaLm3Vf6IiWqdM8u5imB%2BNTwj3tQRzOWdTOePjOjPcTpRxBtXix%2BEvwJOZUma9wabv%2BSw6ZHjwmNcVDx8dZXJhVp16Bksiox%2FGrUvrVTCJRTWTLc59oHLLF8sEkKzRmGNzTDGTiV%2BYjHfQj60FD3rVaXmzTsoNxRhKJ72uIHVMGVQiAGgB%2BqAbSqfKHDQtVOmJJgkHug%3D%3D"}),
  184. }
  185. resp, err := q.DeleteMessageBatch(msgList)
  186. c.Assert(err, IsNil)
  187. req := testServer.WaitRequest()
  188. c.Assert(req.Method, Equals, "GET")
  189. c.Assert(req.URL.Path, Equals, "/123456789012/testQueue/")
  190. c.Assert(req.Header["Date"], Not(Equals), "")
  191. for idx, _ := range msgList {
  192. c.Assert(resp.DeleteMessageBatchResult[idx].Id, Equals, fmt.Sprintf("msg%d", idx+1))
  193. }
  194. }
  195. func (s *S) TestDeleteMessageUsingReceiptHandle(c *C) {
  196. testServer.PrepareResponse(200, nil, TestDeleteMessageUsingReceiptXmlOK)
  197. q := &Queue{s.sqs, testServer.URL + "/123456789012/testQueue/"}
  198. msg := &Message{ReceiptHandle: "gfk0T0R0waama4fVFffkjRQrrvzMrOg0fTFk2LxT33EuB8wR0ZCFgKWyXGWFoqqpCIiprQUEhir%2F5LeGPpYTLzjqLQxyQYaQALeSNHb0us3uE84uujxpBhsDkZUQkjFFkNqBXn48xlMcVhTcI3YLH%2Bd%2BIqetIOHgBCZAPx6r%2B09dWaBXei6nbK5Ygih21DCDdAwFV68Jo8DXhb3ErEfoDqx7vyvC5nCpdwqv%2BJhU%2FTNGjNN8t51v5c%2FAXvQsAzyZVNapxUrHIt4NxRhKJ72uICcxruyE8eRXlxIVNgeNP8ZEDcw7zZU1Zw%3D%3D"}
  199. resp, err := q.DeleteMessageUsingReceiptHandle(msg.ReceiptHandle)
  200. c.Assert(err, IsNil)
  201. req := testServer.WaitRequest()
  202. c.Assert(req.Method, Equals, "GET")
  203. c.Assert(req.URL.Path, Equals, "/123456789012/testQueue/")
  204. c.Assert(req.Header["Date"], Not(Equals), "")
  205. c.Assert(resp.ResponseMetadata.RequestId, Equals, "d6d86b7a-74d1-4439-b43f-196a1e29cd85")
  206. }
  207. func (s *S) TestReceiveMessage(c *C) {
  208. testServer.PrepareResponse(200, nil, TestReceiveMessageXmlOK)
  209. q := &Queue{s.sqs, testServer.URL + "/123456789012/testQueue/"}
  210. resp, err := q.ReceiveMessage(5)
  211. req := testServer.WaitRequest()
  212. c.Assert(req.Method, Equals, "GET")
  213. c.Assert(req.URL.Path, Equals, "/123456789012/testQueue/")
  214. c.Assert(req.Header["Date"], Not(Equals), "")
  215. c.Assert(len(resp.Messages), Not(Equals), 0)
  216. c.Assert(resp.Messages[0].MessageId, Equals, "5fea7756-0ea4-451a-a703-a558b933e274")
  217. c.Assert(resp.Messages[0].MD5OfBody, Equals, "fafb00f5732ab283681e124bf8747ed1")
  218. c.Assert(resp.Messages[0].ReceiptHandle, Equals, "MbZj6wDWli+JvwwJaBV+3dcjk2YW2vA3+STFFljTM8tJJg6HRG6PYSasuWXPJB+CwLj1FjgXUv1uSj1gUPAWV66FU/WeR4mq2OKpEGYWbnLmpRCJVAyeMjeU5ZBdtcQ+QEauMZc8ZRv37sIW2iJKq3M9MFx1YvV11A2x/KSbkJ0=")
  219. c.Assert(resp.Messages[0].Body, Equals, "This is a test message")
  220. c.Assert(len(resp.Messages[0].Attribute), Not(Equals), 0)
  221. expectedAttributeResults := []struct {
  222. Name string
  223. Value string
  224. }{
  225. {Name: "SenderId", Value: "195004372649"},
  226. {Name: "SentTimestamp", Value: "1238099229000"},
  227. {Name: "ApproximateReceiveCount", Value: "5"},
  228. {Name: "ApproximateFirstReceiveTimestamp", Value: "1250700979248"},
  229. }
  230. for i, expected := range expectedAttributeResults {
  231. c.Assert(resp.Messages[0].Attribute[i].Name, Equals, expected.Name)
  232. c.Assert(resp.Messages[0].Attribute[i].Value, Equals, expected.Value)
  233. }
  234. c.Assert(len(resp.Messages[0].MessageAttribute), Not(Equals), 0)
  235. expectedMessageAttributeResults := []struct {
  236. Name string
  237. Value struct {
  238. DataType string
  239. BinaryValue []byte
  240. StringValue string
  241. // Not yet implemented (Reserved for future use)
  242. BinaryListValues [][]byte
  243. StringListValues []string
  244. }
  245. }{
  246. {
  247. Name: "CustomAttribute",
  248. Value: struct {
  249. DataType string
  250. BinaryValue []byte
  251. StringValue string
  252. // Not yet implemented (Reserved for future use)
  253. BinaryListValues [][]byte
  254. StringListValues []string
  255. }{
  256. DataType: "String",
  257. StringValue: "Testing, testing, 1, 2, 3",
  258. },
  259. },
  260. {
  261. Name: "BinaryCustomAttribute",
  262. Value: struct {
  263. DataType string
  264. BinaryValue []byte
  265. StringValue string
  266. // Not yet implemented (Reserved for future use)
  267. BinaryListValues [][]byte
  268. StringListValues []string
  269. }{
  270. DataType: "Binary",
  271. BinaryValue: []byte("iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAABA0lEQVQ4T72UrQ4CMRCEewhyiiBPopBgcfAUSIICB88CDhRB8hTgsCBRyJMEdUFwZJpMs/3LHQlhVdPufJ1ut03UjyKJcR5zVc4umbW87eeqvVFBjTdJwP54D+4xGXVUCGiBxoOsJOCd9IKgRnnV8wAezrnRmwGcpKtCJ8UgJBNWLFNzVAOimyqIhElXGkQ3LmQ6fKrdqaW1cixhdKVBcEOBLEwViBugVv8B1elVuLYcoTea624drcl5LW4KTRsFhQpLtVzzQKGCh2DuHI8FvdVH7vGQKEPerHRjgegKMESsXgAgWBtu5D1a9BQWCXSrzx9BvjPPkRQR6IJcQNTRV/cvkj93DqUTWzVDIQAAAABJRU5ErkJggg=="),
  272. },
  273. },
  274. }
  275. for i, expected := range expectedMessageAttributeResults {
  276. c.Assert(resp.Messages[0].MessageAttribute[i].Name, Equals, expected.Name)
  277. c.Assert(resp.Messages[0].MessageAttribute[i].Value.DataType, Equals, expected.Value.DataType)
  278. c.Assert(string(resp.Messages[0].MessageAttribute[i].Value.BinaryValue), Equals, string(expected.Value.BinaryValue))
  279. c.Assert(resp.Messages[0].MessageAttribute[i].Value.StringValue, Equals, expected.Value.StringValue)
  280. }
  281. c.Assert(err, IsNil)
  282. }
  283. func (s *S) TestChangeMessageVisibility(c *C) {
  284. testServer.PrepareResponse(200, nil, TestReceiveMessageXmlOK)
  285. q := &Queue{s.sqs, testServer.URL + "/123456789012/testQueue/"}
  286. resp1, err := q.ReceiveMessage(1)
  287. req := testServer.WaitRequest()
  288. testServer.PrepareResponse(200, nil, TestChangeMessageVisibilityXmlOK)
  289. resp, err := q.ChangeMessageVisibility(&resp1.Messages[0], 50)
  290. req = testServer.WaitRequest()
  291. c.Assert(req.Method, Equals, "GET")
  292. c.Assert(req.URL.Path, Equals, "/123456789012/testQueue/")
  293. c.Assert(req.Header["Date"], Not(Equals), "")
  294. c.Assert(resp.ResponseMetadata.RequestId, Equals, "6a7a282a-d013-4a59-aba9-335b0fa48bed")
  295. c.Assert(err, IsNil)
  296. }
  297. func (s *S) TestGetQueueAttributes(c *C) {
  298. testServer.PrepareResponse(200, nil, TestGetQueueAttributesXmlOK)
  299. q := &Queue{s.sqs, testServer.URL + "/123456789012/testQueue/"}
  300. resp, err := q.GetQueueAttributes("All")
  301. req := testServer.WaitRequest()
  302. c.Assert(req.Method, Equals, "GET")
  303. c.Assert(req.URL.Path, Equals, "/123456789012/testQueue/")
  304. c.Assert(resp.ResponseMetadata.RequestId, Equals, "1ea71be5-b5a2-4f9d-b85a-945d8d08cd0b")
  305. c.Assert(len(resp.Attributes), Equals, 9)
  306. expectedResults := []struct {
  307. Name string
  308. Value string
  309. }{
  310. {Name: "ReceiveMessageWaitTimeSeconds", Value: "2"},
  311. {Name: "VisibilityTimeout", Value: "30"},
  312. {Name: "ApproximateNumberOfMessages", Value: "0"},
  313. {Name: "ApproximateNumberOfMessagesNotVisible", Value: "0"},
  314. {Name: "CreatedTimestamp", Value: "1286771522"},
  315. {Name: "LastModifiedTimestamp", Value: "1286771522"},
  316. {Name: "QueueArn", Value: "arn:aws:sqs:us-east-1:123456789012:qfoo"},
  317. {Name: "MaximumMessageSize", Value: "8192"},
  318. {Name: "MessageRetentionPeriod", Value: "345600"},
  319. }
  320. for i, expected := range expectedResults {
  321. c.Assert(resp.Attributes[i].Name, Equals, expected.Name)
  322. c.Assert(resp.Attributes[i].Value, Equals, expected.Value)
  323. }
  324. c.Assert(err, IsNil)
  325. }