155e0765ngie#!/usr/bin/env python
255e0765ngie# Copyright 2018, Google Inc.
355e0765ngie# All rights reserved.
455e0765ngie#
555e0765ngie# Redistribution and use in source and binary forms, with or without
655e0765ngie# modification, are permitted provided that the following conditions are
755e0765ngie# met:
855e0765ngie#
955e0765ngie#     * Redistributions of source code must retain the above copyright
1055e0765ngie# notice, this list of conditions and the following disclaimer.
1155e0765ngie#     * Redistributions in binary form must reproduce the above
1255e0765ngie# copyright notice, this list of conditions and the following disclaimer
1355e0765ngie# in the documentation and/or other materials provided with the
1455e0765ngie# distribution.
1555e0765ngie#     * Neither the name of Google Inc. nor the names of its
1655e0765ngie# contributors may be used to endorse or promote products derived from
1755e0765ngie# this software without specific prior written permission.
1855e0765ngie#
1955e0765ngie# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2055e0765ngie# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2155e0765ngie# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2255e0765ngie# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2355e0765ngie# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2455e0765ngie# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2555e0765ngie# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2655e0765ngie# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2755e0765ngie# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2855e0765ngie# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2955e0765ngie# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3055e0765ngie
3155e0765ngie"""Unit test for the gtest_json_output module."""
3255e0765ngie
3355e0765ngieimport datetime
3455e0765ngieimport errno
3555e0765ngieimport json
3655e0765ngieimport os
3755e0765ngieimport re
3855e0765ngieimport sys
3955e0765ngie
4055e0765ngieimport gtest_json_test_utils
4155e0765ngieimport gtest_test_utils
4255e0765ngie
4355e0765ngieGTEST_FILTER_FLAG = '--gtest_filter'
4455e0765ngieGTEST_LIST_TESTS_FLAG = '--gtest_list_tests'
4555e0765ngieGTEST_OUTPUT_FLAG = '--gtest_output'
4655e0765ngieGTEST_DEFAULT_OUTPUT_FILE = 'test_detail.json'
4755e0765ngieGTEST_PROGRAM_NAME = 'gtest_xml_output_unittest_'
4855e0765ngie
4955e0765ngie# The flag indicating stacktraces are not supported
5055e0765ngieNO_STACKTRACE_SUPPORT_FLAG = '--no_stacktrace_support'
5155e0765ngie
5255e0765ngieSUPPORTS_STACK_TRACES = NO_STACKTRACE_SUPPORT_FLAG not in sys.argv
5355e0765ngie
5455e0765ngieif SUPPORTS_STACK_TRACES:
5555e0765ngie  STACK_TRACE_TEMPLATE = '\nStack trace:\n*'
5655e0765ngieelse:
5755e0765ngie  STACK_TRACE_TEMPLATE = ''
5855e0765ngie
5955e0765ngieEXPECTED_NON_EMPTY = {
6055e0765ngie    u'tests': 23,
6155e0765ngie    u'failures': 4,
6255e0765ngie    u'disabled': 2,
6355e0765ngie    u'errors': 0,
6455e0765ngie    u'timestamp': u'*',
6555e0765ngie    u'time': u'*',
6655e0765ngie    u'ad_hoc_property': u'42',
6755e0765ngie    u'name': u'AllTests',
6855e0765ngie    u'testsuites': [
6955e0765ngie        {
7055e0765ngie            u'name': u'SuccessfulTest',
7155e0765ngie            u'tests': 1,
7255e0765ngie            u'failures': 0,
7355e0765ngie            u'disabled': 0,
7455e0765ngie            u'errors': 0,
7555e0765ngie            u'time': u'*',
7655e0765ngie            u'testsuite': [
7755e0765ngie                {
7855e0765ngie                    u'name': u'Succeeds',
7955e0765ngie                    u'status': u'RUN',
8055e0765ngie                    u'time': u'*',
8155e0765ngie                    u'classname': u'SuccessfulTest'
8255e0765ngie                }
8355e0765ngie            ]
8455e0765ngie        },
8555e0765ngie        {
8655e0765ngie            u'name': u'FailedTest',
8755e0765ngie            u'tests': 1,
8855e0765ngie            u'failures': 1,
8955e0765ngie            u'disabled': 0,
9055e0765ngie            u'errors': 0,
9155e0765ngie            u'time': u'*',
9255e0765ngie            u'testsuite': [
9355e0765ngie                {
9455e0765ngie                    u'name': u'Fails',
9555e0765ngie                    u'status': u'RUN',
9655e0765ngie                    u'time': u'*',
9755e0765ngie                    u'classname': u'FailedTest',
9855e0765ngie                    u'failures': [
9955e0765ngie                        {
10055e0765ngie                            u'failure':
10155e0765ngie                                u'gtest_xml_output_unittest_.cc:*\n'
10255e0765ngie                                u'Expected equality of these values:\n'
10355e0765ngie                                u'  1\n  2' + STACK_TRACE_TEMPLATE,
10455e0765ngie                            u'type': u''
10555e0765ngie                        }
10655e0765ngie                    ]
10755e0765ngie                }
10855e0765ngie            ]
10955e0765ngie        },
11055e0765ngie        {
11155e0765ngie            u'name': u'DisabledTest',
11255e0765ngie            u'tests': 1,
11355e0765ngie            u'failures': 0,
11455e0765ngie            u'disabled': 1,
11555e0765ngie            u'errors': 0,
11655e0765ngie            u'time': u'*',
11755e0765ngie            u'testsuite': [
11855e0765ngie                {
11955e0765ngie                    u'name': u'DISABLED_test_not_run',
12055e0765ngie                    u'status': u'NOTRUN',
12155e0765ngie                    u'time': u'*',
12255e0765ngie                    u'classname': u'DisabledTest'
12355e0765ngie                }
12455e0765ngie            ]
12555e0765ngie        },
12655e0765ngie        {
12755e0765ngie            u'name': u'MixedResultTest',
12855e0765ngie            u'tests': 3,
12955e0765ngie            u'failures': 1,
13055e0765ngie            u'disabled': 1,
13155e0765ngie            u'errors': 0,
13255e0765ngie            u'time': u'*',
13355e0765ngie            u'testsuite': [
13455e0765ngie                {
13555e0765ngie                    u'name': u'Succeeds',
13655e0765ngie                    u'status': u'RUN',
13755e0765ngie                    u'time': u'*',
13855e0765ngie                    u'classname': u'MixedResultTest'
13955e0765ngie                },
14055e0765ngie                {
14155e0765ngie                    u'name': u'Fails',
14255e0765ngie                    u'status': u'RUN',
14355e0765ngie                    u'time': u'*',
14455e0765ngie                    u'classname': u'MixedResultTest',
14555e0765ngie                    u'failures': [
14655e0765ngie                        {
14755e0765ngie                            u'failure':
14855e0765ngie                                u'gtest_xml_output_unittest_.cc:*\n'
14955e0765ngie                                u'Expected equality of these values:\n'
15055e0765ngie                                u'  1\n  2' + STACK_TRACE_TEMPLATE,
15155e0765ngie                            u'type': u''
15255e0765ngie                        },
15355e0765ngie                        {
15455e0765ngie                            u'failure':
15555e0765ngie                                u'gtest_xml_output_unittest_.cc:*\n'
15655e0765ngie                                u'Expected equality of these values:\n'
15755e0765ngie                                u'  2\n  3' + STACK_TRACE_TEMPLATE,
15855e0765ngie                            u'type': u''
15955e0765ngie                        }
16055e0765ngie                    ]
16155e0765ngie                },
16255e0765ngie                {
16355e0765ngie                    u'name': u'DISABLED_test',
16455e0765ngie                    u'status': u'NOTRUN',
16555e0765ngie                    u'time': u'*',
16655e0765ngie                    u'classname': u'MixedResultTest'
16755e0765ngie                }
16855e0765ngie            ]
16955e0765ngie        },
17055e0765ngie        {
17155e0765ngie            u'name': u'XmlQuotingTest',
17255e0765ngie            u'tests': 1,
17355e0765ngie            u'failures': 1,
17455e0765ngie            u'disabled': 0,
17555e0765ngie            u'errors': 0,
17655e0765ngie            u'time': u'*',
17755e0765ngie            u'testsuite': [
17855e0765ngie                {
17955e0765ngie                    u'name': u'OutputsCData',
18055e0765ngie                    u'status': u'RUN',
18155e0765ngie                    u'time': u'*',
18255e0765ngie                    u'classname': u'XmlQuotingTest',
18355e0765ngie                    u'failures': [
18455e0765ngie                        {
18555e0765ngie                            u'failure':
18655e0765ngie                                u'gtest_xml_output_unittest_.cc:*\n'
18755e0765ngie                                u'Failed\nXML output: <?xml encoding="utf-8">'
18855e0765ngie                                u'<top><![CDATA[cdata text]]></top>' +
18955e0765ngie                                STACK_TRACE_TEMPLATE,
19055e0765ngie                            u'type': u''
19155e0765ngie                        }
19255e0765ngie                    ]
19355e0765ngie                }
19455e0765ngie            ]
19555e0765ngie        },
19655e0765ngie        {
19755e0765ngie            u'name': u'InvalidCharactersTest',
19855e0765ngie            u'tests': 1,
19955e0765ngie            u'failures': 1,
20055e0765ngie            u'disabled': 0,
20155e0765ngie            u'errors': 0,
20255e0765ngie            u'time': u'*',
20355e0765ngie            u'testsuite': [
20455e0765ngie                {
20555e0765ngie                    u'name': u'InvalidCharactersInMessage',
20655e0765ngie                    u'status': u'RUN',
20755e0765ngie                    u'time': u'*',
20855e0765ngie                    u'classname': u'InvalidCharactersTest',
20955e0765ngie                    u'failures': [
21055e0765ngie                        {
21155e0765ngie                            u'failure':
21255e0765ngie                                u'gtest_xml_output_unittest_.cc:*\n'
21355e0765ngie                                u'Failed\nInvalid characters in brackets'
21455e0765ngie                                u' [\x01\x02]' + STACK_TRACE_TEMPLATE,
21555e0765ngie                            u'type': u''
21655e0765ngie                        }
21755e0765ngie                    ]
21855e0765ngie                }
21955e0765ngie            ]
22055e0765ngie        },
22155e0765ngie        {
22255e0765ngie            u'name': u'PropertyRecordingTest',
22355e0765ngie            u'tests': 4,
22455e0765ngie            u'failures': 0,
22555e0765ngie            u'disabled': 0,
22655e0765ngie            u'errors': 0,
22755e0765ngie            u'time': u'*',
22855e0765ngie            u'SetUpTestCase': u'yes',
22955e0765ngie            u'TearDownTestCase': u'aye',
23055e0765ngie            u'testsuite': [
23155e0765ngie                {
23255e0765ngie                    u'name': u'OneProperty',
23355e0765ngie                    u'status': u'RUN',
23455e0765ngie                    u'time': u'*',
23555e0765ngie                    u'classname': u'PropertyRecordingTest',
23655e0765ngie                    u'key_1': u'1'
23755e0765ngie                },
23855e0765ngie                {
23955e0765ngie                    u'name': u'IntValuedProperty',
24055e0765ngie                    u'status': u'RUN',
24155e0765ngie                    u'time': u'*',
24255e0765ngie                    u'classname': u'PropertyRecordingTest',
24355e0765ngie                    u'key_int': u'1'
24455e0765ngie                },
24555e0765ngie                {
24655e0765ngie                    u'name': u'ThreeProperties',
24755e0765ngie                    u'status': u'RUN',
24855e0765ngie                    u'time': u'*',
24955e0765ngie                    u'classname': u'PropertyRecordingTest',
25055e0765ngie                    u'key_1': u'1',
25155e0765ngie                    u'key_2': u'2',
25255e0765ngie                    u'key_3': u'3'
25355e0765ngie                },
25455e0765ngie                {
25555e0765ngie                    u'name': u'TwoValuesForOneKeyUsesLastValue',
25655e0765ngie                    u'status': u'RUN',
25755e0765ngie                    u'time': u'*',
25855e0765ngie                    u'classname': u'PropertyRecordingTest',
25955e0765ngie                    u'key_1': u'2'
26055e0765ngie                }
26155e0765ngie            ]
26255e0765ngie        },
26355e0765ngie        {
26455e0765ngie            u'name': u'NoFixtureTest',
26555e0765ngie            u'tests': 3,
26655e0765ngie            u'failures': 0,
26755e0765ngie            u'disabled': 0,
26855e0765ngie            u'errors': 0,
26955e0765ngie            u'time': u'*',
27055e0765ngie            u'testsuite': [
27155e0765ngie                {
27255e0765ngie                    u'name': u'RecordProperty',
27355e0765ngie                    u'status': u'RUN',
27455e0765ngie                    u'time': u'*',
27555e0765ngie                    u'classname': u'NoFixtureTest',
27655e0765ngie                    u'key': u'1'
27755e0765ngie                },
27855e0765ngie                {
27955e0765ngie                    u'name': u'ExternalUtilityThatCallsRecordIntValuedProperty',
28055e0765ngie                    u'status': u'RUN',
28155e0765ngie                    u'time': u'*',
28255e0765ngie                    u'classname': u'NoFixtureTest',
28355e0765ngie                    u'key_for_utility_int': u'1'
28455e0765ngie                },
28555e0765ngie                {
28655e0765ngie                    u'name':
28755e0765ngie                        u'ExternalUtilityThatCallsRecordStringValuedProperty',
28855e0765ngie                    u'status': u'RUN',
28955e0765ngie                    u'time': u'*',
29055e0765ngie                    u'classname': u'NoFixtureTest',
29155e0765ngie                    u'key_for_utility_string': u'1'
29255e0765ngie                }
29355e0765ngie            ]
29455e0765ngie        },
29555e0765ngie        {
29655e0765ngie            u'name': u'TypedTest/0',
29755e0765ngie            u'tests': 1,
29855e0765ngie            u'failures': 0,
29955e0765ngie            u'disabled': 0,
30055e0765ngie            u'errors': 0,
30155e0765ngie            u'time': u'*',
30255e0765ngie            u'testsuite': [
30355e0765ngie                {
30455e0765ngie                    u'name': u'HasTypeParamAttribute',
30555e0765ngie                    u'type_param': u'int',
30655e0765ngie                    u'status': u'RUN',
30755e0765ngie                    u'time': u'*',
30855e0765ngie                    u'classname': u'TypedTest/0'
30955e0765ngie                }
31055e0765ngie            ]
31155e0765ngie        },
31255e0765ngie        {
31355e0765ngie            u'name': u'TypedTest/1',
31455e0765ngie            u'tests': 1,
31555e0765ngie            u'failures': 0,
31655e0765ngie            u'disabled': 0,
31755e0765ngie            u'errors': 0,
31855e0765ngie            u'time': u'*',
31955e0765ngie            u'testsuite': [
32055e0765ngie                {
32155e0765ngie                    u'name': u'HasTypeParamAttribute',
32255e0765ngie                    u'type_param': u'long',
32355e0765ngie                    u'status': u'RUN',
32455e0765ngie                    u'time': u'*',
32555e0765ngie                    u'classname': u'TypedTest/1'
32655e0765ngie                }
32755e0765ngie            ]
32855e0765ngie        },
32955e0765ngie        {
33055e0765ngie            u'name': u'Single/TypeParameterizedTestCase/0',
33155e0765ngie            u'tests': 1,
33255e0765ngie            u'failures': 0,
33355e0765ngie            u'disabled': 0,
33455e0765ngie            u'errors': 0,
33555e0765ngie            u'time': u'*',
33655e0765ngie            u'testsuite': [
33755e0765ngie                {
33855e0765ngie                    u'name': u'HasTypeParamAttribute',
33955e0765ngie                    u'type_param': u'int',
34055e0765ngie                    u'status': u'RUN',
34155e0765ngie                    u'time': u'*',
34255e0765ngie                    u'classname': u'Single/TypeParameterizedTestCase/0'
34355e0765ngie                }
34455e0765ngie            ]
34555e0765ngie        },
34655e0765ngie        {
34755e0765ngie            u'name': u'Single/TypeParameterizedTestCase/1',
34855e0765ngie            u'tests': 1,
34955e0765ngie            u'failures': 0,
35055e0765ngie            u'disabled': 0,
35155e0765ngie            u'errors': 0,
35255e0765ngie            u'time': u'*',
35355e0765ngie            u'testsuite': [
35455e0765ngie                {
35555e0765ngie                    u'name': u'HasTypeParamAttribute',
35655e0765ngie                    u'type_param': u'long',
35755e0765ngie                    u'status': u'RUN',
35855e0765ngie                    u'time': u'*',
35955e0765ngie                    u'classname': u'Single/TypeParameterizedTestCase/1'
36055e0765ngie                }
36155e0765ngie            ]
36255e0765ngie        },
36355e0765ngie        {
36455e0765ngie            u'name': u'Single/ValueParamTest',
36555e0765ngie            u'tests': 4,
36655e0765ngie            u'failures': 0,
36755e0765ngie            u'disabled': 0,
36855e0765ngie            u'errors': 0,
36955e0765ngie            u'time': u'*',
37055e0765ngie            u'testsuite': [
37155e0765ngie                {
37255e0765ngie                    u'name': u'HasValueParamAttribute/0',
37355e0765ngie                    u'value_param': u'33',
37455e0765ngie                    u'status': u'RUN',
37555e0765ngie                    u'time': u'*',
37655e0765ngie                    u'classname': u'Single/ValueParamTest'
37755e0765ngie                },
37855e0765ngie                {
37955e0765ngie                    u'name': u'HasValueParamAttribute/1',
38055e0765ngie                    u'value_param': u'42',
38155e0765ngie                    u'status': u'RUN',
38255e0765ngie                    u'time': u'*',
38355e0765ngie                    u'classname': u'Single/ValueParamTest'
38455e0765ngie                },
38555e0765ngie                {
38655e0765ngie                    u'name': u'AnotherTestThatHasValueParamAttribute/0',
38755e0765ngie                    u'value_param': u'33',
38855e0765ngie                    u'status': u'RUN',
38955e0765ngie                    u'time': u'*',
39055e0765ngie                    u'classname': u'Single/ValueParamTest'
39155e0765ngie                },
39255e0765ngie                {
39355e0765ngie                    u'name': u'AnotherTestThatHasValueParamAttribute/1',
39455e0765ngie                    u'value_param': u'42',
39555e0765ngie                    u'status': u'RUN',
39655e0765ngie                    u'time': u'*',
39755e0765ngie                    u'classname': u'Single/ValueParamTest'
39855e0765ngie                }
39955e0765ngie            ]
40055e0765ngie        }
40155e0765ngie    ]
40255e0765ngie}
40355e0765ngie
40455e0765ngieEXPECTED_FILTERED = {
40555e0765ngie    u'tests': 1,
40655e0765ngie    u'failures': 0,
40755e0765ngie    u'disabled': 0,
40855e0765ngie    u'errors': 0,
40955e0765ngie    u'time': u'*',
41055e0765ngie    u'timestamp': u'*',
41155e0765ngie    u'name': u'AllTests',
41255e0765ngie    u'ad_hoc_property': u'42',
41355e0765ngie    u'testsuites': [{
41455e0765ngie        u'name': u'SuccessfulTest',
41555e0765ngie        u'tests': 1,
41655e0765ngie        u'failures': 0,
41755e0765ngie        u'disabled': 0,
41855e0765ngie        u'errors': 0,
41955e0765ngie        u'time': u'*',
42055e0765ngie        u'testsuite': [{
42155e0765ngie            u'name': u'Succeeds',
42255e0765ngie            u'status': u'RUN',
42355e0765ngie            u'time': u'*',
42455e0765ngie            u'classname': u'SuccessfulTest',
42555e0765ngie        }]
42655e0765ngie    }],
42755e0765ngie}
42855e0765ngie
42955e0765ngieEXPECTED_EMPTY = {
43055e0765ngie    u'tests': 0,
43155e0765ngie    u'failures': 0,
43255e0765ngie    u'disabled': 0,
43355e0765ngie    u'errors': 0,
43455e0765ngie    u'time': u'*',
43555e0765ngie    u'timestamp': u'*',
43655e0765ngie    u'name': u'AllTests',
43755e0765ngie    u'testsuites': [],
43855e0765ngie}
43955e0765ngie
44055e0765ngieGTEST_PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath(GTEST_PROGRAM_NAME)
44155e0765ngie
44255e0765ngieSUPPORTS_TYPED_TESTS = 'TypedTest' in gtest_test_utils.Subprocess(
44355e0765ngie    [GTEST_PROGRAM_PATH, GTEST_LIST_TESTS_FLAG], capture_stderr=False).output
44455e0765ngie
44555e0765ngie
44655e0765ngieclass GTestJsonOutputUnitTest(gtest_test_utils.TestCase):
44755e0765ngie  """Unit test for Google Test's JSON output functionality.
44855e0765ngie  """
44955e0765ngie
45055e0765ngie  # This test currently breaks on platforms that do not support typed and
45155e0765ngie  # type-parameterized tests, so we don't run it under them.
45255e0765ngie  if SUPPORTS_TYPED_TESTS:
45355e0765ngie
45455e0765ngie    def testNonEmptyJsonOutput(self):
45555e0765ngie      """Verifies JSON output for a Google Test binary with non-empty output.
45655e0765ngie
45755e0765ngie      Runs a test program that generates a non-empty JSON output, and
45855e0765ngie      tests that the JSON output is expected.
45955e0765ngie      """
46055e0765ngie      self._TestJsonOutput(GTEST_PROGRAM_NAME, EXPECTED_NON_EMPTY, 1)
46155e0765ngie
46255e0765ngie  def testEmptyJsonOutput(self):
46355e0765ngie    """Verifies JSON output for a Google Test binary without actual tests.
46455e0765ngie
46555e0765ngie    Runs a test program that generates an empty JSON output, and
46655e0765ngie    tests that the JSON output is expected.
46755e0765ngie    """
46855e0765ngie
46955e0765ngie    self._TestJsonOutput('gtest_no_test_unittest', EXPECTED_EMPTY, 0)
47055e0765ngie
47155e0765ngie  def testTimestampValue(self):
47255e0765ngie    """Checks whether the timestamp attribute in the JSON output is valid.
47355e0765ngie
47455e0765ngie    Runs a test program that generates an empty JSON output, and checks if
47555e0765ngie    the timestamp attribute in the testsuites tag is valid.
47655e0765ngie    """
47755e0765ngie    actual = self._GetJsonOutput('gtest_no_test_unittest', [], 0)
47855e0765ngie    date_time_str = actual['timestamp']
47955e0765ngie    # datetime.strptime() is only available in Python 2.5+ so we have to
48055e0765ngie    # parse the expected datetime manually.
48155e0765ngie    match = re.match(r'(\d+)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)', date_time_str)
48255e0765ngie    self.assertTrue(
48355e0765ngie        re.match,
48455e0765ngie        'JSON datettime string %s has incorrect format' % date_time_str)
48555e0765ngie    date_time_from_json = datetime.datetime(
48655e0765ngie        year=int(match.group(1)), month=int(match.group(2)),
48755e0765ngie        day=int(match.group(3)), hour=int(match.group(4)),
48855e0765ngie        minute=int(match.group(5)), second=int(match.group(6)))
48955e0765ngie
49055e0765ngie    time_delta = abs(datetime.datetime.now() - date_time_from_json)
49155e0765ngie    # timestamp value should be near the current local time
49255e0765ngie    self.assertTrue(time_delta < datetime.timedelta(seconds=600),
49355e0765ngie                    'time_delta is %s' % time_delta)
49455e0765ngie
49555e0765ngie  def testDefaultOutputFile(self):
49655e0765ngie    """Verifies the default output file name.
49755e0765ngie
49855e0765ngie    Confirms that Google Test produces an JSON output file with the expected
49955e0765ngie    default name if no name is explicitly specified.
50055e0765ngie    """
50155e0765ngie    output_file = os.path.join(gtest_test_utils.GetTempDir(),
50255e0765ngie                               GTEST_DEFAULT_OUTPUT_FILE)
50355e0765ngie    gtest_prog_path = gtest_test_utils.GetTestExecutablePath(
50455e0765ngie        'gtest_no_test_unittest')
50555e0765ngie    try:
50655e0765ngie      os.remove(output_file)
50755e0765ngie    except OSError:
50855e0765ngie      e = sys.exc_info()[1]
50955e0765ngie      if e.errno != errno.ENOENT:
51055e0765ngie        raise
51155e0765ngie
51255e0765ngie    p = gtest_test_utils.Subprocess(
51355e0765ngie        [gtest_prog_path, '%s=json' % GTEST_OUTPUT_FLAG],
51455e0765ngie        working_dir=gtest_test_utils.GetTempDir())
51555e0765ngie    self.assert_(p.exited)
51655e0765ngie    self.assertEquals(0, p.exit_code)
51755e0765ngie    self.assert_(os.path.isfile(output_file))
51855e0765ngie
51955e0765ngie  def testSuppressedJsonOutput(self):
52055e0765ngie    """Verifies that no JSON output is generated.
52155e0765ngie
52255e0765ngie    Tests that no JSON file is generated if the default JSON listener is
52355e0765ngie    shut down before RUN_ALL_TESTS is invoked.
52455e0765ngie    """
52555e0765ngie
52655e0765ngie    json_path = os.path.join(gtest_test_utils.GetTempDir(),
52755e0765ngie                             GTEST_PROGRAM_NAME + 'out.json')
52855e0765ngie    if os.path.isfile(json_path):
52955e0765ngie      os.remove(json_path)
53055e0765ngie
53155e0765ngie    command = [GTEST_PROGRAM_PATH,
53255e0765ngie               '%s=json:%s' % (GTEST_OUTPUT_FLAG, json_path),
53355e0765ngie               '--shut_down_xml']
53455e0765ngie    p = gtest_test_utils.Subprocess(command)
53555e0765ngie    if p.terminated_by_signal:
53655e0765ngie      # p.signal is available only if p.terminated_by_signal is True.
53755e0765ngie      self.assertFalse(
53855e0765ngie          p.terminated_by_signal,
53955e0765ngie          '%s was killed by signal %d' % (GTEST_PROGRAM_NAME, p.signal))
54055e0765ngie    else:
54155e0765ngie      self.assert_(p.exited)
54255e0765ngie      self.assertEquals(1, p.exit_code,
54355e0765ngie                        "'%s' exited with code %s, which doesn't match "
54455e0765ngie                        'the expected exit code %s.'
54555e0765ngie                        % (command, p.exit_code, 1))
54655e0765ngie
54755e0765ngie    self.assert_(not os.path.isfile(json_path))
54855e0765ngie
54955e0765ngie  def testFilteredTestJsonOutput(self):
55055e0765ngie    """Verifies JSON output when a filter is applied.
55155e0765ngie
55255e0765ngie    Runs a test program that executes only some tests and verifies that
55355e0765ngie    non-selected tests do not show up in the JSON output.
55455e0765ngie    """
55555e0765ngie
55655e0765ngie    self._TestJsonOutput(GTEST_PROGRAM_NAME, EXPECTED_FILTERED, 0,
55755e0765ngie                         extra_args=['%s=SuccessfulTest.*' % GTEST_FILTER_FLAG])
55855e0765ngie
55955e0765ngie  def _GetJsonOutput(self, gtest_prog_name, extra_args, expected_exit_code):
56055e0765ngie    """Returns the JSON output generated by running the program gtest_prog_name.
56155e0765ngie
56255e0765ngie    Furthermore, the program's exit code must be expected_exit_code.
56355e0765ngie
56455e0765ngie    Args:
56555e0765ngie      gtest_prog_name: Google Test binary name.
56655e0765ngie      extra_args: extra arguments to binary invocation.
56755e0765ngie      expected_exit_code: program's exit code.
56855e0765ngie    """
56955e0765ngie    json_path = os.path.join(gtest_test_utils.GetTempDir(),
57055e0765ngie                             gtest_prog_name + 'out.json')
57155e0765ngie    gtest_prog_path = gtest_test_utils.GetTestExecutablePath(gtest_prog_name)
57255e0765ngie
57355e0765ngie    command = (
57455e0765ngie        [gtest_prog_path, '%s=json:%s' % (GTEST_OUTPUT_FLAG, json_path)] +
57555e0765ngie        extra_args
57655e0765ngie    )
57755e0765ngie    p = gtest_test_utils.Subprocess(command)
57855e0765ngie    if p.terminated_by_signal:
57955e0765ngie      self.assert_(False,
58055e0765ngie                   '%s was killed by signal %d' % (gtest_prog_name, p.signal))
58155e0765ngie    else:
58255e0765ngie      self.assert_(p.exited)
58355e0765ngie      self.assertEquals(expected_exit_code, p.exit_code,
58455e0765ngie                        "'%s' exited with code %s, which doesn't match "
58555e0765ngie                        'the expected exit code %s.'
58655e0765ngie                        % (command, p.exit_code, expected_exit_code))
58755e0765ngie    with open(json_path) as f:
58855e0765ngie      actual = json.load(f)
58955e0765ngie    return actual
59055e0765ngie
59155e0765ngie  def _TestJsonOutput(self, gtest_prog_name, expected,
59255e0765ngie                      expected_exit_code, extra_args=None):
59355e0765ngie    """Checks the JSON output generated by the Google Test binary.
59455e0765ngie
59555e0765ngie    Asserts that the JSON document generated by running the program
59655e0765ngie    gtest_prog_name matches expected_json, a string containing another
59755e0765ngie    JSON document.  Furthermore, the program's exit code must be
59855e0765ngie    expected_exit_code.
59955e0765ngie
60055e0765ngie    Args:
60155e0765ngie      gtest_prog_name: Google Test binary name.
60255e0765ngie      expected: expected output.
60355e0765ngie      expected_exit_code: program's exit code.
60455e0765ngie      extra_args: extra arguments to binary invocation.
60555e0765ngie    """
60655e0765ngie
60755e0765ngie    actual = self._GetJsonOutput(gtest_prog_name, extra_args or [],
60855e0765ngie                                 expected_exit_code)
60955e0765ngie    self.assertEqual(expected, gtest_json_test_utils.normalize(actual))
61055e0765ngie
61155e0765ngie
61255e0765ngieif __name__ == '__main__':
61355e0765ngie  if NO_STACKTRACE_SUPPORT_FLAG in sys.argv:
61455e0765ngie    # unittest.main() can't handle unknown flags
61555e0765ngie    sys.argv.remove(NO_STACKTRACE_SUPPORT_FLAG)
61655e0765ngie
61755e0765ngie  os.environ['GTEST_STACK_TRACE_DEPTH'] = '1'
61855e0765ngie  gtest_test_utils.Main()
619