1 #!/usr/bin/python 2 # 3 # 4 # Copyright 2011, The Android Open Source Project 5 # 6 # Licensed under the Apache License, Version 2.0 (the "License"); 7 # you may not use this file except in compliance with the License. 8 # You may obtain a copy of the License at 9 # 10 # http://www.apache.org/licenses/LICENSE-2.0 11 # 12 # Unless required by applicable law or agreed to in writing, software 13 # distributed under the License is distributed on an "AS IS" BASIS, 14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 # See the License for the specific language governing permissions and 16 # limitations under the License. 17 18 """TestSuite for running C/C++ Android tests using gtest framework.""" 19 20 # python imports 21 import os 22 import re 23 24 # local imports 25 import logger 26 import run_command 27 import test_suite 28 29 30 class GTestSuite(test_suite.AbstractTestSuite): 31 """A test suite for running gtest on device.""" 32 33 def __init__(self): 34 test_suite.AbstractTestSuite.__init__(self) 35 self._target_exec_path = None 36 37 def GetTargetExecPath(self): 38 """Get the target path to gtest executable.""" 39 return self._target_exec_path 40 41 def SetTargetExecPath(self, path): 42 self._target_exec_path = path 43 return self 44 45 def Run(self, options, adb): 46 """Run the provided gtest test suite. 47 48 Args: 49 options: command line options 50 adb: adb interface 51 """ 52 53 test_class = "*" 54 test_method = "*" 55 if options.test_class is not None: 56 test_class = options.test_class.lstrip() 57 if options.test_method is not None: 58 test_method = options.test_method.lstrip() 59 filter_arg = "" 60 if test_class != "*" or test_method != "*": 61 filter_arg = "--gtest_filter=%s.%s" % (test_class, test_method) 62 63 shell_cmd = adb.PreviewShellCommand( 64 " ".join((self.GetTargetExecPath(), filter_arg))) 65 logger.Log(shell_cmd) 66 if not options.preview: 67 # gtest will log to test results to stdout, so no need to do any 68 # extra processing 69 run_command.RunCommand(shell_cmd, return_output=False) 70 71 72 class GTestFactory(test_suite.AbstractTestFactory): 73 74 def __init__(self, test_root_path, build_path): 75 test_suite.AbstractTestFactory.__init__(self, test_root_path, 76 build_path) 77 78 def CreateTests(self, sub_tests_path=None): 79 """Create tests found in sub_tests_path. 80 81 Looks for test files matching a pattern, and assumes each one is a separate 82 binary on target. 83 84 Test files must match one of the following pattern: 85 - test_*.[c|cc|cpp] 86 - *_test.[c|cc|cpp] 87 - *_unittest.[c|cc|cpp] 88 - *Tests.[cc|cpp] 89 90 """ 91 if not sub_tests_path: 92 sub_tests_path = self.GetTestRootPath() 93 test_file_list = [] 94 if os.path.isfile(sub_tests_path): 95 self._EvaluateFile(test_file_list, os.path.basename(sub_tests_path)) 96 else: 97 os.path.walk(sub_tests_path, self._CollectTestSources, test_file_list) 98 # TODO: obtain this from makefile instead of hardcoding 99 target_root_path = os.path.join('/data', 'nativetest') 100 test_suites = [] 101 for test_file in test_file_list: 102 logger.SilentLog('Creating gtest suite for file %s' % test_file) 103 suite = GTestSuite() 104 suite.SetBuildPath(self.GetBuildPath()) 105 # expect tests in /data/nativetest/test_file/test_file 106 suite.SetTargetExecPath(os.path.join(target_root_path, test_file, test_file)) 107 test_suites.append(suite) 108 return test_suites 109 110 def _CollectTestSources(self, test_list, dirname, files): 111 """For each directory, find tests source file and add them to the list. 112 113 Test files must match one of the following pattern: 114 - test_*.[cc|cpp] 115 - *_test.[cc|cpp] 116 - *_unittest.[cc|cpp] 117 - *Tests.[cc|cpp] 118 119 This method is a callback for os.path.walk. 120 121 Args: 122 test_list: Where new tests should be inserted. 123 dirname: Current directory. 124 files: List of files in the current directory. 125 """ 126 for f in files: 127 self._EvaluateFile(test_list, f) 128 129 def _EvaluateFile(self, test_list, file): 130 (name, ext) = os.path.splitext(file) 131 if ext == ".cc" or ext == ".cpp" or ext == ".c": 132 if re.search("_test$|_test_$|_unittest$|_unittest_$|^test_|Tests$", name): 133 logger.SilentLog("Found native test file %s" % file) 134 test_list.append(name) 135