instana-haskell-trace-sdk-0.2.0.0: test/integration/Instana/SDK/IntegrationTest/Metrics.hs
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Instana.SDK.IntegrationTest.Metrics
( shouldReportMetrics
) where
import qualified Data.Aeson as Aeson
import qualified Data.HashMap.Strict as HashMap
import qualified Data.List as List
import Data.Maybe (isJust)
import Data.Text (Text)
import qualified Data.Text as T
import Test.HUnit
import Instana.SDK.AgentStub.EntityDataRequest (EntityDataRequest)
import qualified Instana.SDK.AgentStub.EntityDataRequest as EntityDataRequest
import Instana.SDK.IntegrationTest.HUnitExtra (applyLabel,
assertAllIO, failIO)
import qualified Instana.SDK.IntegrationTest.TestHelper as TestHelper
shouldReportMetrics :: String -> IO Test
shouldReportMetrics pid =
applyLabel "shouldReportMetrics" $ do
entityDataRequestsResult <- TestHelper.waitForEntityDataWithPid pid
case entityDataRequestsResult of
Left failure ->
failIO $
"Could not load recorded entity data requests from agent stub: " ++
failure
Right [] -> do
failIO $
"Could not load recorded entity data requests from agent stub " ++
"- received empty list."
Right [entityData] -> do
assertAllIO
[ assertLabelIs "pid" pid (EntityDataRequest.pid entityData)
, assertLabelContains
"executable path"
"instana-haskell-test-wai-server"
(EntityDataRequest.executablePath entityData)
, assertLabelIs
"program name"
"instana-haskell-test-wai-server"
(EntityDataRequest.programName entityData)
, assertLabelIs
"arguments"
""
(EntityDataRequest.arguments entityData)
, assertLabelIs
"sensorVersion"
"0.2.0.0"
(EntityDataRequest.sensorVersion entityData)
, assertCounterSatisfies
"startTime"
(1545570995405 <)
(EntityDataRequest.startTime entityData)
, assertMetricsArePresent
"RTS GC metrics does not contain all expected metric keys"
-- The list of metrics might depend on GHC version and ekg-core
-- version, so this test is potentially fragile. If it starts to
-- make trouble, we could also just check for one well known
-- metric that is always present, should be good enough.
[
-- Counters:
"bytes_allocated_delta"
, "num_gcs_delta"
, "num_bytes_usage_samples_delta"
, "cumulative_bytes_used_delta"
, "bytes_copied_delta"
, "mutator_cpu_ms_delta"
, "mutator_wall_ms_delta"
, "gc_cpu_ms_delta"
, "gc_wall_ms_delta"
, "cpu_ms_delta"
, "wall_ms_delta"
-- Gauges:
, "max_bytes_used"
, "current_bytes_used"
, "current_bytes_slop"
, "max_bytes_slop"
, "peak_megabytes_allocated"
, "par_tot_bytes_copied"
, "par_avg_bytes_copied"
, "par_max_bytes_copied"
]
entityData
]
_ -> do
failIO $
"Unexpectedly received multiple recorded entity data requests " ++
"from agent stub "
assertLabelIs ::
String
-> String
-> Maybe Text
-> Assertion
assertLabelIs testLabel expectedValue labelMetric =
assertEqual testLabel (label expectedValue) labelMetric
assertLabelContains ::
String
-> String
-> Maybe Text
-> Assertion
assertLabelContains testLabel expectedValue labelMetric =
if isJust labelMetric then
let
Just labelContent = labelMetric
in
assertBool testLabel (T.isInfixOf (T.pack expectedValue) labelContent)
else
assertFailure $ testLabel ++ " - label metric is Nothing"
label :: String -> Maybe Text
label s =
Just $ T.pack s
assertCounterSatisfies ::
String
-> (Int -> Bool)
-> Maybe Int
-> Assertion
assertCounterSatisfies testLabel predicate counterMetric =
case counterMetric of
Just metric ->
assertBool testLabel (predicate $ metric)
Nothing ->
assertFailure $ testLabel ++ " - counter metric is Nothing"
assertMetricsArePresent :: String -> [String] -> EntityDataRequest -> Assertion
assertMetricsArePresent testLabel expectedMetrics entityData =
if isJust $ EntityDataRequest.rts entityData then
let
Just rtsData = EntityDataRequest.rts entityData
gcMetricsJson = EntityDataRequest.gc rtsData
(decodingResult :: Aeson.Result Aeson.Object) = Aeson.fromJSON gcMetricsJson
in
case decodingResult of
Aeson.Error e ->
assertFailure $ testLabel ++ " - unparseable GC metrics - " ++ e
Aeson.Success decoded ->
let
containsAllMetrics =
List.foldl
(\allTrue metricKey ->
allTrue && HashMap.member (T.pack metricKey) decoded
)
True
expectedMetrics
in
assertBool testLabel containsAllMetrics
else
assertFailure $ testLabel ++ " - no rts data"