##// END OF EJS Templates
run-tests: switch all uses of iolock.acquire() to a context manager
Augie Fackler -
r25046:40b4308d default
parent child Browse files
Show More
@@ -371,14 +371,13 b' def log(*msg):'
371
371
372 Arguments are strings to print.
372 Arguments are strings to print.
373 """
373 """
374 iolock.acquire()
374 with iolock:
375 if verbose:
375 if verbose:
376 print(verbose, end=' ')
376 print(verbose, end=' ')
377 for m in msg:
377 for m in msg:
378 print(m, end=' ')
378 print(m, end=' ')
379 print()
379 print()
380 sys.stdout.flush()
380 sys.stdout.flush()
381 iolock.release()
382
381
383 def terminate(proc):
382 def terminate(proc):
384 """Terminate subprocess (with fallback for Python versions < 2.6)"""
383 """Terminate subprocess (with fallback for Python versions < 2.6)"""
@@ -1209,18 +1208,16 b' class TestResult(unittest._TextTestResul'
1209 if self._options.first:
1208 if self._options.first:
1210 self.stop()
1209 self.stop()
1211 else:
1210 else:
1212 iolock.acquire()
1211 with iolock:
1213 if not self._options.nodiff:
1212 if not self._options.nodiff:
1214 self.stream.write('\nERROR: %s output changed\n' % test)
1213 self.stream.write('\nERROR: %s output changed\n' % test)
1215
1214
1216 self.stream.write('!')
1215 self.stream.write('!')
1217 self.stream.flush()
1216 self.stream.flush()
1218 iolock.release()
1219
1217
1220 def addSuccess(self, test):
1218 def addSuccess(self, test):
1221 iolock.acquire()
1219 with iolock:
1222 super(TestResult, self).addSuccess(test)
1220 super(TestResult, self).addSuccess(test)
1223 iolock.release()
1224 self.successes.append(test)
1221 self.successes.append(test)
1225
1222
1226 def addError(self, test, err):
1223 def addError(self, test, err):
@@ -1231,26 +1228,24 b' class TestResult(unittest._TextTestResul'
1231 # Polyfill.
1228 # Polyfill.
1232 def addSkip(self, test, reason):
1229 def addSkip(self, test, reason):
1233 self.skipped.append((test, reason))
1230 self.skipped.append((test, reason))
1234 iolock.acquire()
1231 with iolock:
1235 if self.showAll:
1232 if self.showAll:
1236 self.stream.writeln('skipped %s' % reason)
1233 self.stream.writeln('skipped %s' % reason)
1237 else:
1234 else:
1238 self.stream.write('s')
1235 self.stream.write('s')
1239 self.stream.flush()
1236 self.stream.flush()
1240 iolock.release()
1241
1237
1242 def addIgnore(self, test, reason):
1238 def addIgnore(self, test, reason):
1243 self.ignored.append((test, reason))
1239 self.ignored.append((test, reason))
1244 iolock.acquire()
1240 with iolock:
1245 if self.showAll:
1241 if self.showAll:
1246 self.stream.writeln('ignored %s' % reason)
1242 self.stream.writeln('ignored %s' % reason)
1247 else:
1248 if reason != 'not retesting' and reason != "doesn't match keyword":
1249 self.stream.write('i')
1250 else:
1243 else:
1251 self.testsRun += 1
1244 if reason not in ('not retesting', "doesn't match keyword"):
1252 self.stream.flush()
1245 self.stream.write('i')
1253 iolock.release()
1246 else:
1247 self.testsRun += 1
1248 self.stream.flush()
1254
1249
1255 def addWarn(self, test, reason):
1250 def addWarn(self, test, reason):
1256 self.warned.append((test, reason))
1251 self.warned.append((test, reason))
@@ -1258,13 +1253,12 b' class TestResult(unittest._TextTestResul'
1258 if self._options.first:
1253 if self._options.first:
1259 self.stop()
1254 self.stop()
1260
1255
1261 iolock.acquire()
1256 with iolock:
1262 if self.showAll:
1257 if self.showAll:
1263 self.stream.writeln('warned %s' % reason)
1258 self.stream.writeln('warned %s' % reason)
1264 else:
1259 else:
1265 self.stream.write('~')
1260 self.stream.write('~')
1266 self.stream.flush()
1261 self.stream.flush()
1267 iolock.release()
1268
1262
1269 def addOutputMismatch(self, test, ret, got, expected):
1263 def addOutputMismatch(self, test, ret, got, expected):
1270 """Record a mismatch in test output for a particular test."""
1264 """Record a mismatch in test output for a particular test."""
@@ -1278,38 +1272,37 b' class TestResult(unittest._TextTestResul'
1278 failed = False
1272 failed = False
1279 lines = []
1273 lines = []
1280
1274
1281 iolock.acquire()
1275 with iolock:
1282 if self._options.nodiff:
1276 if self._options.nodiff:
1283 pass
1277 pass
1284 elif self._options.view:
1278 elif self._options.view:
1285 os.system("%s %s %s" %
1279 os.system("%s %s %s" %
1286 (self._options.view, test.refpath, test.errpath))
1280 (self._options.view, test.refpath, test.errpath))
1287 else:
1288 servefail, lines = getdiff(expected, got,
1289 test.refpath, test.errpath)
1290 if servefail:
1291 self.addFailure(
1292 test,
1293 'server failed to start (HGPORT=%s)' % test._startport)
1294 else:
1281 else:
1295 self.stream.write('\n')
1282 servefail, lines = getdiff(expected, got,
1296 for line in lines:
1283 test.refpath, test.errpath)
1297 self.stream.write(line)
1284 if servefail:
1298 self.stream.flush()
1285 self.addFailure(
1286 test,
1287 'server failed to start (HGPORT=%s)' % test._startport)
1288 else:
1289 self.stream.write('\n')
1290 for line in lines:
1291 self.stream.write(line)
1292 self.stream.flush()
1299
1293
1300 # handle interactive prompt without releasing iolock
1294 # handle interactive prompt without releasing iolock
1301 if self._options.interactive:
1295 if self._options.interactive:
1302 self.stream.write('Accept this change? [n] ')
1296 self.stream.write('Accept this change? [n] ')
1303 answer = sys.stdin.readline().strip()
1297 answer = sys.stdin.readline().strip()
1304 if answer.lower() in ('y', 'yes'):
1298 if answer.lower() in ('y', 'yes'):
1305 if test.name.endswith('.t'):
1299 if test.name.endswith('.t'):
1306 rename(test.errpath, test.path)
1300 rename(test.errpath, test.path)
1307 else:
1301 else:
1308 rename(test.errpath, '%s.out' % test.path)
1302 rename(test.errpath, '%s.out' % test.path)
1309 accepted = True
1303 accepted = True
1310 if not accepted and not failed:
1304 if not accepted and not failed:
1311 self.faildata[test.name] = ''.join(lines)
1305 self.faildata[test.name] = ''.join(lines)
1312 iolock.release()
1313
1306
1314 return accepted
1307 return accepted
1315
1308
@@ -1336,10 +1329,9 b' class TestResult(unittest._TextTestResul'
1336 ))
1329 ))
1337
1330
1338 if interrupted:
1331 if interrupted:
1339 iolock.acquire()
1332 with iolock:
1340 self.stream.writeln('INTERRUPTED: %s (after %d seconds)' % (
1333 self.stream.writeln('INTERRUPTED: %s (after %d seconds)' % (
1341 test.name, self.times[-1][3]))
1334 test.name, self.times[-1][3]))
1342 iolock.release()
1343
1335
1344 class TestSuite(unittest.TestSuite):
1336 class TestSuite(unittest.TestSuite):
1345 """Custom unittest TestSuite that knows how to execute Mercurial tests."""
1337 """Custom unittest TestSuite that knows how to execute Mercurial tests."""
@@ -1502,91 +1494,91 b' class TextTestRunner(unittest.TextTestRu'
1502 skipped = len(result.skipped)
1494 skipped = len(result.skipped)
1503 ignored = len(result.ignored)
1495 ignored = len(result.ignored)
1504
1496
1505 iolock.acquire()
1497 with iolock:
1506 self.stream.writeln('')
1498 self.stream.writeln('')
1507
1499
1508 if not self._runner.options.noskips:
1500 if not self._runner.options.noskips:
1509 for test, msg in result.skipped:
1501 for test, msg in result.skipped:
1510 self.stream.writeln('Skipped %s: %s' % (test.name, msg))
1502 self.stream.writeln('Skipped %s: %s' % (test.name, msg))
1511 for test, msg in result.warned:
1503 for test, msg in result.warned:
1512 self.stream.writeln('Warned %s: %s' % (test.name, msg))
1504 self.stream.writeln('Warned %s: %s' % (test.name, msg))
1513 for test, msg in result.failures:
1505 for test, msg in result.failures:
1514 self.stream.writeln('Failed %s: %s' % (test.name, msg))
1506 self.stream.writeln('Failed %s: %s' % (test.name, msg))
1515 for test, msg in result.errors:
1507 for test, msg in result.errors:
1516 self.stream.writeln('Errored %s: %s' % (test.name, msg))
1508 self.stream.writeln('Errored %s: %s' % (test.name, msg))
1517
1509
1518 if self._runner.options.xunit:
1510 if self._runner.options.xunit:
1519 xuf = open(self._runner.options.xunit, 'wb')
1511 xuf = open(self._runner.options.xunit, 'wb')
1520 try:
1512 try:
1521 timesd = dict((t[0], t[3]) for t in result.times)
1513 timesd = dict((t[0], t[3]) for t in result.times)
1522 doc = minidom.Document()
1514 doc = minidom.Document()
1523 s = doc.createElement('testsuite')
1515 s = doc.createElement('testsuite')
1524 s.setAttribute('name', 'run-tests')
1516 s.setAttribute('name', 'run-tests')
1525 s.setAttribute('tests', str(result.testsRun))
1517 s.setAttribute('tests', str(result.testsRun))
1526 s.setAttribute('errors', "0") # TODO
1518 s.setAttribute('errors', "0") # TODO
1527 s.setAttribute('failures', str(failed))
1519 s.setAttribute('failures', str(failed))
1528 s.setAttribute('skipped', str(skipped + ignored))
1520 s.setAttribute('skipped', str(skipped + ignored))
1529 doc.appendChild(s)
1521 doc.appendChild(s)
1530 for tc in result.successes:
1522 for tc in result.successes:
1531 t = doc.createElement('testcase')
1523 t = doc.createElement('testcase')
1532 t.setAttribute('name', tc.name)
1524 t.setAttribute('name', tc.name)
1533 t.setAttribute('time', '%.3f' % timesd[tc.name])
1525 t.setAttribute('time', '%.3f' % timesd[tc.name])
1534 s.appendChild(t)
1526 s.appendChild(t)
1535 for tc, err in sorted(result.faildata.iteritems()):
1527 for tc, err in sorted(result.faildata.iteritems()):
1536 t = doc.createElement('testcase')
1528 t = doc.createElement('testcase')
1537 t.setAttribute('name', tc)
1529 t.setAttribute('name', tc)
1538 t.setAttribute('time', '%.3f' % timesd[tc])
1530 t.setAttribute('time', '%.3f' % timesd[tc])
1539 # createCDATASection expects a unicode or it will convert
1531 # createCDATASection expects a unicode or it will
1540 # using default conversion rules, which will fail if
1532 # convert using default conversion rules, which will
1541 # string isn't ASCII.
1533 # fail if string isn't ASCII.
1542 err = cdatasafe(err).decode('utf-8', 'replace')
1534 err = cdatasafe(err).decode('utf-8', 'replace')
1543 cd = doc.createCDATASection(err)
1535 cd = doc.createCDATASection(err)
1544 t.appendChild(cd)
1536 t.appendChild(cd)
1545 s.appendChild(t)
1537 s.appendChild(t)
1546 xuf.write(doc.toprettyxml(indent=' ', encoding='utf-8'))
1538 xuf.write(doc.toprettyxml(indent=' ', encoding='utf-8'))
1547 finally:
1539 finally:
1548 xuf.close()
1540 xuf.close()
1549
1541
1550 if self._runner.options.json:
1542 if self._runner.options.json:
1551 if json is None:
1543 if json is None:
1552 raise ImportError("json module not installed")
1544 raise ImportError("json module not installed")
1553 jsonpath = os.path.join(self._runner._testdir, 'report.json')
1545 jsonpath = os.path.join(self._runner._testdir, 'report.json')
1554 fp = open(jsonpath, 'w')
1546 fp = open(jsonpath, 'w')
1555 try:
1547 try:
1556 timesd = {}
1548 timesd = {}
1557 for tdata in result.times:
1549 for tdata in result.times:
1558 test = tdata[0]
1550 test = tdata[0]
1559 timesd[test] = tdata[1:]
1551 timesd[test] = tdata[1:]
1560
1552
1561 outcome = {}
1553 outcome = {}
1562 groups = [('success', ((tc, None) for tc in result.successes)),
1554 groups = [('success', ((tc, None)
1563 ('failure', result.failures),
1555 for tc in result.successes)),
1564 ('skip', result.skipped)]
1556 ('failure', result.failures),
1565 for res, testcases in groups:
1557 ('skip', result.skipped)]
1566 for tc, __ in testcases:
1558 for res, testcases in groups:
1567 testresult = {'result': res,
1559 for tc, __ in testcases:
1568 'time': ('%0.3f' % timesd[tc.name][2]),
1560 tres = {'result': res,
1569 'cuser': ('%0.3f' % timesd[tc.name][0]),
1561 'time': ('%0.3f' % timesd[tc.name][2]),
1570 'csys': ('%0.3f' % timesd[tc.name][1])}
1562 'cuser': ('%0.3f' % timesd[tc.name][0]),
1571 outcome[tc.name] = testresult
1563 'csys': ('%0.3f' % timesd[tc.name][1])}
1564 outcome[tc.name] = tres
1572
1565
1573 jsonout = json.dumps(outcome, sort_keys=True, indent=4)
1566 jsonout = json.dumps(outcome, sort_keys=True, indent=4)
1574 fp.writelines(("testreport =", jsonout))
1567 fp.writelines(("testreport =", jsonout))
1575 finally:
1568 finally:
1576 fp.close()
1569 fp.close()
1577
1570
1578 self._runner._checkhglib('Tested')
1571 self._runner._checkhglib('Tested')
1579
1572
1580 self.stream.writeln('# Ran %d tests, %d skipped, %d warned, %d failed.'
1573 self.stream.writeln(
1581 % (result.testsRun,
1574 '# Ran %d tests, %d skipped, %d warned, %d failed.'
1582 skipped + ignored, warned, failed))
1575 % (result.testsRun,
1583 if failed:
1576 skipped + ignored, warned, failed))
1584 self.stream.writeln('python hash seed: %s' %
1577 if failed:
1585 os.environ['PYTHONHASHSEED'])
1578 self.stream.writeln('python hash seed: %s' %
1586 if self._runner.options.time:
1579 os.environ['PYTHONHASHSEED'])
1587 self.printtimes(result.times)
1580 if self._runner.options.time:
1588
1581 self.printtimes(result.times)
1589 iolock.release()
1590
1582
1591 return result
1583 return result
1592
1584
General Comments 0
You need to be logged in to leave comments. Login now