Skip to content

Commit

Permalink
Merge pull request #2147 from Zac-HD/fix-prng-1919
Browse files Browse the repository at this point in the history
Check for PRNG state leaks
  • Loading branch information
Zac-HD committed Oct 21, 2019
2 parents 9344c28 + a70c9d5 commit d13c4ee
Showing 1 changed file with 30 additions and 0 deletions.
30 changes: 30 additions & 0 deletions hypothesis-python/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@
from __future__ import absolute_import, division, print_function

import gc
import random
import sys
import time as time_module

import pytest

from hypothesis.internal.detection import is_hypothesis_test
from tests.common import TIME_INCREMENT
from tests.common.setup import run

Expand Down Expand Up @@ -76,3 +78,31 @@ def freeze():
assert sys.version_info[0] == 2
monkeypatch.setattr(time_module, "sleep", sleep)
monkeypatch.setattr(time_module, "freeze", freeze, raising=False)


random_states_after_tests = {}
independent_random = random.Random()


@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_call(item):
# This hookwrapper checks for PRNG state leaks from Hypothesis tests.
# See: https://github.com/HypothesisWorks/hypothesis/issues/1919
if not (hasattr(item, "obj") and is_hypothesis_test(item.obj)):
yield
else:
# We start by peturbing the state of the PRNG, because repeatedly
# leaking PRNG state resets state_after to the (previously leaked)
# state_before, and that just shows as "no use of random".
random.seed(independent_random.randrange(2 ** 32))
before = random.getstate()
yield
after = random.getstate()
if before != after:
if after in random_states_after_tests:
raise Exception(
"%r and %r both used the `random` module, and finished with the "
"same global `random.getstate()`; this is probably a nasty bug!"
% (item.nodeid, random_states_after_tests[after])
)
random_states_after_tests[after] = item.nodeid

0 comments on commit d13c4ee

Please sign in to comment.