~statik/ubuntu/maverick/protobuf/A

« back to all changes in this revision

Viewing changes to gtest/test/gtest_output_test.py

  • Committer: Bazaar Package Importer
  • Author(s): Steve Kowalik
  • Date: 2010-02-11 11:13:19 UTC
  • mfrom: (2.2.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20100211111319-zdn8hmw0gh8s4cf8
Tags: 2.2.0a-0.1ubuntu1
* Merge from Debian testing.
* Remaining Ubuntu changes:
  - Don't use python2.4.
* Ubuntu changes dropped:
  - Disable death tests on Itanium, fixed upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
42
42
 
43
43
import os
44
44
import re
45
 
import string
46
45
import sys
47
 
import unittest
48
46
import gtest_test_utils
49
47
 
50
48
 
62
60
 
63
61
# At least one command we exercise must not have the
64
62
# --gtest_internal_skip_environment_and_ad_hoc_tests flag.
65
 
COMMAND_LIST_TESTS = ({}, PROGRAM_PATH + ' --gtest_list_tests')
66
 
COMMAND_WITH_COLOR = ({}, PROGRAM_PATH + ' --gtest_color=yes')
67
 
COMMAND_WITH_TIME = ({}, PROGRAM_PATH + ' --gtest_print_time '
68
 
                     '--gtest_internal_skip_environment_and_ad_hoc_tests '
69
 
                     '--gtest_filter="FatalFailureTest.*:LoggingTest.*"')
70
 
COMMAND_WITH_DISABLED = ({}, PROGRAM_PATH + ' --gtest_also_run_disabled_tests '
71
 
                         '--gtest_internal_skip_environment_and_ad_hoc_tests '
72
 
                         '--gtest_filter="*DISABLED_*"')
73
 
COMMAND_WITH_SHARDING = ({'GTEST_SHARD_INDEX': '1', 'GTEST_TOTAL_SHARDS': '2'},
74
 
                         PROGRAM_PATH +
75
 
                         ' --gtest_internal_skip_environment_and_ad_hoc_tests '
76
 
                         ' --gtest_filter="PassingTest.*"')
 
63
COMMAND_LIST_TESTS = ({}, [PROGRAM_PATH, '--gtest_list_tests'])
 
64
COMMAND_WITH_COLOR = ({}, [PROGRAM_PATH, '--gtest_color=yes'])
 
65
COMMAND_WITH_TIME = ({}, [PROGRAM_PATH,
 
66
                          '--gtest_print_time',
 
67
                          '--gtest_internal_skip_environment_and_ad_hoc_tests',
 
68
                          '--gtest_filter=FatalFailureTest.*:LoggingTest.*'])
 
69
COMMAND_WITH_DISABLED = (
 
70
    {}, [PROGRAM_PATH,
 
71
         '--gtest_also_run_disabled_tests',
 
72
         '--gtest_internal_skip_environment_and_ad_hoc_tests',
 
73
         '--gtest_filter=*DISABLED_*'])
 
74
COMMAND_WITH_SHARDING = (
 
75
    {'GTEST_SHARD_INDEX': '1', 'GTEST_TOTAL_SHARDS': '2'},
 
76
    [PROGRAM_PATH,
 
77
     '--gtest_internal_skip_environment_and_ad_hoc_tests',
 
78
     '--gtest_filter=PassingTest.*'])
77
79
 
78
80
GOLDEN_PATH = os.path.join(gtest_test_utils.GetSourceDir(), GOLDEN_NAME)
79
81
 
84
86
  return s.replace('\r\n', '\n').replace('\r', '\n')
85
87
 
86
88
 
87
 
def RemoveLocations(output):
 
89
def RemoveLocations(test_output):
88
90
  """Removes all file location info from a Google Test program's output.
89
91
 
90
92
  Args:
91
 
       output:  the output of a Google Test program.
 
93
       test_output:  the output of a Google Test program.
92
94
 
93
95
  Returns:
94
96
       output with all file location info (in the form of
97
99
       'FILE_NAME:#: '.
98
100
  """
99
101
 
100
 
  return re.sub(r'.*[/\\](.+)(\:\d+|\(\d+\))\: ', r'\1:#: ', output)
101
 
 
102
 
 
103
 
def RemoveStackTraces(output):
 
102
  return re.sub(r'.*[/\\](.+)(\:\d+|\(\d+\))\: ', r'\1:#: ', test_output)
 
103
 
 
104
 
 
105
def RemoveStackTraceDetails(output):
104
106
  """Removes all stack traces from a Google Test program's output."""
105
107
 
106
108
  # *? means "find the shortest string that matches".
108
110
                'Stack trace: (omitted)\n\n', output)
