clash-protocols-0.1: tests/Tests/Protocols/PacketStream/Padding.hs
{-# LANGUAGE NoImplicitPrelude #-}
module Tests.Protocols.PacketStream.Padding (
tests,
) where
import Clash.Prelude
import "extra" Data.List.Extra qualified as L
import Hedgehog
import Hedgehog.Gen qualified as Gen
import Hedgehog.Range qualified as Range
import Test.Tasty
import Test.Tasty.Hedgehog (HedgehogTestLimit (HedgehogTestLimit))
import Test.Tasty.Hedgehog.Extra (testProperty)
import Test.Tasty.TH (testGroupGenerator)
import Protocols.Experimental.Hedgehog
import Protocols.Experimental.PacketStream
import Protocols.PacketStream.Hedgehog
-- | Pure model of `stripPaddingC`.
stripPaddingModel ::
forall p.
(KnownNat p) =>
[PacketStreamM2S 1 (Unsigned p)] ->
[PacketStreamM2S 1 (Unsigned p)]
stripPaddingModel packets = L.concatMap go (chunkByPacket packets)
where
go packet
| packetBytes == expectedSize = packet
| packetBytes > expectedSize =
case padding of
[] ->
-- There are (packetBytes - expectedSize) bytes, so more than 0
error "stripPaddingModel: absurd"
(padding0 : _) ->
x L.++ [padding0{_last = Just 0, _abort = any _abort padding}]
| otherwise = a L.++ [b{_abort = True}]
where
(a, b) = case L.unsnoc packet of
Nothing -> error "stripPaddingModel: list should not be empty."
Just (xs, l) -> (xs, l)
packetBytes = L.length packet - (if _last b == Just 0 then 1 else 0)
expectedSize = fromIntegral (_meta b)
(x, padding) = L.splitAt expectedSize packet
{- |
Test `stripPaddingC` with a given @dataWidth@ against a pure model.
We make sure to test integer overflow by making the data type which holds
the expected packet length extra small: @Unsigned 6@.
-}
stripPaddingProperty ::
forall dataWidth.
(1 <= dataWidth) =>
SNat dataWidth ->
Property
stripPaddingProperty SNat =
idWithModelSingleDomain
@System
defExpectOptions
(genPackets 1 10 (genValidPacket defPacketOptions Gen.enumBounded (Range.linear 0 20)))
(exposeClockResetEnable (upConvert . stripPaddingModel @6 . downConvert))
(exposeClockResetEnable (stripPaddingC @dataWidth id))
prop_strip_padding_d1 :: Property
prop_strip_padding_d1 = stripPaddingProperty d1
prop_strip_padding_d2 :: Property
prop_strip_padding_d2 = stripPaddingProperty d2
prop_strip_padding_d4 :: Property
prop_strip_padding_d4 = stripPaddingProperty d4
prop_strip_padding_d5 :: Property
prop_strip_padding_d5 = stripPaddingProperty d5
prop_strip_padding_d8 :: Property
prop_strip_padding_d8 = stripPaddingProperty d8
tests :: TestTree
tests =
localOption (mkTimeout 20_000_000 {- 20 seconds -})
$ localOption
(HedgehogTestLimit (Just 1_000))
$(testGroupGenerator)