# HG changeset patch # User Thomas De Schampheleire # Date 1580589428 -3600 # Node ID cec84c4675ce4be5c38cb1d847f2238685cca99d # Parent ecef27ac1ffa59c48d133df527b051a0cbdf8abb tests: remove race condition in test_forgot_password One in so many times, test_forgot_password failed with: kallithea/tests/functional/test_login.py:427: in test_forgot_password assert '\n%s\n' % token in body E assert ('\n%s\n' % 'd71ad3ed3c6ca637ad00b7098828d33c56579201') in "Password Reset Request\n\nHello passwd reset,\n\nWe have received a request to reset the password for your account.\n\nTo s...7e89326ca372ade1d424dafb106d824cddb\n\nIf it weren't you who requested the password reset, just disregard this message.\n" i.e. the expected token is not the one in the email. The token is calculated based on a timestamp (among others). And the token is calculated twice: once in the real code and once in the test, each time on a slightly different timestamp. Even though there is flooring of the timestamp to a second resolution, there will always be a race condition where the two timestamps floor to a different second, e.g. 4.99 vs 5.01. The problem can be reproduced reliably by adding a sleep of e.g. 2 seconds before generating the password reset mail (after the test has already calculated the expected token). Solve this problem by mocking the time.time() used to generate the timestamp, so that the timestamp used for the real token is the same as the one used for the expected token in the test. diff -r ecef27ac1ffa -r cec84c4675ce kallithea/tests/functional/test_login.py --- a/kallithea/tests/functional/test_login.py Sat Feb 01 21:29:18 2020 +0100 +++ b/kallithea/tests/functional/test_login.py Sat Feb 01 21:37:08 2020 +0100 @@ -415,7 +415,8 @@ def mock_send_email(recipients, subject, body='', html_body='', headers=None, author=None): collected.append((recipients, subject, body, html_body)) - with mock.patch.object(kallithea.lib.celerylib.tasks, 'send_email', mock_send_email): + with mock.patch.object(kallithea.lib.celerylib.tasks, 'send_email', mock_send_email), \ + mock.patch.object(time, 'time', lambda: timestamp): response = self.app.post(url(controller='login', action='password_reset'), {'email': email,