File: Main.hs

package info (click to toggle)
haskell-aws 0.24.1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 868 kB
  • sloc: haskell: 9,593; makefile: 2
file content (158 lines) | stat: -rw-r--r-- 4,515 bytes parent folder | download
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
-- ------------------------------------------------------ --
-- Copyright © 2014 AlephCloud Systems, Inc.
-- ------------------------------------------------------ --

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE FlexibleContexts #-}

-- |
-- Module: Main
-- Copyright: Copyright © 2014 AlephCloud Systems, Inc.
-- License: BSD3
-- Maintainer: Lars Kuhtz <lars@alephcloud.com>
-- Stability: experimental
--
-- Tests for Haskell AWS DynamoDb bindings
--

module Main
( main
) where

import Aws
import qualified Aws.DynamoDb as DY

import Control.Arrow (second)
import Control.Error
import Control.Monad
import Control.Monad.IO.Class

import Data.IORef
import qualified Data.List as L
import qualified Data.Text as T

import qualified Network.HTTP.Client as HTTP

import Test.Tasty
import Test.QuickCheck.Instances ()

import System.Environment
import System.Exit

import Utils
import DynamoDb.Utils

-- -------------------------------------------------------------------------- --
-- Main

main :: IO ()
main = do
    args <- getArgs
    runMain args $ map (second tail . span (/= '=')) args
  where
    runMain :: [String] -> [(String,String)] -> IO ()
    runMain args _argsMap
        | any (`elem` helpArgs) args = defaultMain tests
        | "--run-with-aws-credentials" `elem` args =
            withArgs (tastyArgs args) . defaultMain $ tests
        | otherwise = putStrLn help >> exitFailure

    helpArgs = ["--help", "-h"]
    mainArgs =
        [ "--run-with-aws-credentials"
        ]
    tastyArgs args = flip filter args $ \x -> not
        $ any (`L.isPrefixOf` x) mainArgs


help :: String
help = L.intercalate "\n"
    [ ""
    , "NOTE"
    , ""
    , "This test suite accesses the AWS account that is associated with"
    , "the default credentials from the credential file ~/.aws-keys."
    , ""
    , "By running the tests in this test-suite costs for usage of AWS"
    , "services may incur."
    , ""
    , "In order to actually execute the tests in this test-suite you must"
    , "provide the command line options:"
    , ""
    , "    --run-with-aws-credentials"
    , ""
    , "When running this test-suite through cabal you may use the following"
    , "command:"
    , ""
    , "    cabal test --test-option=--run-with-aws-credentials dynamodb-tests"
    , ""
    ]

tests :: TestTree
tests = testGroup "DynamoDb Tests"
    [ test_table
    -- , test_message
    , test_core
    ]

-- -------------------------------------------------------------------------- --
-- Table Tests

test_table :: TestTree
test_table = testGroup "Table Tests"
    [ eitherTOnceTest1 "CreateDescribeDeleteTable" (prop_createDescribeDeleteTable 10 10)
    ]

-- |
--
prop_createDescribeDeleteTable
    :: Int -- ^ read capacity (#(non-consistent) reads * itemsize/4KB)
    -> Int -- ^ write capacity (#writes * itemsize/1KB)
    -> T.Text -- ^ table name
    -> ExceptT T.Text IO ()
prop_createDescribeDeleteTable readCapacity writeCapacity tableName = do
    tTableName <- testData tableName
    tryT $ createTestTable tTableName readCapacity writeCapacity
    let deleteTable = retryT 6 . void $ simpleDyT (DY.DeleteTable tTableName)
    flip catchE (\e -> deleteTable >> throwE e) $ do
        retryT 6 . void . simpleDyT $ DY.DescribeTable tTableName
        deleteTable

-- -------------------------------------------------------------------------- --
-- Test core functionality

test_core :: TestTree
test_core = testGroup "Core Tests"
        [ eitherTOnceTest0 "connectionReuse" prop_connectionReuse
        ]

prop_connectionReuse
    :: ExceptT T.Text IO ()
prop_connectionReuse = do
    c <- liftIO $ do
        cfg <- baseConfiguration

        -- counts the number of TCP connections
        ref <- newIORef (0 :: Int)

        manager <- HTTP.newManager (managerSettings ref)
        void $ runExceptT $
            flip catchE (error . T.unpack) . replicateM_ 3 $ do
                void $ dyT cfg manager DY.ListTables
                mustFail . dyT cfg manager $ DY.DescribeTable "____"

        readIORef ref
    unless (c == 1) $
        throwE "The TCP connection has not been reused"
  where
    managerSettings ref = HTTP.defaultManagerSettings
        { HTTP.managerRawConnection = do
            mkConn <- HTTP.managerRawConnection HTTP.defaultManagerSettings
            return $ \a b c -> do
                atomicModifyIORef ref $ \i -> (succ i, ())
                mkConn a b c
        }