author | David R. MacIver <david@drmaciver.com> |
Wed, 24 Feb 2016 13:05:45 +0000 | |
changeset 28255 | f75f7d39cca3 |
child 28256 | 55325bdf6c13 |
permissions | -rw-r--r-- |
28255
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
1 |
from __future__ import print_function, absolute_import |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
2 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
3 |
"""Fuzz testing for operations against a Mercurial repository |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
4 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
5 |
This uses Hypothesis's stateful testing to generate random repository |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
6 |
operations and test Mercurial using them, both to see if there are any |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
7 |
unexpected errors and to compare different versions of it.""" |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
8 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
9 |
import os |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
10 |
import sys |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
11 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
12 |
# These tests require Hypothesis and pytz to be installed. |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
13 |
# Running 'pip install hypothesis pytz' will achieve that. |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
14 |
# Note: This won't work if you're running Python < 2.7. |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
15 |
try: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
16 |
from hypothesis.extra.datetime import datetimes |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
17 |
except ImportError: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
18 |
sys.stderr.write("skipped: hypothesis or pytz not installed" + os.linesep) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
19 |
sys.exit(80) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
20 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
21 |
# If you are running an old version of pip you may find that the enum34 |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
22 |
# backport is not installed automatically. If so 'pip install enum34' will |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
23 |
# fix this problem. |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
24 |
try: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
25 |
import enum |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
26 |
assert enum # Silence pyflakes |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
27 |
except ImportError: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
28 |
sys.stderr.write("skipped: enum34 not installed" + os.linesep) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
29 |
sys.exit(80) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
30 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
31 |
import binascii |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
32 |
from contextlib import contextmanager |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
33 |
import errno |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
34 |
import pipes |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
35 |
import shutil |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
36 |
import silenttestrunner |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
37 |
import subprocess |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
38 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
39 |
from hypothesis.errors import HypothesisException |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
40 |
from hypothesis.stateful import rule, RuleBasedStateMachine, Bundle |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
41 |
from hypothesis import settings, note, strategies as st |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
42 |
from hypothesis.configuration import set_hypothesis_home_dir |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
43 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
44 |
testdir = os.path.abspath(os.environ["TESTDIR"]) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
45 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
46 |
# We store Hypothesis examples here rather in the temporary test directory |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
47 |
# so that when rerunning a failing test this always results in refinding the |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
48 |
# previous failure. This directory is in .hgignore and should not be checked in |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
49 |
# but is useful to have for development. |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
50 |
set_hypothesis_home_dir(os.path.join(testdir, ".hypothesis")) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
51 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
52 |
runtests = os.path.join(os.environ["RUNTESTDIR"], "run-tests.py") |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
53 |
testtmp = os.environ["TESTTMP"] |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
54 |
assert os.path.isdir(testtmp) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
55 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
56 |
generatedtests = os.path.join(testdir, "hypothesis-generated") |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
57 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
58 |
try: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
59 |
os.makedirs(generatedtests) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
60 |
except OSError: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
61 |
pass |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
62 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
63 |
# We write out generated .t files to a file in order to ease debugging and to |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
64 |
# give a starting point for turning failures Hypothesis finds into normal |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
65 |
# tests. In order to ensure that multiple copies of this test can be run in |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
66 |
# parallel we use atomic file create to ensure that we always get a unique |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
67 |
# name. |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
68 |
file_index = 0 |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
69 |
while True: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
70 |
file_index += 1 |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
71 |
savefile = os.path.join(generatedtests, "test-generated-%d.t" % ( |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
72 |
file_index, |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
73 |
)) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
74 |
try: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
75 |
os.close(os.open(savefile, os.O_CREAT | os.O_EXCL | os.O_WRONLY)) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
76 |
break |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
77 |
except OSError as e: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
78 |
if e.errno != errno.EEXIST: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
79 |
raise |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
80 |
assert os.path.exists(savefile) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
81 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
82 |
hgrc = os.path.join(".hg", "hgrc") |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
83 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
84 |
filecharacters = ( |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
85 |
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
86 |
"[]^_`;=@{}~ !#$%&'()+,-" |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
87 |
) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
88 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
89 |
files = st.text(filecharacters, min_size=1).map(lambda x: x.strip()).filter( |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
90 |
bool).map(lambda s: s.encode('ascii')) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
91 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
92 |
safetext = st.text(st.characters( |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
93 |
min_codepoint=1, max_codepoint=127, |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
94 |
blacklist_categories=('Cc', 'Cs')), min_size=1).map( |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
95 |
lambda s: s.encode('utf-8') |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
96 |
) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
97 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
98 |
@contextmanager |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
99 |
def acceptableerrors(*args): |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
100 |
"""Sometimes we know an operation we're about to perform might fail, and |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
101 |
we're OK with some of the failures. In those cases this may be used as a |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
102 |
context manager and will swallow expected failures, as identified by |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
103 |
substrings of the error message Mercurial emits.""" |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
104 |
try: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
105 |
yield |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
106 |
except subprocess.CalledProcessError as e: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
107 |
if not any(a in e.output for a in args): |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
108 |
note(e.output) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
109 |
raise |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
110 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
111 |
class verifyingstatemachine(RuleBasedStateMachine): |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
112 |
"""This defines the set of acceptable operations on a Mercurial repository |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
113 |
using Hypothesis's RuleBasedStateMachine. |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
114 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
115 |
The general concept is that we manage multiple repositories inside a |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
116 |
repos/ directory in our temporary test location. Some of these are freshly |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
117 |
inited, some are clones of the others. Our current working directory is |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
118 |
always inside one of these repositories while the tests are running. |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
119 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
120 |
Hypothesis then performs a series of operations against these repositories, |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
121 |
including hg commands, generating contents and editing the .hgrc file. |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
122 |
If these operations fail in unexpected ways or behave differently in |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
123 |
different configurations of Mercurial, the test will fail and a minimized |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
124 |
.t test file will be written to the hypothesis-generated directory to |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
125 |
exhibit that failure. |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
126 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
127 |
Operations are defined as methods with @rule() decorators. See the |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
128 |
Hypothesis documentation at |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
129 |
http://hypothesis.readthedocs.org/en/release/stateful.html for more |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
130 |
details.""" |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
131 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
132 |
# A bundle is a reusable collection of previously generated data which may |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
133 |
# be provided as arguments to future operations. |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
134 |
paths = Bundle('paths') |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
135 |
contents = Bundle('contents') |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
136 |
committimes = Bundle('committimes') |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
137 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
138 |
def __init__(self): |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
139 |
super(verifyingstatemachine, self).__init__() |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
140 |
self.repodir = os.path.join(testtmp, "repo") |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
141 |
if os.path.exists(self.repodir): |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
142 |
shutil.rmtree(self.repodir) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
143 |
os.chdir(testtmp) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
144 |
self.log = [] |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
145 |
self.failed = False |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
146 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
147 |
self.mkdirp("repo") |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
148 |
self.cd("repo") |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
149 |
self.hg("init") |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
150 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
151 |
def teardown(self): |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
152 |
"""On teardown we clean up after ourselves as usual, but we also |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
153 |
do some additional testing: We generate a .t file based on our test |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
154 |
run using run-test.py -i to get the correct output. |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
155 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
156 |
We then test it in a number of other configurations, verifying that |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
157 |
each passes the same test.""" |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
158 |
super(verifyingstatemachine, self).teardown() |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
159 |
try: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
160 |
shutil.rmtree(self.repodir) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
161 |
except OSError: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
162 |
pass |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
163 |
ttest = os.linesep.join(" " + l for l in self.log) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
164 |
os.chdir(testtmp) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
165 |
path = os.path.join(testtmp, "test-generated.t") |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
166 |
with open(path, 'w') as o: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
167 |
o.write(ttest + os.linesep) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
168 |
with open(os.devnull, "w") as devnull: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
169 |
rewriter = subprocess.Popen( |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
170 |
[runtests, "--local", "-i", path], stdin=subprocess.PIPE, |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
171 |
stdout=devnull, stderr=devnull, |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
172 |
) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
173 |
rewriter.communicate("yes") |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
174 |
with open(path, 'r') as i: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
175 |
ttest = i.read() |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
176 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
177 |
e = None |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
178 |
if not self.failed: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
179 |
try: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
180 |
output = subprocess.check_output([ |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
181 |
runtests, path, "--local", "--pure" |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
182 |
], stderr=subprocess.STDOUT) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
183 |
assert "Ran 1 test" in output, output |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
184 |
except subprocess.CalledProcessError as e: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
185 |
note(e.output) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
186 |
finally: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
187 |
os.unlink(path) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
188 |
try: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
189 |
os.unlink(path + ".err") |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
190 |
except OSError: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
191 |
pass |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
192 |
if self.failed or e is not None: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
193 |
with open(savefile, "wb") as o: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
194 |
o.write(ttest) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
195 |
if e is not None: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
196 |
raise e |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
197 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
198 |
def execute_step(self, step): |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
199 |
try: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
200 |
return super(verifyingstatemachine, self).execute_step(step) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
201 |
except (HypothesisException, KeyboardInterrupt): |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
202 |
raise |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
203 |
except Exception: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
204 |
self.failed = True |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
205 |
raise |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
206 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
207 |
# Section: Basic commands. |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
208 |
def mkdirp(self, path): |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
209 |
if os.path.exists(path): |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
210 |
return |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
211 |
self.log.append( |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
212 |
"$ mkdir -p -- %s" % (pipes.quote(os.path.relpath(path)),)) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
213 |
os.makedirs(path) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
214 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
215 |
def cd(self, path): |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
216 |
path = os.path.relpath(path) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
217 |
if path == ".": |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
218 |
return |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
219 |
os.chdir(path) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
220 |
self.log.append("$ cd -- %s" % (pipes.quote(path),)) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
221 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
222 |
def hg(self, *args): |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
223 |
self.command("hg", *args) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
224 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
225 |
def command(self, *args): |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
226 |
self.log.append("$ " + ' '.join(map(pipes.quote, args))) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
227 |
subprocess.check_output(args, stderr=subprocess.STDOUT) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
228 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
229 |
# Section: Set up basic data |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
230 |
# This section has no side effects but generates data that we will want |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
231 |
# to use later. |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
232 |
@rule( |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
233 |
target=paths, |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
234 |
source=st.lists(files, min_size=1).map(lambda l: os.path.join(*l))) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
235 |
def genpath(self, source): |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
236 |
return source |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
237 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
238 |
@rule( |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
239 |
target=committimes, |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
240 |
when=datetimes(min_year=1970, max_year=2038) | st.none()) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
241 |
def gentime(self, when): |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
242 |
return when |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
243 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
244 |
@rule( |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
245 |
target=contents, |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
246 |
content=st.one_of( |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
247 |
st.binary(), |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
248 |
st.text().map(lambda x: x.encode('utf-8')) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
249 |
)) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
250 |
def gencontent(self, content): |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
251 |
return content |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
252 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
253 |
@rule(target=paths, source=paths) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
254 |
def lowerpath(self, source): |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
255 |
return source.lower() |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
256 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
257 |
@rule(target=paths, source=paths) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
258 |
def upperpath(self, source): |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
259 |
return source.upper() |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
260 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
261 |
# Section: Basic path operations |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
262 |
@rule(path=paths, content=contents) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
263 |
def writecontent(self, path, content): |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
264 |
self.unadded_changes = True |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
265 |
if os.path.isdir(path): |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
266 |
return |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
267 |
parent = os.path.dirname(path) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
268 |
if parent: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
269 |
try: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
270 |
self.mkdirp(parent) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
271 |
except OSError: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
272 |
# It may be the case that there is a regular file that has |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
273 |
# previously been created that has the same name as an ancestor |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
274 |
# of the current path. This will cause mkdirp to fail with this |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
275 |
# error. We just turn this into a no-op in that case. |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
276 |
return |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
277 |
with open(path, 'wb') as o: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
278 |
o.write(content) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
279 |
self.log.append(( |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
280 |
"$ python -c 'import binascii; " |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
281 |
"print(binascii.unhexlify(\"%s\"))' > %s") % ( |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
282 |
binascii.hexlify(content), |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
283 |
pipes.quote(path), |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
284 |
)) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
285 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
286 |
@rule(path=paths) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
287 |
def addpath(self, path): |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
288 |
if os.path.exists(path): |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
289 |
self.hg("add", "--", path) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
290 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
291 |
@rule(path=paths) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
292 |
def forgetpath(self, path): |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
293 |
if os.path.exists(path): |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
294 |
with acceptableerrors( |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
295 |
"file is already untracked", |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
296 |
): |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
297 |
self.hg("forget", "--", path) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
298 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
299 |
@rule(s=st.none() | st.integers(0, 100)) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
300 |
def addremove(self, s): |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
301 |
args = ["addremove"] |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
302 |
if s is not None: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
303 |
args.extend(["-s", str(s)]) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
304 |
self.hg(*args) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
305 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
306 |
@rule(path=paths) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
307 |
def removepath(self, path): |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
308 |
if os.path.exists(path): |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
309 |
with acceptableerrors( |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
310 |
'file is untracked', |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
311 |
'file has been marked for add', |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
312 |
'file is modified', |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
313 |
): |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
314 |
self.hg("remove", "--", path) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
315 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
316 |
@rule( |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
317 |
message=safetext, |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
318 |
amend=st.booleans(), |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
319 |
when=committimes, |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
320 |
addremove=st.booleans(), |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
321 |
secret=st.booleans(), |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
322 |
close_branch=st.booleans(), |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
323 |
) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
324 |
def maybecommit( |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
325 |
self, message, amend, when, addremove, secret, close_branch |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
326 |
): |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
327 |
command = ["commit"] |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
328 |
errors = ["nothing changed"] |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
329 |
if amend: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
330 |
errors.append("cannot amend public changesets") |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
331 |
command.append("--amend") |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
332 |
command.append("-m" + pipes.quote(message)) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
333 |
if secret: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
334 |
command.append("--secret") |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
335 |
if close_branch: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
336 |
command.append("--close-branch") |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
337 |
errors.append("can only close branch heads") |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
338 |
if addremove: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
339 |
command.append("--addremove") |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
340 |
if when is not None: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
341 |
if when.year == 1970: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
342 |
errors.append('negative date value') |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
343 |
if when.year == 2038: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
344 |
errors.append('exceeds 32 bits') |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
345 |
command.append("--date=%s" % ( |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
346 |
when.strftime('%Y-%m-%d %H:%M:%S %z'),)) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
347 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
348 |
with acceptableerrors(*errors): |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
349 |
self.hg(*command) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
350 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
351 |
# Section: Simple side effect free "check" operations |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
352 |
@rule() |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
353 |
def log(self): |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
354 |
self.hg("log") |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
355 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
356 |
@rule() |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
357 |
def verify(self): |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
358 |
self.hg("verify") |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
359 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
360 |
@rule() |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
361 |
def diff(self): |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
362 |
self.hg("diff", "--nodates") |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
363 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
364 |
@rule() |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
365 |
def status(self): |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
366 |
self.hg("status") |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
367 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
368 |
@rule() |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
369 |
def export(self): |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
370 |
self.hg("export") |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
371 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
372 |
settings.register_profile( |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
373 |
'default', settings( |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
374 |
timeout=300, |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
375 |
stateful_step_count=50, |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
376 |
max_examples=10, |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
377 |
) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
378 |
) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
379 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
380 |
settings.register_profile( |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
381 |
'fast', settings( |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
382 |
timeout=10, |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
383 |
stateful_step_count=20, |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
384 |
max_examples=5, |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
385 |
min_satisfying_examples=1, |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
386 |
max_shrinks=0, |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
387 |
) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
388 |
) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
389 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
390 |
settings.load_profile(os.getenv('HYPOTHESIS_PROFILE', 'default')) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
391 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
392 |
verifyingtest = verifyingstatemachine.TestCase |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
393 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
394 |
verifyingtest.settings = settings.default |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
395 |
|
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
396 |
if __name__ == '__main__': |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
397 |
try: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
398 |
silenttestrunner.main(__name__) |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
399 |
finally: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
400 |
# So as to prevent proliferation of useless test files, if we never |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
401 |
# actually wrote a failing test we clean up after ourselves and delete |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
402 |
# the file for doing so that we owned. |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
403 |
if os.path.exists(savefile) and os.path.getsize(savefile) == 0: |
f75f7d39cca3
testing: generate tests operations using Hypothesis
David R. MacIver <david@drmaciver.com>
parents:
diff
changeset
|
404 |
os.unlink(savefile) |