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