aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/pytest/py3/_pytest/pastebin.py
diff options
context:
space:
mode:
authornkozlovskiy <nmk@ydb.tech>2023-09-29 12:24:06 +0300
committernkozlovskiy <nmk@ydb.tech>2023-09-29 12:41:34 +0300
commite0e3e1717e3d33762ce61950504f9637a6e669ed (patch)
treebca3ff6939b10ed60c3d5c12439963a1146b9711 /contrib/python/pytest/py3/_pytest/pastebin.py
parent38f2c5852db84c7b4d83adfcb009eb61541d1ccd (diff)
downloadydb-e0e3e1717e3d33762ce61950504f9637a6e669ed.tar.gz
add ydb deps
Diffstat (limited to 'contrib/python/pytest/py3/_pytest/pastebin.py')
-rw-r--r--contrib/python/pytest/py3/_pytest/pastebin.py110
1 files changed, 110 insertions, 0 deletions
diff --git a/contrib/python/pytest/py3/_pytest/pastebin.py b/contrib/python/pytest/py3/_pytest/pastebin.py
new file mode 100644
index 0000000000..22c7a62237
--- /dev/null
+++ b/contrib/python/pytest/py3/_pytest/pastebin.py
@@ -0,0 +1,110 @@
+"""Submit failure or test session information to a pastebin service."""
+import tempfile
+from io import StringIO
+from typing import IO
+from typing import Union
+
+import pytest
+from _pytest.config import Config
+from _pytest.config import create_terminal_writer
+from _pytest.config.argparsing import Parser
+from _pytest.stash import StashKey
+from _pytest.terminal import TerminalReporter
+
+
+pastebinfile_key = StashKey[IO[bytes]]()
+
+
+def pytest_addoption(parser: Parser) -> None:
+ group = parser.getgroup("terminal reporting")
+ group._addoption(
+ "--pastebin",
+ metavar="mode",
+ action="store",
+ dest="pastebin",
+ default=None,
+ choices=["failed", "all"],
+ help="Send failed|all info to bpaste.net pastebin service",
+ )
+
+
+@pytest.hookimpl(trylast=True)
+def pytest_configure(config: Config) -> None:
+ if config.option.pastebin == "all":
+ tr = config.pluginmanager.getplugin("terminalreporter")
+ # If no terminal reporter plugin is present, nothing we can do here;
+ # this can happen when this function executes in a worker node
+ # when using pytest-xdist, for example.
+ if tr is not None:
+ # pastebin file will be UTF-8 encoded binary file.
+ config.stash[pastebinfile_key] = tempfile.TemporaryFile("w+b")
+ oldwrite = tr._tw.write
+
+ def tee_write(s, **kwargs):
+ oldwrite(s, **kwargs)
+ if isinstance(s, str):
+ s = s.encode("utf-8")
+ config.stash[pastebinfile_key].write(s)
+
+ tr._tw.write = tee_write
+
+
+def pytest_unconfigure(config: Config) -> None:
+ if pastebinfile_key in config.stash:
+ pastebinfile = config.stash[pastebinfile_key]
+ # Get terminal contents and delete file.
+ pastebinfile.seek(0)
+ sessionlog = pastebinfile.read()
+ pastebinfile.close()
+ del config.stash[pastebinfile_key]
+ # Undo our patching in the terminal reporter.
+ tr = config.pluginmanager.getplugin("terminalreporter")
+ del tr._tw.__dict__["write"]
+ # Write summary.
+ tr.write_sep("=", "Sending information to Paste Service")
+ pastebinurl = create_new_paste(sessionlog)
+ tr.write_line("pastebin session-log: %s\n" % pastebinurl)
+
+
+def create_new_paste(contents: Union[str, bytes]) -> str:
+ """Create a new paste using the bpaste.net service.
+
+ :contents: Paste contents string.
+ :returns: URL to the pasted contents, or an error message.
+ """
+ import re
+ from urllib.request import urlopen
+ from urllib.parse import urlencode
+
+ params = {"code": contents, "lexer": "text", "expiry": "1week"}
+ url = "https://bpa.st"
+ try:
+ response: str = (
+ urlopen(url, data=urlencode(params).encode("ascii")).read().decode("utf-8")
+ )
+ except OSError as exc_info: # urllib errors
+ return "bad response: %s" % exc_info
+ m = re.search(r'href="/raw/(\w+)"', response)
+ if m:
+ return f"{url}/show/{m.group(1)}"
+ else:
+ return "bad response: invalid format ('" + response + "')"
+
+
+def pytest_terminal_summary(terminalreporter: TerminalReporter) -> None:
+ if terminalreporter.config.option.pastebin != "failed":
+ return
+ if "failed" in terminalreporter.stats:
+ terminalreporter.write_sep("=", "Sending information to Paste Service")
+ for rep in terminalreporter.stats["failed"]:
+ try:
+ msg = rep.longrepr.reprtraceback.reprentries[-1].reprfileloc
+ except AttributeError:
+ msg = terminalreporter._getfailureheadline(rep)
+ file = StringIO()
+ tw = create_terminal_writer(terminalreporter.config, file)
+ rep.toterminal(tw)
+ s = file.getvalue()
+ assert len(s)
+ pastebinurl = create_new_paste(s)
+ terminalreporter.write_line(f"{msg} --> {pastebinurl}")