Blame googletest/test/gtest_xml_output_unittest.py

Packit bd1cd8
#!/usr/bin/env python
Packit bd1cd8
#
Packit bd1cd8
# Copyright 2006, Google Inc.
Packit bd1cd8
# All rights reserved.
Packit bd1cd8
#
Packit bd1cd8
# Redistribution and use in source and binary forms, with or without
Packit bd1cd8
# modification, are permitted provided that the following conditions are
Packit bd1cd8
# met:
Packit bd1cd8
#
Packit bd1cd8
#     * Redistributions of source code must retain the above copyright
Packit bd1cd8
# notice, this list of conditions and the following disclaimer.
Packit bd1cd8
#     * Redistributions in binary form must reproduce the above
Packit bd1cd8
# copyright notice, this list of conditions and the following disclaimer
Packit bd1cd8
# in the documentation and/or other materials provided with the
Packit bd1cd8
# distribution.
Packit bd1cd8
#     * Neither the name of Google Inc. nor the names of its
Packit bd1cd8
# contributors may be used to endorse or promote products derived from
Packit bd1cd8
# this software without specific prior written permission.
Packit bd1cd8
#
Packit bd1cd8
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
Packit bd1cd8
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
Packit bd1cd8
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
Packit bd1cd8
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
Packit bd1cd8
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
Packit bd1cd8
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
Packit bd1cd8
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
Packit bd1cd8
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
Packit bd1cd8
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
Packit bd1cd8
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
Packit bd1cd8
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit bd1cd8
Packit bd1cd8
"""Unit test for the gtest_xml_output module"""
Packit bd1cd8
Packit bd1cd8
__author__ = 'eefacm@gmail.com (Sean Mcafee)'
Packit bd1cd8
Packit bd1cd8
import datetime
Packit bd1cd8
import errno
Packit bd1cd8
import os
Packit bd1cd8
import re
Packit bd1cd8
import sys
Packit bd1cd8
from xml.dom import minidom, Node
Packit bd1cd8
Packit bd1cd8
import gtest_test_utils
Packit bd1cd8
import gtest_xml_test_utils
Packit bd1cd8
Packit bd1cd8
Packit bd1cd8
GTEST_FILTER_FLAG = '--gtest_filter'
Packit bd1cd8
GTEST_LIST_TESTS_FLAG = '--gtest_list_tests'
Packit bd1cd8
GTEST_OUTPUT_FLAG         = "--gtest_output"
Packit bd1cd8
GTEST_DEFAULT_OUTPUT_FILE = "test_detail.xml"
Packit bd1cd8
GTEST_PROGRAM_NAME = "gtest_xml_output_unittest_"
Packit bd1cd8
Packit bd1cd8
SUPPORTS_STACK_TRACES = False
Packit bd1cd8
Packit bd1cd8
if SUPPORTS_STACK_TRACES:
Packit bd1cd8
  STACK_TRACE_TEMPLATE = '\nStack trace:\n*'
Packit bd1cd8
else:
Packit bd1cd8
  STACK_TRACE_TEMPLATE = ''
