glue-0.1.1.1: test/Glue/StatsSpec.hs
{-# LANGUAGE OverloadedStrings, DeriveDataTypeable, ScopedTypeVariables #-}
module Glue.StatsSpec where
import Data.Int
import Data.Typeable
import Glue.Stats
import Glue.Types
import Test.QuickCheck.Instances()
import Test.Hspec
import Data.Text
import Test.QuickCheck
import Control.Exception.Base hiding (throw, throwIO)
import Control.Exception.Lifted
import System.Metrics
import qualified System.Metrics.Distribution as MD
import qualified Data.HashMap.Strict as M
data StatsTestException = StatsTestException deriving (Eq, Show, Typeable)
instance Exception StatsTestException
data MetricsResult = CounterResult Int64
| GaugeResult Int64
| LabelResult Text
| DistributionResult Int64
deriving (Eq, Show)
checkResult :: Store -> Text -> (MetricsResult -> Expectation) -> Expectation
checkResult store name check = do
allMetrics <- sampleAll store
let possibleValue = M.lookup name allMetrics
result <- case possibleValue of
(Just (Counter counterCount)) -> return $ CounterResult counterCount
(Just (Gauge value)) -> return $ GaugeResult value
(Just (Label text)) -> return $ LabelResult text
(Just (Distribution stats)) -> return $ DistributionResult $ MD.count stats
Nothing -> fail "No metric."
check result
testStats :: String ->
(Store -> Text -> BasicService IO Int Int -> IO (BasicService IO Int Int)) ->
(Int -> Int -> MetricsResult -> Expectation) ->
(Int -> Int -> MetricsResult -> Expectation) ->
Spec
testStats methodName method successCheck failureCheck =
describe methodName $ do
it "Successful call" $ do
property $ \(request :: Int, result :: Int, name :: Text) -> do
let service _ = return result :: IO Int
store <- newStore
wrappedService <- method store name service :: IO (BasicService IO Int Int)
(wrappedService request) `shouldReturn` result
checkResult store name $ successCheck request result
it "Failing call" $ do
property $ \(request :: Int, result :: Int, name :: Text) -> do
let service _ = throwIO StatsTestException :: IO Int
store <- newStore
wrappedService <- method store name service :: IO (BasicService IO Int Int)
(wrappedService request) `shouldThrow` (== StatsTestException)
checkResult store name $ failureCheck request result
spec :: Spec
spec = parallel $ do
testStats "recordDistribution" recordDistribution (\_ -> \_ -> \m -> m `shouldBe` (DistributionResult 1)) (\_ -> \_ -> \m -> m `shouldBe` (DistributionResult 1))
testStats "recordAttempts" recordAttempts (\_ -> \_ -> \m -> m `shouldBe` (CounterResult 1)) (\_ -> \_ -> \m -> m `shouldBe` (CounterResult 1))
testStats "recordSuccesses" recordSuccesses (\_ -> \_ -> \m -> m `shouldBe` (CounterResult 1)) (\_ -> \_ -> \m -> m `shouldBe` (CounterResult 0))
testStats "recordFailures" recordFailures (\_ -> \_ -> \m -> m `shouldBe` (CounterResult 0)) (\_ -> \_ -> \m -> m `shouldBe` (CounterResult 1))
testStats "recordLastRequest" recordLastRequest (\r -> \_ -> \m -> m `shouldBe` (LabelResult $ pack $ show r)) (\r -> \_ -> \m -> m `shouldBe` (LabelResult $ pack $ show r))
testStats "recordLastResult" recordLastResult (\_ -> \r -> \m -> m `shouldBe` (LabelResult $ pack $ show r)) (\_ -> \_ -> \m -> m `shouldBe` (LabelResult ""))