109
111
 
110
112
 
 
113
def RemoveStackTraces(output):
 
114
  """Removes all traces of stack traces from a Google Test program's output."""
 
115
 
 
116
  # *? means "find the shortest string that matches".
 
117
  return re.sub(r'Stack trace:(.|\n)*?\n\n', '', output)
 
118
 
 
119
 
111
120
def RemoveTime(output):
112
121
  """Removes all time information from a Google Test program's output."""
113
122
 
123
132
                  '? FAILED TESTS', output)
124
133
  output = re.sub(r'\d+ tests from \d+ test cases',
125
134
                  '? tests from ? test cases', output)
 
135
  output = re.sub(r'\d+ tests from ([a-zA-Z_])',
 
136
                  r'? tests from \1', output)
126
137
  return re.sub(r'\d+ tests\.', '? tests.', output)
127
138
 
128
139
 
129
140
def RemoveMatchingTests(test_output, pattern):
130
 
  """Removes typed test information from a Google Test program's output.
 
141
  """Removes output of specified tests from a Google Test program's output.
131
142
 
132
 
  This function strips not only the beginning and the end of a test but also all
133
 
  output in between.
 
143
  This function strips not only the beginning and the end of a test but also
 
144
  all output in between.
134
145
 
135
146
  Args:
136
147
    test_output:       A string containing the test output.
137
 
    pattern:           A string that matches names of test cases to remove.
 
148
    pattern:           A regex string that matches names of test cases or
 
149
                       tests to remove.
138
150
 
139
151
  Returns:
140
 
    Contents of test_output with removed test case whose names match pattern.
 
152
    Contents of test_output with tests whose names match pattern removed.
141
153
  """
142
154
 
143
155
  test_output = re.sub(
144
 
      r'\[ RUN      \] .*%s(.|\n)*?\[(  FAILED  |       OK )\] .*%s.*\n' % (
 
156
      r'.*\[ RUN      \] .*%s(.|\n)*?\[(  FAILED  |       OK )\] .*%s.*\n' % (
145
157
          pattern, pattern),
146
158
      '',
147
159
      test_output)
153
165
 
154
166
  output = ToUnixLineEnding(output)
155
167
  output = RemoveLocations(output)
156
 
  output = RemoveStackTraces(output)
 
168
  output = RemoveStackTraceDetails(output)
157
169
  output = RemoveTime(output)
158
170
  return output
159
171
 
160
172
 
161
 
def IterShellCommandOutput(env_cmd, stdin_string=None):
162
 
  """Runs a command in a sub-process, and iterates the lines in its STDOUT.
 
173
def GetShellCommandOutput(env_cmd):
 
174
  """Runs a command in a sub-process, and returns its output in a string.
163
175
 
164
176
  Args:
 
177
    env_cmd: The shell command. A 2-tuple where element 0 is a dict of extra
 
178
             environment variables to set, and element 1 is a string with
 
179
             the command and any flags.
165
180
 
166
 
    env_cmd:           The shell command. A 2-tuple where element 0 is a dict
167
 
                       of extra environment variables to set, and element 1
168
 
                       is a string with the command and any flags.
169
 
    stdin_string:      The string to be fed to the STDIN of the sub-process;
170
 
                       If None, the sub-process will inherit the STDIN
171
 
                       from the parent process.
 
181
  Returns:
 
182
    A string with the command's combined standard and diagnostic output.
172
183
  """
