summaryrefslogtreecommitdiff
path: root/bittorrent/tests/Network/BitTorrent/Tracker/RPC
diff options
context:
space:
mode:
Diffstat (limited to 'bittorrent/tests/Network/BitTorrent/Tracker/RPC')
-rw-r--r--bittorrent/tests/Network/BitTorrent/Tracker/RPC/HTTPSpec.hs95
-rw-r--r--bittorrent/tests/Network/BitTorrent/Tracker/RPC/UDPSpec.hs144
2 files changed, 239 insertions, 0 deletions
diff --git a/bittorrent/tests/Network/BitTorrent/Tracker/RPC/HTTPSpec.hs b/bittorrent/tests/Network/BitTorrent/Tracker/RPC/HTTPSpec.hs
new file mode 100644
index 00000000..e928f917
--- /dev/null
+++ b/bittorrent/tests/Network/BitTorrent/Tracker/RPC/HTTPSpec.hs
@@ -0,0 +1,95 @@
1{-# LANGUAGE RecordWildCards #-}
2module Network.BitTorrent.Tracker.RPC.HTTPSpec (spec) where
3import Control.Monad
4import Data.Default
5import Data.List as L
6import Test.Hspec
7
8import Network.BitTorrent.Internal.Progress
9import Network.BitTorrent.Tracker.Message as Message
10import Network.BitTorrent.Tracker.RPC.HTTP
11
12import Network.BitTorrent.Tracker.TestData
13import Network.BitTorrent.Tracker.MessageSpec hiding (spec)
14
15
16validateInfo :: AnnounceQuery -> AnnounceInfo -> Expectation
17validateInfo _ (Message.Failure reason) = do
18 error $ "validateInfo: " ++ show reason
19validateInfo AnnounceQuery {..} AnnounceInfo {..} = do
20 return ()
21-- case respComplete <|> respIncomplete of
22-- Nothing -> return ()
23-- Just n -> n `shouldBe` L.length (getPeerList respPeers)
24
25isUnrecognizedScheme :: RpcException -> Bool
26isUnrecognizedScheme (RequestFailed _) = True
27isUnrecognizedScheme _ = False
28
29isNotResponding :: RpcException -> Bool
30isNotResponding (RequestFailed _) = True
31isNotResponding _ = False
32
33spec :: Spec
34spec = parallel $ do
35 describe "Manager" $ do
36 describe "newManager" $ do
37 it "" $ pending
38
39 describe "closeManager" $ do
40 it "" $ pending
41
42 describe "withManager" $ do
43 it "" $ pending
44
45 describe "RPC" $ do
46 describe "announce" $ do
47 it "must fail on bad uri scheme" $ do
48 withManager def $ \ mgr -> do
49 q <- arbitrarySample
50 announce mgr "magnet://foo.bar" q
51 `shouldThrow` isUnrecognizedScheme
52
53 describe "scrape" $ do
54 it "must fail on bad uri scheme" $ do
55 withManager def $ \ mgr -> do
56 scrape mgr "magnet://foo.bar" []
57 `shouldThrow` isUnrecognizedScheme
58
59 forM_ (L.filter isHttpTracker trackers) $ \ TrackerEntry {..} ->
60 context trackerName $ do
61
62 describe "announce" $ do
63 if tryAnnounce
64 then do
65 it "have valid response" $ do
66 withManager def $ \ mgr -> do
67-- q <- arbitrarySample
68 let ih = maybe def L.head hashList
69 let q = AnnounceQuery ih "-HS0003-203534.37420" 6000
70 (Progress 0 0 0) Nothing Nothing (Just Started)
71 info <- announce mgr trackerURI q
72 validateInfo q info
73 else do
74 it "should fail with RequestFailed" $ do
75 withManager def $ \ mgr -> do
76 q <- arbitrarySample
77 announce mgr trackerURI q
78 `shouldThrow` isNotResponding
79
80 describe "scrape" $ do
81 if tryScraping
82 then do
83 it "have valid response" $ do
84 withManager def $ \ mgr -> do
85 xs <- scrape mgr trackerURI [def]
86 L.length xs `shouldSatisfy` (>= 1)
87 else do
88 it "should fail with ScrapelessTracker" $ do
89 pending
90
91 when (not tryAnnounce) $ do
92 it "should fail with RequestFailed" $ do
93 withManager def $ \ mgr -> do
94 scrape mgr trackerURI [def]
95 `shouldThrow` isNotResponding
diff --git a/bittorrent/tests/Network/BitTorrent/Tracker/RPC/UDPSpec.hs b/bittorrent/tests/Network/BitTorrent/Tracker/RPC/UDPSpec.hs
new file mode 100644
index 00000000..73acb3fa
--- /dev/null
+++ b/bittorrent/tests/Network/BitTorrent/Tracker/RPC/UDPSpec.hs
@@ -0,0 +1,144 @@
1{-# LANGUAGE RecordWildCards #-}
2module Network.BitTorrent.Tracker.RPC.UDPSpec (spec, rpcOpts) where
3import Control.Concurrent
4import Control.Concurrent.Async
5import Control.Exception
6import Control.Monad
7import Data.Default
8import Data.List as L
9import Data.Maybe
10import Test.Hspec
11
12import Network.BitTorrent.Address
13import Network.BitTorrent.Tracker.Message as Message
14
15import Network.BitTorrent.Tracker.TestData
16import Network.BitTorrent.Tracker.MessageSpec hiding (spec)
17import Network.BitTorrent.Tracker.RPC.UDP
18
19
20validateInfo :: AnnounceQuery -> AnnounceInfo -> Expectation
21validateInfo _ Message.Failure {} = error "validateInfo: failure"
22validateInfo AnnounceQuery {..} AnnounceInfo {..} = do
23 respComplete `shouldSatisfy` isJust
24 respIncomplete `shouldSatisfy` isJust
25 respMinInterval `shouldSatisfy` isNothing
26 respWarning `shouldSatisfy` isNothing
27 peerList `shouldSatisfy` L.all (isNothing . peerId)
28 where
29 peerList = getPeerList respPeers
30
31-- | Number of concurrent calls.
32rpcCount :: Int
33rpcCount = 100
34
35rpcOpts :: Options
36rpcOpts = def
37 { optMinTimeout = 1
38 , optMaxTimeout = 10
39 }
40
41isTimeoutExpired :: RpcException -> Bool
42isTimeoutExpired (TimeoutExpired _) = True
43isTimeoutExpired _ = False
44
45isSomeException :: SomeException -> Bool
46isSomeException _ = True
47
48isIOException :: IOException -> Bool
49isIOException _ = True
50
51spec :: Spec
52spec = parallel $ do
53 describe "newManager" $ do
54 it "should throw exception on zero optMaxPacketSize" $ do
55 let opts = def { optMaxPacketSize = 0 }
56 newManager opts `shouldThrow` isSomeException
57
58 it "should throw exception on zero optMinTimout" $ do
59 let opts = def { optMinTimeout = 0 }
60 newManager opts `shouldThrow` isSomeException
61
62 it "should throw exception on zero optMaxTimeout" $ do
63 let opts = def { optMaxTimeout = 0 }
64 newManager opts `shouldThrow` isSomeException
65
66 it "should throw exception on maxTimeout < minTimeout" $ do
67 let opts = def { optMinTimeout = 2, optMaxTimeout = 1 }
68 newManager opts `shouldThrow` isSomeException
69
70 it "should throw exception on zero optMultiplier" $ do
71 let opts = def { optMultiplier = 0 }
72 newManager opts `shouldThrow` isSomeException
73
74 describe "closeManager" $ do
75 it "unblock rpc calls" $ do
76 mgr <- newManager rpcOpts
77 _ <- forkIO $ do
78 threadDelay 10000000
79 closeManager mgr
80 q <- arbitrarySample
81 announce mgr (trackerURI badTracker) q `shouldThrow` (== ManagerClosed)
82
83 it "announce throw exception after manager closed" $ do
84 mgr <- newManager rpcOpts
85 closeManager mgr
86 q <- arbitrarySample
87 announce mgr (trackerURI badTracker) q `shouldThrow` isIOException
88
89 it "scrape throw exception after manager closed" $ do
90 mgr <- newManager rpcOpts
91 closeManager mgr
92 scrape mgr (trackerURI badTracker) [def] `shouldThrow` isIOException
93
94 describe "withManager" $ do
95 it "closesManager at exit" $ do
96 mgr <- withManager rpcOpts return
97 scrape mgr (trackerURI badTracker) [def] `shouldThrow` isSomeException
98
99 describe "RPC" $ do
100 describe "announce" $ do
101 it "must fail on bad scheme" $ do
102 withManager rpcOpts $ \ mgr -> do
103 q <- arbitrarySample
104 announce mgr "magnet://a.com" q
105 `shouldThrow` (== UnrecognizedScheme "magnet:")
106
107 describe "scrape" $ do
108 it "must fail on bad scheme" $ do
109 withManager rpcOpts $ \ mgr -> do
110 scrape mgr "magnet://a.com" []
111 `shouldThrow` (== UnrecognizedScheme "magnet:")
112
113 forM_ (L.filter isUdpTracker trackers) $ \ TrackerEntry {..} ->
114 context trackerName $ do
115
116 describe "announce" $ do
117 if tryAnnounce then do
118 it "have valid response" $ do
119 withManager rpcOpts $ \ mgr -> do
120 q <- arbitrarySample
121 announce mgr trackerURI q >>= validateInfo q
122 else do
123 it "should throw TimeoutExpired" $ do
124 withManager rpcOpts $ \ mgr -> do
125 q <- arbitrarySample
126 announce mgr trackerURI q `shouldThrow` isTimeoutExpired
127
128 describe "scrape" $ do
129 if tryScraping then do
130 it "have valid response" $ do
131 withManager rpcOpts $ \ mgr -> do
132 xs <- scrape mgr trackerURI [def]
133 L.length xs `shouldSatisfy` (>= 1)
134 else do
135 it "should throw TimeoutExpired" $ do
136 withManager rpcOpts $ \ mgr -> do
137 scrape mgr trackerURI [def] `shouldThrow` isTimeoutExpired
138
139 describe "Manager" $ do
140 when tryScraping $ do
141 it "should handle arbitrary intermixed concurrent queries" $ do
142 withManager rpcOpts $ \ mgr -> do
143 _ <- mapConcurrently (\ _ -> scrape mgr trackerURI [def]) [1..rpcCount]
144 return ()