Files
@ cec84c4675ce
Branch filter:
Location: kallithea/scripts/validate-minimum-dependency-versions - annotation
cec84c4675ce
1.7 KiB
text/plain
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.
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.
ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e 28fa94f56370 ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e ac6cc1b8a07e | #!/bin/bash
# Test that installation of all dependencies works fine if versions are set to
# the minimum ones.
set -e
if [ -n "$VIRTUAL_ENV" ]; then
echo "This script will create its own virtualenv - please don't run it inside an existing one." >&2
exit 1
fi
cd "$(hg root)"
venv=build/minimum-dependency-versions-venv
log=build/minimum-dependency-versions.log
min_requirements=build/minimum-dependency-versions-requirements.txt
echo "virtualenv: $venv"
echo "log: $log"
echo "minimum requirements file: $min_requirements"
# clean up previous runs
rm -rf "$venv" "$log"
mkdir -p "$venv"
# Make a light weight parsing of setup.py and dev_requirements.txt,
# finding all >= requirements and dumping into a custom requirements.txt
# while fixating the requirement at the lower bound.
sed -n 's/.*"\(.*\)>=\(.*\)".*/\1==\2/p' setup.py > "$min_requirements"
sed 's/>=/==/p' dev_requirements.txt >> "$min_requirements"
virtualenv -p "$(command -v python2)" "$venv"
source "$venv/bin/activate"
pip install --upgrade pip setuptools
pip install -e . -r "$min_requirements" python-ldap python-pam 2> >(tee "$log" >&2)
# Strip out the known Python 2.7 deprecation message.
sed -i '/DEPRECATION: Python 2\.7 /d' "$log"
# Treat any message on stderr as a problem, for the caller to interpret.
if [ -s "$log" ]; then
echo
echo "Error: pip detected following problems:"
cat "$log"
echo
exit 1
fi
freeze_txt=build/minimum-dependency-versions.txt
pip freeze > $freeze_txt
echo "Installation of minimum packages was successful, providing a set of packages as in $freeze_txt . Now running test suite..."
pytest
echo "Test suite execution was successful."
echo "You can now do additional validation using virtual env '$venv'."
|