run_simpleperf_test.py 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. #!/usr/bin/env vpython3
  2. #
  3. # Copyright 2019 The Chromium Authors. All rights reserved.
  4. # Use of this source code is governed by a BSD-style license that can be
  5. # found in the LICENSE file.
  6. """Unit tests for run_simpleperf.py"""
  7. import os
  8. import unittest
  9. import mock # pylint: disable=import-error
  10. from run_simpleperf import SimplePerfRunner
  11. from run_simpleperf import StackAddressInterpreter
  12. _EXAMPLE_WEBVIEW_PACKAGE_NAME = "com.google.android.webview"
  13. _EXAMPLE_STACK_SCRIPT_INPUT = [
  14. ("11-15 00:00:00.000 11111 11111 E chromium: #00 0x0000001111111111 "
  15. "/data/app/com.google.android.webview--8E2vMMZTpLVeEKY7ZgoHQ=="
  16. "/lib/arm64/libwebviewchromium.so+0x00000000083a4db8"),
  17. ("11-15 00:00:00.000 11111 11111 E chromium: #00 0x0000001111111111 "
  18. "/data/app/com.google.android.webview--8E2vMMZTpLVeEKY7ZgoHQ=="
  19. "/lib/arm64/libwebviewchromium.so+0x00000000083db114"),
  20. ("11-15 00:00:00.000 11111 11111 E chromium: #00 0x0000001111111111 "
  21. "/data/app/com.google.android.webview--8E2vMMZTpLVeEKY7ZgoHQ=="
  22. "/lib/arm64/libwebviewchromium.so+0x000000000abcdef0")]
  23. _EXAMPLE_STACK_SCRIPT_OUTPUT = [
  24. "Stack Trace:",
  25. " RELADDR FUNCTION",
  26. (" 00000000083a4db8 mojo::core::ports::(anonymous namespace)::UpdateTLS("
  27. "mojo::core::ports::PortLocker*, mojo::core::ports::PortLocker*) "
  28. "../../mojo/core/ports/port_locker.cc:26:3"),
  29. "",
  30. "-----------------------------------------------------",
  31. "",
  32. "Stack Trace:",
  33. " RELADDR FUNCTION",
  34. (" 00000000083db114 viz::GLRenderer::SetUseProgram(viz::ProgramKey "
  35. "const&, gfx::ColorSpace const&, gfx::ColorSpace const&) "
  36. "../../components/viz/service/display/gl_renderer.cc:3267:14"),
  37. "",
  38. "-----------------------------------------------------"]
  39. _ADDRESSES = ['83a4db8', '83db114', 'abcdef0'] # 3rd one is ignored
  40. _WEBVIEW_LIB_NAME = 'libwebviewchromium.so'
  41. _WEBVIEW_LIB_PATH = (
  42. '/data/app/com.google.android.webview'
  43. '--8E2vMMZTpLVeEKY7ZgoHQ==/lib/arm64/libwebviewchromium.so')
  44. _EXAMPLE_INTERPRETER_OUTPUT = [
  45. ('83a4db8',
  46. ('mojo::core::ports::(anonymous namespace)::UpdateTLS('
  47. 'mojo::core::ports::PortLocker*, mojo::core::ports::PortLocker*)')),
  48. ('83db114',
  49. ('viz::GLRenderer::SetUseProgram(viz::ProgramKey const&, '
  50. 'gfx::ColorSpace const&, gfx::ColorSpace const&)'))]
  51. _EXAMPLE_INTERPRETER_OUTPUT_WITH_FILE_NAME_LINE = [
  52. ('83a4db8',
  53. ('mojo::core::ports::(anonymous namespace)::UpdateTLS('
  54. 'mojo::core::ports::PortLocker*, mojo::core::ports::PortLocker*)'
  55. ' | ../../mojo/core/ports/port_locker.cc:26:3')),
  56. ('83db114',
  57. ('viz::GLRenderer::SetUseProgram(viz::ProgramKey const&, '
  58. 'gfx::ColorSpace const&, gfx::ColorSpace const&)'
  59. ' | ../../components/viz/service/display/gl_renderer.cc:3267:14'))]
  60. _MOCK_ORIGINAL_REPORT = [
  61. '"442": {"l": 28, "f": "libwebviewchromium.so[+3db7d84]"},',
  62. '"443": {"l": 28, "f": "libwebviewchromium.so[+3db7a5c]"},',
  63. '"444": {"l": 28, "f": "libwebviewchromium.so[+aaaaaaa]"},'
  64. ]
  65. _MOCK_ADDRESSES = ['3db7d84', '3db7a5c', 'aaaaaaa']
  66. _MOCK_ADDRESS_FUNCTION_NAME_PAIRS = [
  67. ('3db7d84', 'MyClass::FirstMethod(const char*)'),
  68. ('3db7a5c', 'MyClass::SecondMethod(int)')]
  69. _MOCK_FINAL_REPORT = [
  70. ('"442": {"l": 28, "f": "libwebviewchromium.so[MyClass::'
  71. 'FirstMethod(const char*)]"},'),
  72. ('"443": {"l": 28, "f": "libwebviewchromium.so[MyClass::'
  73. 'SecondMethod(int)]"},'),
  74. ('"444": {"l": 28, "f": "libwebviewchromium.so[+aaaaaaa]"},')
  75. ]
  76. class _RunSimpleperfTest(unittest.TestCase):
  77. """Unit tests for the run_simpleperf module. """
  78. def _AssertFileLines(self, mock_open, expected_lines):
  79. handle = mock_open()
  80. # Get 'str1', 'str2', ... from the call to f.write(str_i + '\n') which is
  81. # saved as [(str1 + '\n'), (str2 + '\n'), ...].
  82. actual_lines = [args[0][:-1] for (args, _) in
  83. handle.write.call_args_list]
  84. self.assertEqual(expected_lines, actual_lines)
  85. def setUp(self):
  86. self.tmp_dir = '/tmp' # the actual directory won't be used in this test.
  87. self.args = mock.Mock(
  88. report_path=os.path.join(self.tmp_dir, 'report.html'),
  89. show_file_line=False)
  90. self.device = mock.Mock()
  91. self.stack_address_interpreter = StackAddressInterpreter(self.args,
  92. self.tmp_dir)
  93. self.simple_perf_runner = SimplePerfRunner(
  94. self.device, self.args, self.tmp_dir, self.stack_address_interpreter)
  95. @mock.patch('run_simpleperf.open', new_callable=mock.mock_open)
  96. def testStackAddressInterpreter(self, mock_open):
  97. StackAddressInterpreter.RunStackScript = mock.Mock(
  98. return_value=_EXAMPLE_STACK_SCRIPT_OUTPUT)
  99. self.assertEqual(
  100. _EXAMPLE_INTERPRETER_OUTPUT,
  101. self.stack_address_interpreter.Interpret(_ADDRESSES, _WEBVIEW_LIB_PATH))
  102. self._AssertFileLines(mock_open, _EXAMPLE_STACK_SCRIPT_INPUT)
  103. @mock.patch('run_simpleperf.open', new_callable=mock.mock_open)
  104. def testStackAddressInterpreterWithFileNameLine(self, mock_open):
  105. self.args.show_file_line = True
  106. StackAddressInterpreter.RunStackScript = mock.Mock(
  107. return_value=_EXAMPLE_STACK_SCRIPT_OUTPUT)
  108. self.assertEqual(
  109. _EXAMPLE_INTERPRETER_OUTPUT_WITH_FILE_NAME_LINE,
  110. self.stack_address_interpreter.Interpret(_ADDRESSES, _WEBVIEW_LIB_PATH))
  111. self._AssertFileLines(mock_open, _EXAMPLE_STACK_SCRIPT_INPUT)
  112. def testSimplePerfRunner_CollectAddresses(self):
  113. addresses = self.simple_perf_runner.CollectAddresses(
  114. _MOCK_ORIGINAL_REPORT, 'libwebviewchromium.so')
  115. self.assertEqual(set(_MOCK_ADDRESSES), addresses)
  116. def testSimplePerfRunner_ReplaceAddresses(self):
  117. postprocessed_report = (
  118. self.simple_perf_runner.ReplaceAddressesWithFunctionInfos(
  119. _MOCK_ORIGINAL_REPORT, _MOCK_ADDRESS_FUNCTION_NAME_PAIRS,
  120. 'libwebviewchromium.so'))
  121. self.assertEqual(_MOCK_FINAL_REPORT, postprocessed_report)
  122. @mock.patch('run_simpleperf.open', new_callable=mock.mock_open)
  123. def testSimplePerfRunner_Run(self, mock_open):
  124. self.stack_address_interpreter.Interpret = mock.Mock(
  125. return_value=_MOCK_ADDRESS_FUNCTION_NAME_PAIRS)
  126. SimplePerfRunner.RunSimplePerf = mock.Mock()
  127. SimplePerfRunner.RunPackageCompile = mock.Mock()
  128. SimplePerfRunner.GetOriginalReportHtml = mock.Mock(
  129. return_value=_MOCK_ORIGINAL_REPORT)
  130. self.simple_perf_runner.GetCurrentWebViewProvider = mock.Mock(
  131. return_value=_EXAMPLE_WEBVIEW_PACKAGE_NAME)
  132. self.simple_perf_runner.GetWebViewLibraryNameAndPath = mock.Mock(
  133. return_value=(_WEBVIEW_LIB_NAME, _WEBVIEW_LIB_PATH))
  134. self.simple_perf_runner.Run()
  135. self._AssertFileLines(mock_open, _MOCK_FINAL_REPORT)
  136. if __name__ == '__main__':
  137. unittest.main()