diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/integration/harness.py | 4 | ||||
| -rw-r--r-- | tests/integration/test_livesync.py | 63 |
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 | |||
| 10 | import subprocess | 10 | import subprocess |
| 11 | import unittest | 11 | import unittest |
| 12 | 12 | ||
| 13 | from harness import TRACKER, TrackerTestCase | 13 | from 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 |
| 16 | SYNC_PEER4 = 0 | 16 | SYNC_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 | ||
| 170 | OWN_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. | ||
| 177 | UNJOINED_GROUP = "239.192.0.99" | ||
| 178 | |||
| 179 | |||
| 180 | @unittest.skipUnless(has_livesync(), "this build has no WANT_SYNC_LIVE") | ||
| 181 | class 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") | ||
| 201 | class 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() | ||
