Mercurial > hg
comparison tests/run-tests.py @ 24967:00790cc2b753
run-test: ensure the test ports are available before launching test
I'm running into a systematic issue because there is always some port taken in the
1500-wide range of ports used by the test (3 for each test file).
author | Pierre-Yves David <pierre-yves.david@fb.com> |
---|---|
date | Thu, 07 May 2015 17:14:00 -0700 |
parents | cecbe207cebd |
children | 2dadd81c68fb |
comparison
equal
deleted
inserted
replaced
24966:554d6fcc3c84 | 24967:00790cc2b753 |
---|---|
47 import optparse | 47 import optparse |
48 import os | 48 import os |
49 import shutil | 49 import shutil |
50 import subprocess | 50 import subprocess |
51 import signal | 51 import signal |
52 import socket | |
52 import sys | 53 import sys |
53 import tempfile | 54 import tempfile |
54 import time | 55 import time |
55 import random | 56 import random |
56 import re | 57 import re |
75 # zombies but it's pretty harmless even if we do. | 76 # zombies but it's pretty harmless even if we do. |
76 if sys.version_info < (2, 5): | 77 if sys.version_info < (2, 5): |
77 subprocess._cleanup = lambda: None | 78 subprocess._cleanup = lambda: None |
78 | 79 |
79 wifexited = getattr(os, "WIFEXITED", lambda x: False) | 80 wifexited = getattr(os, "WIFEXITED", lambda x: False) |
81 | |
82 def checkportisavailable(port): | |
83 """return true if a port seems free to bind on localhost""" | |
84 try: | |
85 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
86 s.bind(('localhost', port)) | |
87 s.close() | |
88 return True | |
89 except socket.error, exc: | |
90 if not exc.errno == errno.EADDRINUSE: | |
91 raise | |
92 return False | |
80 | 93 |
81 closefds = os.name == 'posix' | 94 closefds = os.name == 'posix' |
82 def Popen4(cmd, wd, timeout, env=None): | 95 def Popen4(cmd, wd, timeout, env=None): |
83 processlock.acquire() | 96 processlock.acquire() |
84 p = subprocess.Popen(cmd, shell=True, bufsize=-1, cwd=wd, env=env, | 97 p = subprocess.Popen(cmd, shell=True, bufsize=-1, cwd=wd, env=env, |
1606 self._tmpbinddir = None | 1619 self._tmpbinddir = None |
1607 self._pythondir = None | 1620 self._pythondir = None |
1608 self._coveragefile = None | 1621 self._coveragefile = None |
1609 self._createdfiles = [] | 1622 self._createdfiles = [] |
1610 self._hgpath = None | 1623 self._hgpath = None |
1624 self._portoffset = 0 | |
1625 self._ports = {} | |
1611 | 1626 |
1612 def run(self, args, parser=None): | 1627 def run(self, args, parser=None): |
1613 """Run the test suite.""" | 1628 """Run the test suite.""" |
1614 oldmask = os.umask(022) | 1629 oldmask = os.umask(022) |
1615 try: | 1630 try: |
1810 if failed: | 1825 if failed: |
1811 return 1 | 1826 return 1 |
1812 if warned: | 1827 if warned: |
1813 return 80 | 1828 return 80 |
1814 | 1829 |
1830 def _getport(self, count): | |
1831 port = self._ports.get(count) # do we have a cached entry? | |
1832 if port is None: | |
1833 port = self.options.port + self._portoffset | |
1834 portneeded = 3 | |
1835 # above 100 tries we just give up and let test reports failure | |
1836 for tries in xrange(100): | |
1837 allfree = True | |
1838 for idx in xrange(portneeded): | |
1839 if not checkportisavailable(port + idx): | |
1840 allfree = False | |
1841 break | |
1842 self._portoffset += portneeded | |
1843 if allfree: | |
1844 break | |
1845 self._ports[count] = port | |
1846 return port | |
1847 | |
1815 def _gettest(self, test, count): | 1848 def _gettest(self, test, count): |
1816 """Obtain a Test by looking at its filename. | 1849 """Obtain a Test by looking at its filename. |
1817 | 1850 |
1818 Returns a Test instance. The Test may not be runnable if it doesn't | 1851 Returns a Test instance. The Test may not be runnable if it doesn't |
1819 map to a known type. | 1852 map to a known type. |
1831 | 1864 |
1832 t = testcls(refpath, tmpdir, | 1865 t = testcls(refpath, tmpdir, |
1833 keeptmpdir=self.options.keep_tmpdir, | 1866 keeptmpdir=self.options.keep_tmpdir, |
1834 debug=self.options.debug, | 1867 debug=self.options.debug, |
1835 timeout=self.options.timeout, | 1868 timeout=self.options.timeout, |
1836 startport=self.options.port + count * 3, | 1869 startport=self._getport(count), |
1837 extraconfigopts=self.options.extra_config_opt, | 1870 extraconfigopts=self.options.extra_config_opt, |
1838 py3kwarnings=self.options.py3k_warnings, | 1871 py3kwarnings=self.options.py3k_warnings, |
1839 shell=self.options.shell) | 1872 shell=self.options.shell) |
1840 t.should_reload = True | 1873 t.should_reload = True |
1841 return t | 1874 return t |