diff options
author | sharpeye <sharpeye@yandex-team.ru> | 2022-03-23 22:30:44 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-03-23 22:30:44 +0300 |
commit | 5962f8c1bf4d647772598f9fc53fa99d2f8450f3 (patch) | |
tree | 7e2ff707c769775ca9444e01f47ee78276a23bc6 | |
parent | 3625b426489dd9c0fba29cf8f6d50cc972984fa9 (diff) | |
download | ydb-5962f8c1bf4d647772598f9fc53fa99d2f8450f3.tar.gz |
merge to stable-22-2
[loadtest] NBS-3062: custom core pattern
REVIEW: 2367932
[yatest] NBS-3062: write backtrace to html with text mode
Если бинарь собирается под python3, то при попытке сдампить корку в html-файл, получаем ошибку:
```
Traceback (most recent call last):
File "library/python/testing/yatest_common/yatest/common/process.py", line 395, in verify_no_coredumps
self._recover_core()
File "library/python/testing/yatest_common/yatest/common/process.py", line 292, in _recover_core
backtrace_to_html(bt_filename, pbt_filename)
File "library/python/testing/yatest_common/yatest/common/process.py", line 737, in backtrace_to_html
coredump_filter.filter_stackdump(bt_filename, stream=afile)
File "sandbox/sdk2/helpers/coredump_filter/__init__.py", line 1294, in filter_stackdump
return dumper.dump()
File "sandbox/sdk2/helpers/coredump_filter/__init__.py", line 1130, in dump
html_prolog(self.stream, self.timestamp)
File "sandbox/sdk2/helpers/coredump_filter/__init__.py", line 927, in html_prolog
stream.write(prolog.format(
TypeError: a bytes-like object is required, not 'str'
```
REVIEW: 2370907
[harness] NBS-3062: forward custom core pattern to yatest.process
REVIEW: 2367454
DEVTOOLSSUPPORT-15739, NBS-3062: custom core pattern
REVIEW: 2367120
REVIEW: 2396836
x-ydb-stable-ref: c381d0acc3d8c7a34a2f1f7a34e7f7b1b177c047
-rw-r--r-- | library/python/cores/__init__.py | 6 | ||||
-rw-r--r-- | library/python/testing/yatest_common/yatest/common/process.py | 35 | ||||
-rw-r--r-- | ydb/tests/library/harness/daemon.py | 8 |
3 files changed, 39 insertions, 10 deletions
diff --git a/library/python/cores/__init__.py b/library/python/cores/__init__.py index fdb1f82a46..e3eea6ab5d 100644 --- a/library/python/cores/__init__.py +++ b/library/python/cores/__init__.py @@ -21,8 +21,7 @@ def _read_file(filename): return afile.read().strip("\n") -def recover_core_dump_file(binary_path, cwd, pid): - +def recover_core_dump_file(binary_path, cwd, pid, core_pattern=None): class CoreFilePattern(object): def __init__(self, path, mask): self.path = path @@ -36,7 +35,8 @@ def recover_core_dump_file(binary_path, cwd, pid): logger.debug("hostname = '%s'", socket.gethostname()) logger.debug("rlimit_core = '%s'", str(resource.getrlimit(resource.RLIMIT_CORE))) - core_pattern = _read_file("/proc/sys/kernel/core_pattern") + if core_pattern is None: + core_pattern = _read_file("/proc/sys/kernel/core_pattern") logger.debug("core_pattern = '%s'", core_pattern) if core_pattern.startswith("/"): default_pattern = CoreFilePattern(os.path.dirname(core_pattern), '*') diff --git a/library/python/testing/yatest_common/yatest/common/process.py b/library/python/testing/yatest_common/yatest/common/process.py index a8bcc21f51..7562a91866 100644 --- a/library/python/testing/yatest_common/yatest/common/process.py +++ b/library/python/testing/yatest_common/yatest/common/process.py @@ -5,6 +5,7 @@ import re import time import signal import shutil +import inspect import logging import tempfile import subprocess @@ -91,7 +92,11 @@ class InvalidCommandError(Exception): class _Execution(object): - def __init__(self, command, process, out_file, err_file, process_progress_listener=None, cwd=None, collect_cores=True, check_sanitizer=True, started=0, user_stdout=False, user_stderr=False): + def __init__(self, command, process, out_file, err_file, + process_progress_listener=None, cwd=None, collect_cores=True, + check_sanitizer=True, started=0, user_stdout=False, user_stderr=False, + core_pattern=None): + self._command = command self._process = process self._out_file = out_file @@ -110,6 +115,8 @@ class _Execution(object): self._user_stdout = bool(user_stdout) self._user_stderr = bool(user_stderr) self._exit_code = None + self._core_pattern = core_pattern + if process_progress_listener: process_progress_listener.open(command, process, out_file, err_file) @@ -146,6 +153,10 @@ class _Execution(object): return self._command @property + def core_pattern(self): + return self._core_pattern + + @property def returncode(self): return self.exit_code @@ -253,7 +264,11 @@ class _Execution(object): self._out_file = None def _recover_core(self): - core_path = cores.recover_core_dump_file(self.command[0], self._cwd, self.process.pid) + core_path = cores.recover_core_dump_file( + self.command[0], + self._cwd, + self.process.pid, + self.core_pattern) if core_path: # Core dump file recovering may be disabled (for distbuild for example) - produce only bt store_cores = runtime._get_ya_config().collect_cores @@ -422,6 +437,7 @@ def execute( process_progress_listener=None, close_fds=False, collect_cores=True, check_sanitizer=True, preexec_fn=None, on_timeout=None, executor=_Execution, + core_pattern=None, ): """ Executes a command @@ -527,7 +543,16 @@ def execute( ) yatest_logger.debug("Command pid: %s", process.pid) - res = executor(command, process, out_file, err_file, process_progress_listener, cwd, collect_cores, check_sanitizer, started, user_stdout=user_stdout, user_stderr=user_stderr) + kwargs = { + 'user_stdout': user_stdout, + 'user_stderr': user_stderr, + } + + if 'core_pattern' in inspect.getargspec(executor.__init__).args: + kwargs.update([('core_pattern', core_pattern)]) + + res = executor(command, process, out_file, err_file, process_progress_listener, + cwd, collect_cores, check_sanitizer, started, **kwargs) if wait: res.wait(check_exit_code, timeout, on_timeout) return res @@ -708,11 +733,11 @@ def check_glibc_version(binary_path): def backtrace_to_html(bt_filename, output): try: from library.python import coredump_filter - with open(output, "wb") as afile: + with open(output, "w") as afile: coredump_filter.filter_stackdump(bt_filename, stream=afile) except ImportError as e: yatest_logger.debug("Failed to import coredump_filter: %s", e) - with open(output, "wb") as afile: + with open(output, "w") as afile: afile.write("<html>Failed to import coredump_filter in USE_ARCADIA_PYTHON=no mode</html>") diff --git a/ydb/tests/library/harness/daemon.py b/ydb/tests/library/harness/daemon.py index edabe07262..c34c7ce927 100644 --- a/ydb/tests/library/harness/daemon.py +++ b/ydb/tests/library/harness/daemon.py @@ -55,13 +55,16 @@ class SeveralDaemonErrors(RuntimeError): class Daemon(object): - def __init__(self, command, cwd, timeout, stdin_file=None, stdout_file=None, stderr_file=None, stderr_on_error_lines=0): + def __init__(self, command, cwd, timeout, stdin_file=None, stdout_file=None, + stderr_file=None, stderr_on_error_lines=0, core_pattern=None): + self.__cwd = cwd self.__timeout = timeout self.__command = tuple(command) self.__stderr_on_error_lines = stderr_on_error_lines self.__daemon = None self.__killed = False + self.__core_pattern = core_pattern self.logger = logger.getChild(self.__class__.__name__) if stdout_file is None: self.__stdout_file = tempfile.NamedTemporaryFile(dir=self.__cwd, prefix="stdout_", delete=False) @@ -104,7 +107,8 @@ class Daemon(object): stdin=self.__stdin_file, stdout=self.__stdout_file, stderr=stderr_stream, - wait=False + wait=False, + core_pattern=self.__core_pattern ) wait_for(self.is_alive, self.__timeout) |