Merge tag 'trace-printf-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/trace...
[drm/drm-misc.git] / tools / perf / pmu-events / metric_test.py
blobee22ff43ddd7e92c1f223809757c5c00e7768138
1 #!/usr/bin/env python3
2 # SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
3 import unittest
4 from metric import Constant
5 from metric import Event
6 from metric import Expression
7 from metric import ParsePerfJson
8 from metric import RewriteMetricsInTermsOfOthers
11 class TestMetricExpressions(unittest.TestCase):
13 def test_Operators(self):
14 a = Event('a')
15 b = Event('b')
16 self.assertEqual((a | b).ToPerfJson(), 'a | b')
17 self.assertEqual((a ^ b).ToPerfJson(), 'a ^ b')
18 self.assertEqual((a & b).ToPerfJson(), 'a & b')
19 self.assertEqual((a < b).ToPerfJson(), 'a < b')
20 self.assertEqual((a > b).ToPerfJson(), 'a > b')
21 self.assertEqual((a + b).ToPerfJson(), 'a + b')
22 self.assertEqual((a - b).ToPerfJson(), 'a - b')
23 self.assertEqual((a * b).ToPerfJson(), 'a * b')
24 self.assertEqual((a / b).ToPerfJson(), 'a / b')
25 self.assertEqual((a % b).ToPerfJson(), 'a % b')
26 one = Constant(1)
27 self.assertEqual((a + one).ToPerfJson(), 'a + 1')
29 def test_Brackets(self):
30 a = Event('a')
31 b = Event('b')
32 c = Event('c')
33 self.assertEqual((a * b + c).ToPerfJson(), 'a * b + c')
34 self.assertEqual((a + b * c).ToPerfJson(), 'a + b * c')
35 self.assertEqual(((a + a) + a).ToPerfJson(), 'a + a + a')
36 self.assertEqual(((a + b) * c).ToPerfJson(), '(a + b) * c')
37 self.assertEqual((a + (b * c)).ToPerfJson(), 'a + b * c')
38 self.assertEqual(((a / b) * c).ToPerfJson(), 'a / b * c')
39 self.assertEqual((a / (b * c)).ToPerfJson(), 'a / (b * c)')
41 def test_ParsePerfJson(self):
42 # Based on an example of a real metric.
43 before = '(a + b + c + d) / (2 * e)'
44 after = before
45 self.assertEqual(ParsePerfJson(before).ToPerfJson(), after)
47 # Parsing should handle events with '-' in their name. Note, in
48 # the json file the '\' are doubled to '\\'.
49 before = r'topdown\-fe\-bound / topdown\-slots - 1'
50 after = before
51 self.assertEqual(ParsePerfJson(before).ToPerfJson(), after)
53 # Parsing should handle escaped modifiers. Note, in the json file
54 # the '\' are doubled to '\\'.
55 before = r'arb@event\=0x81\,umask\=0x1@ + arb@event\=0x84\,umask\=0x1@'
56 after = before
57 self.assertEqual(ParsePerfJson(before).ToPerfJson(), after)
59 # Parsing should handle exponents in numbers.
60 before = r'a + 1e12 + b'
61 after = before
62 self.assertEqual(ParsePerfJson(before).ToPerfJson(), after)
64 def test_IfElseTests(self):
65 # if-else needs rewriting to Select and back.
66 before = r'Event1 if #smt_on else Event2'
67 after = f'({before})'
68 self.assertEqual(ParsePerfJson(before).ToPerfJson(), after)
70 before = r'Event1 if 0 else Event2'
71 after = f'({before})'
72 self.assertEqual(ParsePerfJson(before).ToPerfJson(), after)
74 before = r'Event1 if 1 else Event2'
75 after = f'({before})'
76 self.assertEqual(ParsePerfJson(before).ToPerfJson(), after)
78 # Ensure the select is evaluate last.
79 before = r'Event1 + 1 if Event2 < 2 else Event3 + 3'
80 after = (r'Select(Event(r"Event1") + Constant(1), Event(r"Event2") < '
81 r'Constant(2), Event(r"Event3") + Constant(3))')
82 self.assertEqual(ParsePerfJson(before).ToPython(), after)
84 before = r'Event1 > 1 if Event2 < 2 else Event3 > 3'
85 after = (r'Select(Event(r"Event1") > Constant(1), Event(r"Event2") < '
86 r'Constant(2), Event(r"Event3") > Constant(3))')
87 self.assertEqual(ParsePerfJson(before).ToPython(), after)
89 before = r'min(a + b if c > 1 else c + d, e + f)'
90 after = r'min((a + b if c > 1 else c + d), e + f)'
91 self.assertEqual(ParsePerfJson(before).ToPerfJson(), after)
93 before = r'a if b else c if d else e'
94 after = r'(a if b else (c if d else e))'
95 self.assertEqual(ParsePerfJson(before).ToPerfJson(), after)
97 def test_ToPython(self):
98 # pylint: disable=eval-used
99 # Based on an example of a real metric.
100 before = '(a + b + c + d) / (2 * e)'
101 py = ParsePerfJson(before).ToPython()
102 after = eval(py).ToPerfJson()
103 self.assertEqual(before, after)
105 def test_Simplify(self):
106 before = '1 + 2 + 3'
107 after = '6'
108 self.assertEqual(ParsePerfJson(before).Simplify().ToPerfJson(), after)
110 before = 'a + 0'
111 after = 'a'
112 self.assertEqual(ParsePerfJson(before).Simplify().ToPerfJson(), after)
114 before = '0 + a'
115 after = 'a'
116 self.assertEqual(ParsePerfJson(before).Simplify().ToPerfJson(), after)
118 before = 'a | 0'
119 after = 'a'
120 self.assertEqual(ParsePerfJson(before).Simplify().ToPerfJson(), after)
122 before = '0 | a'
123 after = 'a'
124 self.assertEqual(ParsePerfJson(before).Simplify().ToPerfJson(), after)
126 before = 'a * 0'
127 after = '0'
128 self.assertEqual(ParsePerfJson(before).Simplify().ToPerfJson(), after)
130 before = '0 * a'
131 after = '0'
132 self.assertEqual(ParsePerfJson(before).Simplify().ToPerfJson(), after)
134 before = 'a * 1'
135 after = 'a'
136 self.assertEqual(ParsePerfJson(before).Simplify().ToPerfJson(), after)
138 before = '1 * a'
139 after = 'a'
140 self.assertEqual(ParsePerfJson(before).Simplify().ToPerfJson(), after)
142 before = 'a if 0 else b'
143 after = 'b'
144 self.assertEqual(ParsePerfJson(before).Simplify().ToPerfJson(), after)
146 before = 'a if 1 else b'
147 after = 'a'
148 self.assertEqual(ParsePerfJson(before).Simplify().ToPerfJson(), after)
150 before = 'a if b else a'
151 after = 'a'
152 self.assertEqual(ParsePerfJson(before).Simplify().ToPerfJson(), after)
154 # Pattern used to add a slots event to metrics that require it.
155 before = '0 * SLOTS'
156 after = '0 * SLOTS'
157 self.assertEqual(ParsePerfJson(before).Simplify().ToPerfJson(), after)
159 def test_RewriteMetricsInTermsOfOthers(self):
160 Expression.__eq__ = lambda e1, e2: e1.Equals(e2)
161 before = [('cpu', 'm1', ParsePerfJson('a + b + c + d')),
162 ('cpu', 'm2', ParsePerfJson('a + b + c'))]
163 after = {('cpu', 'm1'): ParsePerfJson('m2 + d')}
164 self.assertEqual(RewriteMetricsInTermsOfOthers(before), after)
165 Expression.__eq__ = None
167 if __name__ == '__main__':
168 unittest.main()