kafka-effectful-0.2.0.0: test/Kafka/Effectful/OpenTelemetry/SemanticTest.hs
module Kafka.Effectful.OpenTelemetry.SemanticTest (tests) where
import Data.ByteString (ByteString)
import Data.ByteString qualified as BS
import Data.HashMap.Strict qualified as HashMap
import Data.Int (Int64)
import Data.Text (Text)
import Kafka.Consumer.Types (
ConsumerRecord (..),
Offset (..),
Timestamp (NoTimestamp),
)
import Kafka.Effectful.OpenTelemetry.Semantic (
consumerRecordAttributes,
producerRecordAttributes,
)
import Kafka.Producer.Types (
ProducePartition (SpecifiedPartition, UnassignedPartition),
ProducerRecord (..),
)
import Kafka.Types (
PartitionId (..),
TopicName (..),
headersFromList,
)
import OpenTelemetry.Attributes.Attribute (
Attribute (AttributeValue),
PrimitiveAttribute (IntAttribute, TextAttribute),
)
import Test.Tasty (TestTree, testGroup)
import Test.Tasty.HUnit (assertEqual, assertFailure, testCase, (@?=))
tests :: TestTree
tests =
testGroup
"Semantic"
[ producerTests
, consumerTests
]
-- Producer-side attribute coverage
producerTests :: TestTree
producerTests =
testGroup
"producerRecordAttributes"
[ testCase "adds messaging.system=kafka" $ do
let attrs = producerRecordAttributes (sampleProducerRecord (Just "k1"))
HashMap.lookup "messaging.system" attrs
@?= Just (textAttr "kafka")
, testCase "adds messaging.destination.name from topic" $ do
let attrs = producerRecordAttributes (sampleProducerRecord (Just "k1"))
HashMap.lookup "messaging.destination.name" attrs
@?= Just (textAttr "orders")
, testCase "adds messaging.operation=send" $ do
let attrs = producerRecordAttributes (sampleProducerRecord (Just "k1"))
HashMap.lookup "messaging.operation" attrs
@?= Just (textAttr "send")
, testCase "adds messaging.kafka.destination.partition for SpecifiedPartition" $ do
let attrs = producerRecordAttributes (sampleProducerRecord (Just "k1"))
HashMap.lookup "messaging.kafka.destination.partition" attrs
@?= Just (intAttr 42)
, testCase "omits messaging.kafka.destination.partition for UnassignedPartition" $ do
let attrs =
producerRecordAttributes
(sampleProducerRecord (Just "k1"))
{ prPartition = UnassignedPartition
}
assertEqual
"partition attribute should not be present"
Nothing
(HashMap.lookup "messaging.kafka.destination.partition" attrs)
, testCase "adds messaging.kafka.message.key when valid UTF-8" $ do
let attrs = producerRecordAttributes (sampleProducerRecord (Just "hello"))
HashMap.lookup "messaging.kafka.message.key" attrs
@?= Just (textAttr "hello")
, testCase "omits messaging.kafka.message.key when invalid UTF-8" $ do
let attrs =
producerRecordAttributes
(sampleProducerRecord (Just (BS.pack [0xC3, 0x28])))
case HashMap.lookup "messaging.kafka.message.key" attrs of
Nothing -> pure ()
Just _ ->
assertFailure
"expected messaging.kafka.message.key to be omitted for invalid UTF-8"
, testCase "omits messaging.kafka.message.key when key is Nothing" $ do
let attrs = producerRecordAttributes (sampleProducerRecord Nothing)
assertEqual
"key attribute should not be present"
Nothing
(HashMap.lookup "messaging.kafka.message.key" attrs)
]
-- Consumer-side attribute coverage
consumerTests :: TestTree
consumerTests =
testGroup
"consumerRecordAttributes"
[ testCase "adds messaging.system=kafka" $ do
let attrs = consumerRecordAttributes (sampleConsumerRecord (Just "k1"))
HashMap.lookup "messaging.system" attrs
@?= Just (textAttr "kafka")
, testCase "adds messaging.destination.name from topic" $ do
let attrs = consumerRecordAttributes (sampleConsumerRecord (Just "k1"))
HashMap.lookup "messaging.destination.name" attrs
@?= Just (textAttr "orders")
, testCase "adds messaging.operation=process" $ do
let attrs = consumerRecordAttributes (sampleConsumerRecord (Just "k1"))
HashMap.lookup "messaging.operation" attrs
@?= Just (textAttr "process")
, testCase "adds messaging.kafka.destination.partition" $ do
let attrs = consumerRecordAttributes (sampleConsumerRecord (Just "k1"))
HashMap.lookup "messaging.kafka.destination.partition" attrs
@?= Just (intAttr 7)
, testCase "adds messaging.kafka.message.offset" $ do
let attrs = consumerRecordAttributes (sampleConsumerRecord (Just "k1"))
HashMap.lookup "messaging.kafka.message.offset" attrs
@?= Just (intAttr 42)
, testCase "adds messaging.kafka.message.key when valid UTF-8" $ do
let attrs = consumerRecordAttributes (sampleConsumerRecord (Just "hello"))
HashMap.lookup "messaging.kafka.message.key" attrs
@?= Just (textAttr "hello")
, testCase "omits messaging.kafka.message.key when invalid UTF-8" $ do
let attrs =
consumerRecordAttributes
(sampleConsumerRecord (Just (BS.pack [0xC3, 0x28])))
case HashMap.lookup "messaging.kafka.message.key" attrs of
Nothing -> pure ()
Just _ ->
assertFailure
"expected messaging.kafka.message.key to be omitted for invalid UTF-8"
, testCase "omits messaging.kafka.message.key when key is Nothing" $ do
let attrs = consumerRecordAttributes (sampleConsumerRecord Nothing)
assertEqual
"key attribute should not be present"
Nothing
(HashMap.lookup "messaging.kafka.message.key" attrs)
]
-- Helpers
sampleProducerRecord :: Maybe ByteString -> ProducerRecord
sampleProducerRecord key =
ProducerRecord
{ prTopic = TopicName "orders"
, prPartition = SpecifiedPartition 42
, prKey = key
, prValue = Just "value"
, prHeaders = headersFromList []
}
sampleConsumerRecord ::
Maybe ByteString ->
ConsumerRecord (Maybe ByteString) (Maybe ByteString)
sampleConsumerRecord key =
ConsumerRecord
{ crTopic = TopicName "orders"
, crPartition = PartitionId 7
, crOffset = Offset 42
, crTimestamp = NoTimestamp
, crHeaders = headersFromList []
, crKey = key
, crValue = Just "value"
}
textAttr :: Text -> Attribute
textAttr = AttributeValue . TextAttribute
intAttr :: Int64 -> Attribute
intAttr = AttributeValue . IntAttribute