module Std.IO.LowResTimerSpec where import Control.Concurrent import Control.Monad import Control.Monad.IO.Class import Std.Data.PrimIORef import Std.IO.LowResTimer import Test.Hspec import Test.HUnit spec :: Spec spec = describe "low resolution timers" $ do it "timers registration should not be missed" $ do c <- newCounter 0 replicateM_ 10000 $ do forM_ [1..10] $ \ i -> do registerLowResTimer i (atomicAddCounter_ c 1) threadDelay 1000 lrtm <- getLowResTimerManager running <- isLowResTimerManagerRunning lrtm assertEqual "timer manager should start" True running threadDelay 1200000 -- make sure all timers are fired c' <- readPrimIORef c assertEqual "timers registration counter" 100000 c' threadDelay 100000 -- another 0.1s lrtm <- getLowResTimerManager running <- isLowResTimerManagerRunning lrtm assertEqual "timer manager should stopped" False running it "throttle" $ do c <- newCounter 0 throttledAdd <- throttle 10 (atomicAddCounter_ c 1) forkIO . replicateM_ 100 $ do throttledAdd threadDelay 50000 threadDelay 10000000 -- wait 10s here c' <- readPrimIORef c assertBool "throttled add" (6 <= c' && c' <= 7) it "throttleTrailing" $ do c <- newCounter 0 throttledAdd <- throttleTrailing_ 10 (atomicAddCounter_ c 1) forkIO . replicateM_ 100 $ do throttledAdd threadDelay 50000 threadDelay 10000000 -- wait 10s here c' <- readPrimIORef c assertBool "throttled add" (5 <= c' && c' <= 6)