File: SQS.hs

package info (click to toggle)
haskell-wreq 0.5.4.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 380 kB
  • sloc: haskell: 2,992; makefile: 25
file content (118 lines) | stat: -rw-r--r-- 5,200 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
{-# LANGUAGE OverloadedStrings #-}
module AWS.SQS (tests) where

import Control.Lens
import Data.Aeson.Lens (key, _String, values)
import Data.IORef (IORef, readIORef, writeIORef)
import Data.Text as T (Text, pack, unpack, split)
import Network.Wreq
import Test.Framework (Test, testGroup)
import Test.Framework.Providers.HUnit (testCase)
import Test.HUnit (assertBool)

-- FIXME: retry create call in case we get the SQS specific "wait 1
-- min after delete" error from a previous test run. For now the
-- 'create' testcase and all others will fails. Rerun after awaiting
-- the SQS 1 min window.

tests :: String -> String -> Options -> IORef String -> Test
tests prefix region baseopts sqsTestState = testGroup "sqs" [
    testCase "createQueue" $ createQueue prefix region baseopts sqsTestState
  , testCase "listQueues"  $ listQueues prefix region baseopts
  , testCase "sendMessage" $ sendMessage prefix region baseopts sqsTestState
  , testCase "receiveMessage" $ receiveMessage prefix region baseopts sqsTestState
  , testCase "deleteQueue" $ deleteQueue prefix region baseopts sqsTestState
  ]

createQueue :: String -> String -> Options -> IORef String -> IO ()
createQueue prefix region baseopts sqsTestState = do
  let opts = baseopts
             & param  "Action" .~ ["CreateQueue"]
             & param  "QueueName" .~ [T.pack $ prefix ++ queuename]
             & param  "Version" .~ ["2009-02-01"]
             & header "Accept" .~ ["application/json"]
  r <- getWith opts (url region)
  assertBool "listQueues 200" $ r ^. responseStatus . statusCode == 200
  assertBool "listQueues OK" $ r ^. responseStatus . statusMessage == "OK"
  let qurl = r ^. responseBody . key "CreateQueueResponse"
                              . key "CreateQueueResult"
                              . key "QueueUrl"
                              . _String
  writeIORef sqsTestState $ acctFromQueueUrl qurl

listQueues :: String -> String -> Options -> IO ()
listQueues prefix region baseopts = do
  let opts = baseopts
             & param  "Action"  .~ ["ListQueues"]
             & param  "Version" .~ ["2009-02-01"]
             & header "Accept"  .~ ["application/json"]
  r <- getWith opts (url region)
  assertBool "listQueues 200" $ r ^. responseStatus . statusCode == 200
  assertBool "listQueues OK" $ r ^. responseStatus . statusMessage == "OK"
  let qurls = r ^.. responseBody . key "ListQueuesResponse" .
                                   key "ListQueuesResult" .
                                   key "queueUrls" .
                                   values . _String
  -- url of form: https://sqs.<region>.amazon.com/<acct>/<queuename>
  let qurls' = map (T.unpack . last . T.split (=='/')) qurls
  assertBool "listQueues contains test queue" $
    elem (prefix ++ queuename) qurls'

deleteQueue :: String -> String -> Options -> IORef String -> IO ()
deleteQueue prefix region baseopts sqsTestState = do
  acct <- readIORef sqsTestState
  let opts = baseopts
             & param "Action" .~ ["DeleteQueue"]
             & param "Version" .~ ["2009-02-01"]
             & header "Accept" .~ ["application/json"]
  r <- getWith opts (url region ++ acct ++ "/" ++ prefix ++ queuename)
  assertBool "deleteQueues 200" $ r ^. responseStatus . statusCode == 200
  assertBool "deleteQueues OK" $ r ^. responseStatus . statusMessage == "OK"

sendMessage :: String -> String -> Options -> IORef String -> IO ()
sendMessage prefix region baseopts sqsTestState = do
  acct <- readIORef sqsTestState
  let opts = baseopts
             & param "Action" .~ ["SendMessage"]
             & param "Version" .~ ["2012-11-05"]
             & param "MessageBody" .~ ["uffda"]
             & header "Accept" .~ ["application/json"]
  r <- getWith opts (url region ++ acct ++ "/" ++ prefix ++ queuename)
  assertBool "sendMessage 200" $ r ^. responseStatus . statusCode == 200
  assertBool "sendMessage OK" $ r ^. responseStatus . statusMessage == "OK"

receiveMessage :: String -> String -> Options -> IORef String -> IO ()
receiveMessage prefix region baseopts sqsTestState = do
  acct <- readIORef sqsTestState
  let opts = baseopts
             & param "Action" .~ ["ReceiveMessage"]
             & param "Version" .~ ["2009-02-01"]
             & header "Accept" .~ ["application/json"]
  r <- getWith opts (url region ++ acct ++ "/" ++ prefix ++ queuename)
  let [msg] = map T.unpack $ r ^.. responseBody . -- we sent only 1 message
                key "ReceiveMessageResponse" .
                key "ReceiveMessageResult" .
                key "messages" .
                values .
                key "Body" .
                _String
  assertBool "receiveMessage 200" $ r ^. responseStatus . statusCode == 200
  assertBool "receiveMessage OK" $ r ^. responseStatus . statusMessage == "OK"
  assertBool "receiveMessage match content" $ msg == "uffda"

url :: String -> String
url region =
  "https://sqs." ++ region ++ ".amazonaws.com/"

queuename :: String
queuename =
  "test"

-- url of form: https://sqs.<region>.amazon.com/<acct>/<queuename>
acctFromQueueUrl :: T.Text -> String
acctFromQueueUrl qurl =
  case T.split (=='/') qurl of
    _:_:_:acct:_ ->
      T.unpack acct
    _ ->
      "dummy"