|
18 | 18 | from hypothesis.errors import DeadlineExceeded, InvalidArgument |
19 | 19 | from hypothesis.internal.conjecture.junkdrawer import ensure_free_stackframes |
20 | 20 | from hypothesis.stateful import RuleBasedStateMachine, invariant, rule |
| 21 | +from hypothesis.strategies import SearchStrategy |
21 | 22 |
|
22 | 23 | from tests.common.debug import check_can_generate_examples |
23 | 24 |
|
@@ -72,9 +73,9 @@ def my_invariant(self): |
72 | 73 | run_concurrently(TestMyStateful, n=2) |
73 | 74 |
|
74 | 75 |
|
75 | | -def do_work(): |
| 76 | +def do_work(*, multiplier=1): |
76 | 77 | # arbitrary moderately-expensive work |
77 | | - for x in range(500): |
| 78 | + for x in range(500 * multiplier): |
78 | 79 | _y = x**x |
79 | 80 |
|
80 | 81 |
|
@@ -213,14 +214,22 @@ def slow_test(n): |
213 | 214 |
|
214 | 215 |
|
215 | 216 | def test_one_of_branches_lock(): |
216 | | - # I can't actually get this test to reproduce the race locally. |
217 | | - # This should in theory reproduce, but the timings here are very tight. |
| 217 | + class SlowBranchesStrategy(SearchStrategy): |
| 218 | + @property |
| 219 | + def branches(self): |
| 220 | + # multiplier=2 reproduces more consistently than multiplier=1 for me |
| 221 | + do_work(multiplier=2) |
| 222 | + return [st.integers(), st.text()] |
| 223 | + |
218 | 224 | branch_counts = set() |
219 | | - s = st.one_of(st.integers(), st.integers(), st.integers()) |
| 225 | + s = st.one_of(SlowBranchesStrategy(), SlowBranchesStrategy()) |
220 | 226 |
|
221 | 227 | def test(): |
222 | 228 | branches = len(s.branches) |
223 | 229 | branch_counts.add(branches) |
224 | 230 |
|
225 | 231 | run_concurrently(test, n=10) |
226 | 232 | assert len(branch_counts) == 1 |
| 233 | + # there are 4 independent strategies, but only 2 distinct ones - |
| 234 | + # st.integers(), and st.text(). |
| 235 | + assert branch_counts == {2} |
0 commit comments