packages feed

data-prometheus-0.1.0.0: test/ParseSpec.hs

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell   #-}
{-# LANGUAGE QuasiQuotes #-}

module ParseSpec where

import SpecHelper
import Text.RawString.QQ
import Data.Either (isRight)
import qualified Data.Map

gauge = [r|# HELP go_memstats_alloc_bytes Number of bytes allocated and still in use.
# TYPE go_memstats_alloc_bytes gauge
go_memstats_alloc_bytes 1.276272e+06
|]

summary = [r|# HELP go_gc_duration_seconds A summary of the GC invocation durations.
# TYPE go_gc_duration_seconds summary
go_gc_duration_seconds{quantile="0"} 8.1545e-05
go_gc_duration_seconds{quantile="0.25"} 0.000103978
go_gc_duration_seconds{quantile="0.5"} 0.000118208
go_gc_duration_seconds{quantile="0.75"} 0.000140686
go_gc_duration_seconds{quantile="1"} 0.000302995
go_gc_duration_seconds_sum 0.006560726
go_gc_duration_seconds_count 51
|]

counter = [r|# HELP node_context_switches_total Total number of context switches.
# TYPE node_context_switches_total counter
node_context_switches_total 1.54296968e+08
|]

countersLabels = [r|# HELP node_cpu_core_throttles_total helptext
# TYPE node_cpu_core_throttles_total counter
node_cpu_core_throttles_total{core="0",package="0"} 0
node_cpu_core_throttles_total{core="1",package="0"} 0
|]

multiple = [r|# HELP node_arp_entries ARP entries by device
# TYPE node_arp_entries gauge
node_arp_entries{device="eth0"} 2
# HELP node_boot_time_seconds Node boot time, in unixtime.
# TYPE node_boot_time_seconds gauge
node_boot_time_seconds 1.537903224e+09
# HELP node_context_switches_total Total number of context switches.
# TYPE node_context_switches_total counter
node_context_switches_total 1.54296968e+08
|]

-- from https://prometheus.io/docs/instrumenting/exposition_formats/#text-format-example
ref = [r|
# HELP http_requests_total The total number of HTTP requests.
# TYPE http_requests_total counter
http_requests_total{method="post",code="200"} 1027 1395066363000
http_requests_total{method="post",code="400"}    3 1395066363000

# Escaping in label values:
msdos_file_access_time_seconds{path="C:\\DIR\\FILE.TXT",error="Cannot find file:\n\"FILE.TXT\""} 1.458255915e9

# Minimalistic line:
metric_without_timestamp_and_labels 12.47

# A weird metric from before the epoch:
something_weird{problem="division by zero"} +Inf -3982045

# A histogram, which has a pretty complex representation in the text format:
# HELP http_request_duration_seconds A histogram of the request duration.
# TYPE http_request_duration_seconds histogram
http_request_duration_seconds_bucket{le="0.05"} 24054
http_request_duration_seconds_bucket{le="0.1"} 33444
http_request_duration_seconds_bucket{le="0.2"} 100392
http_request_duration_seconds_bucket{le="0.5"} 129389
http_request_duration_seconds_bucket{le="1"} 133988
http_request_duration_seconds_bucket{le="+Inf"} 144320
http_request_duration_seconds_sum 53423
http_request_duration_seconds_count 144320

# Finally a summary, which has a complex representation, too:
# HELP rpc_duration_seconds A summary of the RPC duration in seconds.
# TYPE rpc_duration_seconds summary
rpc_duration_seconds{quantile="0.01"} 3102
rpc_duration_seconds{quantile="0.05"} 3272
rpc_duration_seconds{quantile="0.5"} 4773
rpc_duration_seconds{quantile="0.9"} 9001
rpc_duration_seconds{quantile="0.99"} 76656
rpc_duration_seconds_sum 1.7560473e+07
rpc_duration_seconds_count 2693
|]

testCases = [
   ("", Left "not enough input")
 , ( gauge
   , Right
      $ Data.Map.fromList
          [ ( MetricId
                { metricIdName = "go_memstats_alloc_bytes"
                , metricIdHelp = "Number of bytes allocated and still in use."
                , metricIdLabels = mempty
                }
            , Gauge 1276272.0
            )
          ]
   )

 , ( summary
   , Right
      $ Data.Map.fromList
          [ ( MetricId
                { metricIdName = "go_gc_duration_seconds"
                , metricIdHelp = "A summary of the GC invocation durations."
                , metricIdLabels = mempty
                }
             , Summary
                 { sumQuantiles =
                    Data.Map.fromList
                      [ (0.0, 8.1545e-5)
                      , (0.25, 1.03978e-4)
                      , (0.5, 1.18208e-4)
                      , (0.75, 1.40686e-4)
                      , (1.0,3.02995e-4)
                      ]
                  , sumSum = 6.560726e-3
                  , sumCount = 51.0
                  }
              )
          ]
   )
 , ( counter
   , Right
      $ Data.Map.fromList
          [ ( MetricId
                { metricIdName = "node_context_switches_total"
                , metricIdHelp = "Total number of context switches."
                , metricIdLabels = mempty
                }
             , Counter 1.54296968e8
             )
          ]
   )
 , ( countersLabels
   , Right
      $ Data.Map.fromList
          [ ( MetricId
                { metricIdName = "node_cpu_core_throttles_total"
                , metricIdHelp = "helptext"
                , metricIdLabels =
                    Data.Map.fromList
                      [ ("core", "0")
                      , ("package","0")
                      ]
                }
                , Counter 0.0
            )
          , ( MetricId
                { metricIdName = "node_cpu_core_throttles_total"
                , metricIdHelp = "helptext"
                , metricIdLabels =
                    Data.Map.fromList
                      [ ("core", "1")
                      , ("package", "0")
                      ]
                }
                , Counter 0.0
            )
          ]
   )
 , ( multiple
   , Right
      $ Data.Map.fromList
          [ (MetricId
               { metricIdName = "node_arp_entries"
               , metricIdHelp = "ARP entries by device"
               , metricIdLabels = Data.Map.fromList [ ("device", "eth0")]
               }
            , Gauge 2.0
            )
          , ( MetricId
                { metricIdName = "node_boot_time_seconds"
                , metricIdHelp = "Node boot time, in unixtime."
                , metricIdLabels = mempty
                }
            , Gauge 1.537903224e9
            )
          , ( MetricId
                { metricIdName = "node_context_switches_total"
                , metricIdHelp = "Total number of context switches."
                , metricIdLabels = mempty
                }
            , Counter 1.54296968e8
            )
          ]
   )
 ]

spec :: Spec
spec = do
  it "parses samples" $ do
    mapM_ (\(x, y) -> parseProm x `shouldBe` y) testCases

  xit "parses reference"
    $ parseProm ref `shouldSatisfy` isRight

main :: IO ()
main = do
  hspec spec