268 help='run statprof on run-tests') |
268 help='run statprof on run-tests') |
269 parser.add_option('--allow-slow-tests', action='store_true', |
269 parser.add_option('--allow-slow-tests', action='store_true', |
270 help='allow extremely slow tests') |
270 help='allow extremely slow tests') |
271 parser.add_option('--showchannels', action='store_true', |
271 parser.add_option('--showchannels', action='store_true', |
272 help='show scheduling channels') |
272 help='show scheduling channels') |
|
273 parser.add_option('--known-good-rev', type="string", |
|
274 metavar="known_good_rev", |
|
275 help=("Automatically bisect any failures using this " |
|
276 "revision as a known-good revision.")) |
273 |
277 |
274 for option, (envvar, default) in defaults.items(): |
278 for option, (envvar, default) in defaults.items(): |
275 defaults[option] = type(default)(os.environ.get(envvar, default)) |
279 defaults[option] = type(default)(os.environ.get(envvar, default)) |
276 parser.set_defaults(**defaults) |
280 parser.set_defaults(**defaults) |
277 |
281 |
1810 fp.writelines(("testreport =", jsonout)) |
1814 fp.writelines(("testreport =", jsonout)) |
1811 |
1815 |
1812 self._runner._checkhglib('Tested') |
1816 self._runner._checkhglib('Tested') |
1813 |
1817 |
1814 savetimes(self._runner._testdir, result) |
1818 savetimes(self._runner._testdir, result) |
|
1819 |
|
1820 if failed and self._runner.options.known_good_rev: |
|
1821 def nooutput(args): |
|
1822 p = subprocess.Popen(args, stderr=subprocess.STDOUT, |
|
1823 stdout=subprocess.PIPE) |
|
1824 p.stdout.read() |
|
1825 p.wait() |
|
1826 for test, msg in result.failures: |
|
1827 nooutput(['hg', 'bisect', '--reset']), |
|
1828 nooutput(['hg', 'bisect', '--bad', '.']) |
|
1829 nooutput(['hg', 'bisect', '--good', |
|
1830 self._runner.options.known_good_rev]) |
|
1831 # TODO: we probably need to forward some options |
|
1832 # that alter hg's behavior inside the tests. |
|
1833 rtc = '%s %s %s' % (sys.executable, sys.argv[0], test) |
|
1834 sub = subprocess.Popen(['hg', 'bisect', '--command', rtc], |
|
1835 stderr=subprocess.STDOUT, |
|
1836 stdout=subprocess.PIPE) |
|
1837 data = sub.stdout.read() |
|
1838 sub.wait() |
|
1839 m = re.search( |
|
1840 (r'\nThe first (?P<goodbad>bad|good) revision ' |
|
1841 r'is:\nchangeset: +\d:(?P<node>[a-f0-9]+)\n.*\n' |
|
1842 r'summary: +(?P<summary>[^\n]+)\n'), |
|
1843 data, (re.MULTILINE | re.DOTALL)) |
|
1844 if m is None: |
|
1845 self.stream.writeln( |
|
1846 'Failed to identify failure point for %s' % test) |
|
1847 continue |
|
1848 dat = m.groupdict() |
|
1849 verb = 'broken' if dat['goodbad'] == 'bad' else 'fixed' |
|
1850 self.stream.writeln( |
|
1851 '%s %s by %s (%s)' % ( |
|
1852 test, verb, dat['node'], dat['summary'])) |
1815 self.stream.writeln( |
1853 self.stream.writeln( |
1816 '# Ran %d tests, %d skipped, %d warned, %d failed.' |
1854 '# Ran %d tests, %d skipped, %d warned, %d failed.' |
1817 % (result.testsRun, |
1855 % (result.testsRun, |
1818 skipped + ignored, warned, failed)) |
1856 skipped + ignored, warned, failed)) |
1819 if failed: |
1857 if failed: |