forked from mirrors/gecko-dev
Backed out changeset 19f707f5c097 (bug 1666347) Backed out changeset 3732ee259759 (bug 1666345) Backed out changeset 353d3c9e74b9 (bug 1661624) Backed out changeset a651515586a8 (bug 1667152)
162 lines
5.1 KiB
Python
162 lines
5.1 KiB
Python
#!/usr/bin/env python3
|
|
|
|
# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
|
|
"""
|
|
Unit test runner, providing new features on top of unittest module:
|
|
- colourized output (error, skip)
|
|
- print failures/tracebacks on CTRL+C
|
|
- re-run failed tests only (make test-failed)
|
|
"""
|
|
|
|
from __future__ import print_function
|
|
import optparse
|
|
import os
|
|
import sys
|
|
import unittest
|
|
from unittest import TestResult
|
|
from unittest import TextTestResult
|
|
from unittest import TextTestRunner
|
|
try:
|
|
import ctypes
|
|
except ImportError:
|
|
ctypes = None
|
|
|
|
import psutil
|
|
from psutil._common import hilite
|
|
from psutil._common import print_color
|
|
from psutil._common import term_supports_colors
|
|
from psutil.tests import safe_rmpath
|
|
from psutil.tests import TOX
|
|
|
|
|
|
HERE = os.path.abspath(os.path.dirname(__file__))
|
|
VERBOSITY = 1 if TOX else 2
|
|
FAILED_TESTS_FNAME = '.failed-tests.txt'
|
|
|
|
|
|
# =====================================================================
|
|
# --- unittest subclasses
|
|
# =====================================================================
|
|
|
|
|
|
class ColouredResult(TextTestResult):
|
|
|
|
def _print_color(self, s, color, bold=False):
|
|
file = sys.stderr if color == "red" else sys.stdout
|
|
print_color(s, color, bold=bold, file=file)
|
|
|
|
def addSuccess(self, test):
|
|
TestResult.addSuccess(self, test)
|
|
self._print_color("OK", "green")
|
|
|
|
def addError(self, test, err):
|
|
TestResult.addError(self, test, err)
|
|
self._print_color("ERROR", "red", bold=True)
|
|
|
|
def addFailure(self, test, err):
|
|
TestResult.addFailure(self, test, err)
|
|
self._print_color("FAIL", "red")
|
|
|
|
def addSkip(self, test, reason):
|
|
TestResult.addSkip(self, test, reason)
|
|
self._print_color("skipped: %s" % reason, "brown")
|
|
|
|
def printErrorList(self, flavour, errors):
|
|
flavour = hilite(flavour, "red", bold=flavour == 'ERROR')
|
|
TextTestResult.printErrorList(self, flavour, errors)
|
|
|
|
|
|
class ColouredRunner(TextTestRunner):
|
|
resultclass = ColouredResult if term_supports_colors() else TextTestResult
|
|
|
|
def _makeResult(self):
|
|
# Store result instance so that it can be accessed on
|
|
# KeyboardInterrupt.
|
|
self.result = TextTestRunner._makeResult(self)
|
|
return self.result
|
|
|
|
|
|
# =====================================================================
|
|
# --- public API
|
|
# =====================================================================
|
|
|
|
|
|
def setup_tests():
|
|
if 'PSUTIL_TESTING' not in os.environ:
|
|
# This won't work on Windows but set_testing() below will do it.
|
|
os.environ['PSUTIL_TESTING'] = '1'
|
|
psutil._psplatform.cext.set_testing()
|
|
|
|
|
|
def get_suite(name=None):
|
|
suite = unittest.TestSuite()
|
|
if name is None:
|
|
testmods = [os.path.splitext(x)[0] for x in os.listdir(HERE)
|
|
if x.endswith('.py') and x.startswith('test_') and not
|
|
x.startswith('test_memory_leaks')]
|
|
if "WHEELHOUSE_UPLOADER_USERNAME" in os.environ:
|
|
testmods = [x for x in testmods if not x.endswith((
|
|
"osx", "posix", "linux"))]
|
|
for tm in testmods:
|
|
# ...so that the full test paths are printed on screen
|
|
tm = "psutil.tests.%s" % tm
|
|
suite.addTest(unittest.defaultTestLoader.loadTestsFromName(tm))
|
|
else:
|
|
name = os.path.splitext(os.path.basename(name))[0]
|
|
suite.addTest(unittest.defaultTestLoader.loadTestsFromName(name))
|
|
return suite
|
|
|
|
|
|
def get_suite_from_failed():
|
|
# ...from previously failed test run
|
|
suite = unittest.TestSuite()
|
|
if not os.path.isfile(FAILED_TESTS_FNAME):
|
|
return suite
|
|
with open(FAILED_TESTS_FNAME, 'rt') as f:
|
|
names = f.read().split()
|
|
for n in names:
|
|
suite.addTest(unittest.defaultTestLoader.loadTestsFromName(n))
|
|
return suite
|
|
|
|
|
|
def save_failed_tests(result):
|
|
if result.wasSuccessful():
|
|
return safe_rmpath(FAILED_TESTS_FNAME)
|
|
with open(FAILED_TESTS_FNAME, 'wt') as f:
|
|
for t in result.errors + result.failures:
|
|
tname = str(t[0])
|
|
unittest.defaultTestLoader.loadTestsFromName(tname)
|
|
f.write(tname + '\n')
|
|
|
|
|
|
def run(name=None, last_failed=False):
|
|
setup_tests()
|
|
runner = ColouredRunner(verbosity=VERBOSITY)
|
|
suite = get_suite_from_failed() if last_failed else get_suite(name)
|
|
try:
|
|
result = runner.run(suite)
|
|
except (KeyboardInterrupt, SystemExit) as err:
|
|
print("received %s" % err.__class__.__name__, file=sys.stderr)
|
|
runner.result.printErrors()
|
|
sys.exit(1)
|
|
else:
|
|
save_failed_tests(result)
|
|
success = result.wasSuccessful()
|
|
sys.exit(0 if success else 1)
|
|
|
|
|
|
def main():
|
|
usage = "python3 -m psutil.tests [opts]"
|
|
parser = optparse.OptionParser(usage=usage, description="run unit tests")
|
|
parser.add_option("--last-failed",
|
|
action="store_true", default=False,
|
|
help="only run last failed tests")
|
|
opts, args = parser.parse_args()
|
|
run(last_failed=opts.last_failed)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|