forked from getsentry/sentry
-
Notifications
You must be signed in to change notification settings - Fork 0
/
conftest.py
122 lines (92 loc) · 4.04 KB
/
conftest.py
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
import os
import sys
from collections import OrderedDict
import pytest
pytest_plugins = ["sentry.utils.pytest"]
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "src"))
def pytest_configure(config):
import warnings
# XXX(dcramer): Kombu throws a warning due to transaction.commit_manually
# being used
warnings.filterwarnings("error", "", Warning, r"^(?!(|kombu|raven|sentry))")
def pytest_addoption(parser):
parser.addoption(
"--itunes",
action="store_true",
help="Run iTunes tests, see tests/sentry/utils/appleconnect/itunes",
)
def pytest_runtest_setup(item):
if item.get_closest_marker("itunes") and not item.config.getoption("--itunes"):
pytest.skip("Test requires --itunes")
# XXX: The below code is vendored code from https://github.com/utgwkk/pytest-github-actions-annotate-failures
# so that we can add support for pytest_rerunfailures
# retried tests will no longer be annotated in GHA
#
# Reference:
# https://docs.pytest.org/en/latest/writing_plugins.html#hookwrapper-executing-around-other-hooks
# https://docs.pytest.org/en/latest/writing_plugins.html#hook-function-ordering-call-example
# https://docs.pytest.org/en/stable/reference.html#pytest.hookspec.pytest_runtest_makereport
#
# Inspired by:
# https://github.com/pytest-dev/pytest/blob/master/src/_pytest/terminal.py
@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item, call):
# execute all other hooks to obtain the report object
outcome = yield
report = outcome.get_result()
# enable only in a workflow of GitHub Actions
# ref: https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables#default-environment-variables
if os.environ.get("GITHUB_ACTIONS") != "true":
return
try:
# If we have the pytest_rerunfailures plugin,
# and there are still retries to be run,
# then do not return the error
import pytest_rerunfailures
if item.execution_count <= pytest_rerunfailures.get_reruns_count(item):
return
except ImportError:
pass
if report.when == "call" and report.failed:
# collect information to be annotated
filesystempath, lineno, _ = report.location
# try to convert to absolute path in GitHub Actions
workspace = os.environ.get("GITHUB_WORKSPACE")
if workspace:
full_path = os.path.abspath(filesystempath)
try:
rel_path = os.path.relpath(full_path, workspace)
except ValueError:
# os.path.relpath() will raise ValueError on Windows
# when full_path and workspace have different mount points.
# https://github.com/utgwkk/pytest-github-actions-annotate-failures/issues/20
rel_path = filesystempath
if not rel_path.startswith(".."):
filesystempath = rel_path
# 0-index to 1-index
lineno += 1
# get the name of the current failed test, with parametrize info
longrepr = report.head_line or item.name
# get the error message and line number from the actual error
try:
longrepr += "\n\n" + report.longrepr.reprcrash.message
lineno = report.longrepr.reprcrash.lineno
except AttributeError:
pass
print( # noqa: B314
_error_workflow_command(filesystempath, lineno, longrepr), file=sys.stderr
)
def _error_workflow_command(filesystempath, lineno, longrepr):
# Build collection of arguments. Ordering is strict for easy testing
details_dict = OrderedDict()
details_dict["file"] = filesystempath
if lineno is not None:
details_dict["line"] = lineno
details = ",".join(f"{k}={v}" for k, v in details_dict.items())
if longrepr is None:
return f"\n::error {details}"
else:
longrepr = _escape(longrepr)
return f"\n::error {details}::{longrepr}"
def _escape(s):
return s.replace("%", "%25").replace("\r", "%0D").replace("\n", "%0A")