1#!/usr/bin/env python 2# 3# Copyright 2006, 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"""Unit test for the gtest_xml_output module""" 33 34import datetime 35import errno 36import os 37import re 38import sys 39from xml.dom import minidom, Node 40 41from googletest.test import gtest_test_utils 42from googletest.test import gtest_xml_test_utils 43 44GTEST_FILTER_FLAG = '--gtest_filter' 45GTEST_LIST_TESTS_FLAG = '--gtest_list_tests' 46GTEST_OUTPUT_FLAG = '--gtest_output' 47GTEST_DEFAULT_OUTPUT_FILE = 'test_detail.xml' 48GTEST_PROGRAM_NAME = 'gtest_xml_output_unittest_' 49 50# The flag indicating stacktraces are not supported 51NO_STACKTRACE_SUPPORT_FLAG = '--no_stacktrace_support' 52 53# The environment variables for test sharding. 54TOTAL_SHARDS_ENV_VAR = 'GTEST_TOTAL_SHARDS' 55SHARD_INDEX_ENV_VAR = 'GTEST_SHARD_INDEX' 56SHARD_STATUS_FILE_ENV_VAR = 'GTEST_SHARD_STATUS_FILE' 57 58SUPPORTS_STACK_TRACES = NO_STACKTRACE_SUPPORT_FLAG not in sys.argv 59 60if SUPPORTS_STACK_TRACES: 61 STACK_TRACE_TEMPLATE = '\nStack trace:\n*' 62 STACK_TRACE_ENTITY_TEMPLATE = '' 63else: 64 STACK_TRACE_TEMPLATE = '\n' 65 STACK_TRACE_ENTITY_TEMPLATE = '
' 66 # unittest.main() can't handle unknown flags 67 sys.argv.remove(NO_STACKTRACE_SUPPORT_FLAG) 68 69EXPECTED_NON_EMPTY_XML = """<?xml version="1.0" encoding="UTF-8"?> 70<testsuites tests="26" failures="5" disabled="2" errors="0" time="*" timestamp="*" name="AllTests" ad_hoc_property="42"> 71 <testsuite name="SuccessfulTest" tests="1" failures="0" disabled="0" skipped="0" errors="0" time="*" timestamp="*"> 72 <testcase name="Succeeds" file="gtest_xml_output_unittest_.cc" line="53" status="run" result="completed" time="*" timestamp="*" classname="SuccessfulTest"/> 73 </testsuite> 74 <testsuite name="FailedTest" tests="1" failures="1" disabled="0" skipped="0" errors="0" time="*" timestamp="*"> 75 <testcase name="Fails" file="gtest_xml_output_unittest_.cc" line="61" status="run" result="completed" time="*" timestamp="*" classname="FailedTest"> 76 <failure message="gtest_xml_output_unittest_.cc:*
Expected equality of these values:
 1
 2%(stack_entity)s" type=""><![CDATA[gtest_xml_output_unittest_.cc:* 77Expected equality of these values: 78 1 79 2%(stack)s]]></failure> 80 </testcase> 81 </testsuite> 82 <testsuite name="MixedResultTest" tests="3" failures="1" disabled="1" skipped="0" errors="0" time="*" timestamp="*"> 83 <testcase name="Succeeds" file="gtest_xml_output_unittest_.cc" line="88" status="run" result="completed" time="*" timestamp="*" classname="MixedResultTest"/> 84 <testcase name="Fails" file="gtest_xml_output_unittest_.cc" line="93" status="run" result="completed" time="*" timestamp="*" classname="MixedResultTest"> 85 <failure message="gtest_xml_output_unittest_.cc:*
Expected equality of these values:
 1
 2%(stack_entity)s" type=""><![CDATA[gtest_xml_output_unittest_.cc:* 86Expected equality of these values: 87 1 88 2%(stack)s]]></failure> 89 <failure message="gtest_xml_output_unittest_.cc:*
Expected equality of these values:
 2
 3%(stack_entity)s" type=""><![CDATA[gtest_xml_output_unittest_.cc:* 90Expected equality of these values: 91 2 92 3%(stack)s]]></failure> 93 </testcase> 94 <testcase name="DISABLED_test" file="gtest_xml_output_unittest_.cc" line="98" status="notrun" result="suppressed" time="*" timestamp="*" classname="MixedResultTest"/> 95 </testsuite> 96 <testsuite name="XmlQuotingTest" tests="1" failures="1" disabled="0" skipped="0" errors="0" time="*" timestamp="*"> 97 <testcase name="OutputsCData" file="gtest_xml_output_unittest_.cc" line="102" status="run" result="completed" time="*" timestamp="*" classname="XmlQuotingTest"> 98 <failure message="gtest_xml_output_unittest_.cc:*
Failed
XML output: <?xml encoding="utf-8"><top><![CDATA[cdata text]]></top>%(stack_entity)s" type=""><![CDATA[gtest_xml_output_unittest_.cc:* 99Failed 100XML output: <?xml encoding="utf-8"><top><![CDATA[cdata text]]>]]><![CDATA[</top>%(stack)s]]></failure> 101 </testcase> 102 </testsuite> 103 <testsuite name="InvalidCharactersTest" tests="1" failures="1" disabled="0" skipped="0" errors="0" time="*" timestamp="*"> 104 <testcase name="InvalidCharactersInMessage" file="gtest_xml_output_unittest_.cc" line="109" status="run" result="completed" time="*" timestamp="*" classname="InvalidCharactersTest"> 105 <failure message="gtest_xml_output_unittest_.cc:*
Failed
Invalid characters in brackets []%(stack_entity)s" type=""><![CDATA[gtest_xml_output_unittest_.cc:* 106Failed 107Invalid characters in brackets []%(stack)s]]></failure> 108 </testcase> 109 </testsuite> 110 <testsuite name="DisabledTest" tests="1" failures="0" disabled="1" skipped="0" errors="0" time="*" timestamp="*"> 111 <testcase name="DISABLED_test_not_run" file="gtest_xml_output_unittest_.cc" line="68" status="notrun" result="suppressed" time="*" timestamp="*" classname="DisabledTest"/> 112 </testsuite> 113 <testsuite name="SkippedTest" tests="3" failures="1" disabled="0" skipped="2" errors="0" time="*" timestamp="*"> 114 <testcase name="Skipped" status="run" file="gtest_xml_output_unittest_.cc" line="75" result="skipped" time="*" timestamp="*" classname="SkippedTest"> 115 <skipped message="gtest_xml_output_unittest_.cc:*
%(stack_entity)s"><![CDATA[gtest_xml_output_unittest_.cc:* 116%(stack)s]]></skipped> 117 </testcase> 118 <testcase name="SkippedWithMessage" file="gtest_xml_output_unittest_.cc" line="79" status="run" result="skipped" time="*" timestamp="*" classname="SkippedTest"> 119 <skipped message="gtest_xml_output_unittest_.cc:*
It is good practice to tell why you skip a test.%(stack_entity)s"><![CDATA[gtest_xml_output_unittest_.cc:* 120It is good practice to tell why you skip a test.%(stack)s]]></skipped> 121 </testcase> 122 <testcase name="SkippedAfterFailure" file="gtest_xml_output_unittest_.cc" line="83" status="run" result="completed" time="*" timestamp="*" classname="SkippedTest"> 123 <failure message="gtest_xml_output_unittest_.cc:*
Expected equality of these values:
 1
 2%(stack_entity)s" type=""><![CDATA[gtest_xml_output_unittest_.cc:* 124Expected equality of these values: 125 1 126 2%(stack)s]]></failure> 127 <skipped message="gtest_xml_output_unittest_.cc:*
It is good practice to tell why you skip a test.%(stack_entity)s"><![CDATA[gtest_xml_output_unittest_.cc:* 128It is good practice to tell why you skip a test.%(stack)s]]></skipped> 129 </testcase> 130 131 </testsuite> 132 <testsuite name="PropertyRecordingTest" tests="4" failures="0" disabled="0" skipped="0" errors="0" time="*" timestamp="*" SetUpTestSuite="yes" TearDownTestSuite="aye"> 133 <testcase name="OneProperty" file="gtest_xml_output_unittest_.cc" line="121" status="run" result="completed" time="*" timestamp="*" classname="PropertyRecordingTest"> 134 <properties> 135 <property name="key_1" value="1"/> 136 </properties> 137 </testcase> 138 <testcase name="IntValuedProperty" file="gtest_xml_output_unittest_.cc" line="125" status="run" result="completed" time="*" timestamp="*" classname="PropertyRecordingTest"> 139 <properties> 140 <property name="key_int" value="1"/> 141 </properties> 142 </testcase> 143 <testcase name="ThreeProperties" file="gtest_xml_output_unittest_.cc" line="129" status="run" result="completed" time="*" timestamp="*" classname="PropertyRecordingTest"> 144 <properties> 145 <property name="key_1" value="1"/> 146 <property name="key_2" value="2"/> 147 <property name="key_3" value="3"/> 148 </properties> 149 </testcase> 150 <testcase name="TwoValuesForOneKeyUsesLastValue" file="gtest_xml_output_unittest_.cc" line="135" status="run" result="completed" time="*" timestamp="*" classname="PropertyRecordingTest"> 151 <properties> 152 <property name="key_1" value="2"/> 153 </properties> 154 </testcase> 155 </testsuite> 156 <testsuite name="NoFixtureTest" tests="3" failures="0" disabled="0" skipped="0" errors="0" time="*" timestamp="*"> 157 <testcase name="RecordProperty" file="gtest_xml_output_unittest_.cc" line="140" status="run" result="completed" time="*" timestamp="*" classname="NoFixtureTest"> 158 <properties> 159 <property name="key" value="1"/> 160 </properties> 161 </testcase> 162 <testcase name="ExternalUtilityThatCallsRecordIntValuedProperty" file="gtest_xml_output_unittest_.cc" line="153" status="run" result="completed" time="*" timestamp="*" classname="NoFixtureTest"> 163 <properties> 164 <property name="key_for_utility_int" value="1"/> 165 </properties> 166 </testcase> 167 <testcase name="ExternalUtilityThatCallsRecordStringValuedProperty" file="gtest_xml_output_unittest_.cc" line="157" status="run" result="completed" time="*" timestamp="*" classname="NoFixtureTest"> 168 <properties> 169 <property name="key_for_utility_string" value="1"/> 170 </properties> 171 </testcase> 172 </testsuite> 173 <testsuite name="Single/ValueParamTest" tests="4" failures="0" disabled="0" skipped="0" errors="0" time="*" timestamp="*"> 174 <testcase name="HasValueParamAttribute/0" file="gtest_xml_output_unittest_.cc" line="164" value_param="33" status="run" result="completed" time="*" timestamp="*" classname="Single/ValueParamTest" /> 175 <testcase name="HasValueParamAttribute/1" file="gtest_xml_output_unittest_.cc" line="164" value_param="42" status="run" result="completed" time="*" timestamp="*" classname="Single/ValueParamTest" /> 176 <testcase name="AnotherTestThatHasValueParamAttribute/0" file="gtest_xml_output_unittest_.cc" line="165" value_param="33" status="run" result="completed" time="*" timestamp="*" classname="Single/ValueParamTest" /> 177 <testcase name="AnotherTestThatHasValueParamAttribute/1" file="gtest_xml_output_unittest_.cc" line="165" value_param="42" status="run" result="completed" time="*" timestamp="*" classname="Single/ValueParamTest" /> 178 </testsuite> 179 <testsuite name="TypedTest/0" tests="1" failures="0" disabled="0" skipped="0" errors="0" time="*" timestamp="*"> 180 <testcase name="HasTypeParamAttribute" file="gtest_xml_output_unittest_.cc" line="173" type_param="*" status="run" result="completed" time="*" timestamp="*" classname="TypedTest/0" /> 181 </testsuite> 182 <testsuite name="TypedTest/1" tests="1" failures="0" disabled="0" skipped="0" errors="0" time="*" timestamp="*"> 183 <testcase name="HasTypeParamAttribute" file="gtest_xml_output_unittest_.cc" line="173" type_param="*" status="run" result="completed" time="*" timestamp="*" classname="TypedTest/1" /> 184 </testsuite> 185 <testsuite name="Single/TypeParameterizedTestSuite/0" tests="1" failures="0" disabled="0" skipped="0" errors="0" time="*" timestamp="*"> 186 <testcase name="HasTypeParamAttribute" file="gtest_xml_output_unittest_.cc" line="180" type_param="*" status="run" result="completed" time="*" timestamp="*" classname="Single/TypeParameterizedTestSuite/0" /> 187 </testsuite> 188 <testsuite name="Single/TypeParameterizedTestSuite/1" tests="1" failures="0" disabled="0" skipped="0" errors="0" time="*" timestamp="*"> 189 <testcase name="HasTypeParamAttribute" file="gtest_xml_output_unittest_.cc" line="180" type_param="*" status="run" result="completed" time="*" timestamp="*" classname="Single/TypeParameterizedTestSuite/1" /> 190 </testsuite> 191</testsuites>""" % { 192 'stack': STACK_TRACE_TEMPLATE, 193 'stack_entity': STACK_TRACE_ENTITY_TEMPLATE, 194} 195 196EXPECTED_FILTERED_TEST_XML = """<?xml version="1.0" encoding="UTF-8"?> 197<testsuites tests="1" failures="0" disabled="0" errors="0" time="*" 198 timestamp="*" name="AllTests" ad_hoc_property="42"> 199 <testsuite name="SuccessfulTest" tests="1" failures="0" disabled="0" skipped="0" 200 errors="0" time="*" timestamp="*"> 201 <testcase name="Succeeds" file="gtest_xml_output_unittest_.cc" line="53" status="run" result="completed" time="*" timestamp="*" classname="SuccessfulTest"/> 202 </testsuite> 203</testsuites>""" 204 205EXPECTED_SHARDED_TEST_XML = """<?xml version="1.0" encoding="UTF-8"?> 206<testsuites tests="3" failures="0" disabled="0" errors="0" time="*" timestamp="*" name="AllTests" ad_hoc_property="42"> 207 <testsuite name="SuccessfulTest" tests="1" failures="0" disabled="0" skipped="0" errors="0" time="*" timestamp="*"> 208 <testcase name="Succeeds" file="gtest_xml_output_unittest_.cc" line="53" status="run" result="completed" time="*" timestamp="*" classname="SuccessfulTest"/> 209 </testsuite> 210 <testsuite name="PropertyRecordingTest" tests="1" failures="0" disabled="0" skipped="0" errors="0" time="*" timestamp="*" SetUpTestSuite="yes" TearDownTestSuite="aye"> 211 <testcase name="IntValuedProperty" file="gtest_xml_output_unittest_.cc" line="125" status="run" result="completed" time="*" timestamp="*" classname="PropertyRecordingTest"> 212 <properties> 213 <property name="key_int" value="1"/> 214 </properties> 215 </testcase> 216 </testsuite> 217 <testsuite name="Single/ValueParamTest" tests="1" failures="0" disabled="0" skipped="0" errors="0" time="*" timestamp="*"> 218 <testcase name="HasValueParamAttribute/0" file="gtest_xml_output_unittest_.cc" line="164" value_param="33" status="run" result="completed" time="*" timestamp="*" classname="Single/ValueParamTest" /> 219 </testsuite> 220</testsuites>""" 221 222EXPECTED_NO_TEST_XML = """<?xml version="1.0" encoding="UTF-8"?> 223<testsuites tests="0" failures="0" disabled="0" errors="0" time="*" 224 timestamp="*" name="AllTests"> 225 <testsuite name="NonTestSuiteFailure" tests="1" failures="1" disabled="0" skipped="0" errors="0" time="*" timestamp="*"> 226 <testcase name="" status="run" result="completed" time="*" timestamp="*" classname=""> 227 <failure message="gtest_no_test_unittest.cc:*
Expected equality of these values:
 1
 2%(stack_entity)s" type=""><![CDATA[gtest_no_test_unittest.cc:* 228Expected equality of these values: 229 1 230 2%(stack)s]]></failure> 231 </testcase> 232 </testsuite> 233</testsuites>""" % { 234 'stack': STACK_TRACE_TEMPLATE, 235 'stack_entity': STACK_TRACE_ENTITY_TEMPLATE, 236} 237 238GTEST_PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath(GTEST_PROGRAM_NAME) 239 240SUPPORTS_TYPED_TESTS = ( 241 'TypedTest' 242 in gtest_test_utils.Subprocess( 243 [GTEST_PROGRAM_PATH, GTEST_LIST_TESTS_FLAG], capture_stderr=False 244 ).output 245) 246 247 248class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): 249 """Unit test for Google Test's XML output functionality.""" 250 251 # This test currently breaks on platforms that do not support typed and 252 # type-parameterized tests, so we don't run it under them. 253 if SUPPORTS_TYPED_TESTS: 254 255 def testNonEmptyXmlOutput(self): 256 """Generates non-empty XML and verifies it matches the expected output. 257 258 Runs a test program that generates a non-empty XML output, and 259 tests that the XML output is expected. 260 """ 261 self._TestXmlOutput(GTEST_PROGRAM_NAME, EXPECTED_NON_EMPTY_XML, 1) 262 263 def testNoTestXmlOutput(self): 264 """Verifies XML output for a Google Test binary without actual tests. 265 266 Runs a test program that generates an XML output for a binary without tests, 267 and tests that the XML output is expected. 268 """ 269 270 self._TestXmlOutput('gtest_no_test_unittest', EXPECTED_NO_TEST_XML, 0) 271 272 def testTimestampValue(self): 273 """Checks whether the timestamp attribute in the XML output is valid. 274 275 Runs a test program that generates an empty XML output, and checks if 276 the timestamp attribute in the testsuites tag is valid. 277 """ 278 actual = self._GetXmlOutput('gtest_no_test_unittest', [], {}, 0) 279 date_time_str = actual.documentElement.getAttributeNode('timestamp').value 280 # datetime.strptime() is only available in Python 2.5+ so we have to 281 # parse the expected datetime manually. 282 match = re.match(r'(\d+)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)', date_time_str) 283 self.assertTrue( 284 re.match, 'XML datettime string %s has incorrect format' % date_time_str 285 ) 286 date_time_from_xml = datetime.datetime( 287 year=int(match.group(1)), 288 month=int(match.group(2)), 289 day=int(match.group(3)), 290 hour=int(match.group(4)), 291 minute=int(match.group(5)), 292 second=int(match.group(6)), 293 ) 294 295 time_delta = abs(datetime.datetime.now() - date_time_from_xml) 296 # timestamp value should be near the current local time 297 self.assertLess(time_delta, datetime.timedelta(seconds=600)) 298 actual.unlink() 299 300 def testDefaultOutputFile(self): 301 """Tests XML file with default name is created when name is not specified. 302 303 Confirms that Google Test produces an XML output file with the expected 304 default name if no name is explicitly specified. 305 """ 306 output_file = os.path.join( 307 gtest_test_utils.GetTempDir(), GTEST_DEFAULT_OUTPUT_FILE 308 ) 309 gtest_prog_path = gtest_test_utils.GetTestExecutablePath( 310 'gtest_no_test_unittest' 311 ) 312 try: 313 os.remove(output_file) 314 except OSError: 315 e = sys.exc_info()[1] 316 if e.errno != errno.ENOENT: 317 raise 318 319 p = gtest_test_utils.Subprocess( 320 [gtest_prog_path, '%s=xml' % GTEST_OUTPUT_FLAG], 321 working_dir=gtest_test_utils.GetTempDir(), 322 ) 323 self.assertTrue(p.exited) 324 self.assertEqual(0, p.exit_code) 325 self.assertTrue(os.path.isfile(output_file)) 326 327 def testSuppressedXmlOutput(self): 328 """Verifies XML output is suppressed if default listener is shut down. 329 330 Tests that no XML file is generated if the default XML listener is 331 shut down before RUN_ALL_TESTS is invoked. 332 """ 333 334 xml_path = os.path.join( 335 gtest_test_utils.GetTempDir(), GTEST_PROGRAM_NAME + 'out.xml' 336 ) 337 if os.path.isfile(xml_path): 338 os.remove(xml_path) 339 340 command = [ 341 GTEST_PROGRAM_PATH, 342 '%s=xml:%s' % (GTEST_OUTPUT_FLAG, xml_path), 343 '--shut_down_xml', 344 ] 345 p = gtest_test_utils.Subprocess(command) 346 if p.terminated_by_signal: 347 # p.signal is available only if p.terminated_by_signal is True. 348 self.assertFalse( 349 p.terminated_by_signal, 350 '%s was killed by signal %d' % (GTEST_PROGRAM_NAME, p.signal), 351 ) 352 else: 353 self.assertTrue(p.exited) 354 self.assertEqual( 355 1, 356 p.exit_code, 357 "'%s' exited with code %s, which doesn't match " 358 'the expected exit code %s.' % (command, p.exit_code, 1), 359 ) 360 361 self.assertFalse(os.path.isfile(xml_path)) 362 363 def testFilteredTestXmlOutput(self): 364 """Verifies XML output when a filter is applied. 365 366 Runs a test program that executes only some tests and verifies that 367 non-selected tests do not show up in the XML output. 368 """ 369 370 self._TestXmlOutput( 371 GTEST_PROGRAM_NAME, 372 EXPECTED_FILTERED_TEST_XML, 373 0, 374 extra_args=['%s=SuccessfulTest.*' % GTEST_FILTER_FLAG], 375 ) 376 377 def testShardedTestXmlOutput(self): 378 """Verifies XML output when run using multiple shards. 379 380 Runs a test program that executes only one shard and verifies that tests 381 from other shards do not show up in the XML output. 382 """ 383 384 self._TestXmlOutput( 385 GTEST_PROGRAM_NAME, 386 EXPECTED_SHARDED_TEST_XML, 387 0, 388 extra_env={SHARD_INDEX_ENV_VAR: '0', TOTAL_SHARDS_ENV_VAR: '10'}, 389 ) 390 391 def _GetXmlOutput( 392 self, gtest_prog_name, extra_args, extra_env, expected_exit_code 393 ): 394 """Returns the XML output generated by running the program gtest_prog_name. 395 396 Furthermore, the program's exit code must be expected_exit_code. 397 398 Args: 399 gtest_prog_name: Program to run. 400 extra_args: Optional arguments to pass to program. 401 extra_env: Optional environment variables to set. 402 expected_exit_code: Expected exit code from running gtest_prog_name. 403 """ 404 xml_path = os.path.join( 405 gtest_test_utils.GetTempDir(), gtest_prog_name + 'out.xml' 406 ) 407 gtest_prog_path = gtest_test_utils.GetTestExecutablePath(gtest_prog_name) 408 409 command = [ 410 gtest_prog_path, 411 '%s=xml:%s' % (GTEST_OUTPUT_FLAG, xml_path), 412 ] + extra_args 413 environ_copy = os.environ.copy() 414 if extra_env: 415 environ_copy.update(extra_env) 416 p = gtest_test_utils.Subprocess(command, env=environ_copy) 417 418 if p.terminated_by_signal: 419 self.assertTrue( 420 False, '%s was killed by signal %d' % (gtest_prog_name, p.signal) 421 ) 422 else: 423 self.assertTrue(p.exited) 424 self.assertEqual( 425 expected_exit_code, 426 p.exit_code, 427 "'%s' exited with code %s, which doesn't match " 428 'the expected exit code %s.' 429 % (command, p.exit_code, expected_exit_code), 430 ) 431 actual = minidom.parse(xml_path) 432 return actual 433 434 def _TestXmlOutput( 435 self, 436 gtest_prog_name, 437 expected_xml, 438 expected_exit_code, 439 extra_args=None, 440 extra_env=None, 441 ): 442 """Asserts that the XML document matches. 443 444 Asserts that the XML document generated by running the program 445 gtest_prog_name matches expected_xml, a string containing another 446 XML document. Furthermore, the program's exit code must be 447 expected_exit_code. 448 449 Args: 450 gtest_prog_name: Program to run. 451 expected_xml: Path to XML document to match. 452 expected_exit_code: Expected exit code from running gtest_prog_name. 453 extra_args: Optional arguments to pass to program. 454 extra_env: Optional environment variables to set. 455 """ 456 457 actual = self._GetXmlOutput( 458 gtest_prog_name, extra_args or [], extra_env or {}, expected_exit_code 459 ) 460 expected = minidom.parseString(expected_xml) 461 self.NormalizeXml(actual.documentElement) 462 self.AssertEquivalentNodes(expected.documentElement, actual.documentElement) 463 expected.unlink() 464 actual.unlink() 465 466 467if __name__ == '__main__': 468 os.environ['GTEST_STACK_TRACE_DEPTH'] = '1' 469 gtest_test_utils.Main() 470