[Buildroot] [next v2 4/7] testing/tests/download: add infra for git tests

Ricardo Martincoski ricardo.martincoski at gmail.com
Sat Aug 26 22:20:53 UTC 2017


From: Ricardo Martincoski <ricardo.martincoski at datacom.ind.br>

Add GitRemote class, that can start a git server in the host machine to
emulate a remote git server under the control of the test.

Add a new base class, called GitTestBase, that inherits from BRTest and
must be subclassed by all git test cases.
Its setUp() method takes care of configuring the build with a
br2-external, avoiding to hit http://sources.buildroot.net by using an
empty BR2_BACKUP_SITE. It also avoids downloading not pre-installed
dependencies (i.e. lzip) every time by calling 'make dependencies' using
the common dl directory, and it instantiates the GitRemote object.
Its tearDown() method cleans things up similarly to the one from BRTest.

Cc: Arnout Vandecappelle <arnout at mind.be>
Signed-off-by: Ricardo Martincoski <ricardo.martincoski at datacom.ind.br>
---
Changes v1 -> v2:
  - use git daemon + git:// instead of ssh (Arnout);
  - remove __main__ handling since the test infra already does that;
  - use the logging support from test infra;
  - this patch is part of series 1/3 of a new version of
    http://patchwork.ozlabs.org/patch/690097/
---
 support/testing/tests/download/__init__.py  |  0
 support/testing/tests/download/gitbase.py   | 41 +++++++++++++++++++++++
 support/testing/tests/download/gitremote.py | 50 +++++++++++++++++++++++++++++
 3 files changed, 91 insertions(+)
 create mode 100644 support/testing/tests/download/__init__.py
 create mode 100644 support/testing/tests/download/gitbase.py
 create mode 100644 support/testing/tests/download/gitremote.py

diff --git a/support/testing/tests/download/__init__.py b/support/testing/tests/download/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/support/testing/tests/download/gitbase.py b/support/testing/tests/download/gitbase.py
new file mode 100644
index 0000000000..b259914c77
--- /dev/null
+++ b/support/testing/tests/download/gitbase.py
@@ -0,0 +1,41 @@
+import infra.basetest
+from infra.builder import Builder
+from gitremote import GitRemote
+
+
+class GitTestBase(infra.basetest.BRTest):
+    config = \
+        """
+        BR2_BACKUP_SITE=""
+        """
+    br2_external = None
+    serveddir = None
+    gitremote = None
+    logfile = None
+
+    def setUp(self):
+        self.show_msg("Starting")
+        self.b = Builder(self.config, self.builddir, self.logtofile)
+
+        if not self.keepbuilds:
+            self.b.delete()
+
+        if not self.b.is_finished():
+            self.show_msg("Configuring")
+            self.b.configure(["BR2_EXTERNAL={}".format(self.br2_external)])
+            # do not download not pre-installed dependencies (i.e. lzip) every
+            # time a test runs
+            self.b.build(["dependencies"])
+
+        self.gitremote = GitRemote(self.builddir, self.serveddir,
+                                   self.logtofile)
+        # send output from the test to the logfile created by GitRemote
+        self.logfile = self.gitremote.logfile
+        self.gitremote.start()
+
+    def tearDown(self):
+        self.show_msg("Cleaning up")
+        if self.gitremote:
+            self.gitremote.stop()
+        if self.b and not self.keepbuilds:
+            self.b.delete()
diff --git a/support/testing/tests/download/gitremote.py b/support/testing/tests/download/gitremote.py
new file mode 100644
index 0000000000..84d1036889
--- /dev/null
+++ b/support/testing/tests/download/gitremote.py
@@ -0,0 +1,50 @@
+# subprocess does not kill the child daemon when a test case fails by raising
+# an exception. So use pexpect instead.
+import pexpect
+
+import infra
+
+GIT_REMOTE_PORT_INITIAL = 9418
+GIT_REMOTE_PORT_LAST = GIT_REMOTE_PORT_INITIAL + 99
+
+
+class GitRemote(object):
+
+    def __init__(self, builddir, serveddir, logtofile):
+        self.daemon = None
+        self.port = None
+        self.serveddir = serveddir
+        self.logfile = infra.open_log_file(builddir, "run", logtofile)
+
+    # Start a local git server
+    #
+    # In order to support test cases in parallel, select the port the server
+    # will listen to in runtime. Since there is no reliable way to allocate the
+    # port prior to starting the server (another process in the host machine
+    # can use the port between it is selected from a list and it is really
+    # allocated to the server) try to start the server in a port and in the
+    # case it is already in use, try the next one in the allowed range.
+    #
+    def start(self):
+        daemon_cmd = ["git", "daemon", "--reuseaddr", "--verbose",
+                      "--listen=localhost", "--export-all",
+                      "--base-path={}".format(self.serveddir)]
+        for port in range(GIT_REMOTE_PORT_INITIAL, GIT_REMOTE_PORT_LAST):
+            port_arg = ["--port={}".format(port)]
+            cmd = daemon_cmd + port_arg
+            self.logfile.write("> starting git remote with '{}'\n"
+                               .format(" ".join(cmd)))
+            self.daemon = pexpect.spawn(cmd[0], cmd[1:], logfile=self.logfile)
+            ret = self.daemon.expect(["Ready to rumble",
+                                      "Address already in use"])
+            if ret == 0:
+                self.port = port
+                break
+            self.daemon.read()
+        if not self.port:
+            raise SystemError("Could not find a free port to run git remote")
+
+    def stop(self):
+        if self.daemon is None:
+            return
+        self.daemon.terminate(force=True)
-- 
2.13.0




More information about the buildroot mailing list