Packit bd1cd8
Packit bd1cd8
EXPECTED_NON_EMPTY_XML = """
Packit bd1cd8
<testsuites tests="23" failures="4" disabled="2" errors="0" time="*" timestamp="*" name="AllTests" ad_hoc_property="42">
Packit bd1cd8
  <testsuite name="SuccessfulTest" tests="1" failures="0" disabled="0" errors="0" time="*">
Packit bd1cd8
    <testcase name="Succeeds" status="run" time="*" classname="SuccessfulTest"/>
Packit bd1cd8
  </testsuite>
Packit bd1cd8
  <testsuite name="FailedTest" tests="1" failures="1" disabled="0" errors="0" time="*">
Packit bd1cd8
    <testcase name="Fails" status="run" time="*" classname="FailedTest">
Packit bd1cd8
      <failure message="gtest_xml_output_unittest_.cc:*
      Expected: 1
To be equal to: 2" type="">
Packit bd1cd8
      Expected: 1
Packit bd1cd8
To be equal to: 2%(stack)s]]></failure>
Packit bd1cd8
    </testcase>
Packit bd1cd8
  </testsuite>
Packit bd1cd8
  <testsuite name="MixedResultTest" tests="3" failures="1" disabled="1" errors="0" time="*">
Packit bd1cd8
    <testcase name="Succeeds" status="run" time="*" classname="MixedResultTest"/>
Packit bd1cd8
    <testcase name="Fails" status="run" time="*" classname="MixedResultTest">
Packit bd1cd8
      <failure message="gtest_xml_output_unittest_.cc:*
      Expected: 1
To be equal to: 2" type="">
Packit bd1cd8
      Expected: 1
Packit bd1cd8
To be equal to: 2%(stack)s]]></failure>
Packit bd1cd8
      <failure message="gtest_xml_output_unittest_.cc:*
      Expected: 2
To be equal to: 3" type="">
Packit bd1cd8
      Expected: 2
Packit bd1cd8
To be equal to: 3%(stack)s]]></failure>
Packit bd1cd8
    </testcase>
Packit bd1cd8
    <testcase name="DISABLED_test" status="notrun" time="*" classname="MixedResultTest"/>
Packit bd1cd8
  </testsuite>
Packit bd1cd8
  <testsuite name="XmlQuotingTest" tests="1" failures="1" disabled="0" errors="0" time="*">
Packit bd1cd8
    <testcase name="OutputsCData" status="run" time="*" classname="XmlQuotingTest">
Packit bd1cd8
      <failure message="gtest_xml_output_unittest_.cc:*
Failed
XML output: <?xml encoding="utf-8"><top><![CDATA[cdata text]]></top>" type="">
Packit bd1cd8
Failed
Packit bd1cd8
XML output: <top>]]>%(stack)s]]></failure>
Packit bd1cd8
    </testcase>
Packit bd1cd8
  </testsuite>
Packit bd1cd8
  <testsuite name="InvalidCharactersTest" tests="1" failures="1" disabled="0" errors="0" time="*">
Packit bd1cd8
    <testcase name="InvalidCharactersInMessage" status="run" time="*" classname="InvalidCharactersTest">
Packit bd1cd8
      <failure message="gtest_xml_output_unittest_.cc:*
Failed
Invalid characters in brackets []" type="">
Packit bd1cd8
Failed
Packit bd1cd8
Invalid characters in brackets []%(stack)s]]></failure>
Packit bd1cd8
    </testcase>
Packit bd1cd8
  </testsuite>
Packit bd1cd8
  <testsuite name="DisabledTest" tests="1" failures="0" disabled="1" errors="0" time="*">
Packit bd1cd8
    <testcase name="DISABLED_test_not_run" status="notrun" time="*" classname="DisabledTest"/>
Packit bd1cd8
  </testsuite>
Packit bd1cd8
  <testsuite name="PropertyRecordingTest" tests="4" failures="0" disabled="0" errors="0" time="*" SetUpTestCase="yes" TearDownTestCase="aye">
Packit bd1cd8
    <testcase name="OneProperty" status="run" time="*" classname="PropertyRecordingTest" key_1="1"/>
Packit bd1cd8
    <testcase name="IntValuedProperty" status="run" time="*" classname="PropertyRecordingTest" key_int="1"/>
Packit bd1cd8
    <testcase name="ThreeProperties" status="run" time="*" classname="PropertyRecordingTest" key_1="1" key_2="2" key_3="3"/>
Packit bd1cd8
    <testcase name="TwoValuesForOneKeyUsesLastValue" status="run" time="*" classname="PropertyRecordingTest" key_1="2"/>
Packit bd1cd8
  </testsuite>
Packit bd1cd8
  <testsuite name="NoFixtureTest" tests="3" failures="0" disabled="0" errors="0" time="*">
Packit bd1cd8
     <testcase name="RecordProperty" status="run" time="*" classname="NoFixtureTest" key="1"/>
Packit bd1cd8
     <testcase name="ExternalUtilityThatCallsRecordIntValuedProperty" status="run" time="*" classname="NoFixtureTest" key_for_utility_int="1"/>
Packit bd1cd8
     <testcase name="ExternalUtilityThatCallsRecordStringValuedProperty" status="run" time="*" classname="NoFixtureTest" key_for_utility_string="1"/>
Packit bd1cd8
  </testsuite>
Packit bd1cd8
  <testsuite name="Single/ValueParamTest" tests="4" failures="0" disabled="0" errors="0" time="*">
Packit bd1cd8
    <testcase name="HasValueParamAttribute/0" value_param="33" status="run" time="*" classname="Single/ValueParamTest" />
Packit bd1cd8
    <testcase name="HasValueParamAttribute/1" value_param="42" status="run" time="*" classname="Single/ValueParamTest" />
Packit bd1cd8
    <testcase name="AnotherTestThatHasValueParamAttribute/0" value_param="33" status="run" time="*" classname="Single/ValueParamTest" />
Packit bd1cd8
    <testcase name="AnotherTestThatHasValueParamAttribute/1" value_param="42" status="run" time="*" classname="Single/ValueParamTest" />
Packit bd1cd8
  </testsuite>
Packit bd1cd8
  <testsuite name="TypedTest/0" tests="1" failures="0" disabled="0" errors="0" time="*">
Packit bd1cd8
    <testcase name="HasTypeParamAttribute" type_param="*" status="run" time="*" classname="TypedTest/0" />
Packit bd1cd8
  </testsuite>
Packit bd1cd8
  <testsuite name="TypedTest/1" tests="1" failures="0" disabled="0" errors="0" time="*">
Packit bd1cd8
    <testcase name="HasTypeParamAttribute" type_param="*" status="run" time="*" classname="TypedTest/1" />
Packit bd1cd8
  </testsuite>
Packit bd1cd8
  <testsuite name="Single/TypeParameterizedTestCase/0" tests="1" failures="0" disabled="0" errors="0" time="*">
Packit bd1cd8
    <testcase name="HasTypeParamAttribute" type_param="*" status="run" time="*" classname="Single/TypeParameterizedTestCase/0" />
Packit bd1cd8
  </testsuite>
Packit bd1cd8
  <testsuite name="Single/TypeParameterizedTestCase/1" tests="1" failures="0" disabled="0" errors="0" time="*">
Packit bd1cd8
    <testcase name="HasTypeParamAttribute" type_param="*" status="run" time="*" classname="Single/TypeParameterizedTestCase/1" />
Packit bd1cd8
  </testsuite>
Packit bd1cd8
</testsuites>""" % {'stack': STACK_TRACE_TEMPLATE}
Packit bd1cd8
Packit bd1cd8
EXPECTED_FILTERED_TEST_XML = """
Packit bd1cd8
Packit bd1cd8
            timestamp="*" name="AllTests" ad_hoc_property="42">
Packit bd1cd8
  
Packit bd1cd8
             errors="0" time="*">
Packit bd1cd8
    <testcase name="Succeeds" status="run" time="*" classname="SuccessfulTest"/>
Packit bd1cd8
  </testsuite>
Packit bd1cd8
</testsuites>"""
Packit bd1cd8
Packit bd1cd8
EXPECTED_EMPTY_XML = """
Packit bd1cd8
Packit bd1cd8
            timestamp="*" name="AllTests">
Packit bd1cd8
</testsuites>"""
Packit bd1cd8
Packit bd1cd8
GTEST_PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath(GTEST_PROGRAM_NAME)
Packit bd1cd8
Packit bd1cd8
SUPPORTS_TYPED_TESTS = 'TypedTest' in gtest_test_utils.Subprocess(
Packit bd1cd8
    [GTEST_PROGRAM_PATH, GTEST_LIST_TESTS_FLAG], capture_stderr=False).output
