~renatofilho/sync-monitor/remove-addressbook

« back to all changes in this revision

Viewing changes to 3rd_party/gmock/gtest/test/gtest_output_test.py

  • Committer: Renato Araujo Oliveira Filho
  • Date: 2014-04-07 19:53:07 UTC
  • Revision ID: renato.filho@canonical.com-20140407195307-1jdcln7nz4ulxf0r
Added gmock source code. (necessary in tests)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
#
 
3
# Copyright 2008, Google Inc.
 
4
# All rights reserved.
 
5
#
 
6
# Redistribution and use in source and binary forms, with or without
 
7
# modification, are permitted provided that the following conditions are
 
8
# met:
 
9
#
 
10
#     * Redistributions of source code must retain the above copyright
 
11
# notice, this list of conditions and the following disclaimer.
 
12
#     * Redistributions in binary form must reproduce the above
 
13
# copyright notice, this list of conditions and the following disclaimer
 
14
# in the documentation and/or other materials provided with the
 
15
# distribution.
 
16
#     * Neither the name of Google Inc. nor the names of its
 
17
# contributors may be used to endorse or promote products derived from
 
18
# this software without specific prior written permission.
 
19
#
 
20
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 
21
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 
22
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
23
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 
24
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
25
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 
26
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
27
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
28
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
29
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 
30
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
31
 
 
32
"""Tests the text output of Google C++ Testing Framework.
 
33
 
 
34
SYNOPSIS
 
35
       gtest_output_test.py --build_dir=BUILD/DIR --gengolden
 
36
         # where BUILD/DIR contains the built gtest_output_test_ file.
 
37
       gtest_output_test.py --gengolden
 
38
       gtest_output_test.py
 
39
"""
 
40
 
 
41
__author__ = 'wan@google.com (Zhanyong Wan)'
 
42
 
 
43
import os
 
44
import re
 
45
import sys
 
46
import gtest_test_utils
 
47
 
 
48
 
 
49
# The flag for generating the golden file
 
50
GENGOLDEN_FLAG = '--gengolden'
 
51
CATCH_EXCEPTIONS_ENV_VAR_NAME = 'GTEST_CATCH_EXCEPTIONS'
 
52
 
 
53
IS_WINDOWS = os.name == 'nt'
 
54
 
 
55
# TODO(vladl@google.com): remove the _lin suffix.
 
56
GOLDEN_NAME = 'gtest_output_test_golden_lin.txt'
 
57
 
 
58
PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath('gtest_output_test_')
 
59
 
 
60
# At least one command we exercise must not have the
 
61
# --gtest_internal_skip_environment_and_ad_hoc_tests flag.
 
62
COMMAND_LIST_TESTS = ({}, [PROGRAM_PATH, '--gtest_list_tests'])
 
63
COMMAND_WITH_COLOR = ({}, [PROGRAM_PATH, '--gtest_color=yes'])
 
64
COMMAND_WITH_TIME = ({}, [PROGRAM_PATH,
 
65
                          '--gtest_print_time',
 
66
                          '--gtest_internal_skip_environment_and_ad_hoc_tests',
 
67
                          '--gtest_filter=FatalFailureTest.*:LoggingTest.*'])
 
68
COMMAND_WITH_DISABLED = (
 
69
    {}, [PROGRAM_PATH,
 
70
         '--gtest_also_run_disabled_tests',
 
71
         '--gtest_internal_skip_environment_and_ad_hoc_tests',
 
72
         '--gtest_filter=*DISABLED_*'])
 
73
COMMAND_WITH_SHARDING = (
 
74
    {'GTEST_SHARD_INDEX': '1', 'GTEST_TOTAL_SHARDS': '2'},
 
75
    [PROGRAM_PATH,
 
76
     '--gtest_internal_skip_environment_and_ad_hoc_tests',
 
77
     '--gtest_filter=PassingTest.*'])
 
78
 
 
79
GOLDEN_PATH = os.path.join(gtest_test_utils.GetSourceDir(), GOLDEN_NAME)
 
