2018-03-09 20:07:34 +03:00
|
|
|
module Semantic.Stat.Spec (spec) where
|
2017-10-04 21:12:24 +03:00
|
|
|
|
|
|
|
import Control.Exception
|
2017-10-04 21:40:39 +03:00
|
|
|
import Network.Socket hiding (recv)
|
|
|
|
import Network.Socket.ByteString
|
2018-06-14 03:03:15 +03:00
|
|
|
import Semantic.Telemetry.Stat
|
|
|
|
import Semantic.Config
|
2018-03-13 21:10:50 +03:00
|
|
|
import System.Environment
|
2017-10-04 21:40:39 +03:00
|
|
|
|
2018-03-13 21:10:50 +03:00
|
|
|
import SpecHelpers
|
2017-10-04 21:40:39 +03:00
|
|
|
|
|
|
|
withSocketPair :: ((Socket, Socket) -> IO c) -> IO c
|
|
|
|
withSocketPair = bracket create release
|
|
|
|
where create = socketPair AF_UNIX Datagram defaultProtocol
|
|
|
|
release (client, server) = close client >> close server
|
2017-10-04 21:12:24 +03:00
|
|
|
|
|
|
|
withEnvironment :: String -> String -> (() -> IO ()) -> IO ()
|
|
|
|
withEnvironment key value = bracket (setEnv key value) (const (unsetEnv key))
|
|
|
|
|
|
|
|
-- NOTE: These cannot easily run in parallel because we test things like
|
|
|
|
-- setting/unsetting the environment.
|
|
|
|
spec :: Spec
|
|
|
|
spec = do
|
|
|
|
describe "defaultStatsClient" $ do
|
|
|
|
it "sets appropriate defaults" $ do
|
|
|
|
StatsClient{..} <- defaultStatsClient
|
2017-10-05 20:26:11 +03:00
|
|
|
statsClientNamespace `shouldBe` "semantic"
|
|
|
|
statsClientUDPHost `shouldBe` "127.0.0.1"
|
|
|
|
statsClientUDPPort `shouldBe` "28125"
|
2017-10-04 21:12:24 +03:00
|
|
|
|
|
|
|
around (withEnvironment "STATS_ADDR" "localhost:8125") $
|
|
|
|
it "takes STATS_ADDR from environment" $ do
|
|
|
|
StatsClient{..} <- defaultStatsClient
|
2017-10-05 20:26:11 +03:00
|
|
|
statsClientUDPHost `shouldBe` "localhost"
|
|
|
|
statsClientUDPPort `shouldBe` "8125"
|
|
|
|
|
|
|
|
around (withEnvironment "STATS_ADDR" "localhost") $
|
|
|
|
it "handles STATS_ADDR with just hostname" $ do
|
|
|
|
StatsClient{..} <- defaultStatsClient
|
|
|
|
statsClientUDPHost `shouldBe` "localhost"
|
|
|
|
statsClientUDPPort `shouldBe` "28125"
|
2017-10-04 21:12:24 +03:00
|
|
|
|
|
|
|
around (withEnvironment "DOGSTATSD_HOST" "0.0.0.0") $
|
|
|
|
it "takes DOGSTATSD_HOST from environment" $ do
|
|
|
|
StatsClient{..} <- defaultStatsClient
|
2017-10-05 20:26:11 +03:00
|
|
|
statsClientUDPHost `shouldBe` "0.0.0.0"
|
|
|
|
statsClientUDPPort `shouldBe` "28125"
|
2017-10-04 21:12:24 +03:00
|
|
|
|
|
|
|
describe "renderDatagram" $ do
|
|
|
|
let key = "app.metric"
|
|
|
|
|
|
|
|
describe "counters" $ do
|
|
|
|
it "renders increment" $
|
|
|
|
renderDatagram "" (increment key []) `shouldBe` "app.metric:1|c"
|
2017-10-05 00:21:06 +03:00
|
|
|
it "renders decrement" $
|
2017-10-04 21:12:24 +03:00
|
|
|
renderDatagram "" (decrement key []) `shouldBe` "app.metric:-1|c"
|
2017-10-05 00:21:06 +03:00
|
|
|
it "renders count" $
|
2017-10-04 21:12:24 +03:00
|
|
|
renderDatagram "" (count key 8 []) `shouldBe` "app.metric:8|c"
|
|
|
|
|
2017-10-05 20:26:11 +03:00
|
|
|
it "renders statsClientNamespace" $
|
2017-10-04 21:12:24 +03:00
|
|
|
renderDatagram "pre" (increment key []) `shouldBe` "pre.app.metric:1|c"
|
|
|
|
|
|
|
|
describe "tags" $ do
|
|
|
|
it "renders a tag" $ do
|
|
|
|
let inc = increment key [("key", "value")]
|
|
|
|
renderDatagram "" inc `shouldBe` "app.metric:1|c|#key:value"
|
|
|
|
it "renders a tag without value" $ do
|
|
|
|
let inc = increment key [("a", "")]
|
|
|
|
renderDatagram "" inc `shouldBe` "app.metric:1|c|#a"
|
|
|
|
it "renders tags" $ do
|
|
|
|
let inc = increment key [("key", "value"), ("a", "true")]
|
|
|
|
renderDatagram "" inc `shouldBe` "app.metric:1|c|#key:value,a:true"
|
|
|
|
it "renders tags without value" $ do
|
|
|
|
let inc = increment key [("key", "value"), ("a", "")]
|
|
|
|
renderDatagram "" inc `shouldBe` "app.metric:1|c|#key:value,a"
|
2017-10-04 21:40:39 +03:00
|
|
|
|
2017-10-05 20:26:11 +03:00
|
|
|
describe "sendStat" $
|
2017-10-04 21:40:39 +03:00
|
|
|
it "delivers datagram" $ do
|
|
|
|
client@StatsClient{..} <- defaultStatsClient
|
|
|
|
withSocketPair $ \(clientSoc, serverSoc) -> do
|
2017-10-05 20:26:11 +03:00
|
|
|
sendStat client { statsClientUDPSocket = clientSoc } (increment "app.metric" [])
|
2017-10-04 21:40:39 +03:00
|
|
|
info <- recv serverSoc 1024
|
|
|
|
info `shouldBe` "semantic.app.metric:1|c"
|
2018-06-14 03:03:15 +03:00
|
|
|
|
2018-06-14 03:48:22 +03:00
|
|
|
-- Defaults are all driven by defaultConfig.
|
2018-06-14 03:03:15 +03:00
|
|
|
defaultStatsClient :: IO StatsClient
|
2018-06-15 20:31:51 +03:00
|
|
|
defaultStatsClient = defaultConfig defaultOptions >>= \Config{..} -> statsClient configStatsHost configStatsPort configAppName
|