Packit bd1cd8
Packit bd1cd8
Packit bd1cd8
class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase):
Packit bd1cd8
  """
Packit bd1cd8
  Unit test for Google Test's XML output functionality.
Packit bd1cd8
  """
Packit bd1cd8
Packit bd1cd8
  # This test currently breaks on platforms that do not support typed and
Packit bd1cd8
  # type-parameterized tests, so we don't run it under them.
Packit bd1cd8
  if SUPPORTS_TYPED_TESTS:
Packit bd1cd8
    def testNonEmptyXmlOutput(self):
Packit bd1cd8
      """
Packit bd1cd8
      Runs a test program that generates a non-empty XML output, and
Packit bd1cd8
      tests that the XML output is expected.
Packit bd1cd8
      """
Packit bd1cd8
      self._TestXmlOutput(GTEST_PROGRAM_NAME, EXPECTED_NON_EMPTY_XML, 1)
Packit bd1cd8
Packit bd1cd8
  def testEmptyXmlOutput(self):
Packit bd1cd8
    """Verifies XML output for a Google Test binary without actual tests.
Packit bd1cd8
Packit bd1cd8
    Runs a test program that generates an empty XML output, and
Packit bd1cd8
    tests that the XML output is expected.
Packit bd1cd8
    """
Packit bd1cd8
Packit bd1cd8
    self._TestXmlOutput('gtest_no_test_unittest', EXPECTED_EMPTY_XML, 0)
