<div dir="ltr">Acked-by: Jeremy Spweock <<a href="mailto:jspweock@iol.unh.edu">jspweock@iol.unh.edu</a>></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Mar 23, 2023 at 6:40 AM Juraj Linkeš <juraj.linkes@pantheon.tech> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">WIP: only one module is reformatted to serve as a demonstration.<br>
<br>
The google format is documented here [0].<br>
<br>
[0]: <a href="https://google.github.io/styleguide/pyguide.html" rel="noreferrer" target="_blank">https://google.github.io/styleguide/pyguide.html</a><br>
<br>
Signed-off-by: Juraj Linkeš <juraj.linkes@pantheon.tech><br>
---<br>
dts/framework/testbed_model/node.py | 152 +++++++++++++++++++---------<br>
1 file changed, 103 insertions(+), 49 deletions(-)<br>
<br>
diff --git a/dts/framework/testbed_model/node.py b/dts/framework/testbed_model/node.py<br>
index 90467981c3..ad8ef442af 100644<br>
--- a/dts/framework/testbed_model/node.py<br>
+++ b/dts/framework/testbed_model/node.py<br>
@@ -3,8 +3,13 @@<br>
# Copyright(c) 2022-2023 PANTHEON.tech s.r.o.<br>
# Copyright(c) 2022-2023 University of New Hampshire<br>
<br>
-"""<br>
-A node is a generic host that DTS connects to and manages.<br>
+"""Common functionality for node management.<br>
+<br>
+There's a base class, Node, that's supposed to be extended by other classes<br>
+with functionality specific to that node type.<br>
+The only part that can be used standalone is the Node.skip_setup static method,<br>
+which is a decorator used to skip method execution<br>
+if skip_setup is passed by the user on the cmdline or in an env variable.<br>
"""<br>
<br>
from typing import Any, Callable<br>
@@ -26,10 +31,25 @@<br>
<br>
<br>
class Node(object):<br>
- """<br>
- Basic class for node management. This class implements methods that<br>
- manage a node, such as information gathering (of CPU/PCI/NIC) and<br>
- environment setup.<br>
+ """The base class for node management.<br>
+<br>
+ It shouldn't be instantiated, but rather extended.<br>
+ It implements common methods to manage any node:<br>
+<br>
+ * connection to the node<br>
+ * information gathering of CPU<br>
+ * hugepages setup<br>
+<br>
+ Arguments:<br>
+ node_config: The config from the input configuration file.<br>
+<br>
+ Attributes:<br>
+ main_session: The primary OS-agnostic remote session used<br>
+ to communicate with the node.<br>
+ config: The configuration used to create the node.<br>
+ name: The name of the node.<br>
+ lcores: The list of logical cores that DTS can use on the node.<br>
+ It's derived from logical cores present on the node and user configuration.<br>
"""<br>
<br>
main_session: OSSession<br>
@@ -56,65 +76,89 @@ def __init__(self, node_config: NodeConfiguration):<br>
self._<a href="http://logger.info" rel="noreferrer" target="_blank">logger.info</a>(f"Created node: {<a href="http://self.name" rel="noreferrer" target="_blank">self.name</a>}")<br>
<br>
def set_up_execution(self, execution_config: ExecutionConfiguration) -> None:<br>
- """<br>
- Perform the execution setup that will be done for each execution<br>
- this node is part of.<br>
+ """Execution setup steps.<br>
+<br>
+ Configure hugepages and call self._set_up_execution where<br>
+ the rest of the configuration steps (if any) are implemented.<br>
+<br>
+ Args:<br>
+ execution_config: The execution configuration according to which<br>
+ the setup steps will be taken.<br>
"""<br>
self._setup_hugepages()<br>
self._set_up_execution(execution_config)<br>
<br>
def _set_up_execution(self, execution_config: ExecutionConfiguration) -> None:<br>
- """<br>
- This method exists to be optionally overwritten by derived classes and<br>
- is not decorated so that the derived class doesn't have to use the decorator.<br>
+ """Optional additional execution setup steps for derived classes.<br>
+<br>
+ Derived classes should overwrite this<br>
+ if they want to add additional execution setup steps.<br>
"""<br>
<br>
def tear_down_execution(self) -> None:<br>
- """<br>
- Perform the execution teardown that will be done after each execution<br>
- this node is part of concludes.<br>
+ """Execution teardown steps.<br>
+<br>
+ There are currently no common execution teardown steps<br>
+ common to all DTS node types.<br>
"""<br>
self._tear_down_execution()<br>
<br>
def _tear_down_execution(self) -> None:<br>
- """<br>
- This method exists to be optionally overwritten by derived classes and<br>
- is not decorated so that the derived class doesn't have to use the decorator.<br>
+ """Optional additional execution teardown steps for derived classes.<br>
+<br>
+ Derived classes should overwrite this<br>
+ if they want to add additional execution teardown steps.<br>
"""<br>
<br>
def set_up_build_target(<br>
self, build_target_config: BuildTargetConfiguration<br>
) -> None:<br>
- """<br>
- Perform the build target setup that will be done for each build target<br>
- tested on this node.<br>
+ """Build target setup steps.<br>
+<br>
+ There are currently no common build target setup steps<br>
+ common to all DTS node types.<br>
+<br>
+ Args:<br>
+ build_target_config: The build target configuration according to which<br>
+ the setup steps will be taken.<br>
"""<br>
self._set_up_build_target(build_target_config)<br>
<br>
def _set_up_build_target(<br>
self, build_target_config: BuildTargetConfiguration<br>
) -> None:<br>
- """<br>
- This method exists to be optionally overwritten by derived classes and<br>
- is not decorated so that the derived class doesn't have to use the decorator.<br>
+ """Optional additional build target setup steps for derived classes.<br>
+<br>
+ Derived classes should optionally overwrite this<br>
+ if they want to add additional build target setup steps.<br>
"""<br>
<br>
def tear_down_build_target(self) -> None:<br>
- """<br>
- Perform the build target teardown that will be done after each build target<br>
- tested on this node.<br>
+ """Build target teardown steps.<br>
+<br>
+ There are currently no common build target teardown steps<br>
+ common to all DTS node types.<br>
"""<br>
self._tear_down_build_target()<br>
<br>
def _tear_down_build_target(self) -> None:<br>
- """<br>
- This method exists to be optionally overwritten by derived classes and<br>
- is not decorated so that the derived class doesn't have to use the decorator.<br>
+ """Optional additional build target teardown steps for derived classes.<br>
+<br>
+ Derived classes should overwrite this<br>
+ if they want to add additional build target teardown steps.<br>
"""<br>
<br>
def create_session(self, name: str) -> OSSession:<br>
- """<br>
- Create and return a new OSSession tailored to the remote OS.<br>
+ """Create and return a new OS-agnostic remote session.<br>
+<br>
+ The returned session won't be used by the object creating it.<br>
+ Will be cleaned up automatically.<br>
+<br>
+ Args:<br>
+ name: The name of the session.<br>
+<br>
+ Returns:<br>
+ A new OS-agnostic remote session.<br>
"""<br>
session_name = f"{<a href="http://self.name" rel="noreferrer" target="_blank">self.name</a>} {name}"<br>
connection = create_session(<br>
@@ -130,14 +174,24 @@ def filter_lcores(<br>
filter_specifier: LogicalCoreCount | LogicalCoreList,<br>
ascending: bool = True,<br>
) -> list[LogicalCore]:<br>
- """<br>
- Filter the LogicalCores found on the Node according to<br>
- a LogicalCoreCount or a LogicalCoreList.<br>
+ """Filter the node's logical cores that DTS can use.<br>
<br>
- If ascending is True, use cores with the lowest numerical id first<br>
- and continue in ascending order. If False, start with the highest<br>
- id and continue in descending order. This ordering affects which<br>
- sockets to consider first as well.<br>
+ Logical cores that DTS can use are ones that are present on the node,<br>
+ but filtered according to user config.<br>
+ The filter_specifier will filter cores from those logical cores.<br>
+<br>
+ Args:<br>
+ filter_specifier: Two different filters can be used, one that specifies<br>
+ the number of logical cores per core, cores per socket and<br>
+ the number of sockets,<br>
+ the other that specifies a logical core list.<br>
+ ascending: If True, use cores with the lowest numerical id first<br>
+ and continue in ascending order. If False, start with the highest<br>
+ id and continue in descending order. This ordering affects which<br>
+ sockets to consider first as well.<br>
+<br>
+ Returns:<br>
+ A list of logical cores.<br>
"""<br>
self._logger.debug(f"Filtering {filter_specifier} from {self.lcores}.")<br>
return lcore_filter(<br>
@@ -147,17 +201,14 @@ def filter_lcores(<br>
).filter()<br>
<br>
def _get_remote_cpus(self) -> None:<br>
- """<br>
- Scan CPUs in the remote OS and store a list of LogicalCores.<br>
- """<br>
+ """Scan CPUs in the remote OS and store a list of LogicalCores."""<br>
self._<a href="http://logger.info" rel="noreferrer" target="_blank">logger.info</a>("Getting CPU information.")<br>
self.lcores = self.main_session.get_remote_cpus(self.config.use_first_core)<br>
<br>
def _setup_hugepages(self):<br>
- """<br>
- Setup hugepages on the Node. Different architectures can supply different<br>
- amounts of memory for hugepages and numa-based hugepage allocation may need<br>
- to be considered.<br>
+ """Setup hugepages on the Node.<br>
+<br>
+ Configure the hugepages only if they're specified in user configuration.<br>
"""<br>
if self.config.hugepages:<br>
self.main_session.setup_hugepages(<br>
@@ -165,9 +216,7 @@ def _setup_hugepages(self):<br>
)<br>
<br>
def close(self) -> None:<br>
- """<br>
- Close all connections and free other resources.<br>
- """<br>
+ """Close all connections and free other resources."""<br>
if self.main_session:<br>
self.main_session.close()<br>
for session in self._other_sessions:<br>
@@ -176,6 +225,11 @@ def close(self) -> None:<br>
<br>
@staticmethod<br>
def skip_setup(func: Callable[..., Any]) -> Callable[..., Any]:<br>
+ """A decorator that skips the decorated function.<br>
+<br>
+ When used, the decorator executes an empty lambda function<br>
+ instead of the decorated function.<br>
+ """<br>
if SETTINGS.skip_setup:<br>
return lambda *args: None<br>
else:<br>
-- <br>
2.30.2<br>
<br>
</blockquote></div>