hal-0.4.10: test/AWS/Lambda/Events/Kafka/Gen.hs
{-# LANGUAGE CPP #-}
module AWS.Lambda.Events.Kafka.Gen where
import AWS.Lambda.Events.Kafka (KafkaEvent(KafkaEvent),
EventSource (..),
Header(..),
Record,
Record' (Record),
Timestamp (..),
int64ToUTCTime)
import Control.Applicative (liftA2)
import Data.Char (isPrint)
import Data.Foldable (fold)
import Data.List (intersperse)
import qualified Data.List.NonEmpty as NE
import Data.List.NonEmpty (NonEmpty)
import Data.Map (Map)
#if !MIN_VERSION_base(4,11,0)
import Data.Semigroup ((<>))
#endif
import Data.Text (Text)
import qualified Data.Text as T
import Data.Time (UTCTime)
import Data.Traversable (for)
import Hedgehog (Gen)
import qualified Hedgehog.Gen as Gen
import qualified Hedgehog.Range as Range
kafkaEvent :: Gen KafkaEvent
kafkaEvent = KafkaEvent
<$> eventSource
<*> Gen.maybe eventSourceArn
<*> bootstrapServers
<*> records
eventSource :: Gen EventSource
eventSource = Gen.enumBounded
eventSourceArn :: Gen Text
eventSourceArn = do
region <- Gen.element ["ap-south-1", "us-east-2", "eu-west-3"]
account <- Gen.text (Range.singleton 12) Gen.digit
clusterName <- Gen.text (Range.linear 1 20) printable
uuidParts <- for [ 7, 4, 4, 4, 12, 2 ] $ \n ->
Gen.text (Range.singleton n) Gen.hexit
let uuid = fold $ intersperse "-" uuidParts
resource = T.intercalate "/" ["cluster", clusterName, uuid]
pure $ T.intercalate ":" ["arn:aws:kafka", region, account, resource]
bootstrapServers :: Gen (NonEmpty Text)
bootstrapServers = Gen.nonEmpty (Range.linear 1 5) server
where
server :: Gen Text
server = (\h p -> h <> ":" <> p) <$> host <*> port
host :: Gen Text
host = fold . NE.intersperse "." <$> domainParts
domainParts :: Gen (NonEmpty Text)
domainParts = Gen.nonEmpty (Range.linear 1 5) fragment
fragment :: Gen Text
fragment = Gen.text (Range.linear 1 20) .
Gen.element $ ['A'..'Z'] <> ['a'..'z'] <> ['0'..'9'] <> ['-', '_']
port :: Gen Text
port = T.pack . show <$> Gen.int (Range.linear 0 65535)
records :: Gen (Map Text [Record])
records = Gen.map (Range.exponential 1 3)
. liftA2 (,) topicKey
$ Gen.list (Range.linear 1 5) record
where
topicKey :: Gen Text
topicKey = do
t <- topic
n <- T.pack . show <$> Gen.int (Range.linear 0 10)
pure $ t <> "-" <> n
record :: Gen Record
record = Record
<$> topic
<*> Gen.int32 (Range.exponential 0 maxBound)
<*> Gen.int64 (Range.linear 0 maxBound)
<*> timestamp
<*> headers
<*> Gen.maybe (Gen.bytes (Range.exponential 0 512))
<*> Gen.maybe (Gen.bytes (Range.exponential 0 512))
timestamp :: Gen Timestamp
timestamp = Gen.choice
[ pure NoTimestampType
, CreateTime <$> utcTime
, LogAppendTime <$> utcTime
]
where
utcTime :: Gen UTCTime
utcTime = int64ToUTCTime <$> Gen.int64
(Range.exponentialFrom 1600000000000 1650000000000 1700000000000)
headers :: Gen [Header]
headers = Gen.list (Range.linear 0 10)
(Header
<$> Gen.text (Range.linear 0 512) Gen.unicode
<*> Gen.bytes (Range.linear 0 512))
topic :: Gen Text
topic = Gen.text (Range.linear 1 20) printable
printable :: Gen Char
printable = Gen.filter isPrint Gen.ascii