Packit bd1cd8
Packit bd1cd8
  def testTimestampValue(self):
Packit bd1cd8
    """Checks whether the timestamp attribute in the XML output is valid.
Packit bd1cd8
Packit bd1cd8
    Runs a test program that generates an empty XML output, and checks if
Packit bd1cd8
    the timestamp attribute in the testsuites tag is valid.
Packit bd1cd8
    """
Packit bd1cd8
    actual = self._GetXmlOutput('gtest_no_test_unittest', [], 0)
Packit bd1cd8
    date_time_str = actual.documentElement.getAttributeNode('timestamp').value
Packit bd1cd8
    # datetime.strptime() is only available in Python 2.5+ so we have to
Packit bd1cd8
    # parse the expected datetime manually.
Packit bd1cd8
    match = re.match(r'(\d+)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)', date_time_str)
Packit bd1cd8
    self.assertTrue(
Packit bd1cd8
        re.match,
Packit bd1cd8
        'XML datettime string %s has incorrect format' % date_time_str)
Packit bd1cd8
    date_time_from_xml = datetime.datetime(
Packit bd1cd8
        year=int(match.group(1)), month=int(match.group(2)),
Packit bd1cd8
        day=int(match.group(3)), hour=int(match.group(4)),
Packit bd1cd8
        minute=int(match.group(5)), second=int(match.group(6)))
Packit bd1cd8
Packit bd1cd8
    time_delta = abs(datetime.datetime.now() - date_time_from_xml)
Packit bd1cd8
    # timestamp value should be near the current local time
Packit bd1cd8
    self.assertTrue(time_delta < datetime.timedelta(seconds=600),
Packit bd1cd8
                    'time_delta is %s' % time_delta)
Packit bd1cd8
    actual.unlink()
Packit bd1cd8
Packit bd1cd8
  def testDefaultOutputFile(self):
Packit bd1cd8
    """
Packit bd1cd8
    Confirms that Google Test produces an XML output file with the expected
Packit bd1cd8
    default name if no name is explicitly specified.
Packit bd1cd8
    """
Packit bd1cd8
    output_file = os.path.join(gtest_test_utils.GetTempDir(),
Packit bd1cd8
                               GTEST_DEFAULT_OUTPUT_FILE)
Packit bd1cd8
    gtest_prog_path = gtest_test_utils.GetTestExecutablePath(
Packit bd1cd8
        'gtest_no_test_unittest')
Packit bd1cd8
    try:
Packit bd1cd8
      os.remove(output_file)
Packit bd1cd8
    except OSError:
Packit bd1cd8
      e = sys.exc_info()[1]
Packit bd1cd8
      if e.errno != errno.ENOENT:
Packit bd1cd8
        raise
Packit bd1cd8
Packit bd1cd8
    p = gtest_test_utils.Subprocess(
Packit bd1cd8
        [gtest_prog_path, '%s=xml' % GTEST_OUTPUT_FLAG],
Packit bd1cd8
        working_dir=gtest_test_utils.GetTempDir())
Packit bd1cd8
    self.assert_(p.exited)
Packit bd1cd8
    self.assertEquals(0, p.exit_code)
Packit bd1cd8
    self.assert_(os.path.isfile(output_file))
Packit bd1cd8
Packit bd1cd8
  def testSuppressedXmlOutput(self):
Packit bd1cd8
    """
Packit bd1cd8
    Tests that no XML file is generated if the default XML listener is
Packit bd1cd8
    shut down before RUN_ALL_TESTS is invoked.
Packit bd1cd8
    """
Packit bd1cd8
Packit bd1cd8
    xml_path = os.path.join(gtest_test_utils.GetTempDir(),
Packit bd1cd8
                            GTEST_PROGRAM_NAME + 'out.xml')
Packit bd1cd8
    if os.path.isfile(xml_path):
Packit bd1cd8
      os.remove(xml_path)
Packit bd1cd8
Packit bd1cd8
    command = [GTEST_PROGRAM_PATH,
Packit bd1cd8
               '%s=xml:%s' % (GTEST_OUTPUT_FLAG, xml_path),
Packit bd1cd8
               '--shut_down_xml']
Packit bd1cd8
    p = gtest_test_utils.Subprocess(command)
Packit bd1cd8
    if p.terminated_by_signal:
Packit bd1cd8
      # p.signal is avalable only if p.terminated_by_signal is True.
