diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/integration/harness.py | 4 | ||||
| -rw-r--r-- | tests/integration/test_livesync.py | 87 | ||||
| -rw-r--r-- | tests/t_trackerlogic.c | 2 |
3 files changed, 90 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 8dd754b..52e871f 100644 --- a/tests/integration/test_livesync.py +++ b/tests/integration/test_livesync.py | |||
| @@ -102,6 +102,17 @@ class LiveSyncIn(TrackerTestCase): | |||
| 102 | self.tracker.livesync_send(packet(99, [(info_hash, peer4("10.1.2.11", 6881, FLAG_SEEDING))])) | 102 | self.tracker.livesync_send(packet(99, [(info_hash, peer4("10.1.2.11", 6881, FLAG_SEEDING))])) |
| 103 | self.assertFalse(self.tracker.wait_until(lambda: self.counts(info_hash) is not None, timeout=1)) | 103 | self.assertFalse(self.tracker.wait_until(lambda: self.counts(info_hash) is not None, timeout=1)) |
| 104 | 104 | ||
| 105 | def test_synced_peers_are_counted(self): | ||
| 106 | """The live sync worker keeps its own tally like every other worker, | ||
| 107 | and ?mode=syncs is the sum of them.""" | ||
| 108 | before = int(self.tracker.stats("syncs").split()[0]) | ||
| 109 | hashes = [self.hash_for("sync-count-%d" % i) for i in range(3)] | ||
| 110 | self.tracker.livesync_send(packet(SYNC_PEER4, [(h, peer4("10.1.2.%d" % (20 + i), 6881, FLAG_SEEDING)) | ||
| 111 | for i, h in enumerate(hashes)])) | ||
| 112 | self.assertTrue(self.tracker.wait_until( | ||
| 113 | lambda: int(self.tracker.stats("syncs").split()[0]) == before + 3), | ||
| 114 | "syncs says %s" % self.tracker.stats("syncs").split()[0]) | ||
| 115 | |||
| 105 | def test_a_packet_with_nothing_but_a_header_is_ignored(self): | 116 | def test_a_packet_with_nothing_but_a_header_is_ignored(self): |
| 106 | before = self.tracker.torrent_count() | 117 | before = self.tracker.torrent_count() |
| 107 | self.tracker.livesync_send(struct.pack("!I", 0xDEADBEEF) + struct.pack("!I", SYNC_PEER4)) | 118 | self.tracker.livesync_send(struct.pack("!I", 0xDEADBEEF) + struct.pack("!I", SYNC_PEER4)) |
| @@ -119,3 +130,79 @@ class LiveSyncAccess(TrackerTestCase): | |||
| 119 | info_hash = self.hash_for("sync-unblessed") | 130 | info_hash = self.hash_for("sync-unblessed") |
| 120 | self.tracker.livesync_send(packet(SYNC_PEER4, [(info_hash, peer4("10.1.2.12", 6881, FLAG_SEEDING))])) | 131 | self.tracker.livesync_send(packet(SYNC_PEER4, [(info_hash, peer4("10.1.2.12", 6881, FLAG_SEEDING))])) |
| 121 | self.assertFalse(self.tracker.wait_until(lambda: self.tracker.torrent_count() != 0, timeout=1)) | 132 | self.assertFalse(self.tracker.wait_until(lambda: self.tracker.torrent_count() != 0, timeout=1)) |
| 133 | |||
| 134 | |||
| 135 | @unittest.skipUnless(has_livesync(), "this build has no WANT_SYNC_LIVE") | ||
| 136 | class LiveSyncUnconfigured(TrackerTestCase): | ||
| 137 | """A binary that has the feature but no cluster to join. Somebody whose | ||
| 138 | packager turned WANT_SYNC_LIVE on did not ask for live sync and should | ||
| 139 | not be able to tell that it is there.""" | ||
| 140 | |||
| 141 | config = "" | ||
| 142 | |||
| 143 | def test_the_tracker_runs_anyway(self): | ||
| 144 | info_hash = self.hash_for("no-cluster") | ||
| 145 | self.tracker.announce(info_hash, port=6881, left=0) | ||
| 146 | self.assertEqual(self.tracker.torrent_count(), 1) | ||
| 147 | |||
| 148 | def test_nothing_is_said_about_the_missing_cluster(self): | ||
| 149 | self.assertNotIn("sync", self.tracker.output().lower()) | ||
| 150 | |||
| 151 | def test_no_socket_is_bound_for_it(self): | ||
| 152 | """A configured tracker holds the wildcard address on that port, so | ||
| 153 | taking it here proves nothing was started.""" | ||
| 154 | sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) | ||
| 155 | try: | ||
| 156 | sock.bind(("0.0.0.0", self.tracker.livesync_port)) | ||
| 157 | finally: | ||
| 158 | sock.close() | ||
| 159 | |||
| 160 | def test_announcing_stays_clean(self): | ||
| 161 | """Enough announces to pass the watermark that would flush an | ||
| 162 | outgoing buffer, if there were one to flush. The sanitizers in this | ||
| 163 | build turn anything the attempt touched into a failure.""" | ||
| 164 | for i in range(200): | ||
| 165 | self.tracker.announce(self.hash_for("no-cluster-%d" % i), port=6881 + i, left=0) | ||
| 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 | |||
| 172 | |||
| 173 | @unittest.skipUnless(has_livesync(), "this build has no WANT_SYNC_LIVE") | ||
| 174 | class LiveSyncGroup(TrackerTestCase): | ||
| 175 | config = ("livesync.cluster.group %s\n" | ||
| 176 | "livesync.cluster.listen 127.0.0.1:{livesync_port}\n" | ||
| 177 | "livesync.cluster.node_ip 127.0.0.1\n" % OWN_GROUP) | ||
| 178 | |||
| 179 | def test_the_configured_group_is_joined(self): | ||
| 180 | info_hash = self.hash_for("own-group") | ||
| 181 | self.tracker.livesync_send(packet(SYNC_PEER4, [(info_hash, peer4("10.1.3.1", 6881, FLAG_SEEDING))]), | ||
| 182 | group=OWN_GROUP) | ||
| 183 | self.assertTrue(self.tracker.wait_until(lambda: self.tracker.torrent_count() == 1)) | ||
| 184 | |||
| 185 | def test_the_default_group_is_left_alone(self): | ||
| 186 | """A cluster that picked its own group should not hear the one every | ||
| 187 | other opentracker is on.""" | ||
| 188 | info_hash = self.hash_for("not-our-group") | ||
| 189 | self.tracker.livesync_send(packet(SYNC_PEER4, [(info_hash, peer4("10.1.3.2", 6881, FLAG_SEEDING))])) | ||
| 190 | self.assertFalse(self.tracker.wait_until(lambda: self.tracker.torrent_count() != 0, timeout=1)) | ||
| 191 | |||
| 192 | |||
| 193 | @unittest.skipUnless(has_livesync(), "this build has no WANT_SYNC_LIVE") | ||
| 194 | class LiveSyncGroupRefused(TrackerTestCase): | ||
| 195 | """A unicast address is not a group. The line is refused like any other | ||
| 196 | bad config line, which leaves the default standing.""" | ||
| 197 | |||
| 198 | config = ("livesync.cluster.group 10.0.0.1\n" | ||
| 199 | "livesync.cluster.listen 127.0.0.1:{livesync_port}\n" | ||
| 200 | "livesync.cluster.node_ip 127.0.0.1\n") | ||
| 201 | |||
| 202 | def test_the_line_is_refused(self): | ||
| 203 | self.assertIn("Parse error", self.tracker.output()) | ||
| 204 | |||
| 205 | def test_and_the_default_group_still_works(self): | ||
| 206 | info_hash = self.hash_for("fallback-group") | ||
| 207 | self.tracker.livesync_send(packet(SYNC_PEER4, [(info_hash, peer4("10.1.3.3", 6881, FLAG_SEEDING))])) | ||
| 208 | self.assertTrue(self.tracker.wait_until(lambda: self.tracker.torrent_count() == 1)) | ||
diff --git a/tests/t_trackerlogic.c b/tests/t_trackerlogic.c index f64977f..1cf9141 100644 --- a/tests/t_trackerlogic.c +++ b/tests/t_trackerlogic.c | |||
| @@ -224,7 +224,7 @@ void test_trackerlogic(void) { | |||
| 224 | pthread_sigmask(SIG_BLOCK, &signal_mask, NULL); | 224 | pthread_sigmask(SIG_BLOCK, &signal_mask, NULL); |
| 225 | 225 | ||
| 226 | trackerlogic_init(); | 226 | trackerlogic_init(); |
| 227 | CHECK_INT(workstruct_init(&ws), 0); | 227 | CHECK_INT(workstruct_init(&ws, G_INBUF_SIZE), 0); |
| 228 | 228 | ||
| 229 | case_an_announce_makes_a_torrent(); | 229 | case_an_announce_makes_a_torrent(); |
| 230 | case_the_same_peer_twice_is_one_peer(); | 230 | case_the_same_peer_twice_is_one_peer(); |
