1- module Semantic.Stat.Spec (spec ) where
1+ {-# LANGUAGE TemplateHaskell #-}
2+
3+ module Semantic.Stat.Spec (testTree ) where
24
35import Control.Exception
46import Network.Socket hiding (recv )
@@ -7,80 +9,95 @@ import Semantic.Telemetry.Stat
79import Semantic.Config
810import System.Environment
911
10- import SpecHelpers
12+ import Test.Tasty
13+ import Test.Tasty.HUnit
14+ import Test.Tasty.Runners
1115
1216withSocketPair :: ((Socket , Socket ) -> IO c ) -> IO c
1317withSocketPair = bracket create release
1418 where create = socketPair AF_UNIX Datagram defaultProtocol
1519 release (client, server) = close client >> close server
1620
17- withEnvironment :: String -> String -> ( () -> IO () ) -> IO ()
18- withEnvironment key value = bracket (setEnv key value) (const (unsetEnv key))
21+ withEnvironment :: String -> String -> IO () -> IO ()
22+ withEnvironment key value = bracket (setEnv key value) (const (unsetEnv key)) . const
1923
2024-- NOTE: These cannot easily run in parallel because we test things like
2125-- setting/unsetting the environment.
22- spec :: Spec
23- spec = do
24- describe " defaultStatsClient" $ do
25- it " sets appropriate defaults" $ do
26- StatsClient {.. } <- defaultStatsClient
27- statsClientNamespace `shouldBe` " semantic"
28- statsClientUDPHost `shouldBe` " 127.0.0.1"
29- statsClientUDPPort `shouldBe` " 28125"
30-
31- around (withEnvironment " STATS_ADDR" " localhost:8125" ) $
32- it " takes STATS_ADDR from environment" $ do
33- StatsClient {.. } <- defaultStatsClient
34- statsClientUDPHost `shouldBe` " localhost"
35- statsClientUDPPort `shouldBe` " 8125"
36-
37- around (withEnvironment " STATS_ADDR" " localhost" ) $
38- it " handles STATS_ADDR with just hostname" $ do
39- StatsClient {.. } <- defaultStatsClient
40- statsClientUDPHost `shouldBe` " localhost"
41- statsClientUDPPort `shouldBe` " 28125"
42-
43- around (withEnvironment " DOGSTATSD_HOST" " 0.0.0.0" ) $
44- it " takes DOGSTATSD_HOST from environment" $ do
45- StatsClient {.. } <- defaultStatsClient
46- statsClientUDPHost `shouldBe` " 0.0.0.0"
47- statsClientUDPPort `shouldBe` " 28125"
48-
49- describe " renderDatagram" $ do
50- let key = " app.metric"
51-
52- describe " counters" $ do
53- it " renders increment" $
54- renderDatagram " " (increment key [] ) `shouldBe` " app.metric:1|c"
55- it " renders decrement" $
56- renderDatagram " " (decrement key [] ) `shouldBe` " app.metric:-1|c"
57- it " renders count" $
58- renderDatagram " " (count key 8 [] ) `shouldBe` " app.metric:8|c"
59-
60- it " renders statsClientNamespace" $
61- renderDatagram " pre" (increment key [] ) `shouldBe` " pre.app.metric:1|c"
62-
63- describe " tags" $ do
64- it " renders a tag" $ do
65- let inc = increment key [(" key" , " value" )]
66- renderDatagram " " inc `shouldBe` " app.metric:1|c|#key:value"
67- it " renders a tag without value" $ do
68- let inc = increment key [(" a" , " " )]
69- renderDatagram " " inc `shouldBe` " app.metric:1|c|#a"
70- it " renders tags" $ do
71- let inc = increment key [(" key" , " value" ), (" a" , " true" )]
72- renderDatagram " " inc `shouldBe` " app.metric:1|c|#key:value,a:true"
73- it " renders tags without value" $ do
74- let inc = increment key [(" key" , " value" ), (" a" , " " )]
75- renderDatagram " " inc `shouldBe` " app.metric:1|c|#key:value,a"
76-
77- describe " sendStat" $
78- it " delivers datagram" $ do
79- client@ StatsClient {.. } <- defaultStatsClient
80- withSocketPair $ \ (clientSoc, serverSoc) -> do
81- sendStat client { statsClientUDPSocket = clientSoc } (increment " app.metric" [] )
82- info <- recv serverSoc 1024
83- info `shouldBe` " semantic.app.metric:1|c"
26+ testTree :: TestTree
27+ testTree = testCaseSteps " Semantic.Stat.Spec" $ \ step -> do
28+ step " Sets appropriate defaults"
29+ case_sets_appropriate_defaults
30+ step " Takes stats addr from environment"
31+ case_takes_stats_addr_from_environment
32+ step " Handles stats addr with just hostname"
33+ case_handles_stats_addr_with_just_hostname
34+ step " takes dogstats host from environment"
35+ case_takes_stats_addr_from_environment
36+ step " rendering"
37+ case_render_counters *> case_render_tags
38+ step " stats deliver datagram"
39+ case_sendstat_delivers_datagram
40+
41+
42+ case_sets_appropriate_defaults :: Assertion
43+ case_sets_appropriate_defaults = do
44+ StatsClient {.. } <- defaultStatsClient
45+ statsClientNamespace @?= " semantic"
46+ statsClientUDPHost @?= " 127.0.0.1"
47+ statsClientUDPPort @?= " 28125"
48+
49+ case_takes_stats_addr_from_environment :: Assertion
50+ case_takes_stats_addr_from_environment =
51+ withEnvironment " STATS_ADDR" " localhost:8125" $ do
52+ StatsClient {.. } <- defaultStatsClient
53+ statsClientUDPHost @?= " localhost"
54+ statsClientUDPPort @?= " 8125"
55+
56+ case_handles_stats_addr_with_just_hostname :: Assertion
57+ case_handles_stats_addr_with_just_hostname =
58+ withEnvironment " STATS_ADDR" " localhost" $ do
59+ StatsClient {.. } <- defaultStatsClient
60+ statsClientUDPHost @?= " localhost"
61+ statsClientUDPPort @?= " 28125"
62+
63+ case_takes_dogstats_host_from_environment :: Assertion
64+ case_takes_dogstats_host_from_environment =
65+ withEnvironment " DOGSTATSD_HOST" " 0.0.0.0" $ do
66+ StatsClient {.. } <- defaultStatsClient
67+ statsClientUDPHost @?= " 0.0.0.0"
68+ statsClientUDPPort @?= " 28125"
69+
70+ key :: String
71+ key = " app.metric"
72+
73+ case_render_counters :: Assertion
74+ case_render_counters = do
75+ renderDatagram " " (increment key [] ) @?= " app.metric:1|c"
76+ renderDatagram " " (decrement key [] ) @?= " app.metric:-1|c"
77+ renderDatagram " " (count key 8 [] ) @?= " app.metric:8|c"
78+ renderDatagram " pre" (increment key [] ) @?= " pre.app.metric:1|c"
79+
80+ case_render_tags :: Assertion
81+ case_render_tags = do
82+ let incTag = increment key [(" key" , " value" )]
83+ renderDatagram " " incTag @?= " app.metric:1|c|#key:value"
84+
85+ let tagWithoutValue = increment key [(" a" , " " )]
86+ renderDatagram " " tagWithoutValue @?= " app.metric:1|c|#a"
87+
88+ let tags = increment key [(" key" , " value" ), (" a" , " true" )]
89+ renderDatagram " " tags @?= " app.metric:1|c|#key:value,a:true"
90+
91+ let tagsWithoutValue = increment key [(" key" , " value" ), (" a" , " " )]
92+ renderDatagram " " tagsWithoutValue @?= " app.metric:1|c|#key:value,a"
93+
94+ case_sendstat_delivers_datagram :: Assertion
95+ case_sendstat_delivers_datagram = do
96+ client@ StatsClient {.. } <- defaultStatsClient
97+ withSocketPair $ \ (clientSoc, serverSoc) -> do
98+ sendStat client { statsClientUDPSocket = clientSoc } (increment " app.metric" [] )
99+ info <- recv serverSoc 1024
100+ info @?= " semantic.app.metric:1|c"
84101
85102-- Defaults are all driven by defaultConfig.
86103defaultStatsClient :: IO StatsClient
0 commit comments