From: Ondrej Lichtner <olichtne(a)redhat.com>
__repr__ methods return a string that can be put back to python to
interpret it and create an "equal/identical" object instance. This can
be quite useful when printing logs - the method makes the objects self
describe themselves without any specific format.
The exception is that some of these can't be cleanly interpreted because
they require references to some internal objects that would be clumsy to
also provide... In those cases, the __str__ method is defined instead
which only provides some informal description of the object but in a
similar format.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
---
lnst/Common/IpAddress.py | 3 +++
lnst/Controller/Namespace.py | 7 +++++
lnst/Devices/RemoteDevice.py | 13 +++++++++
.../Perf/Measurements/BaseFlowMeasurement.py | 27 +++++++++++++++++++
.../Perf/Measurements/BaseMeasurement.py | 6 +++++
lnst/Tests/BaseTestModule.py | 12 +++++++++
6 files changed, 68 insertions(+)
diff --git a/lnst/Common/IpAddress.py b/lnst/Common/IpAddress.py
index ef410c6..54c3735 100644
--- a/lnst/Common/IpAddress.py
+++ b/lnst/Common/IpAddress.py
@@ -48,6 +48,9 @@ def __ne__(self, other):
def _parse_addr(addr):
raise NotImplementedError()
+ def __repr__(self):
+ return "{}({}/{})".format(self.__class__.__name__, str(self),
self.prefixlen)
+
class Ip4Address(BaseIpAddress):
def __init__(self, addr):
super(Ip4Address, self).__init__(addr)
diff --git a/lnst/Controller/Namespace.py b/lnst/Controller/Namespace.py
index f3b3960..8c96ced 100644
--- a/lnst/Controller/Namespace.py
+++ b/lnst/Controller/Namespace.py
@@ -214,3 +214,10 @@ def _unset(self, value):
return True
else:
return False
+
+ def __str__(self):
+ return "{cls}(machine_id={m_id}{namespace})".format(
+ cls=self.__class__.__name__,
+ m_id=self._machine.get_id(),
+ namespace=", namespace_name={}".format(self.name) if self.name else
"",
+ )
diff --git a/lnst/Devices/RemoteDevice.py b/lnst/Devices/RemoteDevice.py
index 00d937b..4184bed 100644
--- a/lnst/Devices/RemoteDevice.py
+++ b/lnst/Devices/RemoteDevice.py
@@ -149,6 +149,19 @@ def __iter__(self):
def _match_update_data(self, data):
return False
+ def __repr__(self):
+ args = [
+ "{}={}".format(k, v)
+ for k, v in [
+ ("machine", self._machine.get_id()),
+ ("id", self._id),
+ ("name", self.name),
+ ("ifindex", self.ifindex),
+ ]
+ ]
+
+ return "{}({})".format(self._dev_cls.__name__, ",
".join(args))
+
class PairedRemoteDevice(RemoteDevice):
"""RemoteDevice class for paired Devices (such as
veth)"""
def __init__(self, peer, dev_cls, args=[], kwargs={}):
diff --git a/lnst/RecipeCommon/Perf/Measurements/BaseFlowMeasurement.py
b/lnst/RecipeCommon/Perf/Measurements/BaseFlowMeasurement.py
index c4448b7..bf04201 100644
--- a/lnst/RecipeCommon/Perf/Measurements/BaseFlowMeasurement.py
+++ b/lnst/RecipeCommon/Perf/Measurements/BaseFlowMeasurement.py
@@ -1,3 +1,4 @@
+import textwrap
import signal
from lnst.RecipeCommon.Perf.Measurements.MeasurementError import MeasurementError
from lnst.RecipeCommon.Perf.Measurements.BaseMeasurement import BaseMeasurement
@@ -58,6 +59,32 @@ def parallel_streams(self):
def cpupin(self):
return self._cpupin
+ def __repr__(self):
+ string = """
+ Flow(
+ type={type},
+ generator={generator},
+ generator_bind={generator_bind},
+ receiver={receiver},
+ receiver_bind={receiver_bind},
+ msg_size={msg_size},
+ duration={duration},
+ parallel_streams={parallel_streams},
+ cpupin={cpupin},
+ )""".format(
+ type=self.type,
+ generator=str(self.generator),
+ generator_bind=self.generator_bind,
+ receiver=str(self.receiver),
+ receiver_bind=self.receiver_bind,
+ msg_size=self.msg_size,
+ duration=self.duration,
+ parallel_streams=self.parallel_streams,
+ cpupin=self.cpupin,
+ )
+ string = textwrap.dedent(string).strip()
+ return string
+
class NetworkFlowTest(object):
def __init__(self, flow, server_job, client_job):
self._flow = flow
diff --git a/lnst/RecipeCommon/Perf/Measurements/BaseMeasurement.py
b/lnst/RecipeCommon/Perf/Measurements/BaseMeasurement.py
index 287f4c8..e577469 100644
--- a/lnst/RecipeCommon/Perf/Measurements/BaseMeasurement.py
+++ b/lnst/RecipeCommon/Perf/Measurements/BaseMeasurement.py
@@ -36,6 +36,12 @@ def report_results(recipe, results):
def aggregate_results(first, second):
raise NotImplementedError()
+ def __repr__(self):
+ return "{}({})".format(
+ self.__class__.__name__,
+ repr(self.conf),
+ )
+
class BaseMeasurementResults(object):
def __init__(self, measurement):
diff --git a/lnst/Tests/BaseTestModule.py b/lnst/Tests/BaseTestModule.py
index 27ba378..c103d87 100644
--- a/lnst/Tests/BaseTestModule.py
+++ b/lnst/Tests/BaseTestModule.py
@@ -59,6 +59,7 @@ def __init__(self, **kwargs):
to class attributes (Param type). Values will be parsed and
set to Param instances under the self.params object.
"""
+ self._orig_kwargs = kwargs.copy()
#by defaults loads the params into self.params - no checks pseudocode:
self.params = Parameters()
@@ -101,3 +102,14 @@ def handler(signum, frame):
def _get_res_data(self):
return self._res_data
+
+ def __repr__(self):
+ return "{}({})".format(
+ self.__class__.__name__,
+ ", ".join(
+ [
+ "{}={}".format(k, repr(v))
+ for k, v in self._orig_kwargs.items()
+ ]
+ ),
+ )
--
2.21.0