Add test for profiling handler
This commit is contained in:
parent
4cb73fb9b6
commit
fdeb4a5d48
1 changed files with 320 additions and 0 deletions
|
@ -0,0 +1,320 @@
|
|||
# Copyright 2019 Robert Bosch GmbH
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from typing import Any
|
||||
from typing import Dict
|
||||
from typing import List
|
||||
import unittest
|
||||
|
||||
from pandas import DataFrame
|
||||
from pandas.util.testing import assert_frame_equal
|
||||
|
||||
from tracetools_analysis.processor import Processor
|
||||
from tracetools_analysis.processor.profile import ProfileHandler
|
||||
from tracetools_read import DictEvent
|
||||
|
||||
|
||||
# TEST DATA
|
||||
#
|
||||
# + Threads:
|
||||
# 0: does whatever
|
||||
# 1: contains one instance of the functions of interest
|
||||
# 2: contains another instance of the functions of interest
|
||||
#
|
||||
# + Functions structure
|
||||
# function_a
|
||||
# function_aa
|
||||
# function_b
|
||||
#
|
||||
# + Timeline
|
||||
# tid 1 2
|
||||
# func a aa b a aa b
|
||||
# time
|
||||
# 0 : whatever
|
||||
# 3 : sched_switch from tid 0 to tid 1
|
||||
# 5 : tid 1, func_entry: function_a
|
||||
# 7 : sched_switch from tid 1 to tid 0 2
|
||||
# 10 : sched_switch from tid 0 to tid 2
|
||||
# 11 : tid 2, func_entry: function_a
|
||||
# 15 : sched_switch from tid 2 to tid 1 4
|
||||
# 16 : tid 1, func_entry: function_aa 1
|
||||
# 20 : sched_switch from tid 1 to tid 2 4 4
|
||||
# 27 : tid 2, func_entry: function_aa 7
|
||||
# 29 : sched_switch from tid 2 to tid 1 2 2
|
||||
# 30 : tid 1, func_exit: (function_aa) 1 1
|
||||
# 32 : sched_switch from tid 1 to tid 0 2
|
||||
# 34 : sched_switch from tid 0 to tid 2
|
||||
# 35 : tid 2, func_exit: (function_aa) 1 1
|
||||
# 37 : tid 2, func_exit: (function_a) 2
|
||||
# 39 : tid 2, func_entry: function_b
|
||||
# 40 : tid 2, func_exit: (function_b) 1
|
||||
# 41 : sched_switch from tid 2 to tid 1
|
||||
# 42 : tid 1, func_exit: (function_a) 1
|
||||
# 44 : tid 1, func_entry: function_b
|
||||
# 47 : sched_switch from tid 1 to tid 0 3
|
||||
# 49 : sched_switch from tid 0 to tid 1
|
||||
# 60 : tid 1, func_exit: (function_b) 11
|
||||
# 69 : sched_switch from tid 1 to tid 0
|
||||
#
|
||||
# total 11 5 14 16 3 1
|
||||
|
||||
|
||||
input_events = [
|
||||
{
|
||||
'_name': 'sched_switch',
|
||||
'_timestamp': 3,
|
||||
'prev_tid': 0,
|
||||
'next_tid': 1,
|
||||
},
|
||||
{
|
||||
'_name': 'lttng_ust_cyg_profile_fast:func_entry',
|
||||
'_timestamp': 5,
|
||||
'vtid': 1,
|
||||
'addr': '0xfA',
|
||||
},
|
||||
{
|
||||
'_name': 'sched_switch',
|
||||
'_timestamp': 7,
|
||||
'prev_tid': 1,
|
||||
'next_tid': 0,
|
||||
},
|
||||
{
|
||||
'_name': 'sched_switch',
|
||||
'_timestamp': 10,
|
||||
'prev_tid': 0,
|
||||
'next_tid': 2,
|
||||
},
|
||||
{
|
||||
'_name': 'lttng_ust_cyg_profile_fast:func_entry',
|
||||
'_timestamp': 11,
|
||||
'vtid': 2,
|
||||
'addr': '0xfA',
|
||||
},
|
||||
{
|
||||
'_name': 'sched_switch',
|
||||
'_timestamp': 15,
|
||||
'prev_tid': 2,
|
||||
'next_tid': 1,
|
||||
},
|
||||
{
|
||||
'_name': 'lttng_ust_cyg_profile_fast:func_entry',
|
||||
'_timestamp': 16,
|
||||
'vtid': 1,
|
||||
'addr': '0xfAA',
|
||||
},
|
||||
{
|
||||
'_name': 'sched_switch',
|
||||
'_timestamp': 20,
|
||||
'prev_tid': 1,
|
||||
'next_tid': 2,
|
||||
},
|
||||
{
|
||||
'_name': 'lttng_ust_cyg_profile_fast:func_entry',
|
||||
'_timestamp': 27,
|
||||
'vtid': 2,
|
||||
'addr': '0xfAA',
|
||||
},
|
||||
{
|
||||
'_name': 'sched_switch',
|
||||
'_timestamp': 29,
|
||||
'prev_tid': 2,
|
||||
'next_tid': 1,
|
||||
},
|
||||
{
|
||||
'_name': 'lttng_ust_cyg_profile_fast:func_exit',
|
||||
'_timestamp': 30,
|
||||
'vtid': 1,
|
||||
},
|
||||
{
|
||||
'_name': 'sched_switch',
|
||||
'_timestamp': 32,
|
||||
'prev_tid': 1,
|
||||
'next_tid': 0,
|
||||
},
|
||||
{
|
||||
'_name': 'sched_switch',
|
||||
'_timestamp': 34,
|
||||
'prev_tid': 0,
|
||||
'next_tid': 2,
|
||||
},
|
||||
{
|
||||
'_name': 'lttng_ust_cyg_profile_fast:func_exit',
|
||||
'_timestamp': 35,
|
||||
'vtid': 2,
|
||||
},
|
||||
{
|
||||
'_name': 'lttng_ust_cyg_profile_fast:func_exit',
|
||||
'_timestamp': 37,
|
||||
'vtid': 2,
|
||||
},
|
||||
{
|
||||
'_name': 'lttng_ust_cyg_profile_fast:func_entry',
|
||||
'_timestamp': 39,
|
||||
'vtid': 2,
|
||||
'addr': '0xfB',
|
||||
},
|
||||
{
|
||||
'_name': 'lttng_ust_cyg_profile_fast:func_exit',
|
||||
'_timestamp': 40,
|
||||
'vtid': 2,
|
||||
},
|
||||
{
|
||||
'_name': 'sched_switch',
|
||||
'_timestamp': 41,
|
||||
'prev_tid': 2,
|
||||
'next_tid': 1,
|
||||
},
|
||||
{
|
||||
'_name': 'lttng_ust_cyg_profile_fast:func_exit',
|
||||
'_timestamp': 42,
|
||||
'vtid': 1,
|
||||
},
|
||||
{
|
||||
'_name': 'lttng_ust_cyg_profile_fast:func_entry',
|
||||
'_timestamp': 44,
|
||||
'vtid': 1,
|
||||
'addr': '0xfB',
|
||||
},
|
||||
{
|
||||
'_name': 'sched_switch',
|
||||
'_timestamp': 47,
|
||||
'prev_tid': 1,
|
||||
'next_tid': 0,
|
||||
},
|
||||
{
|
||||
'_name': 'sched_switch',
|
||||
'_timestamp': 49,
|
||||
'prev_tid': 0,
|
||||
'next_tid': 1,
|
||||
},
|
||||
{
|
||||
'_name': 'lttng_ust_cyg_profile_fast:func_exit',
|
||||
'_timestamp': 60,
|
||||
'vtid': 1,
|
||||
},
|
||||
{
|
||||
'_name': 'sched_switch',
|
||||
'_timestamp': 69,
|
||||
'prev_tid': 1,
|
||||
'next_tid': 0,
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
expected = [
|
||||
{
|
||||
'tid': 1,
|
||||
'depth': 1,
|
||||
'function_name': '0xfAA',
|
||||
'parent_name': '0xfA',
|
||||
'start_timestamp': 16,
|
||||
'duration': 14,
|
||||
'actual_duration': 5,
|
||||
},
|
||||
{
|
||||
'tid': 2,
|
||||
'depth': 1,
|
||||
'function_name': '0xfAA',
|
||||
'parent_name': '0xfA',
|
||||
'start_timestamp': 27,
|
||||
'duration': 8,
|
||||
'actual_duration': 3,
|
||||
},
|
||||
{
|
||||
'tid': 2,
|
||||
'depth': 0,
|
||||
'function_name': '0xfA',
|
||||
'parent_name': None,
|
||||
'start_timestamp': 11,
|
||||
'duration': 26,
|
||||
'actual_duration': 16,
|
||||
},
|
||||
{
|
||||
'tid': 2,
|
||||
'depth': 0,
|
||||
'function_name': '0xfB',
|
||||
'parent_name': None,
|
||||
'start_timestamp': 39,
|
||||
'duration': 1,
|
||||
'actual_duration': 1,
|
||||
},
|
||||
{
|
||||
'tid': 1,
|
||||
'depth': 0,
|
||||
'function_name': '0xfA',
|
||||
'parent_name': None,
|
||||
'start_timestamp': 5,
|
||||
'duration': 37,
|
||||
'actual_duration': 11,
|
||||
},
|
||||
{
|
||||
'tid': 1,
|
||||
'depth': 0,
|
||||
'function_name': '0xfB',
|
||||
'parent_name': None,
|
||||
'start_timestamp': 44,
|
||||
'duration': 16,
|
||||
'actual_duration': 14,
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
class TestProfileHandler(unittest.TestCase):
|
||||
|
||||
def __init__(self, *args) -> None:
|
||||
super().__init__(
|
||||
*args,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def build_expected_df(expected_data: List[Dict[str, Any]]) -> DataFrame:
|
||||
# Make sure the columns are in the same order
|
||||
expected_df = DataFrame(columns=[
|
||||
'tid',
|
||||
'depth',
|
||||
'function_name',
|
||||
'parent_name',
|
||||
'start_timestamp',
|
||||
'duration',
|
||||
'actual_duration',
|
||||
])
|
||||
return expected_df.append(expected_data, ignore_index=True)
|
||||
|
||||
@staticmethod
|
||||
def add_fake_fields(events: List[DictEvent]) -> None:
|
||||
# Actual value does not matter here; it just needs to be there
|
||||
for event in events:
|
||||
event['cpu_id'] = 69
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.add_fake_fields(input_events)
|
||||
cls.expected = cls.build_expected_df(expected)
|
||||
cls.handler = ProfileHandler()
|
||||
cls.processor = Processor(cls.handler)
|
||||
cls.processor.process(input_events)
|
||||
|
||||
def test_profiling(self) -> None:
|
||||
handler = self.__class__.handler
|
||||
expected_df = self.__class__.expected
|
||||
result_df = handler.get_data_model().times
|
||||
print('RESULT')
|
||||
print(result_df.to_string())
|
||||
print('EXPECTED')
|
||||
print(expected_df.to_string())
|
||||
assert_frame_equal(result_df, expected_df)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
Loading…
Add table
Add a link
Reference in a new issue