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