summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bittorrent.cabal4
-rw-r--r--tests/Network/BitTorrent/Core/FingerprintSpec.hs33
-rw-r--r--tests/Network/BitTorrent/Core/NodeInfoSpec.hs52
-rw-r--r--tests/Network/BitTorrent/Core/PeerAddrSpec.hs221
-rw-r--r--tests/Network/BitTorrent/Core/PeerIdSpec.hs25
-rw-r--r--tests/Network/BitTorrent/CoreSpec.hs308
6 files changed, 301 insertions, 342 deletions
diff --git a/bittorrent.cabal b/bittorrent.cabal
index 761ed1c4..6df074bb 100644
--- a/bittorrent.cabal
+++ b/bittorrent.cabal
@@ -177,10 +177,6 @@ test-suite spec
177 Data.Torrent.ProgressSpec 177 Data.Torrent.ProgressSpec
178 Network.BitTorrent.Client.HandleSpec 178 Network.BitTorrent.Client.HandleSpec
179 Network.BitTorrent.CoreSpec 179 Network.BitTorrent.CoreSpec
180 Network.BitTorrent.Core.FingerprintSpec
181 Network.BitTorrent.Core.NodeInfoSpec
182 Network.BitTorrent.Core.PeerAddrSpec
183 Network.BitTorrent.Core.PeerIdSpec
184 Network.BitTorrent.DHTSpec 180 Network.BitTorrent.DHTSpec
185 Network.BitTorrent.DHT.TestData 181 Network.BitTorrent.DHT.TestData
186 Network.BitTorrent.DHT.MessageSpec 182 Network.BitTorrent.DHT.MessageSpec
diff --git a/tests/Network/BitTorrent/Core/FingerprintSpec.hs b/tests/Network/BitTorrent/Core/FingerprintSpec.hs
deleted file mode 100644
index f8ed6950..00000000
--- a/tests/Network/BitTorrent/Core/FingerprintSpec.hs
+++ /dev/null
@@ -1,33 +0,0 @@
1-- | see <http://bittorrent.org/beps/bep_0020.html>
2module Network.BitTorrent.Core.FingerprintSpec (spec) where
3import Test.Hspec
4import Network.BitTorrent.Address
5
6spec :: Spec
7spec = do
8 describe "client info" $ do
9 it "decode mainline encoded peer id" $ do
10 fingerprint "M4-3-6--xxxxxxxxxxxx" `shouldBe` "Mainline-4.3.6"
11 fingerprint "M4-20-8-xxxxxxxxxxxx" `shouldBe` "Mainline-4.20.8"
12
13 it "decode azureus encoded peer id" $ do
14 fingerprint "-AZ2060-xxxxxxxxxxxx" `shouldBe` "Azureus-2060"
15 fingerprint "-BS0000-xxxxxxxxxxxx" `shouldBe` "BTSlave-0"
16
17 it "decode Shad0w style peer id" $ do
18 fingerprint "S58B-----xxxxxxxxxxx" `shouldBe` "Shadow-5.8.11"
19 fingerprint "T58B-----xxxxxxxxxxx" `shouldBe` "BitTornado-5.8.11"
20
21 it "decode bitcomet style peer id" $ do
22 fingerprint "exbc01xxxxxxxxxxxxxx" `shouldBe` "BitComet-48.49"
23 fingerprint "FUTB01xxxxxxxxxxxxxx" `shouldBe` "BitComet-48.49"
24 fingerprint "exbc01LORDxxxxxxxxxx" `shouldBe` "BitLord-48.49"
25
26 it "decode opera style peer id" $ do
27 fingerprint "OP0123xxxxxxxxxxxxxx" `shouldBe` "Opera-123"
28
29 it "decode ML donkey style peer id" $ do
30 fingerprint "-ML2.7.2-xxxxxxxxxxx" `shouldBe` "MLdonkey-0"
31
32-- TODO XBT, Bits on Wheels, Queen Bee, BitTyrant, TorrenTopia,
33-- BitSpirit, Rufus, G3 Torrent, FlashGet \ No newline at end of file
diff --git a/tests/Network/BitTorrent/Core/NodeInfoSpec.hs b/tests/Network/BitTorrent/Core/NodeInfoSpec.hs
deleted file mode 100644
index 0d30b9a6..00000000
--- a/tests/Network/BitTorrent/Core/NodeInfoSpec.hs
+++ /dev/null
@@ -1,52 +0,0 @@
1{-# OPTIONS -fno-warn-orphans #-}
2module Network.BitTorrent.Core.NodeInfoSpec (spec) where
3import Control.Applicative
4import Data.Serialize as S
5import Data.String
6import Test.Hspec
7import Test.QuickCheck
8
9import Network.BitTorrent.Address
10import Network.BitTorrent.Core.PeerAddrSpec ()
11
12instance Arbitrary NodeId where
13 arbitrary = fromString <$> vector 20
14
15instance Arbitrary a => Arbitrary (NodeAddr a) where
16 arbitrary = NodeAddr <$> arbitrary <*> arbitrary
17
18instance Arbitrary a => Arbitrary (NodeInfo a) where
19 arbitrary = NodeInfo <$> arbitrary <*> arbitrary
20
21spec :: Spec
22spec = do
23 describe "NodeId" $ do
24 it "properly serialized" $ do
25 S.decode "mnopqrstuvwxyz123456"
26 `shouldBe` Right ("mnopqrstuvwxyz123456" :: NodeId)
27
28 S.encode ("mnopqrstuvwxyz123456" :: NodeId)
29 `shouldBe` "mnopqrstuvwxyz123456"
30
31 it "properly serialized (iso)" $ property $ \ nid ->
32 S.decode (S.encode nid) `shouldBe`
33 Right (nid :: NodeId)
34
35 describe "NodeAddr" $ do
36 it "properly serialized" $ do
37 S.decode "\127\0\0\1\1\2" `shouldBe`
38 Right ("127.0.0.1:258" :: NodeAddr IPv4)
39
40 it "properly serialized (iso)" $ property $ \ nid ->
41 S.decode (S.encode nid) `shouldBe`
42 Right (nid :: NodeAddr IPv4)
43
44 describe "NodeInfo" $ do
45 it "properly serialized" $ do
46 S.decode "mnopqrstuvwxyz123456\
47 \\127\0\0\1\1\2" `shouldBe` Right
48 (NodeInfo "mnopqrstuvwxyz123456" "127.0.0.1:258" :: NodeInfo IPv4)
49
50 it "properly serialized (iso)" $ property $ \ nid ->
51 S.decode (S.encode nid) `shouldBe`
52 Right (nid :: NodeInfo IPv4)
diff --git a/tests/Network/BitTorrent/Core/PeerAddrSpec.hs b/tests/Network/BitTorrent/Core/PeerAddrSpec.hs
deleted file mode 100644
index 387126db..00000000
--- a/tests/Network/BitTorrent/Core/PeerAddrSpec.hs
+++ /dev/null
@@ -1,221 +0,0 @@
1{-# LANGUAGE FlexibleInstances #-}
2{-# OPTIONS_GHC -fno-warn-orphans #-}
3module Network.BitTorrent.Core.PeerAddrSpec (spec) where
4import Control.Applicative
5import Data.BEncode as BE
6import Data.ByteString.Lazy as BL
7import Data.IP
8import Data.Serialize as S
9import Data.Word
10import Network
11import Test.Hspec
12import Test.QuickCheck
13
14import Network.BitTorrent.Core.PeerIdSpec ()
15import Network.BitTorrent.Address
16
17instance Arbitrary IPv4 where
18 arbitrary = do
19 a <- choose (0, 255)
20 b <- choose (0, 255)
21 c <- choose (0, 255)
22 d <- choose (0, 255)
23 return $ toIPv4 [a, b, c, d]
24
25instance Arbitrary IPv6 where
26 arbitrary = do
27 a <- choose (0, fromIntegral (maxBound :: Word16))
28 b <- choose (0, fromIntegral (maxBound :: Word16))
29 c <- choose (0, fromIntegral (maxBound :: Word16))
30 d <- choose (0, fromIntegral (maxBound :: Word16))
31 e <- choose (0, fromIntegral (maxBound :: Word16))
32 f <- choose (0, fromIntegral (maxBound :: Word16))
33 g <- choose (0, fromIntegral (maxBound :: Word16))
34 h <- choose (0, fromIntegral (maxBound :: Word16))
35 return $ toIPv6 [a, b, c, d, e, f, g, h]
36
37instance Arbitrary IP where
38 arbitrary = frequency
39 [ (1, IPv4 <$> arbitrary)
40 , (1, IPv6 <$> arbitrary)
41 ]
42
43instance Arbitrary PortNumber where
44 arbitrary = fromIntegral <$> (arbitrary :: Gen Word16)
45
46instance Arbitrary a => Arbitrary (PeerAddr a) where
47 arbitrary = PeerAddr <$> arbitrary <*> arbitrary <*> arbitrary
48
49spec :: Spec
50spec = do
51 describe "PortNumber" $ do
52 it "properly serialized" $ do
53 S.decode "\x1\x2" `shouldBe` Right (258 :: PortNumber)
54 S.encode (258 :: PortNumber) `shouldBe` "\x1\x2"
55
56 it "properly bencoded" $ do
57 BE.decode "i80e" `shouldBe` Right (80 :: PortNumber)
58
59 it "fail if port number is invalid" $ do
60 (BE.decode "i-10e" :: BE.Result PortNumber)
61 `shouldBe`
62 Left "fromBEncode: unable to decode PortNumber: -10"
63
64 (BE.decode "i70000e" :: BE.Result PortNumber)
65 `shouldBe`
66 Left "fromBEncode: unable to decode PortNumber: 70000"
67
68 describe "Peer IPv4" $ do
69 it "properly serialized" $ do
70 S.decode "\x1\x2\x3\x4" `shouldBe` Right (toIPv4 [1, 2, 3, 4])
71 S.encode (toIPv4 [1, 2, 3, 4]) `shouldBe` "\x1\x2\x3\x4"
72
73 it "properly serialized (iso)" $ property $ \ ip -> do
74 S.decode (S.encode ip) `shouldBe` Right (ip :: IPv4)
75
76 it "properly bencoded" $ do
77 BE.decode "11:168.192.0.1" `shouldBe` Right (toIPv4 [168, 192, 0, 1])
78 BE.encode (toIPv4 [168, 192, 0, 1]) `shouldBe` "11:168.192.0.1"
79
80 it "properly bencoded (iso)" $ property $ \ ip ->
81 BE.decode (BL.toStrict (BE.encode ip)) `shouldBe` Right (ip :: IPv4)
82
83 it "fail gracefully on invalid strings" $ do
84 BE.decode "3:1.1" `shouldBe`
85 (Left "fromBEncode: unable to decode IP: 1.1" :: BE.Result IPv4)
86
87 it "fail gracefully on invalid bencode" $ do
88 BE.decode "i10e" `shouldBe`
89 (Left "fromBEncode: unable to decode IP: addr should be a bstring"
90 :: BE.Result IPv4)
91
92 describe "Peer IPv6" $ do
93 it "properly serialized" $ do
94 S.decode "\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf\x10"
95 `shouldBe`
96 Right ("102:304:506:708:90a:b0c:d0e:f10" :: IPv6)
97
98 S.encode ("102:304:506:708:90a:b0c:d0e:f10" :: IPv6)
99 `shouldBe`
100 "\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf\x10"
101
102 it "properly serialized (iso)" $ property $ \ ip ->
103 S.decode (S.encode ip) `shouldBe` Right (ip :: IPv6)
104
105 it "properly bencoded" $ do
106 BE.decode "3:::1" `shouldBe` Right (toIPv6 [0, 0, 0, 0, 0, 0, 0, 1])
107 BE.encode (toIPv6 [0, 0, 0, 0, 0, 0, 0, 1]) `shouldBe`
108 "23:00:00:00:00:00:00:00:01"
109
110 BE.decode "23:00:00:00:00:00:00:00:01"
111 `shouldBe`
112 Right (toIPv6 [0, 0, 0, 0, 0, 0, 0, 1])
113
114 it "properly bencoded iso" $ property $ \ ip ->
115 BE.decode (BL.toStrict (BE.encode ip)) `shouldBe` Right (ip :: IPv4)
116
117 it "fail gracefully on invalid strings" $ do
118 BE.decode "4:g::1" `shouldBe`
119 (Left "fromBEncode: unable to decode IP: g::1" :: BE.Result IPv6)
120
121 it "fail gracefully on invalid bencode" $ do
122 BE.decode "i10e" `shouldBe`
123 (Left "fromBEncode: unable to decode IP: addr should be a bstring"
124 :: BE.Result IPv6)
125
126
127 describe "Peer IP" $ do
128 it "properly serialized IPv6" $ do
129 S.decode "\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf\x10"
130 `shouldBe`
131 Right ("102:304:506:708:90a:b0c:d0e:f10" :: IP)
132
133 S.encode ("102:304:506:708:90a:b0c:d0e:f10" :: IP)
134 `shouldBe`
135 "\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf\x10"
136
137 it "properly serialized (iso) IPv6" $ property $ \ ip ->
138 S.decode (S.encode ip) `shouldBe` Right (ip :: IP)
139
140 it "properly serialized IPv4" $ do
141 S.decode "\x1\x2\x3\x4" `shouldBe` Right (IPv4 $ toIPv4 [1, 2, 3, 4])
142 S.encode (toIPv4 [1, 2, 3, 4]) `shouldBe` "\x1\x2\x3\x4"
143
144 it "properly serialized (iso) IPv4" $ property $ \ ip -> do
145 S.decode (S.encode ip) `shouldBe` Right (ip :: IP)
146
147 it "properly bencoded" $ do
148 BE.decode "11:168.192.0.1" `shouldBe`
149 Right (IPv4 (toIPv4 [168, 192, 0, 1]))
150
151 BE.decode "3:::1" `shouldBe` Right
152 (IPv6 (toIPv6 [0, 0, 0, 0, 0, 0, 0, 1]))
153
154 BE.encode (IPv6 (toIPv6 [0, 0, 0, 0, 0, 0, 0, 1])) `shouldBe`
155 "23:00:00:00:00:00:00:00:01"
156
157 BE.decode "23:00:00:00:00:00:00:00:01"
158 `shouldBe`
159 Right (IPv6 (toIPv6 [0, 0, 0, 0, 0, 0, 0, 1]))
160
161 it "properly bencoded iso" $ property $ \ ip ->
162 BE.decode (BL.toStrict (BE.encode ip)) `shouldBe` Right (ip :: IP)
163
164 it "fail gracefully on invalid strings" $ do
165 BE.decode "4:g::1" `shouldBe`
166 (Left "fromBEncode: unable to decode IP: g::1" :: BE.Result IP)
167
168 it "fail gracefully on invalid bencode" $ do
169 BE.decode "i10e" `shouldBe`
170 (Left "fromBEncode: unable to decode IP: addr should be a bstring"
171 :: BE.Result IP)
172
173 describe "PeerAddr" $ do
174 it "IsString" $ do
175 ("127.0.0.1:80" :: PeerAddr IP)
176 `shouldBe` PeerAddr Nothing "127.0.0.1" 80
177
178 ("127.0.0.1:80" :: PeerAddr IPv4)
179 `shouldBe` PeerAddr Nothing "127.0.0.1" 80
180
181 ("[::1]:80" :: PeerAddr IP)
182 `shouldBe` PeerAddr Nothing "::1" 80
183
184 ("[::1]:80" :: PeerAddr IPv6)
185 `shouldBe` PeerAddr Nothing "::1" 80
186
187 it "properly bencoded (iso)" $ property $ \ addr ->
188 BE.decode (BL.toStrict (BE.encode addr))
189 `shouldBe` Right (addr :: PeerAddr IP)
190
191
192 it "properly bencoded (ipv4)" $ do
193 BE.decode "d2:ip11:168.192.0.1\
194 \7:peer id20:01234567890123456789\
195 \4:porti6881e\
196 \e"
197 `shouldBe`
198 Right (PeerAddr (Just "01234567890123456789")
199 (IPv4 (toIPv4 [168, 192, 0, 1]))
200 6881)
201
202 it "properly bencoded (ipv6)" $ do
203 BE.decode "d2:ip3:::1\
204 \7:peer id20:01234567890123456789\
205 \4:porti6881e\
206 \e"
207 `shouldBe`
208 Right (PeerAddr (Just "01234567890123456789")
209 (IPv6 (toIPv6 [0, 0, 0, 0, 0, 0, 0, 1]))
210 6881)
211
212 it "peer id is optional" $ do
213 BE.decode "d2:ip11:168.192.0.1\
214 \4:porti6881e\
215 \e"
216 `shouldBe`
217 Right (PeerAddr Nothing (IPv4 (toIPv4 [168, 192, 0, 1])) 6881)
218
219 it "has sock addr for both ipv4 and ipv6" $ do
220 show (peerSockAddr "128.0.0.1:80") `shouldBe` "128.0.0.1:80"
221 show (peerSockAddr "[::1]:8080" ) `shouldBe` "[::1]:8080"
diff --git a/tests/Network/BitTorrent/Core/PeerIdSpec.hs b/tests/Network/BitTorrent/Core/PeerIdSpec.hs
deleted file mode 100644
index 29b98bbc..00000000
--- a/tests/Network/BitTorrent/Core/PeerIdSpec.hs
+++ /dev/null
@@ -1,25 +0,0 @@
1{-# OPTIONS -fno-warn-orphans #-}
2module Network.BitTorrent.Core.PeerIdSpec (spec) where
3import Control.Applicative
4import Data.BEncode as BE
5import Data.Text.Encoding as T
6import Test.Hspec
7import Test.QuickCheck
8import Test.QuickCheck.Instances ()
9import Network.BitTorrent.Address
10
11
12instance Arbitrary PeerId where
13 arbitrary = oneof
14 [ azureusStyle defaultClientId defaultVersionNumber
15 <$> (T.encodeUtf8 <$> arbitrary)
16 , shadowStyle 'X' defaultVersionNumber
17 <$> (T.encodeUtf8 <$> arbitrary)
18 ]
19
20spec :: Spec
21spec = do
22 describe "PeerId" $ do
23 it "properly bencoded" $ do
24 BE.decode "20:01234567890123456789"
25 `shouldBe` Right ("01234567890123456789" :: PeerId) \ No newline at end of file
diff --git a/tests/Network/BitTorrent/CoreSpec.hs b/tests/Network/BitTorrent/CoreSpec.hs
index 1e1a21a1..5bf900b2 100644
--- a/tests/Network/BitTorrent/CoreSpec.hs
+++ b/tests/Network/BitTorrent/CoreSpec.hs
@@ -1,11 +1,305 @@
1-- | Re-export modules. 1{-# LANGUAGE FlexibleInstances #-}
2{-# OPTIONS_GHC -fno-warn-orphans #-}
2module Network.BitTorrent.CoreSpec (spec) where 3module Network.BitTorrent.CoreSpec (spec) where
3import Network.BitTorrent.Core.FingerprintSpec as CoreSpec () 4import Control.Applicative
4import Network.BitTorrent.Core.PeerAddrSpec as CoreSpec () 5import Data.BEncode as BE
5import Network.BitTorrent.Core.NodeInfoSpec as CoreSpec () 6import Data.ByteString.Lazy as BL
6import Network.BitTorrent.Core.PeerIdSpec as CoreSpec () 7import Data.IP
8import Data.Serialize as S
9import Data.String
10import Data.Text.Encoding as T
11import Data.Word
12import Network
13import Test.Hspec
14import Test.QuickCheck
15import Test.QuickCheck.Instances ()
7 16
8import Test.Hspec (Spec) 17import Network.BitTorrent.Address
18
19
20instance Arbitrary IPv4 where
21 arbitrary = do
22 a <- choose (0, 255)
23 b <- choose (0, 255)
24 c <- choose (0, 255)
25 d <- choose (0, 255)
26 return $ toIPv4 [a, b, c, d]
27
28instance Arbitrary IPv6 where
29 arbitrary = do
30 a <- choose (0, fromIntegral (maxBound :: Word16))
31 b <- choose (0, fromIntegral (maxBound :: Word16))
32 c <- choose (0, fromIntegral (maxBound :: Word16))
33 d <- choose (0, fromIntegral (maxBound :: Word16))
34 e <- choose (0, fromIntegral (maxBound :: Word16))
35 f <- choose (0, fromIntegral (maxBound :: Word16))
36 g <- choose (0, fromIntegral (maxBound :: Word16))
37 h <- choose (0, fromIntegral (maxBound :: Word16))
38 return $ toIPv6 [a, b, c, d, e, f, g, h]
39
40instance Arbitrary IP where
41 arbitrary = frequency
42 [ (1, IPv4 <$> arbitrary)
43 , (1, IPv6 <$> arbitrary)
44 ]
45
46instance Arbitrary PortNumber where
47 arbitrary = fromIntegral <$> (arbitrary :: Gen Word16)
48
49instance Arbitrary PeerId where
50 arbitrary = oneof
51 [ azureusStyle defaultClientId defaultVersionNumber
52 <$> (T.encodeUtf8 <$> arbitrary)
53 , shadowStyle 'X' defaultVersionNumber
54 <$> (T.encodeUtf8 <$> arbitrary)
55 ]
56
57instance Arbitrary a => Arbitrary (PeerAddr a) where
58 arbitrary = PeerAddr <$> arbitrary <*> arbitrary <*> arbitrary
59
60instance Arbitrary NodeId where
61 arbitrary = fromString <$> vector 20
62
63instance Arbitrary a => Arbitrary (NodeAddr a) where
64 arbitrary = NodeAddr <$> arbitrary <*> arbitrary
65
66instance Arbitrary a => Arbitrary (NodeInfo a) where
67 arbitrary = NodeInfo <$> arbitrary <*> arbitrary
9 68
10spec :: Spec 69spec :: Spec
11spec = return () \ No newline at end of file 70spec = do
71 describe "PeerId" $ do
72 it "properly bencoded" $ do
73 BE.decode "20:01234567890123456789"
74 `shouldBe` Right ("01234567890123456789" :: PeerId)
75
76 describe "PortNumber" $ do
77 it "properly serialized" $ do
78 S.decode "\x1\x2" `shouldBe` Right (258 :: PortNumber)
79 S.encode (258 :: PortNumber) `shouldBe` "\x1\x2"
80
81 it "properly bencoded" $ do
82 BE.decode "i80e" `shouldBe` Right (80 :: PortNumber)
83
84 it "fail if port number is invalid" $ do
85 (BE.decode "i-10e" :: BE.Result PortNumber)
86 `shouldBe`
87 Left "fromBEncode: unable to decode PortNumber: -10"
88
89 (BE.decode "i70000e" :: BE.Result PortNumber)
90 `shouldBe`
91 Left "fromBEncode: unable to decode PortNumber: 70000"
92
93 describe "Peer IPv4" $ do
94 it "properly serialized" $ do
95 S.decode "\x1\x2\x3\x4" `shouldBe` Right (toIPv4 [1, 2, 3, 4])
96 S.encode (toIPv4 [1, 2, 3, 4]) `shouldBe` "\x1\x2\x3\x4"
97
98 it "properly serialized (iso)" $ property $ \ ip -> do
99 S.decode (S.encode ip) `shouldBe` Right (ip :: IPv4)
100
101 it "properly bencoded" $ do
102 BE.decode "11:168.192.0.1" `shouldBe` Right (toIPv4 [168, 192, 0, 1])
103 BE.encode (toIPv4 [168, 192, 0, 1]) `shouldBe` "11:168.192.0.1"
104
105 it "properly bencoded (iso)" $ property $ \ ip ->
106 BE.decode (BL.toStrict (BE.encode ip)) `shouldBe` Right (ip :: IPv4)
107
108 it "fail gracefully on invalid strings" $ do
109 BE.decode "3:1.1" `shouldBe`
110 (Left "fromBEncode: unable to decode IP: 1.1" :: BE.Result IPv4)
111
112 it "fail gracefully on invalid bencode" $ do
113 BE.decode "i10e" `shouldBe`
114 (Left "fromBEncode: unable to decode IP: addr should be a bstring"
115 :: BE.Result IPv4)
116
117 describe "Peer IPv6" $ do
118 it "properly serialized" $ do
119 S.decode "\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf\x10"
120 `shouldBe`
121 Right ("102:304:506:708:90a:b0c:d0e:f10" :: IPv6)
122
123 S.encode ("102:304:506:708:90a:b0c:d0e:f10" :: IPv6)
124 `shouldBe`
125 "\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf\x10"
126
127 it "properly serialized (iso)" $ property $ \ ip ->
128 S.decode (S.encode ip) `shouldBe` Right (ip :: IPv6)
129
130 it "properly bencoded" $ do
131 BE.decode "3:::1" `shouldBe` Right (toIPv6 [0, 0, 0, 0, 0, 0, 0, 1])
132 BE.encode (toIPv6 [0, 0, 0, 0, 0, 0, 0, 1]) `shouldBe`
133 "23:00:00:00:00:00:00:00:01"
134
135 BE.decode "23:00:00:00:00:00:00:00:01"
136 `shouldBe`
137 Right (toIPv6 [0, 0, 0, 0, 0, 0, 0, 1])
138
139 it "properly bencoded iso" $ property $ \ ip ->
140 BE.decode (BL.toStrict (BE.encode ip)) `shouldBe` Right (ip :: IPv4)
141
142 it "fail gracefully on invalid strings" $ do
143 BE.decode "4:g::1" `shouldBe`
144 (Left "fromBEncode: unable to decode IP: g::1" :: BE.Result IPv6)
145
146 it "fail gracefully on invalid bencode" $ do
147 BE.decode "i10e" `shouldBe`
148 (Left "fromBEncode: unable to decode IP: addr should be a bstring"
149 :: BE.Result IPv6)
150
151
152 describe "Peer IP" $ do
153 it "properly serialized IPv6" $ do
154 S.decode "\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf\x10"
155 `shouldBe`
156 Right ("102:304:506:708:90a:b0c:d0e:f10" :: IP)
157
158 S.encode ("102:304:506:708:90a:b0c:d0e:f10" :: IP)
159 `shouldBe`
160 "\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf\x10"
161
162 it "properly serialized (iso) IPv6" $ property $ \ ip ->
163 S.decode (S.encode ip) `shouldBe` Right (ip :: IP)
164
165 it "properly serialized IPv4" $ do
166 S.decode "\x1\x2\x3\x4" `shouldBe` Right (IPv4 $ toIPv4 [1, 2, 3, 4])
167 S.encode (toIPv4 [1, 2, 3, 4]) `shouldBe` "\x1\x2\x3\x4"
168
169 it "properly serialized (iso) IPv4" $ property $ \ ip -> do
170 S.decode (S.encode ip) `shouldBe` Right (ip :: IP)
171
172 it "properly bencoded" $ do
173 BE.decode "11:168.192.0.1" `shouldBe`
174 Right (IPv4 (toIPv4 [168, 192, 0, 1]))
175
176 BE.decode "3:::1" `shouldBe` Right
177 (IPv6 (toIPv6 [0, 0, 0, 0, 0, 0, 0, 1]))
178
179 BE.encode (IPv6 (toIPv6 [0, 0, 0, 0, 0, 0, 0, 1])) `shouldBe`
180 "23:00:00:00:00:00:00:00:01"
181
182 BE.decode "23:00:00:00:00:00:00:00:01"
183 `shouldBe`
184 Right (IPv6 (toIPv6 [0, 0, 0, 0, 0, 0, 0, 1]))
185
186 it "properly bencoded iso" $ property $ \ ip ->
187 BE.decode (BL.toStrict (BE.encode ip)) `shouldBe` Right (ip :: IP)
188
189 it "fail gracefully on invalid strings" $ do
190 BE.decode "4:g::1" `shouldBe`
191 (Left "fromBEncode: unable to decode IP: g::1" :: BE.Result IP)
192
193 it "fail gracefully on invalid bencode" $ do
194 BE.decode "i10e" `shouldBe`
195 (Left "fromBEncode: unable to decode IP: addr should be a bstring"
196 :: BE.Result IP)
197
198 describe "PeerAddr" $ do
199 it "IsString" $ do
200 ("127.0.0.1:80" :: PeerAddr IP)
201 `shouldBe` PeerAddr Nothing "127.0.0.1" 80
202
203 ("127.0.0.1:80" :: PeerAddr IPv4)
204 `shouldBe` PeerAddr Nothing "127.0.0.1" 80
205
206 ("[::1]:80" :: PeerAddr IP)
207 `shouldBe` PeerAddr Nothing "::1" 80
208
209 ("[::1]:80" :: PeerAddr IPv6)
210 `shouldBe` PeerAddr Nothing "::1" 80
211
212 it "properly bencoded (iso)" $ property $ \ addr ->
213 BE.decode (BL.toStrict (BE.encode addr))
214 `shouldBe` Right (addr :: PeerAddr IP)
215
216
217 it "properly bencoded (ipv4)" $ do
218 BE.decode "d2:ip11:168.192.0.1\
219 \7:peer id20:01234567890123456789\
220 \4:porti6881e\
221 \e"
222 `shouldBe`
223 Right (PeerAddr (Just "01234567890123456789")
224 (IPv4 (toIPv4 [168, 192, 0, 1]))
225 6881)
226
227 it "properly bencoded (ipv6)" $ do
228 BE.decode "d2:ip3:::1\
229 \7:peer id20:01234567890123456789\
230 \4:porti6881e\
231 \e"
232 `shouldBe`
233 Right (PeerAddr (Just "01234567890123456789")
234 (IPv6 (toIPv6 [0, 0, 0, 0, 0, 0, 0, 1]))
235 6881)
236
237 it "peer id is optional" $ do
238 BE.decode "d2:ip11:168.192.0.1\
239 \4:porti6881e\
240 \e"
241 `shouldBe`
242 Right (PeerAddr Nothing (IPv4 (toIPv4 [168, 192, 0, 1])) 6881)
243
244 it "has sock addr for both ipv4 and ipv6" $ do
245 show (peerSockAddr "128.0.0.1:80") `shouldBe` "128.0.0.1:80"
246 show (peerSockAddr "[::1]:8080" ) `shouldBe` "[::1]:8080"
247
248 describe "NodeId" $ do
249 it "properly serialized" $ do
250 S.decode "mnopqrstuvwxyz123456"
251 `shouldBe` Right ("mnopqrstuvwxyz123456" :: NodeId)
252
253 S.encode ("mnopqrstuvwxyz123456" :: NodeId)
254 `shouldBe` "mnopqrstuvwxyz123456"
255
256 it "properly serialized (iso)" $ property $ \ nid ->
257 S.decode (S.encode nid) `shouldBe`
258 Right (nid :: NodeId)
259
260 describe "NodeAddr" $ do
261 it "properly serialized" $ do
262 S.decode "\127\0\0\1\1\2" `shouldBe`
263 Right ("127.0.0.1:258" :: NodeAddr IPv4)
264
265 it "properly serialized (iso)" $ property $ \ nid ->
266 S.decode (S.encode nid) `shouldBe`
267 Right (nid :: NodeAddr IPv4)
268
269 describe "NodeInfo" $ do
270 it "properly serialized" $ do
271 S.decode "mnopqrstuvwxyz123456\
272 \\127\0\0\1\1\2" `shouldBe` Right
273 (NodeInfo "mnopqrstuvwxyz123456" "127.0.0.1:258" :: NodeInfo IPv4)
274
275 it "properly serialized (iso)" $ property $ \ nid ->
276 S.decode (S.encode nid) `shouldBe`
277 Right (nid :: NodeInfo IPv4)
278
279 -- see <http://bittorrent.org/beps/bep_0020.html>
280 describe "Fingerprint" $ do
281 it "decode mainline encoded peer id" $ do
282 fingerprint "M4-3-6--xxxxxxxxxxxx" `shouldBe` "Mainline-4.3.6"
283 fingerprint "M4-20-8-xxxxxxxxxxxx" `shouldBe` "Mainline-4.20.8"
284
285 it "decode azureus encoded peer id" $ do
286 fingerprint "-AZ2060-xxxxxxxxxxxx" `shouldBe` "Azureus-2060"
287 fingerprint "-BS0000-xxxxxxxxxxxx" `shouldBe` "BTSlave-0"
288
289 it "decode Shad0w style peer id" $ do
290 fingerprint "S58B-----xxxxxxxxxxx" `shouldBe` "Shadow-5.8.11"
291 fingerprint "T58B-----xxxxxxxxxxx" `shouldBe` "BitTornado-5.8.11"
292
293 it "decode bitcomet style peer id" $ do
294 fingerprint "exbc01xxxxxxxxxxxxxx" `shouldBe` "BitComet-48.49"
295 fingerprint "FUTB01xxxxxxxxxxxxxx" `shouldBe` "BitComet-48.49"
296 fingerprint "exbc01LORDxxxxxxxxxx" `shouldBe` "BitLord-48.49"
297
298 it "decode opera style peer id" $ do
299 fingerprint "OP0123xxxxxxxxxxxxxx" `shouldBe` "Opera-123"
300
301 it "decode ML donkey style peer id" $ do
302 fingerprint "-ML2.7.2-xxxxxxxxxxx" `shouldBe` "MLdonkey-0"
303
304-- TODO XBT, Bits on Wheels, Queen Bee, BitTyrant, TorrenTopia,
305-- BitSpirit, Rufus, G3 Torrent, FlashGet \ No newline at end of file