-# Copyright (c) 2019 Cisco and/or its affiliates.
+# Copyright (c) 2021 Cisco and/or its affiliates.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at:
"""Core dump library."""
-from time import time
-
-from resources.libraries.python.constants import Constants
+from resources.libraries.python.Constants import Constants
from resources.libraries.python.DUTSetup import DUTSetup
from resources.libraries.python.LimitUtil import LimitUtil
from resources.libraries.python.SysctlUtil import SysctlUtil
-from resources.libraries.python.ssh import exec_cmd_no_error, scp_node
+from resources.libraries.python.ssh import exec_cmd_no_error
from resources.libraries.python.topology import NodeType
-__all__ = ["CoreDumpUtil"]
+__all__ = [u"CoreDumpUtil"]
-class CoreDumpUtil(object):
+class CoreDumpUtil:
"""Class contains methods for processing core dumps."""
# Use one instance of class for all tests. If the functionality should
# be enabled per suite or per test case, change the scope to "TEST SUITE" or
# "TEST CASE" respectively.
- ROBOT_LIBRARY_SCOPE = 'GLOBAL'
+ ROBOT_LIBRARY_SCOPE = u"GLOBAL"
def __init__(self):
"""Initialize CoreDumpUtil class."""
# environment, and either have a core dump pipe handler that knows
# to treat privileged core dumps with care, or specific directory
# defined for catching core dumps. If a core dump happens without a
- # pipe handler or fully qualifid path, a message will be emitted to
+ # pipe handler or fully qualified path, a message will be emitted to
# syslog warning about the lack of a correct setting.
- SysctlUtil.set_sysctl_value(node, 'fs.suid_dumpable', 2)
+ SysctlUtil.set_sysctl_value(node, u"fs.suid_dumpable", 2)
# Specify a core dumpfile pattern name (for the output filename).
# %p pid
# %t UNIX time of dump
# %h hostname
# %e executable filename (may be shortened)
- SysctlUtil.set_sysctl_value(node, 'kernel.core_pattern',
- Constants.KERNEL_CORE_PATTERN)
+ SysctlUtil.set_sysctl_value(
+ node, u"kernel.core_pattern", Constants.KERNEL_CORE_PATTERN
+ )
self._corekeeper_configured = True
"""
if isinstance(pid, list):
for item in pid:
- LimitUtil.set_pid_limit(node, item, 'core', 'unlimited')
+ LimitUtil.set_pid_limit(node, item, u"core", u"unlimited")
LimitUtil.get_pid_limit(node, item)
else:
- LimitUtil.set_pid_limit(node, pid, 'core', 'unlimited')
+ LimitUtil.set_pid_limit(node, pid, u"core", u"unlimited")
LimitUtil.get_pid_limit(node, pid)
+ def enable_coredump_limit_vpp(self, node):
+ """Enable coredump for VPP PID by setting no core limits on DUT
+ if setting of core limit by this library is enabled.
+
+ :param node: DUT Node in the topology.
+ :type node: dict
+ """
+ if node[u"type"] == NodeType.DUT and self.is_core_limit_enabled():
+ vpp_pid = DUTSetup.get_pid(node, u"vpp")
+ self.enable_coredump_limit(node, vpp_pid)
+
def enable_coredump_limit_vpp_on_all_duts(self, nodes):
"""Enable coredump for all VPP PIDs by setting no core limits on all
DUTs if setting of core limit by this library is enabled.
:type nodes: dict
"""
for node in nodes.values():
- if node['type'] == NodeType.DUT and self.is_core_limit_enabled():
- vpp_pid = DUTSetup.get_vpp_pid(node)
- self.enable_coredump_limit(node, vpp_pid)
+ self.enable_coredump_limit_vpp(node)
def get_core_files_on_all_nodes(self, nodes, disable_on_success=True):
- """Compress all core files into single file and remove the original
- core files on all nodes.
+ """Process all core files and remove the original core files on all
+ nodes.
:param nodes: Nodes in the topology.
:param disable_on_success: If True, disable setting of core limit by
:type disable_on_success: bool
"""
for node in nodes.values():
- uuid = str(time()).replace('.', '')
- name = '{uuid}.tar.lzo.lrz.xz'.format(uuid=uuid)
-
- command = ('[ -e {dir}/*.core ] && sudo tar c {dir}/*.core | '
- 'lzop -1 | '
- 'lrzip -n -T -p 1 -w 5 | '
- 'xz -9e > {dir}/{name} && '
- 'sudo rm -f {dir}/*.core'
- .format(dir=Constants.CORE_DUMP_DIR, name=name))
- try:
- exec_cmd_no_error(node, command, timeout=3600)
- if disable_on_success:
- self.set_core_limit_disabled()
- except RuntimeError:
- # If compress was not sucessfull ignore error and skip further
- # processing.
- continue
-
- local_path = 'archive/{name}'.format(name=name)
- remote_path = '{dir}/{name}'.format(dir=Constants.CORE_DUMP_DIR,
- name=name)
- try:
- scp_node(node, local_path, remote_path, get=True, timeout=3600)
- command = 'rm -f {dir}/{name}'\
- .format(dir=Constants.CORE_DUMP_DIR, name=name)
- exec_cmd_no_error(node, command, sudo=True)
- except RuntimeError:
- pass
+ if node[u"type"] == NodeType.DUT:
+ command = (
+ f"for f in {Constants.CORE_DUMP_DIR}/*.core; do "
+ f"sudo gdb /usr/bin/vpp ${{f}} "
+ f"-ex 'source -v {Constants.REMOTE_FW_DIR}"
+ f"/resources/tools/scripts/gdb-commands' -ex quit; "
+ f"sudo rm -f ${{f}}; done"
+ )
+ try:
+ exec_cmd_no_error(node, command, timeout=3600)
+ if disable_on_success:
+ self.set_core_limit_disabled()
+ except RuntimeError:
+ # If compress was not successful ignore error and skip
+ # further processing.
+ continue