Patchwork [3,of,5,V4] testing: test multiple repositories with Hypothesis

login
register
mail settings
Submitter David MacIver
Date Feb. 24, 2016, 2:22 p.m.
Message ID <13f223321e26e4dd3873.1456323777@laser-shark>
Download mbox | patch
Permalink /patch/13349/
State Superseded
Headers show

Comments

David MacIver - Feb. 24, 2016, 2:22 p.m.
# HG changeset patch
# User David R. MacIver <david@drmaciver.com>
# Date 1456319346 0
#      Wed Feb 24 13:09:06 2016 +0000
# Node ID 13f223321e26e4dd387367c532366f4e5a63f05b
# Parent  3426830684771340e16691a213d52d92cf655854
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.

Patch

diff -r 342683068477 -r 13f223321e26 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	Wed Feb 24 13:09:06 2016 +0000
@@ -89,6 +89,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.
@@ -112,6 +116,7 @@ 
 
     # A bundle is a reusable collection of data that rules have previously
     # generated which may be provided as arguments to future rules.
+    repos = Bundle('repos')
     paths = Bundle('paths')
     contents = Bundle('contents')
     branches = Bundle('branches')
@@ -119,7 +124,7 @@ 
 
     def __init__(self):
         super(verifyingstatemachine, self).__init__()
-        self.repodir = os.path.join(testtmp, "repo")
+        self.repodir = os.path.join(testtmp, "repos")
         assert self.repodir.startswith("/tmp/")
         if os.path.exists(self.repodir):
             shutil.rmtree(self.repodir)
@@ -127,8 +132,10 @@ 
         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):
@@ -333,6 +340,64 @@ 
         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"):
+            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):