1# 2# Copyright (C) 2016 The Android Open Source Project 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15# 16 17import logging 18import os 19import xml.etree.ElementTree 20 21from vts.runners.host import asserts 22from vts.runners.host import const 23from vts.runners.host import test_runner 24 25from vts.testcases.template.binary_test import binary_test 26from vts.testcases.template.binary_test import binary_test_case 27from vts.testcases.template.gtest_binary_test import gtest_test_case 28 29 30class GtestBinaryTest(binary_test.BinaryTest): 31 '''Base class to run gtests binary on target. 32 33 Attributes: 34 _dut: AndroidDevice, the device under test as config 35 shell: ShellMirrorObject, shell mirror 36 testcases: list of GtestTestCase objects, list of test cases to run 37 tags: all the tags that appeared in binary list 38 DEVICE_TEST_DIR: string, temp location for storing binary 39 TAG_PATH_SEPARATOR: string, separator used to separate tag and path 40 ''' 41 42 # @Override 43 def CreateTestCase(self, path, tag=''): 44 '''Create a list of GtestTestCase objects from a binary path. 45 46 Args: 47 path: string, absolute path of a gtest binary on device 48 tag: string, a tag that will be appended to the end of test name 49 50 Returns: 51 A list of GtestTestCase objects 52 ''' 53 working_directory = self.working_directory[ 54 tag] if tag in self.working_directory else None 55 envp = self.envp[tag] if tag in self.envp else '' 56 args = self.args[tag] if tag in self.args else '' 57 ld_library_path = self.ld_library_path[ 58 tag] if tag in self.ld_library_path else None 59 profiling_library_path = self.profiling_library_path[ 60 tag] if tag in self.ld_library_path else None 61 62 args += " --gtest_list_tests" 63 list_test_case = binary_test_case.BinaryTestCase( 64 'gtest_list_tests', 65 path, 66 path, 67 tag, 68 self.PutTag, 69 working_directory, 70 ld_library_path, 71 profiling_library_path, 72 envp=envp, 73 args=args) 74 cmd = ['chmod 755 %s' % path, list_test_case.GetRunCommand()] 75 cmd_results = self.shell.Execute(cmd) 76 if any(cmd_results[ 77 const. 78 EXIT_CODE]): # gtest binary doesn't exist or is corrupted 79 logging.error('Failed to list test cases from binary %s' % path) 80 81 test_cases = [] 82 83 test_suite = '' 84 for line in cmd_results[const.STDOUT][1].split('\n'): 85 line = str(line) 86 if not len(line.strip()): 87 continue 88 elif line.startswith(' '): # Test case name 89 test_name = line.split('#')[0].strip() 90 test_case = gtest_test_case.GtestTestCase( 91 test_suite, test_name, path, tag, self.PutTag, 92 working_directory, ld_library_path, profiling_library_path) 93 logging.info('Gtest test case: %s' % test_case) 94 test_cases.append(test_case) 95 else: # Test suite name 96 test_suite = line.strip() 97 if test_suite.endswith('.'): 98 test_suite = test_suite[:-1] 99 100 return test_cases 101 102 # @Override 103 def VerifyTestResult(self, test_case, command_results): 104 '''Parse Gtest xml result output. 105 106 Sample 107 <testsuites tests="1" failures="1" disabled="0" errors="0" 108 timestamp="2017-05-24T18:32:10" time="0.012" name="AllTests"> 109 <testsuite name="ConsumerIrHidlTest" 110 tests="1" failures="1" disabled="0" errors="0" time="0.01"> 111 <testcase name="TransmitTest" status="run" time="0.01" 112 classname="ConsumerIrHidlTest"> 113 <failure message="hardware/interfaces..." type=""> 114 <![CDATA[hardware/interfaces...]]> 115 </failure> 116 </testcase> 117 </testsuite> 118 </testsuites> 119 120 Args: 121 test_case: GtestTestCase object, the test being run. This param 122 is not currently used in this method. 123 command_results: dict of lists, shell command result 124 ''' 125 asserts.assertTrue(command_results, 'Empty command response.') 126 asserts.assertEqual( 127 len(command_results), 3, 'Abnormal command response.') 128 for item in command_results[const.STDOUT]: 129 if item and item.strip(): 130 logging.info(item) 131 for item in command_results[const.STDERR]: 132 if item and item.strip(): 133 logging.error(item) 134 135 asserts.assertFalse(command_results[const.EXIT_CODE][1], 136 'Failed to show Gtest XML output: %s' % command_results) 137 138 xml_str = command_results[const.STDOUT][1].strip() 139 root = xml.etree.ElementTree.fromstring(xml_str) 140 asserts.assertEqual(root.get('tests'), '1', 'No tests available') 141 if root.get('errors') != '0' or root.get('failures') != '0': 142 messages = [x.get('message') for x in root.findall('.//failure')] 143 asserts.fail('\n'.join([x for x in messages if x])) 144 asserts.skipIf(root.get('disabled') == '1', 'Gtest test case disabled') 145 146 147if __name__ == "__main__": 148 test_runner.main() 149