summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/integration/harness.py4
-rw-r--r--tests/integration/test_livesync.py63
2 files changed, 64 insertions, 3 deletions
diff --git a/tests/integration/harness.py b/tests/integration/harness.py
index a9d38ca..10aa6de 100644
--- a/tests/integration/harness.py
+++ b/tests/integration/harness.py
@@ -192,7 +192,7 @@ class Tracker:
192 def torrent_count(self): 192 def torrent_count(self):
193 return int(self.stats("torr").split()[0]) 193 return int(self.stats("torr").split()[0])
194 194
195 def livesync_send(self, payload): 195 def livesync_send(self, payload, group=LIVESYNC_GROUP):
196 """Put a packet on the live sync group. 196 """Put a packet on the live sync group.
197 197
198 It has to go to the group rather than straight at the port: the 198 It has to go to the group rather than straight at the port: the
@@ -204,7 +204,7 @@ class Tracker:
204 sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton("127.0.0.1")) 204 sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton("127.0.0.1"))
205 sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, 1) 205 sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, 1)
206 sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 1) 206 sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 1)
207 sock.sendto(payload, (LIVESYNC_GROUP, self.livesync_port)) 207 sock.sendto(payload, (group, self.livesync_port))
208 finally: 208 finally:
209 sock.close() 209 sock.close()
210 210
diff --git a/tests/integration/test_livesync.py b/tests/integration/test_livesync.py
index 3a9ee58..f4cb2db 100644
--- a/tests/integration/test_livesync.py
+++ b/tests/integration/test_livesync.py
@@ -10,7 +10,7 @@ import struct
10import subprocess 10import subprocess
11import unittest 11import unittest
12 12
13from harness import TRACKER, TrackerTestCase 13from harness import TRACKER, Tracker, TrackerTestCase
14 14
15# enum { OT_SYNC_PEER4, OT_SYNC_PEER6 } in src/ot_livesync.c 15# enum { OT_SYNC_PEER4, OT_SYNC_PEER6 } in src/ot_livesync.c
16SYNC_PEER4 = 0 16SYNC_PEER4 = 0
@@ -164,3 +164,64 @@ class LiveSyncUnconfigured(TrackerTestCase):
164 for i in range(200): 164 for i in range(200):
165 self.tracker.announce(self.hash_for("no-cluster-%d" % i), port=6881 + i, left=0) 165 self.tracker.announce(self.hash_for("no-cluster-%d" % i), port=6881 + i, left=0)
166 self.assertEqual(self.tracker.torrent_count(), 200) 166 self.assertEqual(self.tracker.torrent_count(), 200)
167
168
169# RFC 2365 sets 239.192.0.0/14 aside for exactly this kind of use
170OWN_GROUP = "239.192.0.7"
171# A group nothing in this suite ever joins. Deliberately not the default one:
172# other trackers here do join that, on ports the harness picks at random, and
173# a socket bound to the wildcard address shares a port's multicast traffic
174# with anything else on the host that has joined the group it is addressed
175# to. Two clusters sharing a host and a port is pathological in the field but
176# routine in a test suite.
177UNJOINED_GROUP = "239.192.0.99"
178
179
180@unittest.skipUnless(has_livesync(), "this build has no WANT_SYNC_LIVE")
181class LiveSyncGroup(TrackerTestCase):
182 config = ("livesync.cluster.group %s\n"
183 "livesync.cluster.listen 127.0.0.1:{livesync_port}\n"
184 "livesync.cluster.node_ip 127.0.0.1\n" % OWN_GROUP)
185
186 def test_the_configured_group_is_joined(self):
187 info_hash = self.hash_for("own-group")
188 self.tracker.livesync_send(packet(SYNC_PEER4, [(info_hash, peer4("10.1.3.1", 6881, FLAG_SEEDING))]),
189 group=OWN_GROUP)
190 self.assertTrue(self.tracker.wait_until(lambda: self.tracker.torrent_count() == 1))
191
192 def test_another_group_is_left_alone(self):
193 """A cluster that picked its own group hears nothing from the others."""
194 info_hash = self.hash_for("not-our-group")
195 self.tracker.livesync_send(packet(SYNC_PEER4, [(info_hash, peer4("10.1.3.2", 6881, FLAG_SEEDING))]),
196 group=UNJOINED_GROUP)
197 self.assertFalse(self.tracker.wait_until(lambda: self.tracker.torrent_count() != 0, timeout=1))
198
199
200@unittest.skipUnless(has_livesync(), "this build has no WANT_SYNC_LIVE")
201class LiveSyncGroupRefused(unittest.TestCase):
202 """A cluster that asked for a group of its own must not quietly end up on
203 the one every other opentracker is on, so a line that does not name a
204 group stops the tracker rather than falling back."""
205
206 def start_with(self, group):
207 return Tracker("livesync.cluster.group %s\n"
208 "livesync.cluster.listen 127.0.0.1:{livesync_port}\n"
209 "livesync.cluster.node_ip 127.0.0.1\n" % group)
210
211 def test_a_unicast_address_stops_the_tracker(self):
212 with self.assertRaises(AssertionError) as caught:
213 self.start_with("10.0.0.1")
214 self.assertIn("multicast address", str(caught.exception))
215
216 def test_so_does_something_that_is_not_an_address(self):
217 with self.assertRaises(AssertionError) as caught:
218 self.start_with("not-an-address")
219 self.assertIn("multicast address", str(caught.exception))
220
221 def test_a_group_at_either_end_of_the_range_is_taken(self):
222 for group in ("224.0.0.1", "239.255.255.255"):
223 tracker = self.start_with(group)
224 try:
225 self.assertEqual(tracker.torrent_count(), 0)
226 finally:
227 tracker.stop()