1# Copyright 2014 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import sys 6import unittest 7 8from telemetry.core.platform.profiler import vtune_profiler 9from telemetry.unittest import options_for_unittests 10from telemetry.unittest import simple_mock 11from telemetry.unittest import tab_test_case 12 13 14class MockPopen(object): 15 def __init__(self, returncode, stdout=None, stderr=None): 16 self.returncode = returncode 17 self.stdout = stdout 18 self.stderr = stderr 19 20 def communicate(self): 21 return (self.stdout, self.stderr) 22 23 def wait(self): 24 return self.returncode 25 26 27class MockSubprocess(object): 28 def __init__(self): 29 self.PIPE = simple_mock.MockObject() 30 self.STDOUT = simple_mock.MockObject() 31 self._num_collect_calls = 0 32 self._num_stop_calls = 0 33 34 @property 35 def num_collect_calls(self): 36 return self._num_collect_calls 37 38 @property 39 def num_stop_calls(self): 40 return self._num_stop_calls 41 42 def Popen(self, cmd, **_): 43 self._AnalyzeCommand(cmd) 44 return MockPopen(0) 45 46 def call(self, cmd): 47 self._AnalyzeCommand(cmd) 48 49 def _AnalyzeCommand(self, cmd): 50 if MockSubprocess._IsCollectCommand(cmd): 51 self._num_collect_calls += 1 52 elif MockSubprocess._IsStopCommand(cmd): 53 self._num_stop_calls += 1 54 55 @staticmethod 56 def _IsCollectCommand(cmd): 57 return '-collect' in cmd 58 59 @staticmethod 60 def _IsStopCommand(cmd): 61 try: 62 cmd_idx = cmd.index('-command') + 1 63 return cmd_idx < len(cmd) and cmd[cmd_idx] == 'stop' 64 except ValueError: 65 return False 66 67 68class TestVTuneProfiler(unittest.TestCase): 69 70 def testVTuneProfilerIsSupported(self): 71 options = options_for_unittests.GetCopy() 72 73 mock_subprocess = simple_mock.MockObject() 74 mock_subprocess.ExpectCall( 75 'Popen').WithArgs(simple_mock.DONT_CARE).WillReturn(MockPopen(0)) 76 mock_subprocess.SetAttribute('PIPE', simple_mock.MockObject()) 77 mock_subprocess.SetAttribute('STDOUT', simple_mock.MockObject()) 78 79 real_subprocess = vtune_profiler.subprocess 80 vtune_profiler.subprocess = mock_subprocess 81 82 if options.browser_type.startswith('android'): 83 # On Android we're querying if 'su' is available. 84 mock_subprocess.ExpectCall('Popen').WithArgs( 85 simple_mock.DONT_CARE).WillReturn(MockPopen(0, 'su', None)) 86 87 try: 88 self.assertTrue( 89 vtune_profiler.VTuneProfiler.is_supported(options.browser_type) or 90 sys.platform != 'linux2' or 91 options.browser_type.startswith('cros')) 92 finally: 93 vtune_profiler.subprocess = real_subprocess 94 95 96class TestVTuneProfilerTabTestCase(tab_test_case.TabTestCase): 97 98 def testVTuneProfiler(self): 99 mock_subprocess = MockSubprocess() 100 real_subprocess = vtune_profiler.subprocess 101 vtune_profiler.subprocess = mock_subprocess 102 103 try: 104 # pylint: disable=W0212 105 profiler = vtune_profiler.VTuneProfiler(self._browser._browser_backend, 106 self._browser._platform_backend, 107 'tmp', 108 {}) 109 profiler.CollectProfile() 110 self.assertEqual(mock_subprocess.num_collect_calls, 111 mock_subprocess.num_stop_calls) 112 finally: 113 vtune_profiler.subprocess = real_subprocess 114