xref: /dpdk/dts/framework/testbed_model/node.py (revision 680d8a240f1687d455fd62f1376e80d0278c9bc6)
1# SPDX-License-Identifier: BSD-3-Clause
2# Copyright(c) 2010-2014 Intel Corporation
3# Copyright(c) 2022-2023 PANTHEON.tech s.r.o.
4# Copyright(c) 2022-2023 University of New Hampshire
5
6"""
7A node is a generic host that DTS connects to and manages.
8"""
9
10from typing import Any, Callable
11
12from framework.config import (
13    BuildTargetConfiguration,
14    ExecutionConfiguration,
15    NodeConfiguration,
16)
17from framework.logger import DTSLOG, getLogger
18from framework.remote_session import OSSession, create_session
19from framework.settings import SETTINGS
20
21
22class Node(object):
23    """
24    Basic class for node management. This class implements methods that
25    manage a node, such as information gathering (of CPU/PCI/NIC) and
26    environment setup.
27    """
28
29    main_session: OSSession
30    config: NodeConfiguration
31    name: str
32    _logger: DTSLOG
33    _other_sessions: list[OSSession]
34
35    def __init__(self, node_config: NodeConfiguration):
36        self.config = node_config
37        self.name = node_config.name
38        self._logger = getLogger(self.name)
39        self.main_session = create_session(self.config, self.name, self._logger)
40
41        self._other_sessions = []
42
43        self._logger.info(f"Created node: {self.name}")
44
45    def set_up_execution(self, execution_config: ExecutionConfiguration) -> None:
46        """
47        Perform the execution setup that will be done for each execution
48        this node is part of.
49        """
50        self._set_up_execution(execution_config)
51
52    def _set_up_execution(self, execution_config: ExecutionConfiguration) -> None:
53        """
54        This method exists to be optionally overwritten by derived classes and
55        is not decorated so that the derived class doesn't have to use the decorator.
56        """
57
58    def tear_down_execution(self) -> None:
59        """
60        Perform the execution teardown that will be done after each execution
61        this node is part of concludes.
62        """
63        self._tear_down_execution()
64
65    def _tear_down_execution(self) -> None:
66        """
67        This method exists to be optionally overwritten by derived classes and
68        is not decorated so that the derived class doesn't have to use the decorator.
69        """
70
71    def set_up_build_target(
72        self, build_target_config: BuildTargetConfiguration
73    ) -> None:
74        """
75        Perform the build target setup that will be done for each build target
76        tested on this node.
77        """
78        self._set_up_build_target(build_target_config)
79
80    def _set_up_build_target(
81        self, build_target_config: BuildTargetConfiguration
82    ) -> None:
83        """
84        This method exists to be optionally overwritten by derived classes and
85        is not decorated so that the derived class doesn't have to use the decorator.
86        """
87
88    def tear_down_build_target(self) -> None:
89        """
90        Perform the build target teardown that will be done after each build target
91        tested on this node.
92        """
93        self._tear_down_build_target()
94
95    def _tear_down_build_target(self) -> None:
96        """
97        This method exists to be optionally overwritten by derived classes and
98        is not decorated so that the derived class doesn't have to use the decorator.
99        """
100
101    def create_session(self, name: str) -> OSSession:
102        """
103        Create and return a new OSSession tailored to the remote OS.
104        """
105        session_name = f"{self.name} {name}"
106        connection = create_session(
107            self.config,
108            session_name,
109            getLogger(session_name, node=self.name),
110        )
111        self._other_sessions.append(connection)
112        return connection
113
114    def close(self) -> None:
115        """
116        Close all connections and free other resources.
117        """
118        if self.main_session:
119            self.main_session.close()
120        for session in self._other_sessions:
121            session.close()
122        self._logger.logger_exit()
123
124    @staticmethod
125    def skip_setup(func: Callable[..., Any]) -> Callable[..., Any]:
126        if SETTINGS.skip_setup:
127            return lambda *args: None
128        else:
129            return func
130