173
184
 
174
185
  # Spawns cmd in a sub-process, and gets its standard I/O file objects.
175
186
  # Set and save the environment properly.
176
187
  old_env_vars = dict(os.environ)
177
188
  os.environ.update(env_cmd[0])
178
 
  stdin_file, stdout_file = os.popen2(env_cmd[1], 'b')
179
 
  os.environ.clear()
 
189
  p = gtest_test_utils.Subprocess(env_cmd[1])
 
190
 
 
191
  # Changes made by os.environ.clear are not inheritable by child processes
 
192
  # until Python 2.6. To produce inheritable changes we have to delete
 
193
  # environment items with the del statement.
 
194
  for key in os.environ.keys():
 
195
    del os.environ[key]
180
196
  os.environ.update(old_env_vars)
181
197
 
182
 
  # If the caller didn't specify a string for STDIN, gets it from the
183
 
  # parent process.
184
 
  if stdin_string is None:
185
 
    stdin_string = sys.stdin.read()
186
 
 
187
 
  # Feeds the STDIN string to the sub-process.
188
 
  stdin_file.write(stdin_string)
189
 
  stdin_file.close()
190
 
 
191
 
  while True:
192
 
    line = stdout_file.readline()
193
 
    if not line:  # EOF
194
 
      stdout_file.close()
195
 
      break
196
 
 
197
 
    yield line
198
 
 
199
 
 
200
 
def GetShellCommandOutput(env_cmd, stdin_string=None):
201
 
  """Runs a command in a sub-process, and returns its STDOUT in a string.
202
 
 
203
 
  Args:
204
 
 
205
 
    env_cmd:           The shell command. A 2-tuple where element 0 is a dict
206
 
                       of extra environment variables to set, and element 1
207
 
                       is a string with the command and any flags.
208
 
    stdin_string:      The string to be fed to the STDIN of the sub-process;
209
 
                       If None, the sub-process will inherit the STDIN
210
 
                       from the parent process.
211
 
  """
212
 
 
213
 
  lines = list(IterShellCommandOutput(env_cmd, stdin_string))
214
 
  return string.join(lines, '')
 
198
  return p.output
215
199
 
216
200
 
217
201
def GetCommandOutput(env_cmd):
226
210
 
227
211
  # Disables exception pop-ups on Windows.
228
212
  os.environ['GTEST_CATCH_EXCEPTIONS'] = '1'
229
 
  return NormalizeOutput(GetShellCommandOutput(env_cmd, ''))
 
213
  return NormalizeOutput(GetShellCommandOutput(env_cmd))
230
214
 
231
215
 
232
216
def GetOutputOfAllCommands():
238
222
          GetCommandOutput(COMMAND_WITH_SHARDING))
239
223
 
240
224
 
241
 
test_list = GetShellCommandOutput(COMMAND_LIST_TESTS, '')
 
225
test_list = GetShellCommandOutput(COMMAND_LIST_TESTS)
242
226
SUPPORTS_DEATH_TESTS = 'DeathTest' in test_list
243
227
SUPPORTS_TYPED_TESTS = 'TypedTest' in test_list
244
 
 
245
 
 
246
 
class GTestOutputTest(unittest.TestCase):
 
228
SUPPORTS_THREADS = 'ExpectFailureWithThreadsTest' in test_list
 
229
SUPPORTS_STACK_TRACES = False
 
230
 
 
231
CAN_GENERATE_GOLDEN_FILE = SUPPORTS_DEATH_TESTS and SUPPORTS_TYPED_TESTS
 
232
 
 
233
 
 
234
class GTestOutputTest(gtest_test_utils.TestCase):
247
235
  def RemoveUnsupportedTests(self, test_output):
248
236
    if not SUPPORTS_DEATH_TESTS:
249
237
      test_output = RemoveMatchingTests(test_output, 'DeathTest')
250
238
    if not SUPPORTS_TYPED_TESTS:
