aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsharpeye <sharpeye@yandex-team.ru>2022-03-23 22:30:44 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-03-23 22:30:44 +0300
commit5962f8c1bf4d647772598f9fc53fa99d2f8450f3 (patch)
tree7e2ff707c769775ca9444e01f47ee78276a23bc6
parent3625b426489dd9c0fba29cf8f6d50cc972984fa9 (diff)
downloadydb-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__.py6
-rw-r--r--library/python/testing/yatest_common/yatest/common/process.py35
-rw-r--r--ydb/tests/library/harness/daemon.py8
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)