ยปCore Development>Code coverage>Lib/test/libregrtest/runtest.py

Python code coverage for Lib/test/libregrtest/runtest.py

#countcontent
1n/aimport faulthandler
2n/aimport importlib
3n/aimport io
4n/aimport os
5n/aimport sys
6n/aimport time
7n/aimport traceback
8n/aimport unittest
9n/afrom test import support
10n/afrom test.libregrtest.refleak import dash_R, clear_caches
11n/afrom test.libregrtest.save_env import saved_test_environment
12n/a
13n/a
14n/a# Test result constants.
15n/aPASSED = 1
16n/aFAILED = 0
17n/aENV_CHANGED = -1
18n/aSKIPPED = -2
19n/aRESOURCE_DENIED = -3
20n/aINTERRUPTED = -4
21n/aCHILD_ERROR = -5 # error in a child process
22n/a
23n/a_FORMAT_TEST_RESULT = {
24n/a PASSED: '%s passed',
25n/a FAILED: '%s failed',
26n/a ENV_CHANGED: '%s failed (env changed)',
27n/a SKIPPED: '%s skipped',
28n/a RESOURCE_DENIED: '%s skipped (resource denied)',
29n/a INTERRUPTED: '%s interrupted',
30n/a CHILD_ERROR: '%s crashed',
31n/a}
32n/a
33n/a# Minimum duration of a test to display its duration or to mention that
34n/a# the test is running in background
35n/aPROGRESS_MIN_TIME = 30.0 # seconds
36n/a
37n/a# small set of tests to determine if we have a basically functioning interpreter
38n/a# (i.e. if any of these fail, then anything else is likely to follow)
39n/aSTDTESTS = [
40n/a 'test_grammar',
41n/a 'test_opcodes',
42n/a 'test_dict',
43n/a 'test_builtin',
44n/a 'test_exceptions',
45n/a 'test_types',
46n/a 'test_unittest',
47n/a 'test_doctest',
48n/a 'test_doctest2',
49n/a 'test_support'
50n/a]
51n/a
52n/a# set of tests that we don't want to be executed when using regrtest
53n/aNOTTESTS = set()
54n/a
55n/a
56n/adef format_test_result(test_name, result):
57n/a fmt = _FORMAT_TEST_RESULT.get(result, "%s")
58n/a return fmt % test_name
59n/a
60n/a
61n/adef findtests(testdir=None, stdtests=STDTESTS, nottests=NOTTESTS):
62n/a """Return a list of all applicable test modules."""
63n/a testdir = findtestdir(testdir)
64n/a names = os.listdir(testdir)
65n/a tests = []
66n/a others = set(stdtests) | nottests
67n/a for name in names:
68n/a mod, ext = os.path.splitext(name)
69n/a if mod[:5] == "test_" and ext in (".py", "") and mod not in others:
70n/a tests.append(mod)
71n/a return stdtests + sorted(tests)
72n/a
73n/a
74n/adef runtest(ns, test):
75n/a """Run a single test.
76n/a
77n/a ns -- regrtest namespace of options
78n/a test -- the name of the test
79n/a
80n/a Returns the tuple (result, test_time), where result is one of the
81n/a constants:
82n/a
83n/a INTERRUPTED KeyboardInterrupt when run under -j
84n/a RESOURCE_DENIED test skipped because resource denied
85n/a SKIPPED test skipped for some other reason
86n/a ENV_CHANGED test failed because it changed the execution environment
87n/a FAILED test failed
88n/a PASSED test passed
89n/a """
90n/a
91n/a output_on_failure = ns.verbose3
92n/a
93n/a use_timeout = (ns.timeout is not None)
94n/a if use_timeout:
95n/a faulthandler.dump_traceback_later(ns.timeout, exit=True)
96n/a try:
97n/a support.match_tests = ns.match_tests
98n/a if ns.failfast:
99n/a support.failfast = True
100n/a if output_on_failure:
101n/a support.verbose = True
102n/a
103n/a # Reuse the same instance to all calls to runtest(). Some
104n/a # tests keep a reference to sys.stdout or sys.stderr
105n/a # (eg. test_argparse).
106n/a if runtest.stringio is None:
107n/a stream = io.StringIO()
108n/a runtest.stringio = stream
109n/a else:
110n/a stream = runtest.stringio
111n/a stream.seek(0)
112n/a stream.truncate()
113n/a
114n/a orig_stdout = sys.stdout
115n/a orig_stderr = sys.stderr
116n/a try:
117n/a sys.stdout = stream
118n/a sys.stderr = stream
119n/a result = runtest_inner(ns, test, display_failure=False)
120n/a if result[0] != PASSED:
121n/a output = stream.getvalue()
122n/a orig_stderr.write(output)
123n/a orig_stderr.flush()
124n/a finally:
125n/a sys.stdout = orig_stdout
126n/a sys.stderr = orig_stderr
127n/a else:
128n/a support.verbose = ns.verbose # Tell tests to be moderately quiet
129n/a result = runtest_inner(ns, test, display_failure=not ns.verbose)
130n/a return result
131n/a finally:
132n/a if use_timeout:
133n/a faulthandler.cancel_dump_traceback_later()
134n/a cleanup_test_droppings(test, ns.verbose)
135n/aruntest.stringio = None
136n/a
137n/a
138n/adef runtest_inner(ns, test, display_failure=True):
139n/a support.unload(test)
140n/a
141n/a test_time = 0.0
142n/a refleak = False # True if the test leaked references.
143n/a try:
144n/a if test.startswith('test.') or ns.testdir:
145n/a abstest = test
146n/a else:
147n/a # Always import it from the test package
148n/a abstest = 'test.' + test
149n/a clear_caches()
150n/a with saved_test_environment(test, ns.verbose, ns.quiet, pgo=ns.pgo) as environment:
151n/a start_time = time.time()
152n/a the_module = importlib.import_module(abstest)
153n/a # If the test has a test_main, that will run the appropriate
154n/a # tests. If not, use normal unittest test loading.
155n/a test_runner = getattr(the_module, "test_main", None)
156n/a if test_runner is None:
157n/a def test_runner():
158n/a loader = unittest.TestLoader()
159n/a tests = loader.loadTestsFromModule(the_module)
160n/a for error in loader.errors:
161n/a print(error, file=sys.stderr)
162n/a if loader.errors:
163n/a raise Exception("errors while loading tests")
164n/a support.run_unittest(tests)
165n/a test_runner()
166n/a if ns.huntrleaks:
167n/a refleak = dash_R(the_module, test, test_runner, ns.huntrleaks)
168n/a test_time = time.time() - start_time
169n/a except support.ResourceDenied as msg:
170n/a if not ns.quiet and not ns.pgo:
171n/a print(test, "skipped --", msg, flush=True)
172n/a return RESOURCE_DENIED, test_time
173n/a except unittest.SkipTest as msg:
174n/a if not ns.quiet and not ns.pgo:
175n/a print(test, "skipped --", msg, flush=True)
176n/a return SKIPPED, test_time
177n/a except KeyboardInterrupt:
178n/a raise
179n/a except support.TestFailed as msg:
180n/a if not ns.pgo:
181n/a if display_failure:
182n/a print("test", test, "failed --", msg, file=sys.stderr,
183n/a flush=True)
184n/a else:
185n/a print("test", test, "failed", file=sys.stderr, flush=True)
186n/a return FAILED, test_time
187n/a except:
188n/a msg = traceback.format_exc()
189n/a if not ns.pgo:
190n/a print("test", test, "crashed --", msg, file=sys.stderr,
191n/a flush=True)
192n/a return FAILED, test_time
193n/a else:
194n/a if refleak:
195n/a return FAILED, test_time
196n/a if environment.changed:
197n/a return ENV_CHANGED, test_time
198n/a return PASSED, test_time
199n/a
200n/a
201n/adef cleanup_test_droppings(testname, verbose):
202n/a import shutil
203n/a import stat
204n/a import gc
205n/a
206n/a # First kill any dangling references to open files etc.
207n/a # This can also issue some ResourceWarnings which would otherwise get
208n/a # triggered during the following test run, and possibly produce failures.
209n/a gc.collect()
210n/a
211n/a # Try to clean up junk commonly left behind. While tests shouldn't leave
212n/a # any files or directories behind, when a test fails that can be tedious
213n/a # for it to arrange. The consequences can be especially nasty on Windows,
214n/a # since if a test leaves a file open, it cannot be deleted by name (while
215n/a # there's nothing we can do about that here either, we can display the
216n/a # name of the offending test, which is a real help).
217n/a for name in (support.TESTFN,
218n/a "db_home",
219n/a ):
220n/a if not os.path.exists(name):
221n/a continue
222n/a
223n/a if os.path.isdir(name):
224n/a kind, nuker = "directory", shutil.rmtree
225n/a elif os.path.isfile(name):
226n/a kind, nuker = "file", os.unlink
227n/a else:
228n/a raise SystemError("os.path says %r exists but is neither "
229n/a "directory nor file" % name)
230n/a
231n/a if verbose:
232n/a print("%r left behind %s %r" % (testname, kind, name))
233n/a try:
234n/a # if we have chmod, fix possible permissions problems
235n/a # that might prevent cleanup
236n/a if (hasattr(os, 'chmod')):
237n/a os.chmod(name, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)
238n/a nuker(name)
239n/a except Exception as msg:
240n/a print(("%r left behind %s %r and it couldn't be "
241n/a "removed: %s" % (testname, kind, name, msg)), file=sys.stderr)
242n/a
243n/a
244n/adef findtestdir(path=None):
245n/a return path or os.path.dirname(os.path.dirname(__file__)) or os.curdir