From 3dcf1cd303236a93d462eb434dc24fd3f2b38f18 Mon Sep 17 00:00:00 2001 From: Christophe Bedard Date: Wed, 1 Jan 2020 12:46:44 -0500 Subject: [PATCH 1/3] Do check before calling super().__init__() --- .../tracetools_analysis/utils/memory_usage.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tracetools_analysis/tracetools_analysis/utils/memory_usage.py b/tracetools_analysis/tracetools_analysis/utils/memory_usage.py index c42a198..22042d9 100644 --- a/tracetools_analysis/tracetools_analysis/utils/memory_usage.py +++ b/tracetools_analysis/tracetools_analysis/utils/memory_usage.py @@ -40,12 +40,12 @@ class MemoryUsageDataModelUtil(DataModelUtil): :param userspace: the userspace data model object to use :param kernel: the kernel data model object to use """ - # Not giving any model to the base class; we'll own them ourselves - super().__init__(None) - if userspace is None and kernel is None: raise RuntimeError('must provide at least one (userspace or kernel) data model!') + # Not giving any model to the base class; we'll own them ourselves + super().__init__(None) + self.data_ust = userspace self.data_kernel = kernel From 2fee0ced269f1f0c4de6a99d242cc84895df86f6 Mon Sep 17 00:00:00 2001 From: Christophe Bedard Date: Wed, 1 Jan 2020 12:48:12 -0500 Subject: [PATCH 2/3] Add option to simply give an EventHandler when creating a DataModelUtil --- .../tracetools_analysis/utils/__init__.py | 9 +++++---- .../tracetools_analysis/utils/cpu_time.py | 9 ++++++--- .../tracetools_analysis/utils/memory_usage.py | 17 +++++++++++------ .../tracetools_analysis/utils/profile.py | 7 ++++--- .../tracetools_analysis/utils/ros2.py | 7 ++++--- 5 files changed, 30 insertions(+), 19 deletions(-) diff --git a/tracetools_analysis/tracetools_analysis/utils/__init__.py b/tracetools_analysis/tracetools_analysis/utils/__init__.py index 3f30d52..27333ce 100644 --- a/tracetools_analysis/tracetools_analysis/utils/__init__.py +++ b/tracetools_analysis/tracetools_analysis/utils/__init__.py @@ -21,6 +21,7 @@ from typing import Union from pandas import DataFrame from ..data_model import DataModel +from ..processor import EventHandler class DataModelUtil(): @@ -32,17 +33,17 @@ class DataModelUtil(): def __init__( self, - data_model: DataModel, + data_object: Union[DataModel, EventHandler, None], ) -> None: """ Create a DataModelUtil. - :param data_model: the data model + :param data_object: the data model or the event handler which has a data model """ - self.__data = data_model + self.__data = data_object.data if isinstance(data_object, EventHandler) else data_object @property - def data(self) -> DataModel: + def data(self) -> Union[DataModel, None]: return self.__data @staticmethod diff --git a/tracetools_analysis/tracetools_analysis/utils/cpu_time.py b/tracetools_analysis/tracetools_analysis/utils/cpu_time.py index 68a234f..dee8eba 100644 --- a/tracetools_analysis/tracetools_analysis/utils/cpu_time.py +++ b/tracetools_analysis/tracetools_analysis/utils/cpu_time.py @@ -14,10 +14,13 @@ """Module for CPU time data model utils.""" +from typing import Union + from pandas import DataFrame from . import DataModelUtil from ..data_model.cpu_time import CpuTimeDataModel +from ..processor.cpu_time import CpuTimeHandler class CpuTimeDataModelUtil(DataModelUtil): @@ -25,14 +28,14 @@ class CpuTimeDataModelUtil(DataModelUtil): def __init__( self, - data_model: CpuTimeDataModel, + data_object: Union[CpuTimeDataModel, CpuTimeHandler], ) -> None: """ Create a CpuTimeDataModelUtil. - :param data_model: the data model object to use + :param data_object: the data model or the event handler which has a data model """ - super().__init__(data_model) + super().__init__(data_object) def get_time_per_thread(self) -> DataFrame: """Get a DataFrame of total duration for each thread.""" diff --git a/tracetools_analysis/tracetools_analysis/utils/memory_usage.py b/tracetools_analysis/tracetools_analysis/utils/memory_usage.py index 22042d9..3835f46 100644 --- a/tracetools_analysis/tracetools_analysis/utils/memory_usage.py +++ b/tracetools_analysis/tracetools_analysis/utils/memory_usage.py @@ -16,11 +16,14 @@ from collections import defaultdict from typing import Dict +from typing import Union from pandas import DataFrame from . import DataModelUtil from ..data_model.memory_usage import MemoryUsageDataModel +from ..processor.memory_usage import KernelMemoryUsageHandler +from ..processor.memory_usage import UserspaceMemoryUsageHandler class MemoryUsageDataModelUtil(DataModelUtil): @@ -29,16 +32,16 @@ class MemoryUsageDataModelUtil(DataModelUtil): def __init__( self, *, - userspace: MemoryUsageDataModel = None, - kernel: MemoryUsageDataModel = None, + userspace: Union[MemoryUsageDataModel, UserspaceMemoryUsageHandler, None] = None, + kernel: Union[MemoryUsageDataModel, KernelMemoryUsageHandler, None] = None, ) -> None: """ Create a MemoryUsageDataModelUtil. At least one non-`None` `MemoryUsageDataModel` must be given. - :param userspace: the userspace data model object to use - :param kernel: the kernel data model object to use + :param userspace: the userspace data model object to use or the event handler + :param kernel: the kernel data model object to use or the event handler """ if userspace is None and kernel is None: raise RuntimeError('must provide at least one (userspace or kernel) data model!') @@ -46,8 +49,10 @@ class MemoryUsageDataModelUtil(DataModelUtil): # Not giving any model to the base class; we'll own them ourselves super().__init__(None) - self.data_ust = userspace - self.data_kernel = kernel + self.data_ust = userspace.data \ + if isinstance(userspace, UserspaceMemoryUsageHandler) else userspace + self.data_kernel = kernel.data \ + if isinstance(kernel, KernelMemoryUsageHandler) else kernel @staticmethod def format_size(size: int, precision: int = 2): diff --git a/tracetools_analysis/tracetools_analysis/utils/profile.py b/tracetools_analysis/tracetools_analysis/utils/profile.py index 8389381..e25ae79 100644 --- a/tracetools_analysis/tracetools_analysis/utils/profile.py +++ b/tracetools_analysis/tracetools_analysis/utils/profile.py @@ -24,6 +24,7 @@ from pandas import DataFrame from . import DataModelUtil from ..data_model.profile import ProfileDataModel +from ..processor.profile import ProfileHandler class ProfileDataModelUtil(DataModelUtil): @@ -31,14 +32,14 @@ class ProfileDataModelUtil(DataModelUtil): def __init__( self, - data_model: ProfileDataModel, + data_object: Union[ProfileDataModel, ProfileHandler], ) -> None: """ Create a ProfileDataModelUtil. - :param data_model: the data model object to use + :param data_object: the data model or the event handler which has a data model """ - super().__init__(data_model) + super().__init__(data_object) def with_tid( self, diff --git a/tracetools_analysis/tracetools_analysis/utils/ros2.py b/tracetools_analysis/tracetools_analysis/utils/ros2.py index 0db7a8a..de39ae6 100644 --- a/tracetools_analysis/tracetools_analysis/utils/ros2.py +++ b/tracetools_analysis/tracetools_analysis/utils/ros2.py @@ -24,6 +24,7 @@ from pandas import DataFrame from . import DataModelUtil from ..data_model.ros2 import Ros2DataModel +from ..processor.ros2 import Ros2Handler class Ros2DataModelUtil(DataModelUtil): @@ -31,14 +32,14 @@ class Ros2DataModelUtil(DataModelUtil): def __init__( self, - data_model: Ros2DataModel, + data_object: Union[Ros2DataModel, Ros2Handler], ) -> None: """ Create a Ros2DataModelUtil. - :param data_model: the data model object to use + :param data_object: the data model or the event handler which has a data model """ - super().__init__(data_model) + super().__init__(data_object) def _prettify( self, From 8c08cd192ed80f530d2d8f08cae3a80f1bed033c Mon Sep 17 00:00:00 2001 From: Christophe Bedard Date: Wed, 1 Jan 2020 13:01:43 -0500 Subject: [PATCH 3/3] Add DataModelUtil creation test --- .../test_data_model_util.py | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/tracetools_analysis/test/tracetools_analysis/test_data_model_util.py b/tracetools_analysis/test/tracetools_analysis/test_data_model_util.py index 4be009c..c7c8328 100644 --- a/tracetools_analysis/test/tracetools_analysis/test_data_model_util.py +++ b/tracetools_analysis/test/tracetools_analysis/test_data_model_util.py @@ -14,11 +14,15 @@ from datetime import datetime from datetime import timezone +from typing import Dict import unittest from pandas import DataFrame from pandas.util.testing import assert_frame_equal +from tracetools_analysis.data_model import DataModel +from tracetools_analysis.processor import EventHandler +from tracetools_analysis.processor import EventMetadata from tracetools_analysis.utils import DataModelUtil @@ -109,6 +113,38 @@ class TestDataModelUtil(unittest.TestCase): ) assert_frame_equal(input_df, expected_df) + def test_creation(self) -> None: + def handler_whatever( + self, event: Dict, metadata: EventMetadata + ) -> None: + pass + + handler_map = {'fake': handler_whatever} + data_model = DataModel() + + # Should handle the event handler not having any data model + handler_none = EventHandler( + handler_map=handler_map, + ) + data_model_util_none = DataModelUtil(handler_none) + self.assertIsNone(data_model_util_none.data) + + # Should work when given an event handler with a data model + handler_data = EventHandler( + handler_map=handler_map, + data_model=data_model, + ) + data_model_util_data = DataModelUtil(handler_data) + self.assertTrue(data_model_util_data.data is data_model) + + # Should work when given a data model directly + handler_data_direct = EventHandler( + handler_map=handler_map, + data_model=data_model, + ) + data_model_util_direct = DataModelUtil(handler_data_direct.data) + self.assertTrue(data_model_util_direct.data is data_model) + if __name__ == '__main__': unittest.main()