80
 
 
81
 
 
82
def ToUnixLineEnding(s):
 
83
  """Changes all Windows/Mac line endings in s to UNIX line endings."""
 
84
 
 
85
  return s.replace('\r\n', '\n').replace('\r', '\n')
 
86
 
 
87
 
 
88
def RemoveLocations(test_output):
 
89
  """Removes all file location info from a Google Test program's output.
 
90
 
 
91
  Args:
 
92
       test_output:  the output of a Google Test program.
 
93
 
 
94
  Returns:
 
95
       output with all file location info (in the form of
 
96
       'DIRECTORY/FILE_NAME:LINE_NUMBER: 'or
 
97
       'DIRECTORY\\FILE_NAME(LINE_NUMBER): ') replaced by
 
98
       'FILE_NAME:#: '.
 
99
  """
 
100
 
 
101
  return re.sub(r'.*[/\\](.+)(\:\d+|\(\d+\))\: ', r'\1:#: ', test_output)
 
102
 
 
103
 
 
104
def RemoveStackTraceDetails(output):
 
105
  """Removes all stack traces from a Google Test program's output."""
 
106
 
 
107
  # *? means "find the shortest string that matches".
 
108
  return re.sub(r'Stack trace:(.|\n)*?\n\n',
 
109
                'Stack trace: (omitted)\n\n', output)
 
110
 
 
111
 
 
112
def RemoveStackTraces(output):
 
113
  """Removes all traces of stack traces from a Google Test program's output."""
 
114
 
 
115
  # *? means "find the shortest string that matches".
 
116
  return re.sub(r'Stack trace:(.|\n)*?\n\n', '', output)
 
117
 
 
118
 
 
119
def RemoveTime(output):
 
120
  """Removes all time information from a Google Test program's output."""
 
121
 
 
122
  return re.sub(r'\(\d+ ms', '(? ms', output)
 
123
 
 
124
 
 
125
def RemoveTypeInfoDetails(test_output):
 
126
  """Removes compiler-specific type info from Google Test program's output.
 
127
 
 
128
  Args:
 
129
       test_output:  the output of a Google Test program.
 
130
 
 
131
  Returns:
 
132
       output with type information normalized to canonical form.
 
133
  """
 
134
 
 
135
  # some compilers output the name of type 'unsigned int' as 'unsigned'
 
136
  return re.sub(r'unsigned int', 'unsigned', test_output)
 
137
 
 
138
 
 
139
def NormalizeToCurrentPlatform(test_output):
 
140
  """Normalizes platform specific output details for easier comparison."""
 
141
 
 
142
  if IS_WINDOWS:
 
143
    # Removes the color information that is not present on Windows.
 
144
    test_output = re.sub('\x1b\\[(0;3\d)?m', '', test_output)
 
145
    # Changes failure message headers into the Windows format.
 
146
    test_output = re.sub(r': Failure\n', r': error: ', test_output)
 
147
    # Changes file(line_number) to file:line_number.
 
148
    test_output = re.sub(r'((\w|\.)+)\((\d+)\):', r'\1:\3:', test_output)
 
149
 
 
150
  return test_output
 
151
 
 
152
 
 
153
def RemoveTestCounts(output):
 
154
  """Removes test counts from a Google Test program's output."""
 
155
 
 
156
  output = re.sub(r'\d+ tests?, listed below',
 
157
                  '? tests, listed below', output)
 
158
  output = re.sub(r'\d+ FAILED TESTS',
 
159
                  '? FAILED TESTS', output)
 
160
  output = re.sub(r'\d+ tests? from \d+ test cases?',
 
161
                  '? tests from ? test cases', output)
 
162
  output = re.sub(r'\d+ tests? from ([a-zA-Z_])',
 
163
                  r'? tests from \1', output)
 
164
  return re.sub(r'\d+ tests?\.', '? tests.', output)
 
165
 
 
166
 
 
167
def RemoveMatchingTests(test_output, pattern):
 
