"""What the expiry sweep finds, and what it must not find. A plain request is answered and the connection closed by http_close, not by the sweep. If that path left the descriptor's slot behind, the sweep would walk into it once the client timeout had passed and free a cookie that is already gone; the sanitizer build reports that and teardown turns it into a failure. Both halves share one tracker and one wait, because the wait is the whole cost of the test. The two numbers below mirror OT_CLIENT_TIMEOUT and OT_CLIENT_TIMEOUT_CHECKINTERVAL in FEATURES_integration. """ import socket import time import unittest from harness import TrackerTestCase CLIENT_TIMEOUT = 5 CHECK_INTERVAL = 1 class ExpirySweep(TrackerTestCase): def test_the_sweep_takes_the_idle_and_leaves_the_answered(self): idle = socket.create_connection(("127.0.0.1", self.tracker.port), timeout=5) try: self.assertEqual(self.tracker.announce(self.hash_for("expiry-sweep"))[b"complete"], 1) time.sleep(CLIENT_TIMEOUT + 3 * CHECK_INTERVAL) self.assertEqual(self.tracker.torrent_count(), 1, "the tracker stopped serving while sweeping") idle.settimeout(5) self.assertEqual(idle.recv(64), b"", "a connection that never sent a request was not swept") finally: idle.close()