Mercurial > public > mercurial-scm > hg
comparison tests/test-verify-repo-operations.py @ 28258:fc7ee50a0d65
testing: allow Hypothesis to enable extensions
This adds support for testing extensions, including both tests
that extensions don't change behaviour and test for specific
commands.
We use the precondition system to determine what commands are
available to us. If we never use any commands enabled by an
extension then that extension is *skippable* and should not
have changed the behaviour of the test. We thus rerun the test
with an environment variable which is designed to turn off the
extension.
author | David R. MacIver <david@drmaciver.com> |
---|---|
date | Wed, 24 Feb 2016 13:11:30 +0000 |
parents | 7ff725db2fdf |
children | 7829d0ba7459 |
comparison
equal
deleted
inserted
replaced
28257:7ff725db2fdf | 28258:fc7ee50a0d65 |
---|---|
35 import shutil | 35 import shutil |
36 import silenttestrunner | 36 import silenttestrunner |
37 import subprocess | 37 import subprocess |
38 | 38 |
39 from hypothesis.errors import HypothesisException | 39 from hypothesis.errors import HypothesisException |
40 from hypothesis.stateful import rule, RuleBasedStateMachine, Bundle | 40 from hypothesis.stateful import ( |
41 rule, RuleBasedStateMachine, Bundle, precondition) | |
41 from hypothesis import settings, note, strategies as st | 42 from hypothesis import settings, note, strategies as st |
42 from hypothesis.configuration import set_hypothesis_home_dir | 43 from hypothesis.configuration import set_hypothesis_home_dir |
43 | 44 |
44 testdir = os.path.abspath(os.environ["TESTDIR"]) | 45 testdir = os.path.abspath(os.environ["TESTDIR"]) |
45 | 46 |
153 self.mkdirp("repos") | 154 self.mkdirp("repos") |
154 self.cd("repos") | 155 self.cd("repos") |
155 self.mkdirp("repo1") | 156 self.mkdirp("repo1") |
156 self.cd("repo1") | 157 self.cd("repo1") |
157 self.hg("init") | 158 self.hg("init") |
159 self.extensions = {} | |
160 self.all_extensions = set() | |
161 self.non_skippable_extensions = set() | |
158 | 162 |
159 def teardown(self): | 163 def teardown(self): |
160 """On teardown we clean up after ourselves as usual, but we also | 164 """On teardown we clean up after ourselves as usual, but we also |
161 do some additional testing: We generate a .t file based on our test | 165 do some additional testing: We generate a .t file based on our test |
162 run using run-test.py -i to get the correct output. | 166 run using run-test.py -i to get the correct output. |
183 ttest = i.read() | 187 ttest = i.read() |
184 | 188 |
185 e = None | 189 e = None |
186 if not self.failed: | 190 if not self.failed: |
187 try: | 191 try: |
192 for ext in ( | |
193 self.all_extensions - self.non_skippable_extensions | |
194 ): | |
195 try: | |
196 os.environ["SKIP_EXTENSION"] = ext | |
197 output = subprocess.check_output([ | |
198 runtests, path, "--local", | |
199 ], stderr=subprocess.STDOUT) | |
200 assert "Ran 1 test" in output, output | |
201 finally: | |
202 del os.environ["SKIP_EXTENSION"] | |
188 output = subprocess.check_output([ | 203 output = subprocess.check_output([ |
189 runtests, path, "--local", "--pure" | 204 runtests, path, "--local", "--pure" |
190 ], stderr=subprocess.STDOUT) | 205 ], stderr=subprocess.STDOUT) |
191 assert "Ran 1 test" in output, output | 206 assert "Ran 1 test" in output, output |
192 except subprocess.CalledProcessError as e: | 207 except subprocess.CalledProcessError as e: |
469 if clean: | 484 if clean: |
470 self.hg("update", "-C", "--", branch) | 485 self.hg("update", "-C", "--", branch) |
471 else: | 486 else: |
472 self.hg("update", "--", branch) | 487 self.hg("update", "--", branch) |
473 | 488 |
489 # Section: Extension management | |
490 def hasextension(self, extension): | |
491 repo = self.currentrepo | |
492 return repo in self.extensions and extension in self.extensions[repo] | |
493 | |
494 def commandused(self, extension): | |
495 assert extension in self.all_extensions | |
496 self.non_skippable_extensions.add(extension) | |
497 | |
498 @rule(extension=st.sampled_from(( | |
499 'shelve', 'mq', 'blackbox', | |
500 ))) | |
501 def addextension(self, extension): | |
502 self.all_extensions.add(extension) | |
503 extensions = self.extensions.setdefault(self.currentrepo, set()) | |
504 if extension in extensions: | |
505 return | |
506 extensions.add(extension) | |
507 if not os.path.exists(hgrc): | |
508 self.command("touch", hgrc) | |
509 with open(hgrc, 'a') as o: | |
510 line = "[extensions]\n%s=\n" % (extension,) | |
511 o.write(line) | |
512 for l in line.splitlines(): | |
513 self.log.append(( | |
514 '$ if test "$SKIP_EXTENSION" != "%s" ; ' | |
515 'then echo %r >> %s; fi') % ( | |
516 extension, l, hgrc,)) | |
517 | |
518 # Section: Commands from the shelve extension | |
519 @rule() | |
520 @precondition(lambda self: self.hasextension("shelve")) | |
521 def shelve(self): | |
522 self.commandused("shelve") | |
523 with acceptableerrors("nothing changed"): | |
524 self.hg("shelve") | |
525 | |
526 @rule() | |
527 @precondition(lambda self: self.hasextension("shelve")) | |
528 def unshelve(self): | |
529 self.commandused("shelve") | |
530 with acceptableerrors("no shelved changes to apply"): | |
531 self.hg("unshelve") | |
532 | |
474 settings.register_profile( | 533 settings.register_profile( |
475 'default', settings( | 534 'default', settings( |
476 timeout=300, | 535 timeout=300, |
477 stateful_step_count=50, | 536 stateful_step_count=50, |
478 max_examples=10, | 537 max_examples=10, |