Packit bd1cd8
      self.assertFalse(
Packit bd1cd8
          p.terminated_by_signal,
Packit bd1cd8
          '%s was killed by signal %d' % (GTEST_PROGRAM_NAME, p.signal))
Packit bd1cd8
    else:
Packit bd1cd8
      self.assert_(p.exited)
Packit bd1cd8
      self.assertEquals(1, p.exit_code,
Packit bd1cd8
                        "'%s' exited with code %s, which doesn't match "
Packit bd1cd8
                        'the expected exit code %s.'
Packit bd1cd8
                        % (command, p.exit_code, 1))
Packit bd1cd8
Packit bd1cd8
    self.assert_(not os.path.isfile(xml_path))
Packit bd1cd8
Packit bd1cd8
  def testFilteredTestXmlOutput(self):
Packit bd1cd8
    """Verifies XML output when a filter is applied.
Packit bd1cd8
Packit bd1cd8
    Runs a test program that executes only some tests and verifies that
Packit bd1cd8
    non-selected tests do not show up in the XML output.
Packit bd1cd8
    """
Packit bd1cd8
Packit bd1cd8
    self._TestXmlOutput(GTEST_PROGRAM_NAME, EXPECTED_FILTERED_TEST_XML, 0,
Packit bd1cd8
                        extra_args=['%s=SuccessfulTest.*' % GTEST_FILTER_FLAG])
Packit bd1cd8
Packit bd1cd8
  def _GetXmlOutput(self, gtest_prog_name, extra_args, expected_exit_code):
Packit bd1cd8
    """
Packit bd1cd8
    Returns the xml output generated by running the program gtest_prog_name.
Packit bd1cd8
    Furthermore, the program's exit code must be expected_exit_code.
Packit bd1cd8
    """
Packit bd1cd8
    xml_path = os.path.join(gtest_test_utils.GetTempDir(),
Packit bd1cd8
                            gtest_prog_name + 'out.xml')
Packit bd1cd8
    gtest_prog_path = gtest_test_utils.GetTestExecutablePath(gtest_prog_name)
Packit bd1cd8
Packit bd1cd8
    command = ([gtest_prog_path, '%s=xml:%s' % (GTEST_OUTPUT_FLAG, xml_path)] +
Packit bd1cd8
               extra_args)
Packit bd1cd8
    p = gtest_test_utils.Subprocess(command)
Packit bd1cd8
    if p.terminated_by_signal:
Packit bd1cd8
      self.assert_(False,
Packit bd1cd8
                   '%s was killed by signal %d' % (gtest_prog_name, p.signal))
Packit bd1cd8
    else:
Packit bd1cd8
      self.assert_(p.exited)
Packit bd1cd8
      self.assertEquals(expected_exit_code, p.exit_code,
Packit bd1cd8
                        "'%s' exited with code %s, which doesn't match "
Packit bd1cd8
                        'the expected exit code %s.'
Packit bd1cd8
                        % (command, p.exit_code, expected_exit_code))
Packit bd1cd8
    actual = minidom.parse(xml_path)
Packit bd1cd8
    return actual
Packit bd1cd8
Packit bd1cd8
  def _TestXmlOutput(self, gtest_prog_name, expected_xml,
Packit bd1cd8
                     expected_exit_code, extra_args=None):
Packit bd1cd8
    """
Packit bd1cd8
    Asserts that the XML document generated by running the program
Packit bd1cd8
    gtest_prog_name matches expected_xml, a string containing another
Packit bd1cd8
    XML document.  Furthermore, the program's exit code must be
Packit bd1cd8
    expected_exit_code.
Packit bd1cd8
    """
Packit bd1cd8
Packit bd1cd8
    actual = self._GetXmlOutput(gtest_prog_name, extra_args or [],
Packit bd1cd8
                                expected_exit_code)
Packit bd1cd8
    expected = minidom.parseString(expected_xml)
Packit bd1cd8
    self.NormalizeXml(actual.documentElement)
Packit bd1cd8
    self.AssertEquivalentNodes(expected.documentElement,
Packit bd1cd8
                               actual.documentElement)
Packit bd1cd8
    expected.unlink()
Packit bd1cd8
    actual.unlink()
Packit bd1cd8
Packit bd1cd8
Packit bd1cd8
if __name__ == '__main__':
Packit bd1cd8
  os.environ['GTEST_STACK_TRACE_DEPTH'] = '1'
Packit bd1cd8
  gtest_test_utils.Main()