1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
"""That every thread the tracker starts also ends when it is asked to stop.
The rest of the suite stops a tracker too, so a thread left behind already
shows up in teardown as the complaint that the tracker had to be killed.
These ask for the arrangements that park a thread in a blocking read in the
first place, and they time the exit, because a reader woken only by its own
receive timeout passes a correctness check while taking a second over it.
"""
import time
import unittest
from harness import Tracker, TrackerTestCase
# Generous enough for a platform where shutting the socket down does not wake
# the reader and the receive timeout has to expire, tight enough that a reader
# which is never woken at all fails instead of hanging the suite
PATIENCE = 3.0
def time_the_exit(extra_config):
tracker = Tracker(extra_config)
try:
# Serve one request of each kind first, so the threads that are about
# to be joined have actually run
tracker.announce(b"shutdown-probe\0\0\0\0\0\0")
sock, connection_id = tracker.udp_connect()
tracker.udp_announce(sock, connection_id, b"shutdown-probe\0\0\0\0\0\0")
sock.close()
started = time.time()
complaints = tracker.stop()
return time.time() - started, complaints
finally:
tracker._cleanup()
class UdpWorkers(TrackerTestCase):
config = "listen.udp.workers 8\n"
def test_announce_reaches_one_of_eight_workers(self):
"""Keeps the workers from being merely started and never used."""
sock, connection_id = self.tracker.udp_connect()
answer = self.tracker.udp_announce(sock, connection_id, self.hash_for("eight-workers"))
sock.close()
self.assertEqual(answer["seeders"], 1)
class ShutdownEndsEveryThread(unittest.TestCase):
def test_eight_udp_workers_are_joined(self):
took, complaints = time_the_exit("listen.udp.workers 8\n")
self.assertEqual(complaints, [], "the tracker reported:\n" + "\n".join(complaints))
self.assertLess(took, PATIENCE, "stopping eight udp workers took %.1f s" % took)
def test_udp_in_the_event_loop_still_stops(self):
"""Worker count zero leaves no thread to join, which must also work."""
took, complaints = time_the_exit("listen.udp.workers 0\n")
self.assertEqual(complaints, [], "the tracker reported:\n" + "\n".join(complaints))
self.assertLess(took, PATIENCE, "stopping without workers took %.1f s" % took)
|