251
239
      test_output = RemoveMatchingTests(test_output, 'TypedTest')
 
240
    if not SUPPORTS_THREADS:
 
241
      test_output = RemoveMatchingTests(test_output,
 
242
                                        'ExpectFailureWithThreadsTest')
 
243
      test_output = RemoveMatchingTests(test_output,
 
244
                                        'ScopedFakeTestPartResultReporterTest')
 
245
      test_output = RemoveMatchingTests(test_output,
 
246
                                        'WorksConcurrently')
 
247
    if not SUPPORTS_STACK_TRACES:
 
248
      test_output = RemoveStackTraces(test_output)
 
249
 
252
250
    return test_output
253
251
 
254
252
  def testOutput(self):
255
253
    output = GetOutputOfAllCommands()
 
254
 
256
255
    golden_file = open(GOLDEN_PATH, 'rb')
257
 
    golden = golden_file.read()
 
256
    # A mis-configured source control system can cause \r appear in EOL
 
257
    # sequences when we read the golden file irrespective of an operating
 
258
    # system used. Therefore, we need to strip those \r's from newlines
 
259
    # unconditionally.
 
260
    golden = ToUnixLineEnding(golden_file.read())
258
261
    golden_file.close()
259
262
 
260
 
    # We want the test to pass regardless of death tests being
 
263
    # We want the test to pass regardless of certain features being
261
264
    # supported or not.
262
 
    if SUPPORTS_DEATH_TESTS and SUPPORTS_TYPED_TESTS:
 
265
    if CAN_GENERATE_GOLDEN_FILE:
263
266
      self.assert_(golden == output)
264
267
    else:
265
 
      self.assert_(RemoveTestCounts(self.RemoveUnsupportedTests(golden)) ==
266
 
                   RemoveTestCounts(output))
 
268
      normalized_actual = RemoveTestCounts(output)
 
269
      normalized_golden = RemoveTestCounts(self.RemoveUnsupportedTests(golden))
 
270
 
 
271
      # This code is very handy when debugging test differences so I left it
 
272
      # here, commented.
 
273
      # open(os.path.join(
 
274
      #     gtest_test_utils.GetSourceDir(),
 
275
      #     '_gtest_output_test_normalized_actual.txt'), 'wb').write(
 
276
      #         normalized_actual)
 
277
      # open(os.path.join(
 
278
      #     gtest_test_utils.GetSourceDir(),
 
279
      #     '_gtest_output_test_normalized_golden.txt'), 'wb').write(
 
280
      #         normalized_golden)
 
281
 
 
282
      self.assert_(normalized_golden == normalized_actual)
267
283
 
268
284
 
269
285
if __name__ == '__main__':
270
286
  if sys.argv[1:] == [GENGOLDEN_FLAG]:
271
 
    if SUPPORTS_DEATH_TESTS and SUPPORTS_TYPED_TESTS:
 
287
    if CAN_GENERATE_GOLDEN_FILE:
272
288
      output = GetOutputOfAllCommands()
273
289
      golden_file = open(GOLDEN_PATH, 'wb')
274
290
      golden_file.write(output)
275
291
      golden_file.close()
276
292
    else:
277
 
      print >> sys.stderr, ('Unable to write a golden file when compiled in an '
278
 
                            'environment that does not support death tests and '
279
 
                            'typed tests. Are you using VC 7.1?')
 
293
      message = (
 
294
          """Unable to write a golden file when compiled in an environment
 
295
that does not support all the required features (death tests""")
 
296
      if IS_WINDOWS:
 
297
        message += (
 
298
            """\nand typed tests). Please check that you are using VC++ 8.0 SP1
 
299
or higher as your compiler.""")
 
300
      else:
 
301
        message += """\nand typed tests).  Please generate the golden file
 
302
using a binary built with those features enabled."""
 
303
 
 
304
      sys.stderr.write(message)
280
305
      sys.exit(1)
281
306
  else:
282
307
    gtest_test_utils.Main()