2 # SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
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
):
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')
27 self
.assertEqual((a
+ one
).ToPerfJson(), 'a + 1')
29 def test_Brackets(self
):
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)'
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'
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@'
57 self
.assertEqual(ParsePerfJson(before
).ToPerfJson(), after
)
59 # Parsing should handle exponents in numbers.
60 before
= r
'a + 1e12 + b'
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'
68 self
.assertEqual(ParsePerfJson(before
).ToPerfJson(), after
)
70 before
= r
'Event1 if 0 else Event2'
72 self
.assertEqual(ParsePerfJson(before
).ToPerfJson(), after
)
74 before
= r
'Event1 if 1 else Event2'
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
):
108 self
.assertEqual(ParsePerfJson(before
).Simplify().ToPerfJson(), after
)
112 self
.assertEqual(ParsePerfJson(before
).Simplify().ToPerfJson(), after
)
116 self
.assertEqual(ParsePerfJson(before
).Simplify().ToPerfJson(), after
)
120 self
.assertEqual(ParsePerfJson(before
).Simplify().ToPerfJson(), after
)
124 self
.assertEqual(ParsePerfJson(before
).Simplify().ToPerfJson(), after
)
128 self
.assertEqual(ParsePerfJson(before
).Simplify().ToPerfJson(), after
)
132 self
.assertEqual(ParsePerfJson(before
).Simplify().ToPerfJson(), after
)
136 self
.assertEqual(ParsePerfJson(before
).Simplify().ToPerfJson(), after
)
140 self
.assertEqual(ParsePerfJson(before
).Simplify().ToPerfJson(), after
)
142 before
= 'a if 0 else b'
144 self
.assertEqual(ParsePerfJson(before
).Simplify().ToPerfJson(), after
)
146 before
= 'a if 1 else b'
148 self
.assertEqual(ParsePerfJson(before
).Simplify().ToPerfJson(), after
)
150 before
= 'a if b else a'
152 self
.assertEqual(ParsePerfJson(before
).Simplify().ToPerfJson(), after
)
154 # Pattern used to add a slots event to metrics that require it.
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__':