1*481dde66SAndroid Build Coastguard Worker#!/usr/bin/env python 2*481dde66SAndroid Build Coastguard Worker# 3*481dde66SAndroid Build Coastguard Worker# Copyright 2008, Google Inc. 4*481dde66SAndroid Build Coastguard Worker# All rights reserved. 5*481dde66SAndroid Build Coastguard Worker# 6*481dde66SAndroid Build Coastguard Worker# Redistribution and use in source and binary forms, with or without 7*481dde66SAndroid Build Coastguard Worker# modification, are permitted provided that the following conditions are 8*481dde66SAndroid Build Coastguard Worker# met: 9*481dde66SAndroid Build Coastguard Worker# 10*481dde66SAndroid Build Coastguard Worker# * Redistributions of source code must retain the above copyright 11*481dde66SAndroid Build Coastguard Worker# notice, this list of conditions and the following disclaimer. 12*481dde66SAndroid Build Coastguard Worker# * Redistributions in binary form must reproduce the above 13*481dde66SAndroid Build Coastguard Worker# copyright notice, this list of conditions and the following disclaimer 14*481dde66SAndroid Build Coastguard Worker# in the documentation and/or other materials provided with the 15*481dde66SAndroid Build Coastguard Worker# distribution. 16*481dde66SAndroid Build Coastguard Worker# * Neither the name of Google Inc. nor the names of its 17*481dde66SAndroid Build Coastguard Worker# contributors may be used to endorse or promote products derived from 18*481dde66SAndroid Build Coastguard Worker# this software without specific prior written permission. 19*481dde66SAndroid Build Coastguard Worker# 20*481dde66SAndroid Build Coastguard Worker# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21*481dde66SAndroid Build Coastguard Worker# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22*481dde66SAndroid Build Coastguard Worker# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23*481dde66SAndroid Build Coastguard Worker# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24*481dde66SAndroid Build Coastguard Worker# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25*481dde66SAndroid Build Coastguard Worker# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26*481dde66SAndroid Build Coastguard Worker# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27*481dde66SAndroid Build Coastguard Worker# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28*481dde66SAndroid Build Coastguard Worker# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29*481dde66SAndroid Build Coastguard Worker# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30*481dde66SAndroid Build Coastguard Worker# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31*481dde66SAndroid Build Coastguard Worker 32*481dde66SAndroid Build Coastguard Workerr"""Tests the text output of Google C++ Mocking Framework. 33*481dde66SAndroid Build Coastguard Worker 34*481dde66SAndroid Build Coastguard WorkerTo update the golden file: 35*481dde66SAndroid Build Coastguard Workergmock_output_test.py --build_dir=BUILD/DIR --gengolden 36*481dde66SAndroid Build Coastguard Workerwhere BUILD/DIR contains the built gmock_output_test_ file. 37*481dde66SAndroid Build Coastguard Workergmock_output_test.py --gengolden 38*481dde66SAndroid Build Coastguard Workergmock_output_test.py 39*481dde66SAndroid Build Coastguard Worker 40*481dde66SAndroid Build Coastguard Worker""" 41*481dde66SAndroid Build Coastguard Worker 42*481dde66SAndroid Build Coastguard Workerfrom io import open # pylint: disable=redefined-builtin, g-importing-member 43*481dde66SAndroid Build Coastguard Workerimport os 44*481dde66SAndroid Build Coastguard Workerimport re 45*481dde66SAndroid Build Coastguard Workerimport sys 46*481dde66SAndroid Build Coastguard Workerfrom googlemock.test import gmock_test_utils 47*481dde66SAndroid Build Coastguard Worker 48*481dde66SAndroid Build Coastguard Worker 49*481dde66SAndroid Build Coastguard Worker# The flag for generating the golden file 50*481dde66SAndroid Build Coastguard WorkerGENGOLDEN_FLAG = '--gengolden' 51*481dde66SAndroid Build Coastguard Worker 52*481dde66SAndroid Build Coastguard WorkerPROGRAM_PATH = gmock_test_utils.GetTestExecutablePath('gmock_output_test_') 53*481dde66SAndroid Build Coastguard WorkerCOMMAND = [PROGRAM_PATH, '--gtest_stack_trace_depth=0', '--gtest_print_time=0'] 54*481dde66SAndroid Build Coastguard WorkerGOLDEN_NAME = 'gmock_output_test_golden.txt' 55*481dde66SAndroid Build Coastguard WorkerGOLDEN_PATH = os.path.join(gmock_test_utils.GetSourceDir(), GOLDEN_NAME) 56*481dde66SAndroid Build Coastguard Worker 57*481dde66SAndroid Build Coastguard Worker 58*481dde66SAndroid Build Coastguard Workerdef ToUnixLineEnding(s): 59*481dde66SAndroid Build Coastguard Worker """Changes all Windows/Mac line endings in s to UNIX line endings.""" 60*481dde66SAndroid Build Coastguard Worker 61*481dde66SAndroid Build Coastguard Worker return s.replace('\r\n', '\n').replace('\r', '\n') 62*481dde66SAndroid Build Coastguard Worker 63*481dde66SAndroid Build Coastguard Worker 64*481dde66SAndroid Build Coastguard Workerdef RemoveReportHeaderAndFooter(output): 65*481dde66SAndroid Build Coastguard Worker """Removes Google Test result report's header and footer from the output.""" 66*481dde66SAndroid Build Coastguard Worker 67*481dde66SAndroid Build Coastguard Worker output = re.sub(r'.*gtest_main.*\n', '', output) 68*481dde66SAndroid Build Coastguard Worker output = re.sub(r'\[.*\d+ tests.*\n', '', output) 69*481dde66SAndroid Build Coastguard Worker output = re.sub(r'\[.* test environment .*\n', '', output) 70*481dde66SAndroid Build Coastguard Worker output = re.sub(r'\[=+\] \d+ tests .* ran.*', '', output) 71*481dde66SAndroid Build Coastguard Worker output = re.sub(r'.* FAILED TESTS\n', '', output) 72*481dde66SAndroid Build Coastguard Worker return output 73*481dde66SAndroid Build Coastguard Worker 74*481dde66SAndroid Build Coastguard Worker 75*481dde66SAndroid Build Coastguard Workerdef RemoveLocations(output): 76*481dde66SAndroid Build Coastguard Worker """Removes all file location info from a Google Test program's output. 77*481dde66SAndroid Build Coastguard Worker 78*481dde66SAndroid Build Coastguard Worker Args: 79*481dde66SAndroid Build Coastguard Worker output: the output of a Google Test program. 80*481dde66SAndroid Build Coastguard Worker 81*481dde66SAndroid Build Coastguard Worker Returns: 82*481dde66SAndroid Build Coastguard Worker output with all file location info (in the form of 83*481dde66SAndroid Build Coastguard Worker 'DIRECTORY/FILE_NAME:LINE_NUMBER: 'or 84*481dde66SAndroid Build Coastguard Worker 'DIRECTORY\\FILE_NAME(LINE_NUMBER): ') replaced by 85*481dde66SAndroid Build Coastguard Worker 'FILE:#: '. 86*481dde66SAndroid Build Coastguard Worker """ 87*481dde66SAndroid Build Coastguard Worker 88*481dde66SAndroid Build Coastguard Worker return re.sub(r'.*[/\\](.+)(\:\d+|\(\d+\))\:', 'FILE:#:', output) 89*481dde66SAndroid Build Coastguard Worker 90*481dde66SAndroid Build Coastguard Worker 91*481dde66SAndroid Build Coastguard Workerdef NormalizeErrorMarker(output): 92*481dde66SAndroid Build Coastguard Worker """Normalizes the error marker, which is different on Windows vs on Linux.""" 93*481dde66SAndroid Build Coastguard Worker 94*481dde66SAndroid Build Coastguard Worker return re.sub(r' error: ', ' Failure\n', output) 95*481dde66SAndroid Build Coastguard Worker 96*481dde66SAndroid Build Coastguard Worker 97*481dde66SAndroid Build Coastguard Workerdef RemoveMemoryAddresses(output): 98*481dde66SAndroid Build Coastguard Worker """Removes memory addresses from the test output.""" 99*481dde66SAndroid Build Coastguard Worker 100*481dde66SAndroid Build Coastguard Worker return re.sub(r'@\w+', '@0x#', output) 101*481dde66SAndroid Build Coastguard Worker 102*481dde66SAndroid Build Coastguard Worker 103*481dde66SAndroid Build Coastguard Workerdef RemoveTestNamesOfLeakedMocks(output): 104*481dde66SAndroid Build Coastguard Worker """Removes the test names of leaked mock objects from the test output.""" 105*481dde66SAndroid Build Coastguard Worker 106*481dde66SAndroid Build Coastguard Worker return re.sub(r'\(used in test .+\) ', '', output) 107*481dde66SAndroid Build Coastguard Worker 108*481dde66SAndroid Build Coastguard Worker 109*481dde66SAndroid Build Coastguard Workerdef GetLeakyTests(output): 110*481dde66SAndroid Build Coastguard Worker """Returns a list of test names that leak mock objects.""" 111*481dde66SAndroid Build Coastguard Worker 112*481dde66SAndroid Build Coastguard Worker # findall() returns a list of all matches of the regex in output. 113*481dde66SAndroid Build Coastguard Worker # For example, if '(used in test FooTest.Bar)' is in output, the 114*481dde66SAndroid Build Coastguard Worker # list will contain 'FooTest.Bar'. 115*481dde66SAndroid Build Coastguard Worker return re.findall(r'\(used in test (.+)\)', output) 116*481dde66SAndroid Build Coastguard Worker 117*481dde66SAndroid Build Coastguard Worker 118*481dde66SAndroid Build Coastguard Workerdef GetNormalizedOutputAndLeakyTests(output): 119*481dde66SAndroid Build Coastguard Worker """Normalizes the output of gmock_output_test_. 120*481dde66SAndroid Build Coastguard Worker 121*481dde66SAndroid Build Coastguard Worker Args: 122*481dde66SAndroid Build Coastguard Worker output: The test output. 123*481dde66SAndroid Build Coastguard Worker 124*481dde66SAndroid Build Coastguard Worker Returns: 125*481dde66SAndroid Build Coastguard Worker A tuple (the normalized test output, the list of test names that have 126*481dde66SAndroid Build Coastguard Worker leaked mocks). 127*481dde66SAndroid Build Coastguard Worker """ 128*481dde66SAndroid Build Coastguard Worker 129*481dde66SAndroid Build Coastguard Worker output = ToUnixLineEnding(output) 130*481dde66SAndroid Build Coastguard Worker output = RemoveReportHeaderAndFooter(output) 131*481dde66SAndroid Build Coastguard Worker output = NormalizeErrorMarker(output) 132*481dde66SAndroid Build Coastguard Worker output = RemoveLocations(output) 133*481dde66SAndroid Build Coastguard Worker output = RemoveMemoryAddresses(output) 134*481dde66SAndroid Build Coastguard Worker return (RemoveTestNamesOfLeakedMocks(output), GetLeakyTests(output)) 135*481dde66SAndroid Build Coastguard Worker 136*481dde66SAndroid Build Coastguard Worker 137*481dde66SAndroid Build Coastguard Workerdef GetShellCommandOutput(cmd): 138*481dde66SAndroid Build Coastguard Worker """Runs a command in a sub-process, and returns its STDOUT in a string.""" 139*481dde66SAndroid Build Coastguard Worker 140*481dde66SAndroid Build Coastguard Worker return gmock_test_utils.Subprocess(cmd, capture_stderr=False).output 141*481dde66SAndroid Build Coastguard Worker 142*481dde66SAndroid Build Coastguard Worker 143*481dde66SAndroid Build Coastguard Workerdef GetNormalizedCommandOutputAndLeakyTests(cmd): 144*481dde66SAndroid Build Coastguard Worker """Runs a command and returns its normalized output and a list of leaky tests. 145*481dde66SAndroid Build Coastguard Worker 146*481dde66SAndroid Build Coastguard Worker Args: 147*481dde66SAndroid Build Coastguard Worker cmd: the shell command. 148*481dde66SAndroid Build Coastguard Worker """ 149*481dde66SAndroid Build Coastguard Worker 150*481dde66SAndroid Build Coastguard Worker # Disables exception pop-ups on Windows. 151*481dde66SAndroid Build Coastguard Worker os.environ['GTEST_CATCH_EXCEPTIONS'] = '1' 152*481dde66SAndroid Build Coastguard Worker return GetNormalizedOutputAndLeakyTests(GetShellCommandOutput(cmd)) 153*481dde66SAndroid Build Coastguard Worker 154*481dde66SAndroid Build Coastguard Worker 155*481dde66SAndroid Build Coastguard Workerclass GMockOutputTest(gmock_test_utils.TestCase): 156*481dde66SAndroid Build Coastguard Worker 157*481dde66SAndroid Build Coastguard Worker def testOutput(self): 158*481dde66SAndroid Build Coastguard Worker (output, leaky_tests) = GetNormalizedCommandOutputAndLeakyTests(COMMAND) 159*481dde66SAndroid Build Coastguard Worker golden_file = open(GOLDEN_PATH, 'rb') 160*481dde66SAndroid Build Coastguard Worker golden = golden_file.read().decode('utf-8') 161*481dde66SAndroid Build Coastguard Worker golden_file.close() 162*481dde66SAndroid Build Coastguard Worker # On Windows the repository might have been checked out with \r\n line 163*481dde66SAndroid Build Coastguard Worker # endings, so normalize it here. 164*481dde66SAndroid Build Coastguard Worker golden = ToUnixLineEnding(golden) 165*481dde66SAndroid Build Coastguard Worker 166*481dde66SAndroid Build Coastguard Worker # The normalized output should match the golden file. 167*481dde66SAndroid Build Coastguard Worker self.assertEqual(golden, output) 168*481dde66SAndroid Build Coastguard Worker 169*481dde66SAndroid Build Coastguard Worker # The raw output should contain 2 leaked mock object errors for 170*481dde66SAndroid Build Coastguard Worker # test GMockOutputTest.CatchesLeakedMocks. 171*481dde66SAndroid Build Coastguard Worker self.assertEqual( 172*481dde66SAndroid Build Coastguard Worker [ 173*481dde66SAndroid Build Coastguard Worker 'GMockOutputTest.CatchesLeakedMocks', 174*481dde66SAndroid Build Coastguard Worker 'GMockOutputTest.CatchesLeakedMocks', 175*481dde66SAndroid Build Coastguard Worker ], 176*481dde66SAndroid Build Coastguard Worker leaky_tests, 177*481dde66SAndroid Build Coastguard Worker ) 178*481dde66SAndroid Build Coastguard Worker 179*481dde66SAndroid Build Coastguard Worker 180*481dde66SAndroid Build Coastguard Workerif __name__ == '__main__': 181*481dde66SAndroid Build Coastguard Worker if sys.argv[1:] == [GENGOLDEN_FLAG]: 182*481dde66SAndroid Build Coastguard Worker (output, _) = GetNormalizedCommandOutputAndLeakyTests(COMMAND) 183*481dde66SAndroid Build Coastguard Worker golden_file = open(GOLDEN_PATH, 'wb') 184*481dde66SAndroid Build Coastguard Worker golden_file.write(output) 185*481dde66SAndroid Build Coastguard Worker golden_file.close() 186*481dde66SAndroid Build Coastguard Worker # Suppress the error "googletest was imported but a call to its main() 187*481dde66SAndroid Build Coastguard Worker # was never detected." 188*481dde66SAndroid Build Coastguard Worker os._exit(0) 189*481dde66SAndroid Build Coastguard Worker else: 190*481dde66SAndroid Build Coastguard Worker gmock_test_utils.Main() 191