LimitedInput.hs 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. {-# LANGUAGE OverloadedStrings #-}
  2. module LimitedInput where
  3. import Distribution.TestSuite
  4. import Base (simpleTest)
  5. import System.IO.Error
  6. import System.IO.Uniform.ByteString
  7. import qualified System.IO.Uniform.Streamline as S
  8. import System.Timeout (timeout)
  9. import Data.ByteString (ByteString)
  10. import qualified Data.ByteString as BS
  11. import qualified Data.ByteString.Char8 as C8
  12. import qualified Data.Attoparsec.ByteString as A
  13. import Control.Monad
  14. tests :: IO [Test]
  15. tests = return [
  16. simpleTest "recieveLine" $ recvTest False "A test\n" 3 S.recieveLine,
  17. simpleTest "recieveN" $ recvTest False "A test\n" 3 $ S.recieveN 30,
  18. simpleTest "runAttoparsec" $ recvTest False "abcedefghijklmnopqrstuvwxyz" 3 $ runParser parseAlphabet,
  19. simpleTest "recieveLine" $ recvTest True "A test\n" 3 S.recieveLine,
  20. simpleTest "recieveN" $ recvTest True "A test\n" 3 $ S.recieveN 30,
  21. simpleTest "runAttoparsec" $ recvTest True "abcedefghijklmnopqrstuvwxyz" 3 $ runParser parseAlphabet
  22. ]
  23. recvTest :: Bool -> ByteString -> Int -> S.Streamline IO ByteString -> IO Progress
  24. recvTest readFirst input limit f = do
  25. r <- tryIOError $ test readFirst
  26. case r of
  27. Left e -> return . Finished . Fail $ "IO error: " ++ show e
  28. Right v -> return v
  29. where
  30. test recv = do
  31. to <- timeout 1000000 $ do
  32. (r, _) <- withByteStringIO input $ \t -> do
  33. S.withTarget t $ do
  34. when recv $ S.recieveN 1 >> return ()
  35. S.limitInput limit
  36. f
  37. let extra = if readFirst then 1 else 0
  38. if BS.length r <= limit + extra
  39. then return . Finished $ Pass
  40. else return . Finished . Fail $ "Got too much text: " ++ show r
  41. case to of
  42. Nothing -> return . Finished . Fail $ "Execution blocked"
  43. Just v -> return v
  44. parseAlphabet :: A.Parser ByteString
  45. parseAlphabet = A.string "abcedefghijklmnopqrstuvwxyz"
  46. runParser :: A.Parser ByteString -> S.Streamline IO ByteString
  47. runParser p = fst <$> S.runAttoparsecAndReturn p