| Index: tests/fake_repos.py
|
| diff --git a/tests/fake_repos.py b/tests/fake_repos.py
|
| index 7706bb25377970634aeef363ad452688acd4048f..09d873c8e89ba59f30d2c266e2963fa4b20e01bf 100755
|
| --- a/tests/fake_repos.py
|
| +++ b/tests/fake_repos.py
|
| @@ -152,6 +152,68 @@ def commit_git(repo):
|
| return rev
|
|
|
|
|
| +def test_port(host, port):
|
| + s = socket.socket()
|
| + try:
|
| + return s.connect_ex((host, port)) == 0
|
| + finally:
|
| + s.close()
|
| +
|
| +
|
| +def find_free_port(host, base_port):
|
| + """Finds a listening port free to listen to."""
|
| + while base_port < (2<<16):
|
| + if not test_port(host, base_port):
|
| + return base_port
|
| + base_port += 1
|
| + assert False, 'Having issues finding an available port'
|
| +
|
| +
|
| +def wait_for_port_to_bind(host, port, process):
|
| + sock = socket.socket()
|
| +
|
| + if sys.platform == 'darwin':
|
| + # On Mac SnowLeopard, if we attempt to connect to the socket
|
| + # immediately, it fails with EINVAL and never gets a chance to
|
| + # connect (putting us into a hard spin and then failing).
|
| + # Linux doesn't need this.
|
| + time.sleep(0.1)
|
| +
|
| + try:
|
| + start = datetime.datetime.utcnow()
|
| + maxdelay = datetime.timedelta(seconds=30)
|
| + while (datetime.datetime.utcnow() - start) < maxdelay:
|
| + try:
|
| + sock.connect((host, port))
|
| + logging.debug('%d is now bound' % port)
|
| + return
|
| + except EnvironmentError:
|
| + pass
|
| + logging.debug('%d is still not bound' % port)
|
| + finally:
|
| + sock.close()
|
| + # The process failed to bind. Kill it and dump its ouput.
|
| + process.kill()
|
| + logging.error('%s' % process.communicate()[0])
|
| + assert False, '%d is still not bound' % port
|
| +
|
| +
|
| +def wait_for_port_to_free(host, port):
|
| + start = datetime.datetime.utcnow()
|
| + maxdelay = datetime.timedelta(seconds=30)
|
| + while (datetime.datetime.utcnow() - start) < maxdelay:
|
| + try:
|
| + sock = socket.socket()
|
| + sock.connect((host, port))
|
| + logging.debug('%d was bound, waiting to free' % port)
|
| + except EnvironmentError:
|
| + logging.debug('%d now free' % port)
|
| + return
|
| + finally:
|
| + sock.close()
|
| + assert False, '%d is still bound' % port
|
| +
|
| +
|
| _FAKE_LOADED = False
|
|
|
| class FakeReposBase(object):
|
| @@ -195,10 +257,10 @@ class FakeReposBase(object):
|
| self.svn_repo = None
|
| self.git_dirty = False
|
| self.svn_dirty = False
|
| - self.svn_base = 'svn://%s/svn/' % self.host
|
| - self.git_base = 'git://%s/git/' % self.host
|
| - self.svn_port = 3690
|
| - self.git_port = 9418
|
| + self.svn_port = None
|
| + self.git_port = None
|
| + self.svn_base = None
|
| + self.git_base = None
|
|
|
| @property
|
| def root_dir(self):
|
| @@ -244,8 +306,10 @@ class FakeReposBase(object):
|
| except OSError, e:
|
| if e.errno != errno.ESRCH: # no such process
|
| raise
|
| - self.wait_for_port_to_free(self.svn_port)
|
| + wait_for_port_to_free(self.host, self.svn_port)
|
| self.svnserve = None
|
| + self.svn_port = None
|
| + self.svn_base = None
|
| if not self.trial.SHOULD_LEAK:
|
| logging.debug('Removing %s' % self.svn_repo)
|
| gclient_utils.rmtree(self.svn_repo)
|
| @@ -266,7 +330,9 @@ class FakeReposBase(object):
|
| logging.debug('Killing git daemon pid %s' % pid)
|
| kill_pid(pid)
|
| self.git_pid_file = None
|
| - self.wait_for_port_to_free(self.git_port)
|
| + wait_for_port_to_free(self.host, self.git_port)
|
| + self.git_port = None
|
| + self.git_base = None
|
| if not self.trial.SHOULD_LEAK:
|
| logging.debug('Removing %s' % self.git_root)
|
| gclient_utils.rmtree(self.git_root)
|
| @@ -316,12 +382,15 @@ class FakeReposBase(object):
|
| 'enable-rep-sharing = false\n')
|
|
|
| # Start the daemon.
|
| - cmd = ['svnserve', '-d', '--foreground', '-r', self.root_dir]
|
| + self.svn_port = find_free_port(self.host, 10000)
|
| + cmd = ['svnserve', '-d', '--foreground', '-r', self.root_dir,
|
| + '--listen-port=%d' % self.svn_port]
|
| if self.host == '127.0.0.1':
|
| cmd.append('--listen-host=' + self.host)
|
| self.check_port_is_free(self.svn_port)
|
| self.svnserve = Popen(cmd, cwd=self.svn_repo)
|
| - self.wait_for_port_to_bind(self.svn_port, self.svnserve)
|
| + wait_for_port_to_bind(self.host, self.svn_port, self.svnserve)
|
| + self.svn_base = 'svn://%s:%d/svn/' % (self.host, self.svn_port)
|
| self.populateSvn()
|
| self.svn_dirty = False
|
| return True
|
| @@ -337,20 +406,22 @@ class FakeReposBase(object):
|
| for repo in ['repo_%d' % r for r in range(1, self.NB_GIT_REPOS + 1)]:
|
| check_call(['git', 'init', '-q', join(self.git_root, repo)])
|
| self.git_hashes[repo] = [None]
|
| - # Unlike svn, populate git before starting the server.
|
| - self.populateGit()
|
| + self.git_port = find_free_port(self.host, 20000)
|
| + self.git_base = 'git://%s:%d/git/' % (self.host, self.git_port)
|
| # Start the daemon.
|
| self.git_pid_file = tempfile.NamedTemporaryFile()
|
| cmd = ['git', 'daemon',
|
| '--export-all',
|
| '--reuseaddr',
|
| '--base-path=' + self.root_dir,
|
| - '--pid-file=' + self.git_pid_file.name]
|
| + '--pid-file=' + self.git_pid_file.name,
|
| + '--port=%d' % self.git_port]
|
| if self.host == '127.0.0.1':
|
| cmd.append('--listen=' + self.host)
|
| self.check_port_is_free(self.git_port)
|
| self.gitdaemon = Popen(cmd, cwd=self.root_dir)
|
| - self.wait_for_port_to_bind(self.git_port, self.gitdaemon)
|
| + wait_for_port_to_bind(self.host, self.git_port, self.gitdaemon)
|
| + self.populateGit()
|
| self.git_dirty = False
|
| return True
|
|
|
| @@ -386,49 +457,6 @@ class FakeReposBase(object):
|
| finally:
|
| sock.close()
|
|
|
| - def wait_for_port_to_bind(self, port, process):
|
| - sock = socket.socket()
|
| -
|
| - if sys.platform == 'darwin':
|
| - # On Mac SnowLeopard, if we attempt to connect to the socket
|
| - # immediately, it fails with EINVAL and never gets a chance to
|
| - # connect (putting us into a hard spin and then failing).
|
| - # Linux doesn't need this.
|
| - time.sleep(0.1)
|
| -
|
| - try:
|
| - start = datetime.datetime.utcnow()
|
| - maxdelay = datetime.timedelta(seconds=30)
|
| - while (datetime.datetime.utcnow() - start) < maxdelay:
|
| - try:
|
| - sock.connect((self.host, port))
|
| - logging.debug('%d is now bound' % port)
|
| - return
|
| - except EnvironmentError:
|
| - pass
|
| - logging.debug('%d is still not bound' % port)
|
| - finally:
|
| - sock.close()
|
| - # The process failed to bind. Kill it and dump its ouput.
|
| - process.kill()
|
| - logging.error('%s' % process.communicate()[0])
|
| - assert False, '%d is still not bound' % port
|
| -
|
| - def wait_for_port_to_free(self, port):
|
| - start = datetime.datetime.utcnow()
|
| - maxdelay = datetime.timedelta(seconds=30)
|
| - while (datetime.datetime.utcnow() - start) < maxdelay:
|
| - try:
|
| - sock = socket.socket()
|
| - sock.connect((self.host, port))
|
| - logging.debug('%d was bound, waiting to free' % port)
|
| - except EnvironmentError:
|
| - logging.debug('%d now free' % port)
|
| - return
|
| - finally:
|
| - sock.close()
|
| - assert False, '%d is still bound' % port
|
| -
|
| def populateSvn(self):
|
| raise NotImplementedError()
|
|
|
|
|