168
  """Removes output of specified tests from a Google Test program's output.
 
169
 
 
170
  This function strips not only the beginning and the end of a test but also
 
171
  all output in between.
 
172
 
 
173
  Args:
 
174
    test_output:       A string containing the test output.
 
175
    pattern:           A regex string that matches names of test cases or
 
176
                       tests to remove.
 
177
 
 
178
  Returns:
 
179
    Contents of test_output with tests whose names match pattern removed.
 
180
  """
 
181
 
 
182
  test_output = re.sub(
 
183
      r'.*\[ RUN      \] .*%s(.|\n)*?\[(  FAILED  |       OK )\] .*%s.*\n' % (
 
184
          pattern, pattern),
 
185
      '',
 
186
      test_output)
 
187
  return re.sub(r'.*%s.*\n' % pattern, '', test_output)
 
188
 
 
189
 
 
190
def NormalizeOutput(output):
 
191
  """Normalizes output (the output of gtest_output_test_.exe)."""
 
192
 
 
193
  output = ToUnixLineEnding(output)
 
194
  output = RemoveLocations(output)
 
195
  output = RemoveStackTraceDetails(output)
 
196
  output = RemoveTime(output)
 
197
  return output
 
198
 
 
199
 
 
200
def GetShellCommandOutput(env_cmd):
 
201
  """Runs a command in a sub-process, and returns its output in a string.
 
202
 
 
203
  Args:
 
204
    env_cmd: The shell command. A 2-tuple where element 0 is a dict of extra
 
205
             environment variables to set, and element 1 is a string with
 
206
             the command and any flags.
 
207
 
 
208
  Returns:
 
209
    A string with the command's combined standard and diagnostic output.
 
210
  """
 
211
 
 
212
  # Spawns cmd in a sub-process, and gets its standard I/O file objects.
 
213
  # Set and save the environment properly.
 
214
  environ = os.environ.copy()
 
215
  environ.update(env_cmd[0])
 
216
  p = gtest_test_utils.Subprocess(env_cmd[1], env=environ)
 
217
 
 
218
  return p.output
 
219
 
 
220
 
 
221
def GetCommandOutput(env_cmd):
 
222
  """Runs a command and returns its output with all file location
 
223
  info stripped off.
 
224
 
 
225
  Args:
 
226
    env_cmd:  The shell command. A 2-tuple where element 0 is a dict of extra
 
227
              environment variables to set, and element 1 is a string with
 
228
              the command and any flags.
 
229
  """
 
230
 
 
231
  # Disables exception pop-ups on Windows.
 
232
  environ, cmdline = env_cmd
 
233
  environ = dict(environ)  # Ensures we are modifying a copy.
 
234
  environ[CATCH_EXCEPTIONS_ENV_VAR_NAME] = '1'
 
235
  return NormalizeOutput(GetShellCommandOutput((environ, cmdline)))
 
236
 
 
237
 
 
238
def GetOutputOfAllCommands():
 
239
  """Returns concatenated output from several representative commands."""
 
240
 
 
241
  return (GetCommandOutput(COMMAND_WITH_COLOR) +
 
242
          GetCommandOutput(COMMAND_WITH_TIME) +
 
243
          GetCommandOutput(COMMAND_WITH_DISABLED) +
 
244
          GetCommandOutput(COMMAND_WITH_SHARDING))
 
245
 
 
246
 
 
247
test_list = GetShellCommandOutput(COMMAND_LIST_TESTS)
 
248
SUPPORTS_DEATH_TESTS = 'DeathTest' in test_list
 
249
SUPPORTS_TYPED_TESTS = 'TypedTest' in test_list
 
250
SUPPORTS_THREADS = 'ExpectFailureWithThreadsTest' in test_list
 
251
SUPPORTS_STACK_TRACES = False
 
252
 
 
253
CAN_GENERATE_GOLDEN_FILE = (SUPPORTS_DEATH_TESTS and
 
254
                            SUPPORTS_TYPED_TESTS and
 
255
                            SUPPORTS_THREADS)
 
256
 
 
257
 
 
258
class GTestOutputTest(gtest_test_utils.TestCase):
 
