xref: /aosp_15_r20/external/googletest/googlemock/test/gmock_output_test.py (revision 481dde660366d6f317d242b6974ef1b20adb843c)
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