hans-2.4.0.0: tests/Tcp/Window.hs
module Tcp.Window where
import Tcp.Packet
import Hans.Layer.Tcp.Window
(emptyLocalWindow,addInSegment,stepWindow,InSegment(..)
,localWindowSackBlocks)
import Hans.Message.Tcp (TcpHeader(..))
import Control.Arrow ((&&&))
import Test.Framework (Test,testGroup)
import Test.QuickCheck (forAll)
import Test.Framework.Providers.QuickCheck2 (testProperty)
import qualified Data.ByteString as S
import qualified Data.Foldable as F
import qualified Data.Sequence as Seq
tcpWindowTests :: Test
tcpWindowTests = testGroup "tcp window"
[ testProperty "prop_localOrdered" prop_localOrdered
, testProperty "prop_localRandom" prop_localRandom
, testProperty "prop_sackOrdered" prop_sackOrdered
]
-- Local Window ----------------------------------------------------------------
fromInSegment :: InSegment -> (TcpHeader,S.ByteString)
fromInSegment = inHeader &&& inBody
-- | Check that if a stream of packets goes into the @LocalWindow@ in order,
-- that they will come out in the same order.
prop_localOrdered = forAll packetStream $ \ segs ->
let (hdr,_) = Seq.index segs 0
win = emptyLocalWindow (tcpSeqNum hdr) 14600 0
step w (h,body) = addInSegment h body w
win' = F.foldl step win segs
(segs',_) = stepWindow win'
in segs == fmap fromInSegment segs'
-- | Check that if a stream of initially ordered packets goes into the
-- @LocalWindow@ in a random order, that they come out ordered again. In this
-- case, we just reverse the stream, as that should be the degenrate case for
-- incoming packets.
prop_localRandom = forAll packetStream $ \ segs ->
let (hdr,_) = Seq.index segs 0
win = emptyLocalWindow (tcpSeqNum hdr) 14600 0
step (h,body) w = addInSegment h body w
win' = F.foldr step win segs
(segs',_) = stepWindow win'
in segs == fmap fromInSegment segs'
-- | Generating a sequence of sack blocks from a window constructed of in-order
-- packets should generate a single sack block.
prop_sackOrdered = forAll packetStream $ \ segs ->
let (hdr,_) = Seq.index segs 0
win = emptyLocalWindow (tcpSeqNum hdr) 14600 0
step w (h,body) = addInSegment h body w
win' = F.foldl step win segs
in Seq.length (localWindowSackBlocks win') == 1