xref: /OK3568_Linux_fs/buildroot/support/testing/tests/download/gitremote.py (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1# subprocess does not kill the child daemon when a test case fails by raising
2# an exception. So use pexpect instead.
3import infra
4
5import pexpect
6
7
8GIT_REMOTE_PORT_INITIAL = 9418
9GIT_REMOTE_PORT_LAST = GIT_REMOTE_PORT_INITIAL + 99
10
11
12class GitRemote(object):
13    def __init__(self, builddir, serveddir, logtofile):
14        """
15        Start a local git server.
16
17        In order to support test cases in parallel, select the port the
18        server will listen to in runtime. Since there is no reliable way
19        to allocate the port prior to starting the server (another
20        process in the host machine can use the port between it is
21        selected from a list and it is really allocated to the server)
22        try to start the server in a port and in the case it is already
23        in use, try the next one in the allowed range.
24        """
25        self.daemon = None
26        self.port = None
27        self.logfile = infra.open_log_file(builddir, "gitremote", logtofile)
28
29        daemon_cmd = ["git", "daemon", "--reuseaddr", "--verbose",
30                      "--listen=localhost", "--export-all",
31                      "--base-path={}".format(serveddir)]
32        for port in range(GIT_REMOTE_PORT_INITIAL, GIT_REMOTE_PORT_LAST + 1):
33            cmd = daemon_cmd + ["--port={port}".format(port=port)]
34            self.logfile.write("> starting git remote with '{}'\n".format(" ".join(cmd)))
35            self.daemon = pexpect.spawn(cmd[0], cmd[1:], logfile=self.logfile,
36                                        encoding='utf-8')
37            ret = self.daemon.expect(["Ready to rumble",
38                                      "Address already in use"])
39            if ret == 0:
40                self.port = port
41                return
42        raise SystemError("Could not find a free port to run git remote")
43
44    def stop(self):
45        if self.daemon is None:
46            return
47        self.daemon.terminate(force=True)
48