259
  def RemoveUnsupportedTests(self, test_output):
 
260
    if not SUPPORTS_DEATH_TESTS:
 
261
      test_output = RemoveMatchingTests(test_output, 'DeathTest')
 
262
    if not SUPPORTS_TYPED_TESTS:
 
263
      test_output = RemoveMatchingTests(test_output, 'TypedTest')
 
264
      test_output = RemoveMatchingTests(test_output, 'TypedDeathTest')
 
265
      test_output = RemoveMatchingTests(test_output, 'TypeParamDeathTest')
 
266
    if not SUPPORTS_THREADS:
 
267
      test_output = RemoveMatchingTests(test_output,
 
268
                                        'ExpectFailureWithThreadsTest')
 
269
      test_output = RemoveMatchingTests(test_output,
 
270
                                        'ScopedFakeTestPartResultReporterTest')
 
271
      test_output = RemoveMatchingTests(test_output,
 
272
                                        'WorksConcurrently')
 
273
    if not SUPPORTS_STACK_TRACES:
 
274
      test_output = RemoveStackTraces(test_output)
 
275
 
 
276
    return test_output
 
277
 
 
278
  def testOutput(self):
 
279
    output = GetOutputOfAllCommands()
 
280
 
 
281
    golden_file = open(GOLDEN_PATH, 'rb')
 
282
    # A mis-configured source control system can cause \r appear in EOL
 
283
    # sequences when we read the golden file irrespective of an operating
 
284
    # system used. Therefore, we need to strip those \r's from newlines
 
285
    # unconditionally.
 
286
    golden = ToUnixLineEnding(golden_file.read())
 
287
    golden_file.close()
 
288
 
 
289
    # We want the test to pass regardless of certain features being
 
290
    # supported or not.
 
291
 
 
292
    # We still have to remove type name specifics in all cases.
 
293
    normalized_actual = RemoveTypeInfoDetails(output)
 
294
    normalized_golden = RemoveTypeInfoDetails(golden)
 
295
 
 
296
    if CAN_GENERATE_GOLDEN_FILE:
 
297
      self.assertEqual(normalized_golden, normalized_actual)
 
298
    else:
 
299
      normalized_actual = NormalizeToCurrentPlatform(
 
300
          RemoveTestCounts(normalized_actual))
 
301
      normalized_golden = NormalizeToCurrentPlatform(
 
302
          RemoveTestCounts(self.RemoveUnsupportedTests(normalized_golden)))
 
303
 
 
304
      # This code is very handy when debugging golden file differences:
 
305
      if os.getenv('DEBUG_GTEST_OUTPUT_TEST'):
 
306
        open(os.path.join(
 
307
            gtest_test_utils.GetSourceDir(),
 
308
            '_gtest_output_test_normalized_actual.txt'), 'wb').write(
 
309
                normalized_actual)
 
310
        open(os.path.join(
 
311
            gtest_test_utils.GetSourceDir(),
 
312
            '_gtest_output_test_normalized_golden.txt'), 'wb').write(
 
313
                normalized_golden)
 
314
 
 
315
      self.assertEqual(normalized_golden, normalized_actual)
 
316
 
 
317
 
 
318
if __name__ == '__main__':
 
319
  if sys.argv[1:] == [GENGOLDEN_FLAG]:
 
320
    if CAN_GENERATE_GOLDEN_FILE:
 
321
      output = GetOutputOfAllCommands()
 
322
      golden_file = open(GOLDEN_PATH, 'wb')
 
323
      golden_file.write(output)
 
324
      golden_file.close()
 
325
    else:
 
326
      message = (
 
327
          """Unable to write a golden file when compiled in an environment
 
328
that does not support all the required features (death tests, typed tests,
 
329
and multiple threads).  Please generate the golden file using a binary built
 
330
with those features enabled.""")
 
331
 
 
332
      sys.stderr.write(message)
 
333
      sys.exit(1)
 
334
  else:
 
335
    gtest_test_utils.Main()