From 6dba5cc37f756dc6eda6972deea7c23c759149bc Mon Sep 17 00:00:00 2001 From: s3lph <1375407-s3lph@users.noreply.gitlab.com> Date: Mon, 18 Apr 2022 17:14:12 +0200 Subject: [PATCH] Fix test code so that it emulates open(a+) --- multischleuder/conflict.py | 9 ++++----- multischleuder/test/test_conflict.py | 22 ++++++++++++++-------- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/multischleuder/conflict.py b/multischleuder/conflict.py index 0b3bef4..3f378aa 100644 --- a/multischleuder/conflict.py +++ b/multischleuder/conflict.py @@ -86,12 +86,11 @@ class KeyConflictResolution: def _should_send(self, digest: str) -> bool: now = int(datetime.utcnow().timestamp()) - exists = os.path.exists(self._state_file) with open(self._state_file, 'a+') as f: - f.seek(0) - if not exists: - state: Dict[str, int] = {} - else: + state: Dict[str, int] = {} + if f.tell() > 0: + # Only load the state if the file is not empty + f.seek(0) try: state = json.load(f) except BaseException: diff --git a/multischleuder/test/test_conflict.py b/multischleuder/test/test_conflict.py index 3c2d707..cd820dc 100644 --- a/multischleuder/test/test_conflict.py +++ b/multischleuder/test/test_conflict.py @@ -93,6 +93,7 @@ class TestKeyConflictResolution(unittest.TestCase): def test_empty(self): kcr = KeyConflictResolution(3600, '/tmp/state.json', _TEMPLATE) contents = io.StringIO(_CONFLICT_STATE_NONE) + contents.seek(io.SEEK_END) # Opened with 'a+' with patch('builtins.open', mock_open(read_data=_CONFLICT_STATE_NONE)) as mock_statefile: mock_statefile().__enter__.return_value = contents resolved, messages = kcr.resolve('', '', []) @@ -124,6 +125,7 @@ class TestKeyConflictResolution(unittest.TestCase): kcr = KeyConflictResolution(3600, '/tmp/state.json', _TEMPLATE) contents = io.StringIO(_CONFLICT_STATE_NONE) + contents.seek(io.SEEK_END) # Opened with 'a+' with patch('builtins.open', mock_open(read_data=_CONFLICT_STATE_NONE)) as mock_statefile: mock_statefile().__enter__.return_value = contents resolved, messages = kcr.resolve( @@ -150,6 +152,7 @@ class TestKeyConflictResolution(unittest.TestCase): kcr = KeyConflictResolution(3600, '/tmp/state.json', _TEMPLATE) contents = io.StringIO(_CONFLICT_STATE_NONE) + contents.seek(io.SEEK_END) # Opened with 'a+' with patch('builtins.open', mock_open(read_data=_CONFLICT_STATE_NONE)) as mock_statefile: mock_statefile().__enter__.return_value = contents resolved, messages = kcr.resolve( @@ -186,6 +189,7 @@ class TestKeyConflictResolution(unittest.TestCase): kcr = KeyConflictResolution(3600, '/tmp/state.json', _TEMPLATE) contents = io.StringIO(_CONFLICT_STATE_NONE) + contents.seek(io.SEEK_END) # Opened with 'a+' with patch('builtins.open', mock_open(read_data=_CONFLICT_STATE_NONE)) as mock_statefile: mock_statefile().__enter__.return_value = contents resolved, messages = kcr.resolve( @@ -205,6 +209,7 @@ class TestKeyConflictResolution(unittest.TestCase): kcr = KeyConflictResolution(3600, '/tmp/state.json', _TEMPLATE) contents = io.StringIO(_CONFLICT_STATE_NONE) + contents.seek(io.SEEK_END) # Opened with 'a+' with patch('builtins.open', mock_open(read_data=_CONFLICT_STATE_NONE)) as mock_statefile: mock_statefile().__enter__.return_value = contents resolved, messages = kcr.resolve( @@ -220,31 +225,28 @@ class TestKeyConflictResolution(unittest.TestCase): date1 = datetime(2022, 4, 15, 5, 23, 42, 0, tzinfo=tzutc()) date2 = datetime(2022, 4, 13, 5, 23, 42, 0, tzinfo=tzutc()) sub1 = SchleuderSubscriber(3, 'foo@example.org', key1, sch1.id, date1) - sub2 = SchleuderSubscriber(4, 'bar@example.org', key1, sch1.id, date2) # This subscription is older, so its key will be preferred sch2 = SchleuderList(23, 'test-south@schleuder.example.org', 'AF586C0625CF77BBB659747515D41C5D84BF99D3') key2 = SchleuderKey(_PRIVKEY_2.fingerprint.replace(' ', ''), 'foo@example.org', str(_PRIVKEY_2.pubkey), sch2.id) - sub3 = SchleuderSubscriber(7, 'foo@example.org', key2, sch2.id, date2) - sub4 = SchleuderSubscriber(8, 'bar@example.org', key2, sch2.id, date1) + sub2 = SchleuderSubscriber(7, 'foo@example.org', key2, sch2.id, date2) kcr = KeyConflictResolution(3600, '/tmp/state.json', _TEMPLATE) contents = io.StringIO(_CONFLICT_STATE_NONE) + contents.seek(io.SEEK_END) # Opened with 'a+' with patch('builtins.open', mock_open(read_data=_CONFLICT_STATE_NONE)) as mock_statefile: mock_statefile().__enter__.return_value = contents resolved, msgs = kcr.resolve( target='test@schleuder.example.org', mail_from='test-owner@schleuder.example.org', - subscriptions=[sub1, sub2, sub3, sub4]) - self.assertEqual(2, len(msgs)) + subscriptions=[sub1, sub2]) + self.assertEqual(1, len(msgs)) now = datetime.utcnow().timestamp() mock_statefile.assert_called_with('/tmp/state.json', 'a+') contents.seek(0) state = json.loads(contents.read()) - self.assertEqual(2, len(state)) + self.assertEqual(1, len(state)) self.assertIn(msgs[0].mime['X-MultiSchleuder-Digest'], state) - self.assertIn(msgs[1].mime['X-MultiSchleuder-Digest'], state) - self.assertLess(now - state[msgs[0].mime['X-MultiSchleuder-Digest']], 60) self.assertLess(now - state[msgs[0].mime['X-MultiSchleuder-Digest']], 60) # Todo: move this over to test_multilist @@ -266,6 +268,7 @@ class TestKeyConflictResolution(unittest.TestCase): kcr = KeyConflictResolution(3600, '/tmp/state.json', _TEMPLATE) contents = io.StringIO(_CONFLICT_STATE_STALE) + contents.seek(io.SEEK_END) # Opened with 'a+' with patch('builtins.open', mock_open(read_data=_CONFLICT_STATE_STALE)) as mock_statefile: mock_statefile().__enter__.return_value = contents resolved, messages = kcr.resolve( @@ -296,6 +299,7 @@ class TestKeyConflictResolution(unittest.TestCase): kcr = KeyConflictResolution(86400, '/tmp/state.json', _TEMPLATE) contents = io.StringIO(_CONFLICT_STATE_RECENT) + contents.seek(io.SEEK_END) # Opened with 'a+' with patch('builtins.open', mock_open(read_data=_CONFLICT_STATE_RECENT)) as mock_statefile: mock_statefile().__enter__.return_value = contents resolved, messages = kcr.resolve( @@ -328,6 +332,7 @@ class TestKeyConflictResolution(unittest.TestCase): kcr = KeyConflictResolution(3600, '/tmp/state.json', _TEMPLATE) kcr.dry_run() contents = io.StringIO(_CONFLICT_STATE_STALE) + contents.seek(io.SEEK_END) # Opened with 'a+' with patch('builtins.open', mock_open(read_data=_CONFLICT_STATE_STALE)) as mock_statefile: mock_statefile().__enter__.return_value = contents resolved, messages = kcr.resolve( @@ -359,6 +364,7 @@ class TestKeyConflictResolution(unittest.TestCase): kcr = KeyConflictResolution(3600, '/tmp/state.json', _TEMPLATE) contents = io.StringIO(_CONFLICT_STATE_NONE) + contents.seek(io.SEEK_END) # Opened with 'a+' with patch('builtins.open', mock_open(read_data=_CONFLICT_STATE_NONE)) as mock_statefile: mock_statefile().__enter__.return_value = contents resolved, messages = kcr.resolve(