1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
import os
import sys
import time
import __res
FORCE_EXIT_TESTSFAILED_ENV = 'FORCE_EXIT_TESTSFAILED'
def main():
import library.python.pytest.context as context
context.Ctx["YA_PYTEST_START_TIMESTAMP"] = time.time()
profile = None
if '--profile-pytest' in sys.argv:
sys.argv.remove('--profile-pytest')
import pstats
import cProfile
profile = cProfile.Profile()
profile.enable()
# Reset influencing env. vars
# For more info see library/python/testing/yatest_common/yatest/common/errors.py
if FORCE_EXIT_TESTSFAILED_ENV in os.environ:
del os.environ[FORCE_EXIT_TESTSFAILED_ENV]
if "Y_PYTHON_CLEAR_ENTRY_POINT" in os.environ:
if "Y_PYTHON_ENTRY_POINT" in os.environ:
del os.environ["Y_PYTHON_ENTRY_POINT"]
del os.environ["Y_PYTHON_CLEAR_ENTRY_POINT"]
listing_mode = '--collect-only' in sys.argv
yatest_runner = os.environ.get('YA_TEST_RUNNER') == '1'
import pytest
import library.python.pytest.plugins.collection as collection
import library.python.pytest.plugins.ya as ya
import library.python.pytest.plugins.conftests as conftests
import _pytest.assertion
from _pytest.monkeypatch import MonkeyPatch
from . import rewrite
m = MonkeyPatch()
m.setattr(_pytest.assertion.rewrite, "AssertionRewritingHook", rewrite.AssertionRewritingHook)
prefix = '__tests__.'
test_modules = [
# fmt: off
name[len(prefix) :]
for name in sys.extra_modules
if name.startswith(prefix) and not name.endswith('.conftest')
# fmt: on
]
doctest_packages = __res.find("PY_DOCTEST_PACKAGES") or ""
if isinstance(doctest_packages, bytes):
doctest_packages = doctest_packages.decode('utf-8')
doctest_packages = doctest_packages.split()
def is_doctest_module(name):
for package in doctest_packages:
if name == package or name.startswith(str(package) + "."):
return True
return False
doctest_modules = [
# fmt: off
name
for name in sys.extra_modules
if is_doctest_module(name)
# fmt: on
]
def remove_user_site(paths):
site_paths = ('site-packages', 'site-python')
def is_site_path(path):
for p in site_paths:
if path.find(p) != -1:
return True
return False
new_paths = list(paths)
for p in paths:
if is_site_path(p):
new_paths.remove(p)
return new_paths
sys.path = remove_user_site(sys.path)
rc = pytest.main(
plugins=[
collection.CollectionPlugin(test_modules, doctest_modules),
ya,
conftests,
]
)
if rc == 5:
# don't care about EXIT_NOTESTSCOLLECTED
rc = 0
if rc == 1 and yatest_runner and not listing_mode and not os.environ.get(FORCE_EXIT_TESTSFAILED_ENV) == '1':
# XXX it's place for future improvements
# Test wrapper should terminate with 0 exit code if there are common test failures
# and report it with trace-file machinery.
# However, there are several case when we don't want to suppress exit_code:
# - listing machinery doesn't use trace-file currently and rely on stdout and exit_code
# - RestartTestException and InfrastructureException required non-zero exit_code to be processes correctly
rc = 0
if profile:
profile.disable()
ps = pstats.Stats(profile, stream=sys.stderr).sort_stats('cumulative')
ps.print_stats()
if '--output-dir' in sys.argv:
output_dir = sys.argv[sys.argv.index('--output-dir') + 1]
prof_filename = os.path.join(output_dir, 'pytest.profile')
ps.dump_stats(prof_filename)
try:
import gprof2dot
except ImportError as e:
sys.stderr.write("Failed to generate call graph: {}\n".format(e))
gprof2dot = None
if gprof2dot:
import shlex
dot_filename = os.path.join(output_dir, 'pytest.profile.dot')
args = [
prof_filename,
'--format=pstats',
'--output={}'.format(dot_filename),
]
if 'PYTEST_GPROF2DOT_ARGS' in os.environ:
x = os.environ['PYTEST_GPROF2DOT_ARGS']
args.extend(shlex.split(x))
gprof2dot.main(argv=args)
sys.exit(rc)
if __name__ == '__main__':
main()
|