Merge branch 'create-datamodelutil-from-eventhandler' into 'master'

Add option to create a DataModelUtil from an EventHandler

See merge request micro-ROS/ros_tracing/tracetools_analysis!46
This commit is contained in:
Christophe Bedard 2020-01-01 18:06:08 +00:00
commit d95f87c196
6 changed files with 69 additions and 22 deletions

View file

@ -14,11 +14,15 @@
from datetime import datetime from datetime import datetime
from datetime import timezone from datetime import timezone
from typing import Dict
import unittest import unittest
from pandas import DataFrame from pandas import DataFrame
from pandas.util.testing import assert_frame_equal 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 from tracetools_analysis.utils import DataModelUtil
@ -109,6 +113,38 @@ class TestDataModelUtil(unittest.TestCase):
) )
assert_frame_equal(input_df, expected_df) 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__': if __name__ == '__main__':
unittest.main() unittest.main()

View file

@ -21,6 +21,7 @@ from typing import Union
from pandas import DataFrame from pandas import DataFrame
from ..data_model import DataModel from ..data_model import DataModel
from ..processor import EventHandler
class DataModelUtil(): class DataModelUtil():
@ -32,17 +33,17 @@ class DataModelUtil():
def __init__( def __init__(
self, self,
data_model: DataModel, data_object: Union[DataModel, EventHandler, None],
) -> None: ) -> None:
""" """
Create a DataModelUtil. 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 @property
def data(self) -> DataModel: def data(self) -> Union[DataModel, None]:
return self.__data return self.__data
@staticmethod @staticmethod

View file

@ -14,10 +14,13 @@
"""Module for CPU time data model utils.""" """Module for CPU time data model utils."""
from typing import Union
from pandas import DataFrame from pandas import DataFrame
from . import DataModelUtil from . import DataModelUtil
from ..data_model.cpu_time import CpuTimeDataModel from ..data_model.cpu_time import CpuTimeDataModel
from ..processor.cpu_time import CpuTimeHandler
class CpuTimeDataModelUtil(DataModelUtil): class CpuTimeDataModelUtil(DataModelUtil):
@ -25,14 +28,14 @@ class CpuTimeDataModelUtil(DataModelUtil):
def __init__( def __init__(
self, self,
data_model: CpuTimeDataModel, data_object: Union[CpuTimeDataModel, CpuTimeHandler],
) -> None: ) -> None:
""" """
Create a CpuTimeDataModelUtil. 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: def get_time_per_thread(self) -> DataFrame:
"""Get a DataFrame of total duration for each thread.""" """Get a DataFrame of total duration for each thread."""

View file

@ -16,11 +16,14 @@
from collections import defaultdict from collections import defaultdict
from typing import Dict from typing import Dict
from typing import Union
from pandas import DataFrame from pandas import DataFrame
from . import DataModelUtil from . import DataModelUtil
from ..data_model.memory_usage import MemoryUsageDataModel from ..data_model.memory_usage import MemoryUsageDataModel
from ..processor.memory_usage import KernelMemoryUsageHandler
from ..processor.memory_usage import UserspaceMemoryUsageHandler
class MemoryUsageDataModelUtil(DataModelUtil): class MemoryUsageDataModelUtil(DataModelUtil):
@ -29,25 +32,27 @@ class MemoryUsageDataModelUtil(DataModelUtil):
def __init__( def __init__(
self, self,
*, *,
userspace: MemoryUsageDataModel = None, userspace: Union[MemoryUsageDataModel, UserspaceMemoryUsageHandler, None] = None,
kernel: MemoryUsageDataModel = None, kernel: Union[MemoryUsageDataModel, KernelMemoryUsageHandler, None] = None,
) -> None: ) -> None:
""" """
Create a MemoryUsageDataModelUtil. Create a MemoryUsageDataModelUtil.
At least one non-`None` `MemoryUsageDataModel` must be given. At least one non-`None` `MemoryUsageDataModel` must be given.
:param userspace: the userspace 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 :param kernel: the kernel data model object to use or the event handler
""" """
# Not giving any model to the base class; we'll own them ourselves
super().__init__(None)
if userspace is None and kernel is None: if userspace is None and kernel is None:
raise RuntimeError('must provide at least one (userspace or kernel) data model!') raise RuntimeError('must provide at least one (userspace or kernel) data model!')
self.data_ust = userspace # Not giving any model to the base class; we'll own them ourselves
self.data_kernel = kernel super().__init__(None)
self.data_ust = userspace.data \
if isinstance(userspace, UserspaceMemoryUsageHandler) else userspace
self.data_kernel = kernel.data \
if isinstance(kernel, KernelMemoryUsageHandler) else kernel
@staticmethod @staticmethod
def format_size(size: int, precision: int = 2): def format_size(size: int, precision: int = 2):

View file

@ -24,6 +24,7 @@ from pandas import DataFrame
from . import DataModelUtil from . import DataModelUtil
from ..data_model.profile import ProfileDataModel from ..data_model.profile import ProfileDataModel
from ..processor.profile import ProfileHandler
class ProfileDataModelUtil(DataModelUtil): class ProfileDataModelUtil(DataModelUtil):
@ -31,14 +32,14 @@ class ProfileDataModelUtil(DataModelUtil):
def __init__( def __init__(
self, self,
data_model: ProfileDataModel, data_object: Union[ProfileDataModel, ProfileHandler],
) -> None: ) -> None:
""" """
Create a ProfileDataModelUtil. 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( def with_tid(
self, self,

View file

@ -24,6 +24,7 @@ from pandas import DataFrame
from . import DataModelUtil from . import DataModelUtil
from ..data_model.ros2 import Ros2DataModel from ..data_model.ros2 import Ros2DataModel
from ..processor.ros2 import Ros2Handler
class Ros2DataModelUtil(DataModelUtil): class Ros2DataModelUtil(DataModelUtil):
@ -31,14 +32,14 @@ class Ros2DataModelUtil(DataModelUtil):
def __init__( def __init__(
self, self,
data_model: Ros2DataModel, data_object: Union[Ros2DataModel, Ros2Handler],
) -> None: ) -> None:
""" """
Create a Ros2DataModelUtil. 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( def _prettify(
self, self,