summaryrefslogtreecommitdiff
path: root/tests/integration/test_statefile.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/integration/test_statefile.py')
-rw-r--r--tests/integration/test_statefile.py41
1 files changed, 22 insertions, 19 deletions
diff --git a/tests/integration/test_statefile.py b/tests/integration/test_statefile.py
index 21eefae..a3c8d59 100644
--- a/tests/integration/test_statefile.py
+++ b/tests/integration/test_statefile.py
@@ -1,12 +1,12 @@
1"""The state dump and the -l switch that reads it back. 1"""The state dump and the -l switch that reads it back.
2 2
3Nothing exercised the load path before, and the dump's second column is now 3The second column is the minute a torrent was last touched, by the wall
4how long ago a torrent was last touched rather than when, because the clock 4clock, which is what the file has recorded for years and the only clock two
5counts from boot and an absolute stamp would mean nothing to the process 5runs of the tracker agree on.
6that reads the file.
7""" 6"""
8 7
9import os 8import os
9import time
10import unittest 10import unittest
11 11
12from harness import Tracker, TrackerTestCase 12from harness import Tracker, TrackerTestCase
@@ -54,23 +54,26 @@ class StateFileRoundTrip(TrackerTestCase):
54 restarted._cleanup() 54 restarted._cleanup()
55 55
56 56
57class StateFileWithNonsenseAges(TrackerTestCase): 57class StateFileWithNonsenseStamps(TrackerTestCase):
58 """The age column is read as unsigned and handed on as a signed ot_time. 58 """The column is read as unsigned and handed on as a signed ot_time. A
59 A value at or above 2^63 arrived negative, cleared the timeout check, and 59 value at or above 2^63 arrived negative, cleared the timeout check, and
60 put the torrent's base in the future, where the cleaner never reaches it. 60 put the torrent's base in the future, where the cleaner never reaches it.
61 At exactly 2^63 the subtraction itself overflowed.""" 61 At exactly 2^63 the subtraction itself overflowed."""
62 62
63 AGES = { 63 def stamps(self):
64 "overflow": 2**63, 64 now = int(time.time()) // 60
65 "wrapped": 2**63 + 60 * 24, 65 return {
66 "minus-one": 2**64 - 1, 66 "overflow": 2**63,
67 "int64-max": 2**63 - 1, 67 "minus-one": 2**64 - 1,
68 "past-timeout": 60 * 24 + 1, 68 "int64-max": 2**63 - 1,
69 } 69 "in-the-future": now + 60,
70 "past-timeout": now - (24 * 60 + 1),
71 }
70 72
71 def test_no_age_outside_the_timeout_builds_a_torrent(self): 73 def test_no_stamp_outside_the_timeout_builds_a_torrent(self):
72 lines = ["%s:%d:7" % (self.hash_for(name).hex(), age) for name, age in self.AGES.items()] 74 stamps = self.stamps()
73 lines.append("%s:5:7" % self.hash_for("honest").hex()) 75 lines = ["%s:%d:7" % (self.hash_for(name).hex(), stamp) for name, stamp in stamps.items()]
76 lines.append("%s:%d:7" % (self.hash_for("honest").hex(), int(time.time()) // 60 - 5))
74 77
75 path = os.path.join(self.tracker.dir, "nonsense") 78 path = os.path.join(self.tracker.dir, "nonsense")
76 with open(path, "w") as handle: 79 with open(path, "w") as handle:
@@ -78,9 +81,9 @@ class StateFileWithNonsenseAges(TrackerTestCase):
78 81
79 restarted = Tracker(extra_args=["-l", path]) 82 restarted = Tracker(extra_args=["-l", path])
80 try: 83 try:
81 for name in self.AGES: 84 for name, stamp in stamps.items():
82 self.assertNotIn(self.hash_for(name), restarted.scrape(self.hash_for(name))[b"files"], 85 self.assertNotIn(self.hash_for(name), restarted.scrape(self.hash_for(name))[b"files"],
83 "the line with age %d was loaded" % self.AGES[name]) 86 "the line stamped %d was loaded" % stamp)
84 self.assertIn(self.hash_for("honest"), restarted.scrape(self.hash_for("honest"))[b"files"], 87 self.assertIn(self.hash_for("honest"), restarted.scrape(self.hash_for("honest"))[b"files"],
85 "the state file was not read at all") 88 "the state file was not read at all")
86 self.assertEqual(restarted.torrent_count(), 1) 89 self.assertEqual(restarted.torrent_count(), 1)