metric_test.py 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  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
  9. class TestMetricExpressions(unittest.TestCase):
  10. def test_Operators(self):
  11. a = Event('a')
  12. b = Event('b')
  13. self.assertEqual((a | b).ToPerfJson(), 'a | b')
  14. self.assertEqual((a ^ b).ToPerfJson(), 'a ^ b')
  15. self.assertEqual((a & b).ToPerfJson(), 'a & 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. one = Constant(1)
  24. self.assertEqual((a + one).ToPerfJson(), 'a + 1')
  25. def test_Brackets(self):
  26. a = Event('a')
  27. b = Event('b')
  28. c = Event('c')
  29. self.assertEqual((a * b + c).ToPerfJson(), 'a * b + c')
  30. self.assertEqual((a + b * c).ToPerfJson(), 'a + b * c')
  31. self.assertEqual(((a + a) + a).ToPerfJson(), 'a + a + a')
  32. self.assertEqual(((a + b) * c).ToPerfJson(), '(a + b) * 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 / (b * c)).ToPerfJson(), 'a / (b * c)')
  36. def test_ParsePerfJson(self):
  37. # Based on an example of a real metric.
  38. before = '(a + b + c + d) / (2 * e)'
  39. after = before
  40. self.assertEqual(ParsePerfJson(before).ToPerfJson(), after)
  41. # Parsing should handle events with '-' in their name. Note, in
  42. # the json file the '\' are doubled to '\\'.
  43. before = r'topdown\-fe\-bound / topdown\-slots - 1'
  44. after = before
  45. self.assertEqual(ParsePerfJson(before).ToPerfJson(), after)
  46. # Parsing should handle escaped modifiers. Note, in the json file
  47. # the '\' are doubled to '\\'.
  48. before = r'arb@event\=0x81\,umask\=0x1@ + arb@event\=0x84\,umask\=0x1@'
  49. after = before
  50. self.assertEqual(ParsePerfJson(before).ToPerfJson(), after)
  51. # Parsing should handle exponents in numbers.
  52. before = r'a + 1e12 + b'
  53. after = before
  54. self.assertEqual(ParsePerfJson(before).ToPerfJson(), after)
  55. def test_IfElseTests(self):
  56. # if-else needs rewriting to Select and back.
  57. before = r'Event1 if #smt_on else Event2'
  58. after = f'({before})'
  59. self.assertEqual(ParsePerfJson(before).ToPerfJson(), after)
  60. before = r'Event1 if 0 else Event2'
  61. after = f'({before})'
  62. self.assertEqual(ParsePerfJson(before).ToPerfJson(), after)
  63. before = r'Event1 if 1 else Event2'
  64. after = f'({before})'
  65. self.assertEqual(ParsePerfJson(before).ToPerfJson(), after)
  66. # Ensure the select is evaluate last.
  67. before = r'Event1 + 1 if Event2 < 2 else Event3 + 3'
  68. after = (r'Select(Event(r"Event1") + Constant(1), Event(r"Event2") < '
  69. r'Constant(2), Event(r"Event3") + Constant(3))')
  70. self.assertEqual(ParsePerfJson(before).ToPython(), after)
  71. before = r'Event1 > 1 if Event2 < 2 else Event3 > 3'
  72. after = (r'Select(Event(r"Event1") > Constant(1), Event(r"Event2") < '
  73. r'Constant(2), Event(r"Event3") > Constant(3))')
  74. self.assertEqual(ParsePerfJson(before).ToPython(), after)
  75. before = r'min(a + b if c > 1 else c + d, e + f)'
  76. after = r'min((a + b if c > 1 else c + d), e + f)'
  77. self.assertEqual(ParsePerfJson(before).ToPerfJson(), after)
  78. before = r'a if b else c if d else e'
  79. after = r'(a if b else (c if d else e))'
  80. self.assertEqual(ParsePerfJson(before).ToPerfJson(), after)
  81. def test_ToPython(self):
  82. # pylint: disable=eval-used
  83. # Based on an example of a real metric.
  84. before = '(a + b + c + d) / (2 * e)'
  85. py = ParsePerfJson(before).ToPython()
  86. after = eval(py).ToPerfJson()
  87. self.assertEqual(before, after)
  88. def test_Simplify(self):
  89. before = '1 + 2 + 3'
  90. after = '6'
  91. self.assertEqual(ParsePerfJson(before).Simplify().ToPerfJson(), after)
  92. before = 'a + 0'
  93. after = 'a'
  94. self.assertEqual(ParsePerfJson(before).Simplify().ToPerfJson(), after)
  95. before = '0 + a'
  96. after = 'a'
  97. self.assertEqual(ParsePerfJson(before).Simplify().ToPerfJson(), after)
  98. before = 'a | 0'
  99. after = 'a'
  100. self.assertEqual(ParsePerfJson(before).Simplify().ToPerfJson(), after)
  101. before = '0 | a'
  102. after = 'a'
  103. self.assertEqual(ParsePerfJson(before).Simplify().ToPerfJson(), after)
  104. before = 'a * 0'
  105. after = '0'
  106. self.assertEqual(ParsePerfJson(before).Simplify().ToPerfJson(), after)
  107. before = '0 * a'
  108. after = '0'
  109. self.assertEqual(ParsePerfJson(before).Simplify().ToPerfJson(), after)
  110. before = 'a * 1'
  111. after = 'a'
  112. self.assertEqual(ParsePerfJson(before).Simplify().ToPerfJson(), after)
  113. before = '1 * a'
  114. after = 'a'
  115. self.assertEqual(ParsePerfJson(before).Simplify().ToPerfJson(), after)
  116. before = 'a if 0 else b'
  117. after = 'b'
  118. self.assertEqual(ParsePerfJson(before).Simplify().ToPerfJson(), after)
  119. before = 'a if 1 else b'
  120. after = 'a'
  121. self.assertEqual(ParsePerfJson(before).Simplify().ToPerfJson(), after)
  122. before = 'a if b else a'
  123. after = 'a'
  124. self.assertEqual(ParsePerfJson(before).Simplify().ToPerfJson(), after)
  125. # Pattern used to add a slots event to metrics that require it.
  126. before = '0 * SLOTS'
  127. after = '0 * SLOTS'
  128. self.assertEqual(ParsePerfJson(before).Simplify().ToPerfJson(), after)
  129. def test_RewriteMetricsInTermsOfOthers(self):
  130. Expression.__eq__ = lambda e1, e2: e1.Equals(e2)
  131. before = [('cpu', 'm1', ParsePerfJson('a + b + c + d')),
  132. ('cpu', 'm2', ParsePerfJson('a + b + c'))]
  133. after = {('cpu', 'm1'): ParsePerfJson('m2 + d')}
  134. self.assertEqual(RewriteMetricsInTermsOfOthers(before), after)
  135. Expression.__eq__ = None
  136. if __name__ == '__main__':
  137. unittest.main()