From: "Juraj Linkeš" <juraj.linkes@pantheon.tech>
To: thomas@monjalon.net, Honnappa.Nagarahalli@arm.com,
jspewock@iol.unh.edu, probb@iol.unh.edu, paul.szczepanek@arm.com,
yoan.picchi@foss.arm.com, Luca.Vizzarro@arm.com
Cc: dev@dpdk.org, "Juraj Linkeš" <juraj.linkes@pantheon.tech>
Subject: [RFC PATCH v1 5/5] dts: refactor logging configuration
Date: Wed, 20 Dec 2023 11:33:31 +0100 [thread overview]
Message-ID: <20231220103331.60888-6-juraj.linkes@pantheon.tech> (raw)
In-Reply-To: <20231220103331.60888-1-juraj.linkes@pantheon.tech>
Refactor logging for improved configuration and flexibility,
investigating unclear arguments and exploring alternatives
for logging test suites into separate files. In addition,
efforts were made to ensure that the modules remained
independent from the logger module, enabling potential use
by other consumers.
Signed-off-by: Juraj Linkeš <juraj.linkes@pantheon.tech>
---
dts/framework/logger.py | 162 ++++++++----------
dts/framework/remote_session/__init__.py | 4 +-
dts/framework/remote_session/os_session.py | 6 +-
.../remote_session/remote/__init__.py | 7 +-
.../remote/interactive_remote_session.py | 7 +-
.../remote/interactive_shell.py | 7 +-
.../remote_session/remote/remote_session.py | 8 +-
.../remote_session/remote/ssh_session.py | 5 +-
dts/framework/runner.py | 13 +-
dts/framework/test_result.py | 6 +-
dts/framework/test_suite.py | 6 +-
dts/framework/testbed_model/node.py | 10 +-
dts/framework/testbed_model/scapy.py | 6 +-
.../testbed_model/traffic_generator.py | 5 +-
dts/main.py | 6 +-
15 files changed, 124 insertions(+), 134 deletions(-)
diff --git a/dts/framework/logger.py b/dts/framework/logger.py
index bb2991e994..43c49c2d03 100644
--- a/dts/framework/logger.py
+++ b/dts/framework/logger.py
@@ -10,108 +10,98 @@
import logging
import os.path
-from typing import TypedDict
-
-from .settings import SETTINGS
+from enum import Enum
+from logging import FileHandler, StreamHandler
+from pathlib import Path
date_fmt = "%Y/%m/%d %H:%M:%S"
-stream_fmt = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
+stream_fmt = "%(asctime)s - %(stage)s - %(name)s - %(levelname)s - %(message)s"
-class LoggerDictType(TypedDict):
- logger: "DTSLOG"
- name: str
- node: str
+def init_logger(verbose: bool, output_dir: str):
+ logging.raiseExceptions = False
+ DTSLog._output_dir = output_dir
+ logging.setLoggerClass(DTSLog)
-# List for saving all using loggers
-Loggers: list[LoggerDictType] = []
+ root_logger = logging.getLogger()
+ root_logger.setLevel(1)
+ sh = StreamHandler()
+ sh.setFormatter(logging.Formatter(stream_fmt, date_fmt))
+ sh.setLevel(logging.INFO)
+ if verbose:
+ sh.setLevel(logging.DEBUG)
+ root_logger.addHandler(sh)
-class DTSLOG(logging.LoggerAdapter):
- """
- DTS log class for framework and testsuite.
- """
+ if not os.path.exists(output_dir):
+ os.mkdir(output_dir)
- _logger: logging.Logger
- node: str
- sh: logging.StreamHandler
- fh: logging.FileHandler
- verbose_fh: logging.FileHandler
+ add_file_handlers(Path(output_dir, "dts"))
- def __init__(self, logger: logging.Logger, node: str = "suite"):
- self._logger = logger
- # 1 means log everything, this will be used by file handlers if their level
- # is not set
- self._logger.setLevel(1)
- self.node = node
+def add_file_handlers(log_file_path: Path) -> list[FileHandler]:
+ root_logger = logging.getLogger()
- # add handler to emit to stdout
- sh = logging.StreamHandler()
- sh.setFormatter(logging.Formatter(stream_fmt, date_fmt))
- sh.setLevel(logging.INFO) # console handler default level
+ fh = FileHandler(f"{log_file_path}.log")
+ fh.setFormatter(logging.Formatter(stream_fmt, date_fmt))
+ root_logger.addHandler(fh)
- if SETTINGS.verbose is True:
- sh.setLevel(logging.DEBUG)
+ verbose_fh = FileHandler(f"{log_file_path}.verbose.log")
+ verbose_fh.setFormatter(
+ logging.Formatter(
+ "%(asctime)s|%(stage)s|%(name)s|%(levelname)s|%(pathname)s|%(lineno)d|"
+ "%(funcName)s|%(process)d|%(thread)d|%(threadName)s|%(message)s",
+ datefmt=date_fmt,
+ )
+ )
+ root_logger.addHandler(verbose_fh)
- self._logger.addHandler(sh)
- self.sh = sh
+ return [fh, verbose_fh]
- # prepare the output folder
- if not os.path.exists(SETTINGS.output_dir):
- os.mkdir(SETTINGS.output_dir)
- logging_path_prefix = os.path.join(SETTINGS.output_dir, node)
+class DtsStage(Enum):
+ pre_execution = "pre-execution"
+ execution = "execution"
+ build_target = "build-target"
+ suite = "suite"
+ post_execution = "post-execution"
- fh = logging.FileHandler(f"{logging_path_prefix}.log")
- fh.setFormatter(
- logging.Formatter(
- fmt="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
- datefmt=date_fmt,
- )
- )
+ def __str__(self) -> str:
+ return self.value
- self._logger.addHandler(fh)
- self.fh = fh
-
- # This outputs EVERYTHING, intended for post-mortem debugging
- # Also optimized for processing via AWK (awk -F '|' ...)
- verbose_fh = logging.FileHandler(f"{logging_path_prefix}.verbose.log")
- verbose_fh.setFormatter(
- logging.Formatter(
- fmt="%(asctime)s|%(name)s|%(levelname)s|%(pathname)s|%(lineno)d|"
- "%(funcName)s|%(process)d|%(thread)d|%(threadName)s|%(message)s",
- datefmt=date_fmt,
- )
- )
- self._logger.addHandler(verbose_fh)
- self.verbose_fh = verbose_fh
-
- super(DTSLOG, self).__init__(self._logger, dict(node=self.node))
-
- def logger_exit(self) -> None:
- """
- Remove stream handler and logfile handler.
- """
- for handler in (self.sh, self.fh, self.verbose_fh):
- handler.flush()
- self._logger.removeHandler(handler)
-
-
-def getLogger(name: str, node: str = "suite") -> DTSLOG:
- """
- Get logger handler and if there's no handler for specified Node will create one.
- """
- global Loggers
- # return saved logger
- logger: LoggerDictType
- for logger in Loggers:
- if logger["name"] == name and logger["node"] == node:
- return logger["logger"]
-
- # return new logger
- dts_logger: DTSLOG = DTSLOG(logging.getLogger(name), node)
- Loggers.append({"logger": dts_logger, "name": name, "node": node})
- return dts_logger
+class DTSLog(logging.Logger):
+ _stage: DtsStage = DtsStage.pre_execution
+ _extra_file_handlers: list[FileHandler] = []
+ _output_dir: None | str = None
+
+ def makeRecord(self, *args, **kwargs):
+ record = super().makeRecord(*args, **kwargs)
+ record.stage = DTSLog._stage
+ return record
+
+ def set_stage(self, stage: DtsStage, log_file_name: str | None = None):
+ self._remove_extra_file_handlers()
+
+ if DTSLog._stage != stage:
+ self.info(f"Moving from stage '{DTSLog._stage}' to stage '{stage}'.")
+ DTSLog._stage = stage
+
+ if log_file_name:
+ if DTSLog._output_dir:
+ DTSLog._extra_file_handlers.extend(
+ add_file_handlers(Path(DTSLog._output_dir, log_file_name))
+ )
+ else:
+ self.warning(
+ f"Cannot log '{DTSLog._stage}' stage in separate file, "
+ "output dir is not defined."
+ )
+
+ def _remove_extra_file_handlers(self) -> None:
+ if DTSLog._extra_file_handlers:
+ for extra_file_handler in DTSLog._extra_file_handlers:
+ self.root.removeHandler(extra_file_handler)
+
+ DTSLog._extra_file_handlers = []
diff --git a/dts/framework/remote_session/__init__.py b/dts/framework/remote_session/__init__.py
index 6124417bd7..a4ec2f40ae 100644
--- a/dts/framework/remote_session/__init__.py
+++ b/dts/framework/remote_session/__init__.py
@@ -11,10 +11,10 @@
"""
# pylama:ignore=W0611
+import logging
from framework.config import OS, NodeConfiguration
from framework.exception import ConfigurationError
-from framework.logger import DTSLOG
from .linux_session import LinuxSession
from .os_session import InteractiveShellType, OSSession
@@ -30,7 +30,7 @@
)
-def create_session(node_config: NodeConfiguration, name: str, logger: DTSLOG) -> OSSession:
+def create_session(node_config: NodeConfiguration, name: str, logger: logging.Logger) -> OSSession:
match node_config.os:
case OS.linux:
return LinuxSession(node_config, name, logger)
diff --git a/dts/framework/remote_session/os_session.py b/dts/framework/remote_session/os_session.py
index 8a709eac1c..2524a4e669 100644
--- a/dts/framework/remote_session/os_session.py
+++ b/dts/framework/remote_session/os_session.py
@@ -2,6 +2,7 @@
# Copyright(c) 2023 PANTHEON.tech s.r.o.
# Copyright(c) 2023 University of New Hampshire
+import logging
from abc import ABC, abstractmethod
from collections.abc import Iterable
from ipaddress import IPv4Interface, IPv6Interface
@@ -9,7 +10,6 @@
from typing import Type, TypeVar, Union
from framework.config import Architecture, NodeConfiguration, NodeInfo
-from framework.logger import DTSLOG
from framework.remote_session.remote import InteractiveShell
from framework.settings import SETTINGS
from framework.testbed_model import LogicalCore
@@ -36,7 +36,7 @@ class OSSession(ABC):
_config: NodeConfiguration
name: str
- _logger: DTSLOG
+ _logger: logging.Logger
remote_session: RemoteSession
interactive_session: InteractiveRemoteSession
@@ -44,7 +44,7 @@ def __init__(
self,
node_config: NodeConfiguration,
name: str,
- logger: DTSLOG,
+ logger: logging.Logger,
):
self._config = node_config
self.name = name
diff --git a/dts/framework/remote_session/remote/__init__.py b/dts/framework/remote_session/remote/__init__.py
index 06403691a5..4a22155153 100644
--- a/dts/framework/remote_session/remote/__init__.py
+++ b/dts/framework/remote_session/remote/__init__.py
@@ -4,8 +4,9 @@
# pylama:ignore=W0611
+import logging
+
from framework.config import NodeConfiguration
-from framework.logger import DTSLOG
from .interactive_remote_session import InteractiveRemoteSession
from .interactive_shell import InteractiveShell
@@ -16,12 +17,12 @@
def create_remote_session(
- node_config: NodeConfiguration, name: str, logger: DTSLOG
+ node_config: NodeConfiguration, name: str, logger: logging.Logger
) -> RemoteSession:
return SSHSession(node_config, name, logger)
def create_interactive_session(
- node_config: NodeConfiguration, logger: DTSLOG
+ node_config: NodeConfiguration, logger: logging.Logger
) -> InteractiveRemoteSession:
return InteractiveRemoteSession(node_config, logger)
diff --git a/dts/framework/remote_session/remote/interactive_remote_session.py b/dts/framework/remote_session/remote/interactive_remote_session.py
index 098ded1bb0..bf0996a747 100644
--- a/dts/framework/remote_session/remote/interactive_remote_session.py
+++ b/dts/framework/remote_session/remote/interactive_remote_session.py
@@ -2,7 +2,7 @@
# Copyright(c) 2023 University of New Hampshire
"""Handler for an SSH session dedicated to interactive shells."""
-
+import logging
import socket
import traceback
@@ -16,7 +16,6 @@
from framework.config import NodeConfiguration
from framework.exception import SSHConnectionError
-from framework.logger import DTSLOG
class InteractiveRemoteSession:
@@ -54,11 +53,11 @@ class InteractiveRemoteSession:
username: str
password: str
session: SSHClient
- _logger: DTSLOG
+ _logger: logging.Logger
_node_config: NodeConfiguration
_transport: Transport | None
- def __init__(self, node_config: NodeConfiguration, _logger: DTSLOG) -> None:
+ def __init__(self, node_config: NodeConfiguration, _logger: logging.Logger) -> None:
self._node_config = node_config
self._logger = _logger
self.hostname = node_config.hostname
diff --git a/dts/framework/remote_session/remote/interactive_shell.py b/dts/framework/remote_session/remote/interactive_shell.py
index 4db19fb9b3..b6074838c2 100644
--- a/dts/framework/remote_session/remote/interactive_shell.py
+++ b/dts/framework/remote_session/remote/interactive_shell.py
@@ -11,14 +11,13 @@
elevated privileges to start it is expected that the method for gaining those
privileges is provided when initializing the class.
"""
-
+import logging
from abc import ABC
from pathlib import PurePath
from typing import Callable
from paramiko import Channel, SSHClient, channel # type: ignore[import]
-from framework.logger import DTSLOG
from framework.settings import SETTINGS
@@ -58,7 +57,7 @@ class InteractiveShell(ABC):
_stdin: channel.ChannelStdinFile
_stdout: channel.ChannelFile
_ssh_channel: Channel
- _logger: DTSLOG
+ _logger: logging.Logger
_timeout: float
_app_args: str
_default_prompt: str = ""
@@ -69,7 +68,7 @@ class InteractiveShell(ABC):
def __init__(
self,
interactive_session: SSHClient,
- logger: DTSLOG,
+ logger: logging.Logger,
get_privileged_command: Callable[[str], str] | None,
app_args: str = "",
timeout: float = SETTINGS.timeout,
diff --git a/dts/framework/remote_session/remote/remote_session.py b/dts/framework/remote_session/remote/remote_session.py
index 719f7d1ef7..da78e5c921 100644
--- a/dts/framework/remote_session/remote/remote_session.py
+++ b/dts/framework/remote_session/remote/remote_session.py
@@ -2,14 +2,13 @@
# Copyright(c) 2010-2014 Intel Corporation
# Copyright(c) 2022-2023 PANTHEON.tech s.r.o.
# Copyright(c) 2022-2023 University of New Hampshire
-
import dataclasses
+import logging
from abc import ABC, abstractmethod
from pathlib import PurePath
from framework.config import NodeConfiguration
from framework.exception import RemoteCommandExecutionError
-from framework.logger import DTSLOG
from framework.settings import SETTINGS
@@ -50,14 +49,14 @@ class RemoteSession(ABC):
username: str
password: str
history: list[CommandResult]
- _logger: DTSLOG
+ _logger: logging.Logger
_node_config: NodeConfiguration
def __init__(
self,
node_config: NodeConfiguration,
session_name: str,
- logger: DTSLOG,
+ logger: logging.Logger,
):
self._node_config = node_config
@@ -120,7 +119,6 @@ def close(self, force: bool = False) -> None:
"""
Close the remote session and free all used resources.
"""
- self._logger.logger_exit()
self._close(force)
@abstractmethod
diff --git a/dts/framework/remote_session/remote/ssh_session.py b/dts/framework/remote_session/remote/ssh_session.py
index 1a7ee649ab..42441c4587 100644
--- a/dts/framework/remote_session/remote/ssh_session.py
+++ b/dts/framework/remote_session/remote/ssh_session.py
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2023 PANTHEON.tech s.r.o.
-
+import logging
import socket
import traceback
from pathlib import PurePath
@@ -20,7 +20,6 @@
from framework.config import NodeConfiguration
from framework.exception import SSHConnectionError, SSHSessionDeadError, SSHTimeoutError
-from framework.logger import DTSLOG
from .remote_session import CommandResult, RemoteSession
@@ -49,7 +48,7 @@ def __init__(
self,
node_config: NodeConfiguration,
session_name: str,
- logger: DTSLOG,
+ logger: logging.Logger,
):
super(SSHSession, self).__init__(node_config, session_name, logger)
diff --git a/dts/framework/runner.py b/dts/framework/runner.py
index 28570d4a1c..5c06e4ca1a 100644
--- a/dts/framework/runner.py
+++ b/dts/framework/runner.py
@@ -11,6 +11,7 @@
from copy import deepcopy
from dataclasses import dataclass
from types import MethodType, ModuleType
+from typing import cast
from .config import (
BuildTargetConfiguration,
@@ -24,7 +25,7 @@
SSHTimeoutError,
TestCaseVerifyError,
)
-from .logger import DTSLOG, getLogger
+from .logger import DTSLog, DtsStage
from .settings import SETTINGS
from .test_result import (
BuildTargetResult,
@@ -68,12 +69,12 @@ def processed_config(self) -> ExecutionConfiguration:
class DTSRunner:
- _logger: DTSLOG
+ _logger: DTSLog
_result: DTSResult
_executions: list[Execution]
def __init__(self, configuration: Configuration):
- self._logger = getLogger("DTSRunner")
+ self._logger = cast(DTSLog, logging.getLogger("DTSRunner"))
self._result = DTSResult(configuration, self._logger)
self._executions = create_executions(configuration.executions)
@@ -146,6 +147,7 @@ def _run_execution(
Run the given execution. This involves running the execution setup as well as
running all build targets in the given execution.
"""
+ self._logger.set_stage(DtsStage.execution)
self._logger.info(
"Running execution with SUT "
f"'{execution.config.system_under_test_node.name}'."
@@ -175,6 +177,7 @@ def _run_execution(
sut_node.tear_down_execution()
execution_result.update_teardown(Result.PASS)
except Exception as e:
+ self._logger.set_stage(DtsStage.execution)
self._logger.exception("Execution teardown failed.")
execution_result.update_teardown(Result.FAIL, e)
@@ -189,6 +192,7 @@ def _run_build_target(
"""
Run the given build target.
"""
+ self._logger.set_stage(DtsStage.build_target)
self._logger.info(f"Running build target '{build_target.name}'.")
build_target_result = execution_result.add_child_result(build_target)
@@ -209,6 +213,7 @@ def _run_build_target(
sut_node.tear_down_build_target()
build_target_result.update_teardown(Result.PASS)
except Exception as e:
+ self._logger.set_stage(DtsStage.build_target)
self._logger.exception("Build target teardown failed.")
build_target_result.update_teardown(Result.FAIL, e)
@@ -265,6 +270,7 @@ def _run_test_suite(
"""
test_suite = test_suite_setup.test_suite(sut_node, tg_node)
test_suite_name = test_suite_setup.test_suite.__name__
+ self._logger.set_stage(DtsStage.suite, test_suite_name)
test_suite_result = build_target_result.add_child_result(
test_suite_setup.processed_config()
)
@@ -397,6 +403,7 @@ def _exit_dts(self) -> None:
self._result.process()
if self._logger:
+ self._logger.set_stage(DtsStage.post_execution)
self._logger.info("DTS execution has ended.")
logging.shutdown()
diff --git a/dts/framework/test_result.py b/dts/framework/test_result.py
index dba2c55d36..221e75205e 100644
--- a/dts/framework/test_result.py
+++ b/dts/framework/test_result.py
@@ -6,6 +6,7 @@
Generic result container and reporters
"""
+import logging
import os.path
from collections.abc import MutableSequence
from enum import Enum, auto
@@ -24,7 +25,6 @@
TestSuiteConfig,
)
from .exception import DTSError, ErrorSeverity
-from .logger import DTSLOG
from .settings import SETTINGS
@@ -153,13 +153,13 @@ class DTSResult(BaseResult):
dpdk_version: str | None
_child_configs: list[ExecutionConfiguration]
- _logger: DTSLOG
+ _logger: logging.Logger
_errors: list[Exception]
_return_code: ErrorSeverity
_stats_result: Union["Statistics", None]
_stats_filename: str
- def __init__(self, configuration: Configuration, logger: DTSLOG):
+ def __init__(self, configuration: Configuration, logger: logging.Logger):
super(DTSResult, self).__init__()
self.dpdk_version = None
self._child_configs = configuration.executions
diff --git a/dts/framework/test_suite.py b/dts/framework/test_suite.py
index e73206993d..9c9a8c1e08 100644
--- a/dts/framework/test_suite.py
+++ b/dts/framework/test_suite.py
@@ -6,6 +6,7 @@
Base class for creating DTS test cases.
"""
+import logging
from ipaddress import IPv4Interface, IPv6Interface, ip_interface
from typing import Union
@@ -14,7 +15,6 @@
from scapy.packet import Packet, Padding # type: ignore[import]
from .exception import TestCaseVerifyError
-from .logger import DTSLOG, getLogger
from .testbed_model import SutNode, TGNode
from .testbed_model.hw.port import Port, PortLink
from .utils import get_packet_summaries
@@ -41,7 +41,7 @@ class TestSuite(object):
sut_node: SutNode
tg_node: TGNode
is_blocking = False
- _logger: DTSLOG
+ _logger: logging.Logger
_port_links: list[PortLink]
_sut_port_ingress: Port
_sut_port_egress: Port
@@ -59,7 +59,7 @@ def __init__(
):
self.sut_node = sut_node
self.tg_node = tg_node
- self._logger = getLogger(self.__class__.__name__)
+ self._logger = logging.getLogger(self.__class__.__name__)
self._port_links = []
self._process_links()
self._sut_port_ingress, self._tg_port_egress = (
diff --git a/dts/framework/testbed_model/node.py b/dts/framework/testbed_model/node.py
index ef700d8114..a98c58df4f 100644
--- a/dts/framework/testbed_model/node.py
+++ b/dts/framework/testbed_model/node.py
@@ -6,7 +6,7 @@
"""
A node is a generic host that DTS connects to and manages.
"""
-
+import logging
from abc import ABC
from ipaddress import IPv4Interface, IPv6Interface
from typing import Any, Callable, Type, Union
@@ -16,7 +16,6 @@
ExecutionConfiguration,
NodeConfiguration,
)
-from framework.logger import DTSLOG, getLogger
from framework.remote_session import InteractiveShellType, OSSession, create_session
from framework.settings import SETTINGS
@@ -43,7 +42,7 @@ class Node(ABC):
name: str
lcores: list[LogicalCore]
ports: list[Port]
- _logger: DTSLOG
+ _logger: logging.Logger
_other_sessions: list[OSSession]
_execution_config: ExecutionConfiguration
virtual_devices: list[VirtualDevice]
@@ -51,7 +50,7 @@ class Node(ABC):
def __init__(self, node_config: NodeConfiguration):
self.config = node_config
self.name = node_config.name
- self._logger = getLogger(self.name)
+ self._logger = logging.getLogger(self.name)
self.main_session = create_session(self.config, self.name, self._logger)
self._logger.info(f"Connected to node: {self.name}")
@@ -137,7 +136,7 @@ def create_session(self, name: str) -> OSSession:
connection = create_session(
self.config,
session_name,
- getLogger(session_name, node=self.name),
+ logging.getLogger(session_name),
)
self._other_sessions.append(connection)
return connection
@@ -237,7 +236,6 @@ def close(self) -> None:
self.main_session.close()
for session in self._other_sessions:
session.close()
- self._logger.logger_exit()
@staticmethod
def skip_setup(func: Callable[..., Any]) -> Callable[..., Any]:
diff --git a/dts/framework/testbed_model/scapy.py b/dts/framework/testbed_model/scapy.py
index 9083e92b3d..61058cd38a 100644
--- a/dts/framework/testbed_model/scapy.py
+++ b/dts/framework/testbed_model/scapy.py
@@ -13,6 +13,7 @@
"""
import inspect
+import logging
import marshal
import time
import types
@@ -24,7 +25,6 @@
from scapy.packet import Packet # type: ignore[import]
from framework.config import OS, ScapyTrafficGeneratorConfig
-from framework.logger import DTSLOG, getLogger
from framework.remote_session import PythonShell
from framework.settings import SETTINGS
@@ -190,12 +190,12 @@ class ScapyTrafficGenerator(CapturingTrafficGenerator):
rpc_server_proxy: xmlrpc.client.ServerProxy
_config: ScapyTrafficGeneratorConfig
_tg_node: TGNode
- _logger: DTSLOG
+ _logger: logging.Logger
def __init__(self, tg_node: TGNode, config: ScapyTrafficGeneratorConfig):
self._config = config
self._tg_node = tg_node
- self._logger = getLogger(f"{self._tg_node.name} {self._config.traffic_generator_type}")
+ self._logger = logging.getLogger(f"{self._tg_node.name} {self._config.traffic_generator_type}")
assert (
self._tg_node.config.os == OS.linux
diff --git a/dts/framework/testbed_model/traffic_generator.py b/dts/framework/testbed_model/traffic_generator.py
index 28c35d3ce4..6b0838958a 100644
--- a/dts/framework/testbed_model/traffic_generator.py
+++ b/dts/framework/testbed_model/traffic_generator.py
@@ -7,12 +7,11 @@
These traffic generators can't capture received traffic,
only count the number of received packets.
"""
-
+import logging
from abc import ABC, abstractmethod
from scapy.packet import Packet # type: ignore[import]
-from framework.logger import DTSLOG
from framework.utils import get_packet_summaries
from .hw.port import Port
@@ -24,7 +23,7 @@ class TrafficGenerator(ABC):
Defines the few basic methods that each traffic generator must implement.
"""
- _logger: DTSLOG
+ _logger: logging.Logger
def send_packet(self, packet: Packet, port: Port) -> None:
"""Send a packet and block until it is fully sent.
diff --git a/dts/main.py b/dts/main.py
index 879ce5cb89..f2828148f0 100755
--- a/dts/main.py
+++ b/dts/main.py
@@ -8,18 +8,18 @@
A test framework for testing DPDK.
"""
-import logging
-
from framework.config import load_config
+from framework.logger import init_logger
from framework.runner import DTSRunner
+from framework.settings import SETTINGS
def main() -> None:
+ init_logger(SETTINGS.verbose, SETTINGS.output_dir)
dts = DTSRunner(configuration=load_config())
dts.run()
# Main program begins here
if __name__ == "__main__":
- logging.raiseExceptions = True
main()
--
2.34.1
next prev parent reply other threads:[~2023-12-20 10:34 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-12-20 10:33 [RFC PATCH v1 0/5] test case blocking and logging Juraj Linkeš
2023-12-20 10:33 ` [RFC PATCH v1 1/5] dts: convert dts.py methods to class Juraj Linkeš
2023-12-20 10:33 ` [RFC PATCH v1 2/5] dts: move test suite execution logic to DTSRunner Juraj Linkeš
2023-12-20 10:33 ` [RFC PATCH v1 3/5] dts: process test suites at the beginning of run Juraj Linkeš
2023-12-20 10:33 ` [RFC PATCH v1 4/5] dts: block all testcases when earlier setup fails Juraj Linkeš
2023-12-20 10:33 ` Juraj Linkeš [this message]
2024-01-08 18:47 ` [RFC PATCH v1 0/5] test case blocking and logging Jeremy Spewock
2024-02-06 14:57 ` [PATCH v2 0/7] " Juraj Linkeš
2024-02-06 14:57 ` [PATCH v2 1/7] dts: convert dts.py methods to class Juraj Linkeš
2024-02-06 14:57 ` [PATCH v2 2/7] dts: move test suite execution logic to DTSRunner Juraj Linkeš
2024-02-06 14:57 ` [PATCH v2 3/7] dts: filter test suites in executions Juraj Linkeš
2024-02-12 16:44 ` Jeremy Spewock
2024-02-14 9:55 ` Juraj Linkeš
2024-02-06 14:57 ` [PATCH v2 4/7] dts: reorganize test result Juraj Linkeš
2024-02-06 14:57 ` [PATCH v2 5/7] dts: block all test cases when earlier setup fails Juraj Linkeš
2024-02-06 14:57 ` [PATCH v2 6/7] dts: refactor logging configuration Juraj Linkeš
2024-02-12 16:45 ` Jeremy Spewock
2024-02-14 7:49 ` Juraj Linkeš
2024-02-14 16:51 ` Jeremy Spewock
2024-02-06 14:57 ` [PATCH v2 7/7] dts: improve test suite and case filtering Juraj Linkeš
2024-02-23 7:54 ` [PATCH v3 0/7] test case blocking and logging Juraj Linkeš
2024-02-23 7:54 ` [PATCH v3 1/7] dts: convert dts.py methods to class Juraj Linkeš
2024-02-23 7:54 ` [PATCH v3 2/7] dts: move test suite execution logic to DTSRunner Juraj Linkeš
2024-02-23 7:54 ` [PATCH v3 3/7] dts: filter test suites in executions Juraj Linkeš
2024-02-27 21:21 ` Jeremy Spewock
2024-02-28 9:16 ` Juraj Linkeš
2024-02-23 7:54 ` [PATCH v3 4/7] dts: reorganize test result Juraj Linkeš
2024-02-23 7:55 ` [PATCH v3 5/7] dts: block all test cases when earlier setup fails Juraj Linkeš
2024-02-23 7:55 ` [PATCH v3 6/7] dts: refactor logging configuration Juraj Linkeš
2024-02-23 7:55 ` [PATCH v3 7/7] dts: improve test suite and case filtering Juraj Linkeš
2024-02-27 21:24 ` [PATCH v3 0/7] test case blocking and logging Jeremy Spewock
2024-03-01 10:55 ` [PATCH v4 " Juraj Linkeš
2024-03-01 10:55 ` [PATCH v4 1/7] dts: convert dts.py methods to class Juraj Linkeš
2024-03-01 10:55 ` [PATCH v4 2/7] dts: move test suite execution logic to DTSRunner Juraj Linkeš
2024-03-01 10:55 ` [PATCH v4 3/7] dts: filter test suites in executions Juraj Linkeš
2024-03-01 10:55 ` [PATCH v4 4/7] dts: reorganize test result Juraj Linkeš
2024-03-01 10:55 ` [PATCH v4 5/7] dts: block all test cases when earlier setup fails Juraj Linkeš
2024-03-01 10:55 ` [PATCH v4 6/7] dts: refactor logging configuration Juraj Linkeš
2024-03-01 10:55 ` [PATCH v4 7/7] dts: improve test suite and case filtering Juraj Linkeš
2024-03-01 17:41 ` Jeremy Spewock
2024-03-01 17:43 ` Jeremy Spewock
2024-03-07 11:04 ` Thomas Monjalon
2024-03-01 16:11 ` [PATCH v4 0/7] test case blocking and logging Patrick Robb
2024-03-07 14:55 ` Thomas Monjalon
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20231220103331.60888-6-juraj.linkes@pantheon.tech \
--to=juraj.linkes@pantheon.tech \
--cc=Honnappa.Nagarahalli@arm.com \
--cc=Luca.Vizzarro@arm.com \
--cc=dev@dpdk.org \
--cc=jspewock@iol.unh.edu \
--cc=paul.szczepanek@arm.com \
--cc=probb@iol.unh.edu \
--cc=thomas@monjalon.net \
--cc=yoan.picchi@foss.arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).