From 8d094413e88b57dc71f60fb48631fe43174dc696 Mon Sep 17 00:00:00 2001 From: Sam Truzjan Date: Wed, 26 Feb 2014 21:09:46 +0400 Subject: Check udp tracker manager options --- src/Network/BitTorrent/Tracker/RPC/UDP.hs | 16 ++++++++++++++++ tests/Network/BitTorrent/Tracker/RPC/UDPSpec.hs | 25 +++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/Network/BitTorrent/Tracker/RPC/UDP.hs b/src/Network/BitTorrent/Tracker/RPC/UDP.hs index b0f44ec6..a2099ef0 100644 --- a/src/Network/BitTorrent/Tracker/RPC/UDP.hs +++ b/src/Network/BitTorrent/Tracker/RPC/UDP.hs @@ -118,6 +118,20 @@ instance Default Options where , optMultiplier = defMultiplier } +checkOptions :: Options -> IO () +checkOptions Options {..} = do + unless (optMaxPacketSize > 0) $ do + throwIO $ userError "optMaxPacketSize must be positive" + + unless (optMinTimeout > 0) $ do + throwIO $ userError "optMinTimeout must be positive" + + unless (optMaxTimeout > 0) $ do + throwIO $ userError "optMaxTimeout must be greater than optMinTimeout" + + unless (optMinTimeout > 0) $ do + throwIO $ userError "optMinTimeout must be positive" + {----------------------------------------------------------------------- -- Manager state -----------------------------------------------------------------------} @@ -162,8 +176,10 @@ resetState Manager {..} = do where err = error "UDP tracker manager closed" +-- | This function will throw 'IOException' if or newManager :: Options -> IO Manager newManager opts = do + checkOptions opts mgr <- initManager opts tid <- forkIO (listen mgr `finally` resetState mgr) putMVar (listenerThread mgr) tid diff --git a/tests/Network/BitTorrent/Tracker/RPC/UDPSpec.hs b/tests/Network/BitTorrent/Tracker/RPC/UDPSpec.hs index acc60e09..bfe0c92f 100644 --- a/tests/Network/BitTorrent/Tracker/RPC/UDPSpec.hs +++ b/tests/Network/BitTorrent/Tracker/RPC/UDPSpec.hs @@ -1,6 +1,7 @@ {-# LANGUAGE RecordWildCards #-} module Network.BitTorrent.Tracker.RPC.UDPSpec (spec, rpcOpts) where import Control.Concurrent.Async +import Control.Exception import Control.Monad import Data.Default import Data.List as L @@ -40,8 +41,32 @@ isTimeoutExpired :: RpcException -> Bool isTimeoutExpired (TimeoutExpired _) = True isTimeoutExpired _ = False +isSomeException :: SomeException -> Bool +isSomeException _ = True + spec :: Spec spec = parallel $ do + describe "newManager" $ do + it "should throw exception on zero optMaxPacketSize" $ do + let opts = def { optMaxPacketSize = 0 } + newManager opts `shouldThrow` isSomeException + + it "should throw exception on zero optMinTimout" $ do + let opts = def { optMinTimeout = 0 } + newManager opts `shouldThrow` isSomeException + + it "should throw exception on zero optMaxTimeout" $ do + let opts = def { optMaxTimeout = 0 } + newManager opts `shouldThrow` isSomeException + + it "should throw exception on maxTimeout < minTimeout" $ do + let opts = def { optMinTimeout = 2, optMaxTimeout = 1 } + newManager opts `shouldThrow` isSomeException + + it "should throw exception on optMultiplier" $ do + let opts = def { optMultiplier = 0 } + newManager opts `shouldThrow` isSomeException + forM_ (L.filter isUdpTracker trackers) $ \ TrackerEntry {..} -> context trackerName $ do -- cgit v1.2.3