# HG changeset patch # User David R. MacIver # Date 1456507454 0 # Node ID 7ff725db2fdfefa3334df32201bec7919c4358dd # Parent 55325bdf6c13b8c48e7e5dfc9069da6885534645 testing: test multiple repositories with Hypothesis This expands the Hypothesis based stateful testing so that rather than having a single repository under test, Hypothesis manages a family of repositories. Some of these are freshly created, some are clones of others. diff -r 55325bdf6c13 -r 7ff725db2fdf tests/test-verify-repo-operations.py --- a/tests/test-verify-repo-operations.py Wed Feb 24 13:06:43 2016 +0000 +++ b/tests/test-verify-repo-operations.py Fri Feb 26 17:24:14 2016 +0000 @@ -108,6 +108,10 @@ note(e.output) raise +reponames = st.text("abcdefghijklmnopqrstuvwxyz01234556789", min_size=1).map( + lambda s: s.encode('ascii') +) + class verifyingstatemachine(RuleBasedStateMachine): """This defines the set of acceptable operations on a Mercurial repository using Hypothesis's RuleBasedStateMachine. @@ -131,6 +135,7 @@ # A bundle is a reusable collection of previously generated data which may # be provided as arguments to future operations. + repos = Bundle('repos') paths = Bundle('paths') contents = Bundle('contents') branches = Bundle('branches') @@ -138,15 +143,17 @@ def __init__(self): super(verifyingstatemachine, self).__init__() - self.repodir = os.path.join(testtmp, "repo") + self.repodir = os.path.join(testtmp, "repos") if os.path.exists(self.repodir): shutil.rmtree(self.repodir) os.chdir(testtmp) self.log = [] self.failed = False - self.mkdirp("repo") - self.cd("repo") + self.mkdirp("repos") + self.cd("repos") + self.mkdirp("repo1") + self.cd("repo1") self.hg("init") def teardown(self): @@ -356,6 +363,67 @@ with acceptableerrors(*errors): self.hg(*command) + # Section: Repository management + @property + def currentrepo(self): + return os.path.basename(os.getcwd()) + + @rule( + target=repos, + source=repos, + name=reponames, + ) + def clone(self, source, name): + if not os.path.exists(os.path.join("..", name)): + self.cd("..") + self.hg("clone", source, name) + self.cd(name) + return name + + @rule( + target=repos, + name=reponames, + ) + def fresh(self, name): + if not os.path.exists(os.path.join("..", name)): + self.cd("..") + self.mkdirp(name) + self.cd(name) + self.hg("init") + return name + + @rule(name=repos) + def switch(self, name): + self.cd(os.path.join("..", name)) + assert self.currentrepo == name + assert os.path.exists(".hg") + + @rule(target=repos) + def origin(self): + return "repo1" + + @rule() + def pull(self, repo=repos): + with acceptableerrors( + "repository default not found", + "repository is unrelated", + ): + self.hg("pull") + + @rule(newbranch=st.booleans()) + def push(self, newbranch): + with acceptableerrors( + "default repository not configured", + "no changes found", + ): + if newbranch: + self.hg("push", "--new-branch") + else: + with acceptableerrors( + "creates new branches" + ): + self.hg("push") + # Section: Simple side effect free "check" operations @rule() def log(self):