1#    Copyright 2016-2017 ARM Limited
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14#
15
16import utils_tests
17
18import trappy
19
20import numpy as np
21
22class TestSystrace(utils_tests.SetupDirectory):
23
24    def __init__(self, *args, **kwargs):
25        super(TestSystrace, self).__init__(
26             [("trace_systrace.html", "trace.html"),
27             ("trace_surfaceflinger.html", "trace_sf.html")],
28             *args,
29             **kwargs)
30
31    def test_systrace_html(self):
32        """Tests parsing of a systrace embedded textual trace """
33
34        events = ["sched_switch", "sched_wakeup", "trace_event_clock_sync"]
35        trace = trappy.SysTrace("trace.html", events=events)
36
37        self.assertTrue(hasattr(trace, "sched_switch"))
38        self.assertEquals(len(trace.sched_switch.data_frame), 4)
39        self.assertTrue("prev_comm" in trace.sched_switch.data_frame.columns)
40
41        self.assertTrue(hasattr(trace, "sched_wakeup"))
42        self.assertEquals(len(trace.sched_wakeup.data_frame), 4)
43        self.assertTrue("target_cpu" in trace.sched_wakeup.data_frame.columns)
44
45        self.assertTrue(hasattr(trace, "trace_event_clock_sync"))
46        self.assertEquals(len(trace.trace_event_clock_sync.data_frame), 1)
47        self.assertTrue("realtime_ts" in trace.trace_event_clock_sync.data_frame.columns)
48
49    def test_cpu_counting(self):
50        """SysTrace traces know the number of cpus"""
51
52        trace = trappy.SysTrace("trace.html")
53
54        self.assertTrue(hasattr(trace, "_cpus"))
55        self.assertEquals(trace._cpus, 3)
56
57    def test_systrace_userspace(self):
58        """Test parsing of userspace events"""
59
60        # Test a 'B' event (begin)
61        trace = trappy.SysTrace("trace_sf.html")
62        dfr = trace.tracing_mark_write.data_frame
63        self.assertEquals(dfr['__pid'].iloc[2], 7591)
64        self.assertEquals(dfr['__comm'].iloc[2], 'RenderThread')
65        self.assertEquals(dfr['pid'].iloc[2], 7459)
66        self.assertEquals(dfr['event'].iloc[2], 'B')
67        self.assertEquals(dfr['func'].iloc[2], 'notifyFramePending')
68        self.assertEquals(dfr['data'].iloc[2], None)
69
70        # Test a 'C' event (count)
71        self.assertEquals(dfr['__pid'].iloc[-2], 612)
72        self.assertEquals(dfr['__comm'].iloc[-2], 'HwBinder:594_1')
73        self.assertEquals(dfr['pid'].iloc[-2], 594)
74        self.assertEquals(dfr['func'].iloc[-2], 'HW_VSYNC_0')
75        self.assertEquals(dfr['event'].iloc[-2], 'C')
76        self.assertEquals(dfr['data'].iloc[-2], '0')
77
78        # Test an 'E' event (end)
79        edfr = dfr[dfr['event'] == 'E']
80        self.assertEquals(edfr['__pid'].iloc[0], 7591)
81        self.assertEquals(edfr['__comm'].iloc[0], 'RenderThread')
82        self.assertTrue(np.isnan(edfr['pid'].iloc[0]))
83        self.assertEquals(edfr['func'].iloc[0], None)
84        self.assertEquals(edfr['event'].iloc[0], 'E')
85        self.assertEquals(edfr['data'].iloc[0], None)
86
87    def test_systrace_line_num(self):
88        """Test for line numbers in a systrace"""
89        trace = trappy.SysTrace("trace_sf.html")
90        dfr = trace.sched_switch.data_frame
91        self.assertEquals(trace.lines, 2506)
92        self.assertEquals(dfr['__line'].iloc[0], 0)
93        self.assertEquals(dfr['__line'].iloc[1], 6)
94        self.assertEquals(dfr['__line'].iloc[-1], 2505)
95
96    def test_parse_tracing_mark_write_events(self):
97        """Check that tracing_mark_write events are parsed without errors"""
98        events = ['tracing_mark_write']
99        try:
100            trace = trappy.SysTrace("trace.html", events=events)
101        except TypeError as e:
102            self.fail("tracing_mark_write parsing failed with {} exception"\
103                      .format(e.message))
104
105
106class TestLegacySystrace(utils_tests.SetupDirectory):
107
108    def __init__(self, *args, **kwargs):
109        super(TestLegacySystrace, self).__init__(
110             [("trace_legacy_systrace.html", "trace.html")],
111             *args,
112             **kwargs)
113
114    def test_systrace_html(self):
115        """Tests parsing of a legacy systrace embedded textual trace """
116
117        events = ["sched_switch", "sched_wakeup", "sched_contrib_scale_f"]
118        trace = trappy.SysTrace("trace.html", events=events)
119
120        self.assertTrue(hasattr(trace, "sched_switch"))
121        self.assertEquals(len(trace.sched_switch.data_frame), 3)
122        self.assertTrue("prev_comm" in trace.sched_switch.data_frame.columns)
123
124        self.assertTrue(hasattr(trace, "sched_wakeup"))
125        self.assertEquals(len(trace.sched_wakeup.data_frame), 2)
126        self.assertTrue("target_cpu" in trace.sched_wakeup.data_frame.columns)
127
128        self.assertTrue(hasattr(trace, "sched_contrib_scale_f"))
129        self.assertEquals(len(trace.sched_contrib_scale_f.data_frame), 2)
130        self.assertTrue("freq_scale_factor" in trace.sched_contrib_scale_f.data_frame.columns)
131
132    def test_cpu_counting(self):
133        """In a legacy SysTrace trace, trappy gets the number of cpus"""
134
135        trace = trappy.SysTrace("trace.html")
136
137        self.assertTrue(hasattr(trace, "_cpus"))
138        self.assertEquals(trace._cpus, 8)
139