OLD | NEW |
| (Empty) |
1 # Copyright (c) 2012 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 | |
5 """Defines TestPackageExecutable to help run stand-alone executables.""" | |
6 | |
7 import logging | |
8 import os | |
9 import posixpath | |
10 import sys | |
11 import tempfile | |
12 | |
13 from pylib import cmd_helper | |
14 from pylib import constants | |
15 from pylib import pexpect | |
16 from pylib.device import device_errors | |
17 from pylib.gtest import gtest_test_instance | |
18 from pylib.gtest.test_package import TestPackage | |
19 | |
20 | |
21 class TestPackageExecutable(TestPackage): | |
22 """A helper class for running stand-alone executables.""" | |
23 | |
24 _TEST_RUNNER_RET_VAL_FILE = 'gtest_retval' | |
25 | |
26 def __init__(self, suite_name): | |
27 """ | |
28 Args: | |
29 suite_name: Name of the test suite (e.g. base_unittests). | |
30 """ | |
31 TestPackage.__init__(self, suite_name) | |
32 self.suite_path = os.path.join(constants.GetOutDirectory(), suite_name) | |
33 self._symbols_dir = os.path.join(constants.GetOutDirectory(), | |
34 'lib.target') | |
35 | |
36 #override | |
37 def GetGTestReturnCode(self, device): | |
38 ret = None | |
39 ret_code = 1 # Assume failure if we can't find it | |
40 ret_code_file = tempfile.NamedTemporaryFile() | |
41 try: | |
42 if not device.PullFile( | |
43 constants.TEST_EXECUTABLE_DIR + '/' + | |
44 TestPackageExecutable._TEST_RUNNER_RET_VAL_FILE, | |
45 ret_code_file.name): | |
46 logging.critical('Unable to pull gtest ret val file %s', | |
47 ret_code_file.name) | |
48 raise ValueError | |
49 ret_code = file(ret_code_file.name).read() | |
50 ret = int(ret_code) | |
51 except ValueError: | |
52 logging.critical('Error reading gtest ret val file %s [%s]', | |
53 ret_code_file.name, ret_code) | |
54 ret = 1 | |
55 return ret | |
56 | |
57 @staticmethod | |
58 def _AddNativeCoverageExports(device): | |
59 # export GCOV_PREFIX set the path for native coverage results | |
60 # export GCOV_PREFIX_STRIP indicates how many initial directory | |
61 # names to strip off the hardwired absolute paths. | |
62 # This value is calculated in buildbot.sh and | |
63 # depends on where the tree is built. | |
64 # Ex: /usr/local/google/code/chrome will become | |
65 # /code/chrome if GCOV_PREFIX_STRIP=3 | |
66 try: | |
67 depth = os.environ['NATIVE_COVERAGE_DEPTH_STRIP'] | |
68 export_string = ('export GCOV_PREFIX="%s/gcov"\n' % | |
69 device.GetExternalStoragePath()) | |
70 export_string += 'export GCOV_PREFIX_STRIP=%s\n' % depth | |
71 return export_string | |
72 except KeyError: | |
73 logging.info('NATIVE_COVERAGE_DEPTH_STRIP is not defined: ' | |
74 'No native coverage.') | |
75 return '' | |
76 except device_errors.CommandFailedError: | |
77 logging.info('No external storage found: No native coverage.') | |
78 return '' | |
79 | |
80 #override | |
81 def ClearApplicationState(self, device): | |
82 device.KillAll(self.suite_name, blocking=True, timeout=30, quiet=True) | |
83 | |
84 #override | |
85 def CreateCommandLineFileOnDevice(self, device, test_filter, test_arguments): | |
86 tool_wrapper = self.tool.GetTestWrapper() | |
87 sh_script_file = tempfile.NamedTemporaryFile() | |
88 # We need to capture the exit status from the script since adb shell won't | |
89 # propagate to us. | |
90 sh_script_file.write( | |
91 'cd %s\n' | |
92 '%s' | |
93 '%s LD_LIBRARY_PATH=%s/%s_deps %s/%s --gtest_filter=%s %s\n' | |
94 'echo $? > %s' % | |
95 (constants.TEST_EXECUTABLE_DIR, | |
96 self._AddNativeCoverageExports(device), | |
97 tool_wrapper, | |
98 constants.TEST_EXECUTABLE_DIR, | |
99 self.suite_name, | |
100 constants.TEST_EXECUTABLE_DIR, | |
101 self.suite_name, | |
102 test_filter, test_arguments, | |
103 TestPackageExecutable._TEST_RUNNER_RET_VAL_FILE)) | |
104 sh_script_file.flush() | |
105 cmd_helper.RunCmd(['chmod', '+x', sh_script_file.name]) | |
106 device.PushChangedFiles([( | |
107 sh_script_file.name, | |
108 constants.TEST_EXECUTABLE_DIR + '/chrome_test_runner.sh')]) | |
109 logging.info('Conents of the test runner script: ') | |
110 for line in open(sh_script_file.name).readlines(): | |
111 logging.info(' ' + line.rstrip()) | |
112 | |
113 #override | |
114 def GetAllTests(self, device): | |
115 lib_path = posixpath.join( | |
116 constants.TEST_EXECUTABLE_DIR, '%s_deps' % self.suite_name) | |
117 | |
118 cmd = [] | |
119 if self.tool.GetTestWrapper(): | |
120 cmd.append(self.tool.GetTestWrapper()) | |
121 cmd.extend([ | |
122 posixpath.join(constants.TEST_EXECUTABLE_DIR, self.suite_name), | |
123 '--gtest_list_tests']) | |
124 | |
125 output = device.RunShellCommand( | |
126 cmd, check_return=True, env={'LD_LIBRARY_PATH': lib_path}) | |
127 return gtest_test_instance.ParseGTestListTests(output) | |
128 | |
129 #override | |
130 def SpawnTestProcess(self, device): | |
131 args = ['adb', '-s', str(device), 'shell', 'sh', | |
132 constants.TEST_EXECUTABLE_DIR + '/chrome_test_runner.sh'] | |
133 logging.info(args) | |
134 return pexpect.spawn(args[0], args[1:], logfile=sys.stdout) | |
135 | |
136 #override | |
137 def Install(self, device): | |
138 if self.tool.NeedsDebugInfo(): | |
139 target_name = self.suite_path | |
140 else: | |
141 target_name = self.suite_path + '_stripped' | |
142 if not os.path.isfile(target_name): | |
143 raise Exception('Did not find %s, build target %s' % | |
144 (target_name, self.suite_name + '_stripped')) | |
145 | |
146 target_mtime = os.stat(target_name).st_mtime | |
147 source_mtime = os.stat(self.suite_path).st_mtime | |
148 if target_mtime < source_mtime: | |
149 raise Exception( | |
150 'stripped binary (%s, timestamp %d) older than ' | |
151 'source binary (%s, timestamp %d), build target %s' % | |
152 (target_name, target_mtime, self.suite_path, source_mtime, | |
153 self.suite_name + '_stripped')) | |
154 | |
155 test_binary_path = constants.TEST_EXECUTABLE_DIR + '/' + self.suite_name | |
156 device.PushChangedFiles([(target_name, test_binary_path)]) | |
157 deps_path = self.suite_path + '_deps' | |
158 if os.path.isdir(deps_path): | |
159 device.PushChangedFiles([(deps_path, test_binary_path + '_deps')]) | |
160 | |
161 #override | |
162 def PullAppFiles(self, device, files, directory): | |
163 pass | |
OLD | NEW |