1dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter#!/usr/bin/env python
2dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter#
3dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter# Copyright 2006, Google Inc.
4dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter# All rights reserved.
5dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter#
6dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter# Redistribution and use in source and binary forms, with or without
7dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter# modification, are permitted provided that the following conditions are
8dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter# met:
9dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter#
10dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter#     * Redistributions of source code must retain the above copyright
11dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter# notice, this list of conditions and the following disclaimer.
12dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter#     * Redistributions in binary form must reproduce the above
13dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter# copyright notice, this list of conditions and the following disclaimer
14dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter# in the documentation and/or other materials provided with the
15dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter# distribution.
16dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter#     * Neither the name of Google Inc. nor the names of its
17dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter# contributors may be used to endorse or promote products derived from
18dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter# this software without specific prior written permission.
19dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter#
20dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
32dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter"""Unit test for the gtest_xml_output module"""
33dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
34dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter__author__ = 'eefacm@gmail.com (Sean Mcafee)'
35dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
3646108a219a4b812dd8f36fee479a0340ea5963f5Ben Chanimport datetime
37dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixterimport errno
38dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixterimport os
3946108a219a4b812dd8f36fee479a0340ea5963f5Ben Chanimport re
40dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixterimport sys
41dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixterfrom xml.dom import minidom, Node
42dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
43dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixterimport gtest_test_utils
44dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixterimport gtest_xml_test_utils
45dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
46dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
4746108a219a4b812dd8f36fee479a0340ea5963f5Ben ChanGTEST_LIST_TESTS_FLAG = '--gtest_list_tests'
48dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken MixterGTEST_OUTPUT_FLAG         = "--gtest_output"
49dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken MixterGTEST_DEFAULT_OUTPUT_FILE = "test_detail.xml"
5046108a219a4b812dd8f36fee479a0340ea5963f5Ben ChanGTEST_PROGRAM_NAME = "gtest_xml_output_unittest_"
51dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
52dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken MixterSUPPORTS_STACK_TRACES = False
53dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
54dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixterif SUPPORTS_STACK_TRACES:
5546108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  STACK_TRACE_TEMPLATE = '\nStack trace:\n*'
56dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixterelse:
5746108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  STACK_TRACE_TEMPLATE = ''
58dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
59dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken MixterEXPECTED_NON_EMPTY_XML = """<?xml version="1.0" encoding="UTF-8"?>
6046108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan<testsuites tests="23" failures="4" disabled="2" errors="0" time="*" timestamp="*" name="AllTests">
61dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  <testsuite name="SuccessfulTest" tests="1" failures="0" disabled="0" errors="0" time="*">
62dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    <testcase name="Succeeds" status="run" time="*" classname="SuccessfulTest"/>
63dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  </testsuite>
64dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  <testsuite name="FailedTest" tests="1" failures="1" disabled="0" errors="0" time="*">
65dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    <testcase name="Fails" status="run" time="*" classname="FailedTest">
6646108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan      <failure message="gtest_xml_output_unittest_.cc:*&#x0A;Value of: 2&#x0A;Expected: 1" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
67dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken MixterValue of: 2
68dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken MixterExpected: 1%(stack)s]]></failure>
69dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    </testcase>
70dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  </testsuite>
71dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  <testsuite name="MixedResultTest" tests="3" failures="1" disabled="1" errors="0" time="*">
72dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    <testcase name="Succeeds" status="run" time="*" classname="MixedResultTest"/>
73dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    <testcase name="Fails" status="run" time="*" classname="MixedResultTest">
7446108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan      <failure message="gtest_xml_output_unittest_.cc:*&#x0A;Value of: 2&#x0A;Expected: 1" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
75dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken MixterValue of: 2
76dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken MixterExpected: 1%(stack)s]]></failure>
7746108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan      <failure message="gtest_xml_output_unittest_.cc:*&#x0A;Value of: 3&#x0A;Expected: 2" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
78dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken MixterValue of: 3
79dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken MixterExpected: 2%(stack)s]]></failure>
80dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    </testcase>
81dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    <testcase name="DISABLED_test" status="notrun" time="*" classname="MixedResultTest"/>
82dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  </testsuite>
8346108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  <testsuite name="XmlQuotingTest" tests="1" failures="1" disabled="0" errors="0" time="*">
8446108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    <testcase name="OutputsCData" status="run" time="*" classname="XmlQuotingTest">
8546108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan      <failure message="gtest_xml_output_unittest_.cc:*&#x0A;Failed&#x0A;XML output: &lt;?xml encoding=&quot;utf-8&quot;&gt;&lt;top&gt;&lt;![CDATA[cdata text]]&gt;&lt;/top&gt;" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
8646108a219a4b812dd8f36fee479a0340ea5963f5Ben ChanFailed
8746108a219a4b812dd8f36fee479a0340ea5963f5Ben ChanXML output: <?xml encoding="utf-8"><top><![CDATA[cdata text]]>]]&gt;<![CDATA[</top>%(stack)s]]></failure>
8846108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    </testcase>
8946108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  </testsuite>
9046108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  <testsuite name="InvalidCharactersTest" tests="1" failures="1" disabled="0" errors="0" time="*">
9146108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    <testcase name="InvalidCharactersInMessage" status="run" time="*" classname="InvalidCharactersTest">
9246108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan      <failure message="gtest_xml_output_unittest_.cc:*&#x0A;Failed&#x0A;Invalid characters in brackets []" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
9346108a219a4b812dd8f36fee479a0340ea5963f5Ben ChanFailed
9446108a219a4b812dd8f36fee479a0340ea5963f5Ben ChanInvalid characters in brackets []%(stack)s]]></failure>
9546108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    </testcase>
9646108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  </testsuite>
97dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  <testsuite name="DisabledTest" tests="1" failures="0" disabled="1" errors="0" time="*">
98dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    <testcase name="DISABLED_test_not_run" status="notrun" time="*" classname="DisabledTest"/>
99dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  </testsuite>
100dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  <testsuite name="PropertyRecordingTest" tests="4" failures="0" disabled="0" errors="0" time="*">
101dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    <testcase name="OneProperty" status="run" time="*" classname="PropertyRecordingTest" key_1="1"/>
102dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    <testcase name="IntValuedProperty" status="run" time="*" classname="PropertyRecordingTest" key_int="1"/>
103dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    <testcase name="ThreeProperties" status="run" time="*" classname="PropertyRecordingTest" key_1="1" key_2="2" key_3="3"/>
104dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    <testcase name="TwoValuesForOneKeyUsesLastValue" status="run" time="*" classname="PropertyRecordingTest" key_1="2"/>
105dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  </testsuite>
106dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  <testsuite name="NoFixtureTest" tests="3" failures="0" disabled="0" errors="0" time="*">
107dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter     <testcase name="RecordProperty" status="run" time="*" classname="NoFixtureTest" key="1"/>
108dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter     <testcase name="ExternalUtilityThatCallsRecordIntValuedProperty" status="run" time="*" classname="NoFixtureTest" key_for_utility_int="1"/>
109dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter     <testcase name="ExternalUtilityThatCallsRecordStringValuedProperty" status="run" time="*" classname="NoFixtureTest" key_for_utility_string="1"/>
110dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  </testsuite>
11146108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  <testsuite name="Single/ValueParamTest" tests="4" failures="0" disabled="0" errors="0" time="*">
11246108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    <testcase name="HasValueParamAttribute/0" value_param="33" status="run" time="*" classname="Single/ValueParamTest" />
11346108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    <testcase name="HasValueParamAttribute/1" value_param="42" status="run" time="*" classname="Single/ValueParamTest" />
11446108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    <testcase name="AnotherTestThatHasValueParamAttribute/0" value_param="33" status="run" time="*" classname="Single/ValueParamTest" />
11546108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    <testcase name="AnotherTestThatHasValueParamAttribute/1" value_param="42" status="run" time="*" classname="Single/ValueParamTest" />
11646108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  </testsuite>
11746108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  <testsuite name="TypedTest/0" tests="1" failures="0" disabled="0" errors="0" time="*">
11846108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    <testcase name="HasTypeParamAttribute" type_param="*" status="run" time="*" classname="TypedTest/0" />
11946108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  </testsuite>
12046108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  <testsuite name="TypedTest/1" tests="1" failures="0" disabled="0" errors="0" time="*">
12146108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    <testcase name="HasTypeParamAttribute" type_param="*" status="run" time="*" classname="TypedTest/1" />
12246108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  </testsuite>
12346108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  <testsuite name="Single/TypeParameterizedTestCase/0" tests="1" failures="0" disabled="0" errors="0" time="*">
12446108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    <testcase name="HasTypeParamAttribute" type_param="*" status="run" time="*" classname="Single/TypeParameterizedTestCase/0" />
12546108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  </testsuite>
12646108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  <testsuite name="Single/TypeParameterizedTestCase/1" tests="1" failures="0" disabled="0" errors="0" time="*">
12746108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    <testcase name="HasTypeParamAttribute" type_param="*" status="run" time="*" classname="Single/TypeParameterizedTestCase/1" />
12846108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  </testsuite>
129dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter</testsuites>""" % {'stack': STACK_TRACE_TEMPLATE}
130dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
131dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
132dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken MixterEXPECTED_EMPTY_XML = """<?xml version="1.0" encoding="UTF-8"?>
13346108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan<testsuites tests="0" failures="0" disabled="0" errors="0" time="*" timestamp="*" name="AllTests">
134dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter</testsuites>"""
135dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
13646108a219a4b812dd8f36fee479a0340ea5963f5Ben ChanGTEST_PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath(GTEST_PROGRAM_NAME)
13746108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan
13846108a219a4b812dd8f36fee479a0340ea5963f5Ben ChanSUPPORTS_TYPED_TESTS = 'TypedTest' in gtest_test_utils.Subprocess(
13946108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    [GTEST_PROGRAM_PATH, GTEST_LIST_TESTS_FLAG], capture_stderr=False).output
14046108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan
141dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
142dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixterclass GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase):
143dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  """
144dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  Unit test for Google Test's XML output functionality.
145dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  """
146dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
14746108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  # This test currently breaks on platforms that do not support typed and
14846108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  # type-parameterized tests, so we don't run it under them.
14946108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  if SUPPORTS_TYPED_TESTS:
15046108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    def testNonEmptyXmlOutput(self):
15146108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan      """
15246108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan      Runs a test program that generates a non-empty XML output, and
15346108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan      tests that the XML output is expected.
15446108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan      """
15546108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan      self._TestXmlOutput(GTEST_PROGRAM_NAME, EXPECTED_NON_EMPTY_XML, 1)
156dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
157dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  def testEmptyXmlOutput(self):
15846108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    """Verifies XML output for a Google Test binary without actual tests.
15946108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan
160dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    Runs a test program that generates an empty XML output, and
161dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    tests that the XML output is expected.
162dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    """
163dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
16446108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    self._TestXmlOutput('gtest_no_test_unittest', EXPECTED_EMPTY_XML, 0)
16546108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan
16646108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  def testTimestampValue(self):
16746108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    """Checks whether the timestamp attribute in the XML output is valid.
16846108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan
16946108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    Runs a test program that generates an empty XML output, and checks if
17046108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    the timestamp attribute in the testsuites tag is valid.
17146108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    """
17246108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    actual = self._GetXmlOutput('gtest_no_test_unittest', 0)
17346108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    date_time_str = actual.documentElement.getAttributeNode('timestamp').value
17446108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    # datetime.strptime() is only available in Python 2.5+ so we have to
17546108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    # parse the expected datetime manually.
17646108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    match = re.match(r'(\d+)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)', date_time_str)
17746108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    self.assertTrue(
17846108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan        re.match,
17946108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan        'XML datettime string %s has incorrect format' % date_time_str)
18046108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    date_time_from_xml = datetime.datetime(
18146108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan        year=int(match.group(1)), month=int(match.group(2)),
18246108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan        day=int(match.group(3)), hour=int(match.group(4)),
18346108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan        minute=int(match.group(5)), second=int(match.group(6)))
18446108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan
18546108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    time_delta = abs(datetime.datetime.now() - date_time_from_xml)
18646108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    # timestamp value should be near the current local time
18746108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    self.assertTrue(time_delta < datetime.timedelta(seconds=600),
18846108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan                    'time_delta is %s' % time_delta)
18946108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    actual.unlink()
190dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
191dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  def testDefaultOutputFile(self):
192dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    """
193dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    Confirms that Google Test produces an XML output file with the expected
194dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    default name if no name is explicitly specified.
195dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    """
196dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    output_file = os.path.join(gtest_test_utils.GetTempDir(),
197dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter                               GTEST_DEFAULT_OUTPUT_FILE)
198dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    gtest_prog_path = gtest_test_utils.GetTestExecutablePath(
19946108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan        'gtest_no_test_unittest')
200dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    try:
201dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter      os.remove(output_file)
202dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    except OSError, e:
203dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter      if e.errno != errno.ENOENT:
204dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter        raise
205dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
206dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    p = gtest_test_utils.Subprocess(
20746108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan        [gtest_prog_path, '%s=xml' % GTEST_OUTPUT_FLAG],
208dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter        working_dir=gtest_test_utils.GetTempDir())
209dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    self.assert_(p.exited)
210dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    self.assertEquals(0, p.exit_code)
211dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    self.assert_(os.path.isfile(output_file))
212dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
21346108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  def testSuppressedXmlOutput(self):
21446108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    """
21546108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    Tests that no XML file is generated if the default XML listener is
21646108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    shut down before RUN_ALL_TESTS is invoked.
21746108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    """
218dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
21946108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    xml_path = os.path.join(gtest_test_utils.GetTempDir(),
22046108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan                            GTEST_PROGRAM_NAME + 'out.xml')
22146108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    if os.path.isfile(xml_path):
22246108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan      os.remove(xml_path)
22346108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan
22446108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    command = [GTEST_PROGRAM_PATH,
22546108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan               '%s=xml:%s' % (GTEST_OUTPUT_FLAG, xml_path),
22646108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan               '--shut_down_xml']
22746108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    p = gtest_test_utils.Subprocess(command)
22846108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    if p.terminated_by_signal:
22946108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan      # p.signal is avalable only if p.terminated_by_signal is True.
23046108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan      self.assertFalse(
23146108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan          p.terminated_by_signal,
23246108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan          '%s was killed by signal %d' % (GTEST_PROGRAM_NAME, p.signal))
23346108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    else:
23446108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan      self.assert_(p.exited)
23546108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan      self.assertEquals(1, p.exit_code,
23646108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan                        "'%s' exited with code %s, which doesn't match "
23746108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan                        'the expected exit code %s.'
23846108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan                        % (command, p.exit_code, 1))
23946108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan
24046108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    self.assert_(not os.path.isfile(xml_path))
24146108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan
24246108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  def _GetXmlOutput(self, gtest_prog_name, expected_exit_code):
243dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    """
24446108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    Returns the xml output generated by running the program gtest_prog_name.
24546108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    Furthermore, the program's exit code must be expected_exit_code.
246dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    """
247dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    xml_path = os.path.join(gtest_test_utils.GetTempDir(),
24846108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan                            gtest_prog_name + 'out.xml')
249dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    gtest_prog_path = gtest_test_utils.GetTestExecutablePath(gtest_prog_name)
250dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
25146108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    command = [gtest_prog_path, '%s=xml:%s' % (GTEST_OUTPUT_FLAG, xml_path)]
252dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    p = gtest_test_utils.Subprocess(command)
253dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    if p.terminated_by_signal:
254dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter      self.assert_(False,
25546108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan                   '%s was killed by signal %d' % (gtest_prog_name, p.signal))
256dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    else:
257dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter      self.assert_(p.exited)
258dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter      self.assertEquals(expected_exit_code, p.exit_code,
259dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter                        "'%s' exited with code %s, which doesn't match "
26046108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan                        'the expected exit code %s.'
261dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter                        % (command, p.exit_code, expected_exit_code))
26246108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    actual = minidom.parse(xml_path)
26346108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    return actual
264dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
26546108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  def _TestXmlOutput(self, gtest_prog_name, expected_xml, expected_exit_code):
26646108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    """
26746108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    Asserts that the XML document generated by running the program
26846108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    gtest_prog_name matches expected_xml, a string containing another
26946108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    XML document.  Furthermore, the program's exit code must be
27046108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    expected_exit_code.
27146108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    """
27246108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan
27346108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    actual = self._GetXmlOutput(gtest_prog_name, expected_exit_code)
274dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    expected = minidom.parseString(expected_xml)
275dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    self.NormalizeXml(actual.documentElement)
276dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    self.AssertEquivalentNodes(expected.documentElement,
277dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter                               actual.documentElement)
278dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    expected.unlink()
27946108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    actual.unlink()
280dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
281dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
282dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixterif __name__ == '__main__':
283dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  os.environ['GTEST_STACK_TRACE_DEPTH'] = '1'
284dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  gtest_test_utils.Main()
285