gitremote.py 1.9 KB

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