1b89a7cc2SEnji Cooper#!/usr/bin/env python
2b89a7cc2SEnji Cooper# Copyright 2018, Google Inc.
3b89a7cc2SEnji Cooper# All rights reserved.
4b89a7cc2SEnji Cooper#
5b89a7cc2SEnji Cooper# Redistribution and use in source and binary forms, with or without
6b89a7cc2SEnji Cooper# modification, are permitted provided that the following conditions are
7b89a7cc2SEnji Cooper# met:
8b89a7cc2SEnji Cooper#
9b89a7cc2SEnji Cooper#     * Redistributions of source code must retain the above copyright
10b89a7cc2SEnji Cooper# notice, this list of conditions and the following disclaimer.
11b89a7cc2SEnji Cooper#     * Redistributions in binary form must reproduce the above
12b89a7cc2SEnji Cooper# copyright notice, this list of conditions and the following disclaimer
13b89a7cc2SEnji Cooper# in the documentation and/or other materials provided with the
14b89a7cc2SEnji Cooper# distribution.
15b89a7cc2SEnji Cooper#     * Neither the name of Google Inc. nor the names of its
16b89a7cc2SEnji Cooper# contributors may be used to endorse or promote products derived from
17b89a7cc2SEnji Cooper# this software without specific prior written permission.
18b89a7cc2SEnji Cooper#
19b89a7cc2SEnji Cooper# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20b89a7cc2SEnji Cooper# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21b89a7cc2SEnji Cooper# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22b89a7cc2SEnji Cooper# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23b89a7cc2SEnji Cooper# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24b89a7cc2SEnji Cooper# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25b89a7cc2SEnji Cooper# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26b89a7cc2SEnji Cooper# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27b89a7cc2SEnji Cooper# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28b89a7cc2SEnji Cooper# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29b89a7cc2SEnji Cooper# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30b89a7cc2SEnji Cooper
31b89a7cc2SEnji Cooper"""Unit test for the gtest_json_output module."""
32b89a7cc2SEnji Cooper
33b89a7cc2SEnji Cooperimport datetime
34b89a7cc2SEnji Cooperimport errno
35b89a7cc2SEnji Cooperimport json
36b89a7cc2SEnji Cooperimport os
37b89a7cc2SEnji Cooperimport re
38b89a7cc2SEnji Cooperimport sys
39b89a7cc2SEnji Cooper
4028f6c2f2SEnji Cooperfrom googletest.test import gtest_json_test_utils
4128f6c2f2SEnji Cooperfrom googletest.test import gtest_test_utils
42b89a7cc2SEnji Cooper
43b89a7cc2SEnji CooperGTEST_FILTER_FLAG = '--gtest_filter'
44b89a7cc2SEnji CooperGTEST_LIST_TESTS_FLAG = '--gtest_list_tests'
45b89a7cc2SEnji CooperGTEST_OUTPUT_FLAG = '--gtest_output'
46b89a7cc2SEnji CooperGTEST_DEFAULT_OUTPUT_FILE = 'test_detail.json'
47b89a7cc2SEnji CooperGTEST_PROGRAM_NAME = 'gtest_xml_output_unittest_'
48b89a7cc2SEnji Cooper
49b89a7cc2SEnji Cooper# The flag indicating stacktraces are not supported
50b89a7cc2SEnji CooperNO_STACKTRACE_SUPPORT_FLAG = '--no_stacktrace_support'
51b89a7cc2SEnji Cooper
52b89a7cc2SEnji CooperSUPPORTS_STACK_TRACES = NO_STACKTRACE_SUPPORT_FLAG not in sys.argv
53b89a7cc2SEnji Cooper
54b89a7cc2SEnji Cooperif SUPPORTS_STACK_TRACES:
55b89a7cc2SEnji Cooper  STACK_TRACE_TEMPLATE = '\nStack trace:\n*'
56b89a7cc2SEnji Cooperelse:
5728f6c2f2SEnji Cooper  STACK_TRACE_TEMPLATE = '\n'
58b89a7cc2SEnji Cooper
59b89a7cc2SEnji CooperEXPECTED_NON_EMPTY = {
6028f6c2f2SEnji Cooper    'tests': 26,
6128f6c2f2SEnji Cooper    'failures': 5,
6228f6c2f2SEnji Cooper    'disabled': 2,
6328f6c2f2SEnji Cooper    'errors': 0,
6428f6c2f2SEnji Cooper    'timestamp': '*',
6528f6c2f2SEnji Cooper    'time': '*',
6628f6c2f2SEnji Cooper    'ad_hoc_property': '42',
6728f6c2f2SEnji Cooper    'name': 'AllTests',
6828f6c2f2SEnji Cooper    'testsuites': [
69b89a7cc2SEnji Cooper        {
7028f6c2f2SEnji Cooper            'name': 'SuccessfulTest',
7128f6c2f2SEnji Cooper            'tests': 1,
7228f6c2f2SEnji Cooper            'failures': 0,
7328f6c2f2SEnji Cooper            'disabled': 0,
7428f6c2f2SEnji Cooper            'errors': 0,
7528f6c2f2SEnji Cooper            'time': '*',
7628f6c2f2SEnji Cooper            'timestamp': '*',
7728f6c2f2SEnji Cooper            'testsuite': [{
7828f6c2f2SEnji Cooper                'name': 'Succeeds',
7928f6c2f2SEnji Cooper                'file': 'gtest_xml_output_unittest_.cc',
8028f6c2f2SEnji Cooper                'line': 53,
8128f6c2f2SEnji Cooper                'status': 'RUN',
8228f6c2f2SEnji Cooper                'result': 'COMPLETED',
8328f6c2f2SEnji Cooper                'time': '*',
8428f6c2f2SEnji Cooper                'timestamp': '*',
8528f6c2f2SEnji Cooper                'classname': 'SuccessfulTest',
8628f6c2f2SEnji Cooper            }],
87b89a7cc2SEnji Cooper        },
88b89a7cc2SEnji Cooper        {
8928f6c2f2SEnji Cooper            'name': 'FailedTest',
9028f6c2f2SEnji Cooper            'tests': 1,
9128f6c2f2SEnji Cooper            'failures': 1,
9228f6c2f2SEnji Cooper            'disabled': 0,
9328f6c2f2SEnji Cooper            'errors': 0,
9428f6c2f2SEnji Cooper            'time': '*',
9528f6c2f2SEnji Cooper            'timestamp': '*',
9628f6c2f2SEnji Cooper            'testsuite': [{
9728f6c2f2SEnji Cooper                'name': 'Fails',
9828f6c2f2SEnji Cooper                'file': 'gtest_xml_output_unittest_.cc',
9928f6c2f2SEnji Cooper                'line': 61,
10028f6c2f2SEnji Cooper                'status': 'RUN',
10128f6c2f2SEnji Cooper                'result': 'COMPLETED',
10228f6c2f2SEnji Cooper                'time': '*',
10328f6c2f2SEnji Cooper                'timestamp': '*',
10428f6c2f2SEnji Cooper                'classname': 'FailedTest',
10528f6c2f2SEnji Cooper                'failures': [{
10628f6c2f2SEnji Cooper                    'failure': (
10728f6c2f2SEnji Cooper                        'gtest_xml_output_unittest_.cc:*\n'
10828f6c2f2SEnji Cooper                        'Expected equality of these values:\n'
10928f6c2f2SEnji Cooper                        '  1\n  2'
11028f6c2f2SEnji Cooper                        + STACK_TRACE_TEMPLATE
11128f6c2f2SEnji Cooper                    ),
11228f6c2f2SEnji Cooper                    'type': '',
11328f6c2f2SEnji Cooper                }],
11428f6c2f2SEnji Cooper            }],
115b89a7cc2SEnji Cooper        },
116b89a7cc2SEnji Cooper        {
11728f6c2f2SEnji Cooper            'name': 'DisabledTest',
11828f6c2f2SEnji Cooper            'tests': 1,
11928f6c2f2SEnji Cooper            'failures': 0,
12028f6c2f2SEnji Cooper            'disabled': 1,
12128f6c2f2SEnji Cooper            'errors': 0,
12228f6c2f2SEnji Cooper            'time': '*',
12328f6c2f2SEnji Cooper            'timestamp': '*',
12428f6c2f2SEnji Cooper            'testsuite': [{
12528f6c2f2SEnji Cooper                'name': 'DISABLED_test_not_run',
12628f6c2f2SEnji Cooper                'file': 'gtest_xml_output_unittest_.cc',
12728f6c2f2SEnji Cooper                'line': 68,
12828f6c2f2SEnji Cooper                'status': 'NOTRUN',
12928f6c2f2SEnji Cooper                'result': 'SUPPRESSED',
13028f6c2f2SEnji Cooper                'time': '*',
13128f6c2f2SEnji Cooper                'timestamp': '*',
13228f6c2f2SEnji Cooper                'classname': 'DisabledTest',
13328f6c2f2SEnji Cooper            }],
134b89a7cc2SEnji Cooper        },
135b89a7cc2SEnji Cooper        {
13628f6c2f2SEnji Cooper            'name': 'SkippedTest',
13728f6c2f2SEnji Cooper            'tests': 3,
13828f6c2f2SEnji Cooper            'failures': 1,
13928f6c2f2SEnji Cooper            'disabled': 0,
14028f6c2f2SEnji Cooper            'errors': 0,
14128f6c2f2SEnji Cooper            'time': '*',
14228f6c2f2SEnji Cooper            'timestamp': '*',
14328f6c2f2SEnji Cooper            'testsuite': [
144b89a7cc2SEnji Cooper                {
14528f6c2f2SEnji Cooper                    'name': 'Skipped',
14628f6c2f2SEnji Cooper                    'file': 'gtest_xml_output_unittest_.cc',
14728f6c2f2SEnji Cooper                    'line': 75,
14828f6c2f2SEnji Cooper                    'status': 'RUN',
14928f6c2f2SEnji Cooper                    'result': 'SKIPPED',
15028f6c2f2SEnji Cooper                    'time': '*',
15128f6c2f2SEnji Cooper                    'timestamp': '*',
15228f6c2f2SEnji Cooper                    'classname': 'SkippedTest',
153b89a7cc2SEnji Cooper                },
154b89a7cc2SEnji Cooper                {
15528f6c2f2SEnji Cooper                    'name': 'SkippedWithMessage',
15628f6c2f2SEnji Cooper                    'file': 'gtest_xml_output_unittest_.cc',
15728f6c2f2SEnji Cooper                    'line': 79,
15828f6c2f2SEnji Cooper                    'status': 'RUN',
15928f6c2f2SEnji Cooper                    'result': 'SKIPPED',
16028f6c2f2SEnji Cooper                    'time': '*',
16128f6c2f2SEnji Cooper                    'timestamp': '*',
16228f6c2f2SEnji Cooper                    'classname': 'SkippedTest',
163b89a7cc2SEnji Cooper                },
164b89a7cc2SEnji Cooper                {
16528f6c2f2SEnji Cooper                    'name': 'SkippedAfterFailure',
16628f6c2f2SEnji Cooper                    'file': 'gtest_xml_output_unittest_.cc',
16728f6c2f2SEnji Cooper                    'line': 83,
16828f6c2f2SEnji Cooper                    'status': 'RUN',
16928f6c2f2SEnji Cooper                    'result': 'COMPLETED',
17028f6c2f2SEnji Cooper                    'time': '*',
17128f6c2f2SEnji Cooper                    'timestamp': '*',
17228f6c2f2SEnji Cooper                    'classname': 'SkippedTest',
17328f6c2f2SEnji Cooper                    'failures': [{
17428f6c2f2SEnji Cooper                        'failure': (
17528f6c2f2SEnji Cooper                            'gtest_xml_output_unittest_.cc:*\n'
17628f6c2f2SEnji Cooper                            'Expected equality of these values:\n'
17728f6c2f2SEnji Cooper                            '  1\n  2'
17828f6c2f2SEnji Cooper                            + STACK_TRACE_TEMPLATE
17928f6c2f2SEnji Cooper                        ),
18028f6c2f2SEnji Cooper                        'type': '',
18128f6c2f2SEnji Cooper                    }],
18228f6c2f2SEnji Cooper                },
18328f6c2f2SEnji Cooper            ],
184b89a7cc2SEnji Cooper        },
185b89a7cc2SEnji Cooper        {
18628f6c2f2SEnji Cooper            'name': 'MixedResultTest',
18728f6c2f2SEnji Cooper            'tests': 3,
18828f6c2f2SEnji Cooper            'failures': 1,
18928f6c2f2SEnji Cooper            'disabled': 1,
19028f6c2f2SEnji Cooper            'errors': 0,
19128f6c2f2SEnji Cooper            'time': '*',
19228f6c2f2SEnji Cooper            'timestamp': '*',
19328f6c2f2SEnji Cooper            'testsuite': [
19428f6c2f2SEnji Cooper                {
19528f6c2f2SEnji Cooper                    'name': 'Succeeds',
19628f6c2f2SEnji Cooper                    'file': 'gtest_xml_output_unittest_.cc',
19728f6c2f2SEnji Cooper                    'line': 88,
19828f6c2f2SEnji Cooper                    'status': 'RUN',
19928f6c2f2SEnji Cooper                    'result': 'COMPLETED',
20028f6c2f2SEnji Cooper                    'time': '*',
20128f6c2f2SEnji Cooper                    'timestamp': '*',
20228f6c2f2SEnji Cooper                    'classname': 'MixedResultTest',
203b89a7cc2SEnji Cooper                },
204b89a7cc2SEnji Cooper                {
20528f6c2f2SEnji Cooper                    'name': 'Fails',
20628f6c2f2SEnji Cooper                    'file': 'gtest_xml_output_unittest_.cc',
20728f6c2f2SEnji Cooper                    'line': 93,
20828f6c2f2SEnji Cooper                    'status': 'RUN',
20928f6c2f2SEnji Cooper                    'result': 'COMPLETED',
21028f6c2f2SEnji Cooper                    'time': '*',
21128f6c2f2SEnji Cooper                    'timestamp': '*',
21228f6c2f2SEnji Cooper                    'classname': 'MixedResultTest',
21328f6c2f2SEnji Cooper                    'failures': [
214b89a7cc2SEnji Cooper                        {
21528f6c2f2SEnji Cooper                            'failure': (
21628f6c2f2SEnji Cooper                                'gtest_xml_output_unittest_.cc:*\n'
21728f6c2f2SEnji Cooper                                'Expected equality of these values:\n'
21828f6c2f2SEnji Cooper                                '  1\n  2'
21928f6c2f2SEnji Cooper                                + STACK_TRACE_TEMPLATE
22028f6c2f2SEnji Cooper                            ),
22128f6c2f2SEnji Cooper                            'type': '',
222b89a7cc2SEnji Cooper                        },
223b89a7cc2SEnji Cooper                        {
22428f6c2f2SEnji Cooper                            'failure': (
22528f6c2f2SEnji Cooper                                'gtest_xml_output_unittest_.cc:*\n'
22628f6c2f2SEnji Cooper                                'Expected equality of these values:\n'
22728f6c2f2SEnji Cooper                                '  2\n  3'
22828f6c2f2SEnji Cooper                                + STACK_TRACE_TEMPLATE
22928f6c2f2SEnji Cooper                            ),
23028f6c2f2SEnji Cooper                            'type': '',
23128f6c2f2SEnji Cooper                        },
23228f6c2f2SEnji Cooper                    ],
233b89a7cc2SEnji Cooper                },
234b89a7cc2SEnji Cooper                {
23528f6c2f2SEnji Cooper                    'name': 'DISABLED_test',
23628f6c2f2SEnji Cooper                    'file': 'gtest_xml_output_unittest_.cc',
23728f6c2f2SEnji Cooper                    'line': 98,
23828f6c2f2SEnji Cooper                    'status': 'NOTRUN',
23928f6c2f2SEnji Cooper                    'result': 'SUPPRESSED',
24028f6c2f2SEnji Cooper                    'time': '*',
24128f6c2f2SEnji Cooper                    'timestamp': '*',
24228f6c2f2SEnji Cooper                    'classname': 'MixedResultTest',
24328f6c2f2SEnji Cooper                },
24428f6c2f2SEnji Cooper            ],
245b89a7cc2SEnji Cooper        },
246b89a7cc2SEnji Cooper        {
24728f6c2f2SEnji Cooper            'name': 'XmlQuotingTest',
24828f6c2f2SEnji Cooper            'tests': 1,
24928f6c2f2SEnji Cooper            'failures': 1,
25028f6c2f2SEnji Cooper            'disabled': 0,
25128f6c2f2SEnji Cooper            'errors': 0,
25228f6c2f2SEnji Cooper            'time': '*',
25328f6c2f2SEnji Cooper            'timestamp': '*',
25428f6c2f2SEnji Cooper            'testsuite': [{
25528f6c2f2SEnji Cooper                'name': 'OutputsCData',
25628f6c2f2SEnji Cooper                'file': 'gtest_xml_output_unittest_.cc',
25728f6c2f2SEnji Cooper                'line': 102,
25828f6c2f2SEnji Cooper                'status': 'RUN',
25928f6c2f2SEnji Cooper                'result': 'COMPLETED',
26028f6c2f2SEnji Cooper                'time': '*',
26128f6c2f2SEnji Cooper                'timestamp': '*',
26228f6c2f2SEnji Cooper                'classname': 'XmlQuotingTest',
26328f6c2f2SEnji Cooper                'failures': [{
26428f6c2f2SEnji Cooper                    'failure': (
26528f6c2f2SEnji Cooper                        'gtest_xml_output_unittest_.cc:*\n'
26628f6c2f2SEnji Cooper                        'Failed\nXML output: <?xml encoding="utf-8">'
26728f6c2f2SEnji Cooper                        '<top><![CDATA[cdata text]]></top>'
26828f6c2f2SEnji Cooper                        + STACK_TRACE_TEMPLATE
26928f6c2f2SEnji Cooper                    ),
27028f6c2f2SEnji Cooper                    'type': '',
27128f6c2f2SEnji Cooper                }],
27228f6c2f2SEnji Cooper            }],
273b89a7cc2SEnji Cooper        },
274b89a7cc2SEnji Cooper        {
27528f6c2f2SEnji Cooper            'name': 'InvalidCharactersTest',
27628f6c2f2SEnji Cooper            'tests': 1,
27728f6c2f2SEnji Cooper            'failures': 1,
27828f6c2f2SEnji Cooper            'disabled': 0,
27928f6c2f2SEnji Cooper            'errors': 0,
28028f6c2f2SEnji Cooper            'time': '*',
28128f6c2f2SEnji Cooper            'timestamp': '*',
28228f6c2f2SEnji Cooper            'testsuite': [{
28328f6c2f2SEnji Cooper                'name': 'InvalidCharactersInMessage',
28428f6c2f2SEnji Cooper                'file': 'gtest_xml_output_unittest_.cc',
28528f6c2f2SEnji Cooper                'line': 109,
28628f6c2f2SEnji Cooper                'status': 'RUN',
28728f6c2f2SEnji Cooper                'result': 'COMPLETED',
28828f6c2f2SEnji Cooper                'time': '*',
28928f6c2f2SEnji Cooper                'timestamp': '*',
29028f6c2f2SEnji Cooper                'classname': 'InvalidCharactersTest',
29128f6c2f2SEnji Cooper                'failures': [{
29228f6c2f2SEnji Cooper                    'failure': (
29328f6c2f2SEnji Cooper                        'gtest_xml_output_unittest_.cc:*\n'
29428f6c2f2SEnji Cooper                        'Failed\nInvalid characters in brackets'
29528f6c2f2SEnji Cooper                        ' [\x01\x02]'
29628f6c2f2SEnji Cooper                        + STACK_TRACE_TEMPLATE
29728f6c2f2SEnji Cooper                    ),
29828f6c2f2SEnji Cooper                    'type': '',
29928f6c2f2SEnji Cooper                }],
30028f6c2f2SEnji Cooper            }],
301b89a7cc2SEnji Cooper        },
302b89a7cc2SEnji Cooper        {
30328f6c2f2SEnji Cooper            'name': 'PropertyRecordingTest',
30428f6c2f2SEnji Cooper            'tests': 4,
30528f6c2f2SEnji Cooper            'failures': 0,
30628f6c2f2SEnji Cooper            'disabled': 0,
30728f6c2f2SEnji Cooper            'errors': 0,
30828f6c2f2SEnji Cooper            'time': '*',
30928f6c2f2SEnji Cooper            'timestamp': '*',
31028f6c2f2SEnji Cooper            'SetUpTestSuite': 'yes',
31128f6c2f2SEnji Cooper            'TearDownTestSuite': 'aye',
31228f6c2f2SEnji Cooper            'testsuite': [
31328f6c2f2SEnji Cooper                {
31428f6c2f2SEnji Cooper                    'name': 'OneProperty',
31528f6c2f2SEnji Cooper                    'file': 'gtest_xml_output_unittest_.cc',
31628f6c2f2SEnji Cooper                    'line': 121,
31728f6c2f2SEnji Cooper                    'status': 'RUN',
31828f6c2f2SEnji Cooper                    'result': 'COMPLETED',
31928f6c2f2SEnji Cooper                    'time': '*',
32028f6c2f2SEnji Cooper                    'timestamp': '*',
32128f6c2f2SEnji Cooper                    'classname': 'PropertyRecordingTest',
32228f6c2f2SEnji Cooper                    'key_1': '1',
323b89a7cc2SEnji Cooper                },
324b89a7cc2SEnji Cooper                {
32528f6c2f2SEnji Cooper                    'name': 'IntValuedProperty',
32628f6c2f2SEnji Cooper                    'file': 'gtest_xml_output_unittest_.cc',
32728f6c2f2SEnji Cooper                    'line': 125,
32828f6c2f2SEnji Cooper                    'status': 'RUN',
32928f6c2f2SEnji Cooper                    'result': 'COMPLETED',
33028f6c2f2SEnji Cooper                    'time': '*',
33128f6c2f2SEnji Cooper                    'timestamp': '*',
33228f6c2f2SEnji Cooper                    'classname': 'PropertyRecordingTest',
33328f6c2f2SEnji Cooper                    'key_int': '1',
334b89a7cc2SEnji Cooper                },
335b89a7cc2SEnji Cooper                {
33628f6c2f2SEnji Cooper                    'name': 'ThreeProperties',
33728f6c2f2SEnji Cooper                    'file': 'gtest_xml_output_unittest_.cc',
33828f6c2f2SEnji Cooper                    'line': 129,
33928f6c2f2SEnji Cooper                    'status': 'RUN',
34028f6c2f2SEnji Cooper                    'result': 'COMPLETED',
34128f6c2f2SEnji Cooper                    'time': '*',
34228f6c2f2SEnji Cooper                    'timestamp': '*',
34328f6c2f2SEnji Cooper                    'classname': 'PropertyRecordingTest',
34428f6c2f2SEnji Cooper                    'key_1': '1',
34528f6c2f2SEnji Cooper                    'key_2': '2',
34628f6c2f2SEnji Cooper                    'key_3': '3',
347b89a7cc2SEnji Cooper                },
348b89a7cc2SEnji Cooper                {
34928f6c2f2SEnji Cooper                    'name': 'TwoValuesForOneKeyUsesLastValue',
35028f6c2f2SEnji Cooper                    'file': 'gtest_xml_output_unittest_.cc',
35128f6c2f2SEnji Cooper                    'line': 135,
35228f6c2f2SEnji Cooper                    'status': 'RUN',
35328f6c2f2SEnji Cooper                    'result': 'COMPLETED',
35428f6c2f2SEnji Cooper                    'time': '*',
35528f6c2f2SEnji Cooper                    'timestamp': '*',
35628f6c2f2SEnji Cooper                    'classname': 'PropertyRecordingTest',
35728f6c2f2SEnji Cooper                    'key_1': '2',
35828f6c2f2SEnji Cooper                },
35928f6c2f2SEnji Cooper            ],
360b89a7cc2SEnji Cooper        },
361b89a7cc2SEnji Cooper        {
36228f6c2f2SEnji Cooper            'name': 'NoFixtureTest',
36328f6c2f2SEnji Cooper            'tests': 3,
36428f6c2f2SEnji Cooper            'failures': 0,
36528f6c2f2SEnji Cooper            'disabled': 0,
36628f6c2f2SEnji Cooper            'errors': 0,
36728f6c2f2SEnji Cooper            'time': '*',
36828f6c2f2SEnji Cooper            'timestamp': '*',
36928f6c2f2SEnji Cooper            'testsuite': [
370b89a7cc2SEnji Cooper                {
37128f6c2f2SEnji Cooper                    'name': 'RecordProperty',
37228f6c2f2SEnji Cooper                    'file': 'gtest_xml_output_unittest_.cc',
37328f6c2f2SEnji Cooper                    'line': 140,
37428f6c2f2SEnji Cooper                    'status': 'RUN',
37528f6c2f2SEnji Cooper                    'result': 'COMPLETED',
37628f6c2f2SEnji Cooper                    'time': '*',
37728f6c2f2SEnji Cooper                    'timestamp': '*',
37828f6c2f2SEnji Cooper                    'classname': 'NoFixtureTest',
37928f6c2f2SEnji Cooper                    'key': '1',
380b89a7cc2SEnji Cooper                },
381b89a7cc2SEnji Cooper                {
38228f6c2f2SEnji Cooper                    'name': 'ExternalUtilityThatCallsRecordIntValuedProperty',
38328f6c2f2SEnji Cooper                    'file': 'gtest_xml_output_unittest_.cc',
38428f6c2f2SEnji Cooper                    'line': 153,
38528f6c2f2SEnji Cooper                    'status': 'RUN',
38628f6c2f2SEnji Cooper                    'result': 'COMPLETED',
38728f6c2f2SEnji Cooper                    'time': '*',
38828f6c2f2SEnji Cooper                    'timestamp': '*',
38928f6c2f2SEnji Cooper                    'classname': 'NoFixtureTest',
39028f6c2f2SEnji Cooper                    'key_for_utility_int': '1',
391b89a7cc2SEnji Cooper                },
392b89a7cc2SEnji Cooper                {
39328f6c2f2SEnji Cooper                    'name': (
39428f6c2f2SEnji Cooper                        'ExternalUtilityThatCallsRecordStringValuedProperty'
39528f6c2f2SEnji Cooper                    ),
39628f6c2f2SEnji Cooper                    'file': 'gtest_xml_output_unittest_.cc',
39728f6c2f2SEnji Cooper                    'line': 157,
39828f6c2f2SEnji Cooper                    'status': 'RUN',
39928f6c2f2SEnji Cooper                    'result': 'COMPLETED',
40028f6c2f2SEnji Cooper                    'time': '*',
40128f6c2f2SEnji Cooper                    'timestamp': '*',
40228f6c2f2SEnji Cooper                    'classname': 'NoFixtureTest',
40328f6c2f2SEnji Cooper                    'key_for_utility_string': '1',
40428f6c2f2SEnji Cooper                },
40528f6c2f2SEnji Cooper            ],
406b89a7cc2SEnji Cooper        },
407b89a7cc2SEnji Cooper        {
40828f6c2f2SEnji Cooper            'name': 'TypedTest/0',
40928f6c2f2SEnji Cooper            'tests': 1,
41028f6c2f2SEnji Cooper            'failures': 0,
41128f6c2f2SEnji Cooper            'disabled': 0,
41228f6c2f2SEnji Cooper            'errors': 0,
41328f6c2f2SEnji Cooper            'time': '*',
41428f6c2f2SEnji Cooper            'timestamp': '*',
41528f6c2f2SEnji Cooper            'testsuite': [{
41628f6c2f2SEnji Cooper                'name': 'HasTypeParamAttribute',
41728f6c2f2SEnji Cooper                'type_param': 'int',
41828f6c2f2SEnji Cooper                'file': 'gtest_xml_output_unittest_.cc',
41928f6c2f2SEnji Cooper                'line': 173,
42028f6c2f2SEnji Cooper                'status': 'RUN',
42128f6c2f2SEnji Cooper                'result': 'COMPLETED',
42228f6c2f2SEnji Cooper                'time': '*',
42328f6c2f2SEnji Cooper                'timestamp': '*',
42428f6c2f2SEnji Cooper                'classname': 'TypedTest/0',
42528f6c2f2SEnji Cooper            }],
426b89a7cc2SEnji Cooper        },
427b89a7cc2SEnji Cooper        {
42828f6c2f2SEnji Cooper            'name': 'TypedTest/1',
42928f6c2f2SEnji Cooper            'tests': 1,
43028f6c2f2SEnji Cooper            'failures': 0,
43128f6c2f2SEnji Cooper            'disabled': 0,
43228f6c2f2SEnji Cooper            'errors': 0,
43328f6c2f2SEnji Cooper            'time': '*',
43428f6c2f2SEnji Cooper            'timestamp': '*',
43528f6c2f2SEnji Cooper            'testsuite': [{
43628f6c2f2SEnji Cooper                'name': 'HasTypeParamAttribute',
43728f6c2f2SEnji Cooper                'type_param': 'long',
43828f6c2f2SEnji Cooper                'file': 'gtest_xml_output_unittest_.cc',
43928f6c2f2SEnji Cooper                'line': 173,
44028f6c2f2SEnji Cooper                'status': 'RUN',
44128f6c2f2SEnji Cooper                'result': 'COMPLETED',
44228f6c2f2SEnji Cooper                'time': '*',
44328f6c2f2SEnji Cooper                'timestamp': '*',
44428f6c2f2SEnji Cooper                'classname': 'TypedTest/1',
44528f6c2f2SEnji Cooper            }],
446b89a7cc2SEnji Cooper        },
447b89a7cc2SEnji Cooper        {
44828f6c2f2SEnji Cooper            'name': 'Single/TypeParameterizedTestSuite/0',
44928f6c2f2SEnji Cooper            'tests': 1,
45028f6c2f2SEnji Cooper            'failures': 0,
45128f6c2f2SEnji Cooper            'disabled': 0,
45228f6c2f2SEnji Cooper            'errors': 0,
45328f6c2f2SEnji Cooper            'time': '*',
45428f6c2f2SEnji Cooper            'timestamp': '*',
45528f6c2f2SEnji Cooper            'testsuite': [{
45628f6c2f2SEnji Cooper                'name': 'HasTypeParamAttribute',
45728f6c2f2SEnji Cooper                'type_param': 'int',
45828f6c2f2SEnji Cooper                'file': 'gtest_xml_output_unittest_.cc',
45928f6c2f2SEnji Cooper                'line': 180,
46028f6c2f2SEnji Cooper                'status': 'RUN',
46128f6c2f2SEnji Cooper                'result': 'COMPLETED',
46228f6c2f2SEnji Cooper                'time': '*',
46328f6c2f2SEnji Cooper                'timestamp': '*',
46428f6c2f2SEnji Cooper                'classname': 'Single/TypeParameterizedTestSuite/0',
46528f6c2f2SEnji Cooper            }],
466b89a7cc2SEnji Cooper        },
467b89a7cc2SEnji Cooper        {
46828f6c2f2SEnji Cooper            'name': 'Single/TypeParameterizedTestSuite/1',
46928f6c2f2SEnji Cooper            'tests': 1,
47028f6c2f2SEnji Cooper            'failures': 0,
47128f6c2f2SEnji Cooper            'disabled': 0,
47228f6c2f2SEnji Cooper            'errors': 0,
47328f6c2f2SEnji Cooper            'time': '*',
47428f6c2f2SEnji Cooper            'timestamp': '*',
47528f6c2f2SEnji Cooper            'testsuite': [{
47628f6c2f2SEnji Cooper                'name': 'HasTypeParamAttribute',
47728f6c2f2SEnji Cooper                'type_param': 'long',
47828f6c2f2SEnji Cooper                'file': 'gtest_xml_output_unittest_.cc',
47928f6c2f2SEnji Cooper                'line': 180,
48028f6c2f2SEnji Cooper                'status': 'RUN',
48128f6c2f2SEnji Cooper                'result': 'COMPLETED',
48228f6c2f2SEnji Cooper                'time': '*',
48328f6c2f2SEnji Cooper                'timestamp': '*',
48428f6c2f2SEnji Cooper                'classname': 'Single/TypeParameterizedTestSuite/1',
48528f6c2f2SEnji Cooper            }],
486b89a7cc2SEnji Cooper        },
487b89a7cc2SEnji Cooper        {
48828f6c2f2SEnji Cooper            'name': 'Single/ValueParamTest',
48928f6c2f2SEnji Cooper            'tests': 4,
49028f6c2f2SEnji Cooper            'failures': 0,
49128f6c2f2SEnji Cooper            'disabled': 0,
49228f6c2f2SEnji Cooper            'errors': 0,
49328f6c2f2SEnji Cooper            'time': '*',
49428f6c2f2SEnji Cooper            'timestamp': '*',
49528f6c2f2SEnji Cooper            'testsuite': [
49628f6c2f2SEnji Cooper                {
49728f6c2f2SEnji Cooper                    'name': 'HasValueParamAttribute/0',
49828f6c2f2SEnji Cooper                    'value_param': '33',
49928f6c2f2SEnji Cooper                    'file': 'gtest_xml_output_unittest_.cc',
50028f6c2f2SEnji Cooper                    'line': 164,
50128f6c2f2SEnji Cooper                    'status': 'RUN',
50228f6c2f2SEnji Cooper                    'result': 'COMPLETED',
50328f6c2f2SEnji Cooper                    'time': '*',
50428f6c2f2SEnji Cooper                    'timestamp': '*',
50528f6c2f2SEnji Cooper                    'classname': 'Single/ValueParamTest',
50628f6c2f2SEnji Cooper                },
50728f6c2f2SEnji Cooper                {
50828f6c2f2SEnji Cooper                    'name': 'HasValueParamAttribute/1',
50928f6c2f2SEnji Cooper                    'value_param': '42',
51028f6c2f2SEnji Cooper                    'file': 'gtest_xml_output_unittest_.cc',
51128f6c2f2SEnji Cooper                    'line': 164,
51228f6c2f2SEnji Cooper                    'status': 'RUN',
51328f6c2f2SEnji Cooper                    'result': 'COMPLETED',
51428f6c2f2SEnji Cooper                    'time': '*',
51528f6c2f2SEnji Cooper                    'timestamp': '*',
51628f6c2f2SEnji Cooper                    'classname': 'Single/ValueParamTest',
51728f6c2f2SEnji Cooper                },
51828f6c2f2SEnji Cooper                {
51928f6c2f2SEnji Cooper                    'name': 'AnotherTestThatHasValueParamAttribute/0',
52028f6c2f2SEnji Cooper                    'value_param': '33',
52128f6c2f2SEnji Cooper                    'file': 'gtest_xml_output_unittest_.cc',
52228f6c2f2SEnji Cooper                    'line': 165,
52328f6c2f2SEnji Cooper                    'status': 'RUN',
52428f6c2f2SEnji Cooper                    'result': 'COMPLETED',
52528f6c2f2SEnji Cooper                    'time': '*',
52628f6c2f2SEnji Cooper                    'timestamp': '*',
52728f6c2f2SEnji Cooper                    'classname': 'Single/ValueParamTest',
52828f6c2f2SEnji Cooper                },
52928f6c2f2SEnji Cooper                {
53028f6c2f2SEnji Cooper                    'name': 'AnotherTestThatHasValueParamAttribute/1',
53128f6c2f2SEnji Cooper                    'value_param': '42',
53228f6c2f2SEnji Cooper                    'file': 'gtest_xml_output_unittest_.cc',
53328f6c2f2SEnji Cooper                    'line': 165,
53428f6c2f2SEnji Cooper                    'status': 'RUN',
53528f6c2f2SEnji Cooper                    'result': 'COMPLETED',
53628f6c2f2SEnji Cooper                    'time': '*',
53728f6c2f2SEnji Cooper                    'timestamp': '*',
53828f6c2f2SEnji Cooper                    'classname': 'Single/ValueParamTest',
53928f6c2f2SEnji Cooper                },
54028f6c2f2SEnji Cooper            ],
54128f6c2f2SEnji Cooper        },
54228f6c2f2SEnji Cooper    ],
543b89a7cc2SEnji Cooper}
544b89a7cc2SEnji Cooper
545b89a7cc2SEnji CooperEXPECTED_FILTERED = {
54628f6c2f2SEnji Cooper    'tests': 1,
54728f6c2f2SEnji Cooper    'failures': 0,
54828f6c2f2SEnji Cooper    'disabled': 0,
54928f6c2f2SEnji Cooper    'errors': 0,
55028f6c2f2SEnji Cooper    'time': '*',
55128f6c2f2SEnji Cooper    'timestamp': '*',
55228f6c2f2SEnji Cooper    'name': 'AllTests',
55328f6c2f2SEnji Cooper    'ad_hoc_property': '42',
55428f6c2f2SEnji Cooper    'testsuites': [{
55528f6c2f2SEnji Cooper        'name': 'SuccessfulTest',
55628f6c2f2SEnji Cooper        'tests': 1,
55728f6c2f2SEnji Cooper        'failures': 0,
55828f6c2f2SEnji Cooper        'disabled': 0,
55928f6c2f2SEnji Cooper        'errors': 0,
56028f6c2f2SEnji Cooper        'time': '*',
56128f6c2f2SEnji Cooper        'timestamp': '*',
56228f6c2f2SEnji Cooper        'testsuite': [{
56328f6c2f2SEnji Cooper            'name': 'Succeeds',
56428f6c2f2SEnji Cooper            'file': 'gtest_xml_output_unittest_.cc',
56528f6c2f2SEnji Cooper            'line': 53,
56628f6c2f2SEnji Cooper            'status': 'RUN',
56728f6c2f2SEnji Cooper            'result': 'COMPLETED',
56828f6c2f2SEnji Cooper            'time': '*',
56928f6c2f2SEnji Cooper            'timestamp': '*',
57028f6c2f2SEnji Cooper            'classname': 'SuccessfulTest',
57128f6c2f2SEnji Cooper        }],
572b89a7cc2SEnji Cooper    }],
573b89a7cc2SEnji Cooper}
574b89a7cc2SEnji Cooper
57528f6c2f2SEnji CooperEXPECTED_NO_TEST = {
57628f6c2f2SEnji Cooper    'tests': 0,
57728f6c2f2SEnji Cooper    'failures': 0,
57828f6c2f2SEnji Cooper    'disabled': 0,
57928f6c2f2SEnji Cooper    'errors': 0,
58028f6c2f2SEnji Cooper    'time': '*',
58128f6c2f2SEnji Cooper    'timestamp': '*',
58228f6c2f2SEnji Cooper    'name': 'AllTests',
58328f6c2f2SEnji Cooper    'testsuites': [{
58428f6c2f2SEnji Cooper        'name': 'NonTestSuiteFailure',
58528f6c2f2SEnji Cooper        'tests': 1,
58628f6c2f2SEnji Cooper        'failures': 1,
58728f6c2f2SEnji Cooper        'disabled': 0,
58828f6c2f2SEnji Cooper        'skipped': 0,
58928f6c2f2SEnji Cooper        'errors': 0,
59028f6c2f2SEnji Cooper        'time': '*',
59128f6c2f2SEnji Cooper        'timestamp': '*',
59228f6c2f2SEnji Cooper        'testsuite': [{
59328f6c2f2SEnji Cooper            'name': '',
59428f6c2f2SEnji Cooper            'status': 'RUN',
59528f6c2f2SEnji Cooper            'result': 'COMPLETED',
59628f6c2f2SEnji Cooper            'time': '*',
59728f6c2f2SEnji Cooper            'timestamp': '*',
59828f6c2f2SEnji Cooper            'classname': '',
59928f6c2f2SEnji Cooper            'failures': [{
60028f6c2f2SEnji Cooper                'failure': (
60128f6c2f2SEnji Cooper                    'gtest_no_test_unittest.cc:*\n'
60228f6c2f2SEnji Cooper                    'Expected equality of these values:\n'
60328f6c2f2SEnji Cooper                    '  1\n  2'
60428f6c2f2SEnji Cooper                    + STACK_TRACE_TEMPLATE
60528f6c2f2SEnji Cooper                ),
60628f6c2f2SEnji Cooper                'type': '',
60728f6c2f2SEnji Cooper            }],
60828f6c2f2SEnji Cooper        }],
60928f6c2f2SEnji Cooper    }],
610b89a7cc2SEnji Cooper}
611b89a7cc2SEnji Cooper
612b89a7cc2SEnji CooperGTEST_PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath(GTEST_PROGRAM_NAME)
613b89a7cc2SEnji Cooper
61428f6c2f2SEnji CooperSUPPORTS_TYPED_TESTS = (
61528f6c2f2SEnji Cooper    'TypedTest'
61628f6c2f2SEnji Cooper    in gtest_test_utils.Subprocess(
61728f6c2f2SEnji Cooper        [GTEST_PROGRAM_PATH, GTEST_LIST_TESTS_FLAG], capture_stderr=False
61828f6c2f2SEnji Cooper    ).output
61928f6c2f2SEnji Cooper)
620b89a7cc2SEnji Cooper
621b89a7cc2SEnji Cooper
622b89a7cc2SEnji Cooperclass GTestJsonOutputUnitTest(gtest_test_utils.TestCase):
62328f6c2f2SEnji Cooper  """Unit test for Google Test's JSON output functionality."""
624b89a7cc2SEnji Cooper
625b89a7cc2SEnji Cooper  # This test currently breaks on platforms that do not support typed and
626b89a7cc2SEnji Cooper  # type-parameterized tests, so we don't run it under them.
627b89a7cc2SEnji Cooper  if SUPPORTS_TYPED_TESTS:
628b89a7cc2SEnji Cooper
629b89a7cc2SEnji Cooper    def testNonEmptyJsonOutput(self):
630b89a7cc2SEnji Cooper      """Verifies JSON output for a Google Test binary with non-empty output.
631b89a7cc2SEnji Cooper
632b89a7cc2SEnji Cooper      Runs a test program that generates a non-empty JSON output, and
633b89a7cc2SEnji Cooper      tests that the JSON output is expected.
634b89a7cc2SEnji Cooper      """
635b89a7cc2SEnji Cooper      self._TestJsonOutput(GTEST_PROGRAM_NAME, EXPECTED_NON_EMPTY, 1)
636b89a7cc2SEnji Cooper
63728f6c2f2SEnji Cooper  def testNoTestJsonOutput(self):
638b89a7cc2SEnji Cooper    """Verifies JSON output for a Google Test binary without actual tests.
639b89a7cc2SEnji Cooper
64028f6c2f2SEnji Cooper    Runs a test program that generates an JSON output for a binary with no
64128f6c2f2SEnji Cooper    tests, and tests that the JSON output is expected.
642b89a7cc2SEnji Cooper    """
643b89a7cc2SEnji Cooper
64428f6c2f2SEnji Cooper    self._TestJsonOutput('gtest_no_test_unittest', EXPECTED_NO_TEST, 0)
645b89a7cc2SEnji Cooper
646b89a7cc2SEnji Cooper  def testTimestampValue(self):
647b89a7cc2SEnji Cooper    """Checks whether the timestamp attribute in the JSON output is valid.
648b89a7cc2SEnji Cooper
649b89a7cc2SEnji Cooper    Runs a test program that generates an empty JSON output, and checks if
650b89a7cc2SEnji Cooper    the timestamp attribute in the testsuites tag is valid.
651b89a7cc2SEnji Cooper    """
652b89a7cc2SEnji Cooper    actual = self._GetJsonOutput('gtest_no_test_unittest', [], 0)
653b89a7cc2SEnji Cooper    date_time_str = actual['timestamp']
654b89a7cc2SEnji Cooper    # datetime.strptime() is only available in Python 2.5+ so we have to
655b89a7cc2SEnji Cooper    # parse the expected datetime manually.
656b89a7cc2SEnji Cooper    match = re.match(r'(\d+)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)', date_time_str)
657b89a7cc2SEnji Cooper    self.assertTrue(
658b89a7cc2SEnji Cooper        re.match,
65928f6c2f2SEnji Cooper        'JSON datettime string %s has incorrect format' % date_time_str,
66028f6c2f2SEnji Cooper    )
661b89a7cc2SEnji Cooper    date_time_from_json = datetime.datetime(
66228f6c2f2SEnji Cooper        year=int(match.group(1)),
66328f6c2f2SEnji Cooper        month=int(match.group(2)),
66428f6c2f2SEnji Cooper        day=int(match.group(3)),
66528f6c2f2SEnji Cooper        hour=int(match.group(4)),
66628f6c2f2SEnji Cooper        minute=int(match.group(5)),
66728f6c2f2SEnji Cooper        second=int(match.group(6)),
66828f6c2f2SEnji Cooper    )
669b89a7cc2SEnji Cooper
670b89a7cc2SEnji Cooper    time_delta = abs(datetime.datetime.now() - date_time_from_json)
671b89a7cc2SEnji Cooper    # timestamp value should be near the current local time
67228f6c2f2SEnji Cooper    self.assertTrue(
67328f6c2f2SEnji Cooper        time_delta < datetime.timedelta(seconds=600),
67428f6c2f2SEnji Cooper        'time_delta is %s' % time_delta,
67528f6c2f2SEnji Cooper    )
676b89a7cc2SEnji Cooper
677b89a7cc2SEnji Cooper  def testDefaultOutputFile(self):
678b89a7cc2SEnji Cooper    """Verifies the default output file name.
679b89a7cc2SEnji Cooper
680b89a7cc2SEnji Cooper    Confirms that Google Test produces an JSON output file with the expected
681b89a7cc2SEnji Cooper    default name if no name is explicitly specified.
682b89a7cc2SEnji Cooper    """
68328f6c2f2SEnji Cooper    output_file = os.path.join(
68428f6c2f2SEnji Cooper        gtest_test_utils.GetTempDir(), GTEST_DEFAULT_OUTPUT_FILE
68528f6c2f2SEnji Cooper    )
686b89a7cc2SEnji Cooper    gtest_prog_path = gtest_test_utils.GetTestExecutablePath(
68728f6c2f2SEnji Cooper        'gtest_no_test_unittest'
68828f6c2f2SEnji Cooper    )
689b89a7cc2SEnji Cooper    try:
690b89a7cc2SEnji Cooper      os.remove(output_file)
691b89a7cc2SEnji Cooper    except OSError:
692b89a7cc2SEnji Cooper      e = sys.exc_info()[1]
693b89a7cc2SEnji Cooper      if e.errno != errno.ENOENT:
694b89a7cc2SEnji Cooper        raise
695b89a7cc2SEnji Cooper
696b89a7cc2SEnji Cooper    p = gtest_test_utils.Subprocess(
697b89a7cc2SEnji Cooper        [gtest_prog_path, '%s=json' % GTEST_OUTPUT_FLAG],
69828f6c2f2SEnji Cooper        working_dir=gtest_test_utils.GetTempDir(),
69928f6c2f2SEnji Cooper    )
70028f6c2f2SEnji Cooper    self.assertTrue(p.exited)
70128f6c2f2SEnji Cooper    self.assertEqual(0, p.exit_code)
70228f6c2f2SEnji Cooper    self.assertTrue(os.path.isfile(output_file))
703b89a7cc2SEnji Cooper
704b89a7cc2SEnji Cooper  def testSuppressedJsonOutput(self):
705b89a7cc2SEnji Cooper    """Verifies that no JSON output is generated.
706b89a7cc2SEnji Cooper
707b89a7cc2SEnji Cooper    Tests that no JSON file is generated if the default JSON listener is
708b89a7cc2SEnji Cooper    shut down before RUN_ALL_TESTS is invoked.
709b89a7cc2SEnji Cooper    """
710b89a7cc2SEnji Cooper
71128f6c2f2SEnji Cooper    json_path = os.path.join(
71228f6c2f2SEnji Cooper        gtest_test_utils.GetTempDir(), GTEST_PROGRAM_NAME + 'out.json'
71328f6c2f2SEnji Cooper    )
714b89a7cc2SEnji Cooper    if os.path.isfile(json_path):
715b89a7cc2SEnji Cooper      os.remove(json_path)
716b89a7cc2SEnji Cooper
71728f6c2f2SEnji Cooper    command = [
71828f6c2f2SEnji Cooper        GTEST_PROGRAM_PATH,
719b89a7cc2SEnji Cooper        '%s=json:%s' % (GTEST_OUTPUT_FLAG, json_path),
72028f6c2f2SEnji Cooper        '--shut_down_xml',
72128f6c2f2SEnji Cooper    ]
722b89a7cc2SEnji Cooper    p = gtest_test_utils.Subprocess(command)
723b89a7cc2SEnji Cooper    if p.terminated_by_signal:
724b89a7cc2SEnji Cooper      # p.signal is available only if p.terminated_by_signal is True.
725b89a7cc2SEnji Cooper      self.assertFalse(
726b89a7cc2SEnji Cooper          p.terminated_by_signal,
72728f6c2f2SEnji Cooper          '%s was killed by signal %d' % (GTEST_PROGRAM_NAME, p.signal),
72828f6c2f2SEnji Cooper      )
729b89a7cc2SEnji Cooper    else:
73028f6c2f2SEnji Cooper      self.assertTrue(p.exited)
73128f6c2f2SEnji Cooper      self.assertEqual(
73228f6c2f2SEnji Cooper          1,
73328f6c2f2SEnji Cooper          p.exit_code,
734b89a7cc2SEnji Cooper          "'%s' exited with code %s, which doesn't match "
73528f6c2f2SEnji Cooper          'the expected exit code %s.' % (command, p.exit_code, 1),
73628f6c2f2SEnji Cooper      )
737b89a7cc2SEnji Cooper
73828f6c2f2SEnji Cooper    self.assertTrue(not os.path.isfile(json_path))
739b89a7cc2SEnji Cooper
740b89a7cc2SEnji Cooper  def testFilteredTestJsonOutput(self):
741b89a7cc2SEnji Cooper    """Verifies JSON output when a filter is applied.
742b89a7cc2SEnji Cooper
743b89a7cc2SEnji Cooper    Runs a test program that executes only some tests and verifies that
744b89a7cc2SEnji Cooper    non-selected tests do not show up in the JSON output.
745b89a7cc2SEnji Cooper    """
746b89a7cc2SEnji Cooper
74728f6c2f2SEnji Cooper    self._TestJsonOutput(
74828f6c2f2SEnji Cooper        GTEST_PROGRAM_NAME,
74928f6c2f2SEnji Cooper        EXPECTED_FILTERED,
75028f6c2f2SEnji Cooper        0,
75128f6c2f2SEnji Cooper        extra_args=['%s=SuccessfulTest.*' % GTEST_FILTER_FLAG],
75228f6c2f2SEnji Cooper    )
753b89a7cc2SEnji Cooper
754b89a7cc2SEnji Cooper  def _GetJsonOutput(self, gtest_prog_name, extra_args, expected_exit_code):
755b89a7cc2SEnji Cooper    """Returns the JSON output generated by running the program gtest_prog_name.
756b89a7cc2SEnji Cooper
757b89a7cc2SEnji Cooper    Furthermore, the program's exit code must be expected_exit_code.
758b89a7cc2SEnji Cooper
759b89a7cc2SEnji Cooper    Args:
760b89a7cc2SEnji Cooper      gtest_prog_name: Google Test binary name.
761b89a7cc2SEnji Cooper      extra_args: extra arguments to binary invocation.
762b89a7cc2SEnji Cooper      expected_exit_code: program's exit code.
763b89a7cc2SEnji Cooper    """
76428f6c2f2SEnji Cooper    json_path = os.path.join(
76528f6c2f2SEnji Cooper        gtest_test_utils.GetTempDir(), gtest_prog_name + 'out.json'
76628f6c2f2SEnji Cooper    )
767b89a7cc2SEnji Cooper    gtest_prog_path = gtest_test_utils.GetTestExecutablePath(gtest_prog_name)
768b89a7cc2SEnji Cooper
76928f6c2f2SEnji Cooper    command = [
77028f6c2f2SEnji Cooper        gtest_prog_path,
77128f6c2f2SEnji Cooper        '%s=json:%s' % (GTEST_OUTPUT_FLAG, json_path),
77228f6c2f2SEnji Cooper    ] + extra_args
773b89a7cc2SEnji Cooper    p = gtest_test_utils.Subprocess(command)
774b89a7cc2SEnji Cooper    if p.terminated_by_signal:
77528f6c2f2SEnji Cooper      self.assertTrue(
77628f6c2f2SEnji Cooper          False, '%s was killed by signal %d' % (gtest_prog_name, p.signal)
77728f6c2f2SEnji Cooper      )
778b89a7cc2SEnji Cooper    else:
77928f6c2f2SEnji Cooper      self.assertTrue(p.exited)
78028f6c2f2SEnji Cooper      self.assertEqual(
78128f6c2f2SEnji Cooper          expected_exit_code,
78228f6c2f2SEnji Cooper          p.exit_code,
783b89a7cc2SEnji Cooper          "'%s' exited with code %s, which doesn't match "
784b89a7cc2SEnji Cooper          'the expected exit code %s.'
78528f6c2f2SEnji Cooper          % (command, p.exit_code, expected_exit_code),
78628f6c2f2SEnji Cooper      )
787b89a7cc2SEnji Cooper    with open(json_path) as f:
788b89a7cc2SEnji Cooper      actual = json.load(f)
789b89a7cc2SEnji Cooper    return actual
790b89a7cc2SEnji Cooper
79128f6c2f2SEnji Cooper  def _TestJsonOutput(
79228f6c2f2SEnji Cooper      self, gtest_prog_name, expected, expected_exit_code, extra_args=None
79328f6c2f2SEnji Cooper  ):
794b89a7cc2SEnji Cooper    """Checks the JSON output generated by the Google Test binary.
795b89a7cc2SEnji Cooper
796b89a7cc2SEnji Cooper    Asserts that the JSON document generated by running the program
797b89a7cc2SEnji Cooper    gtest_prog_name matches expected_json, a string containing another
798b89a7cc2SEnji Cooper    JSON document.  Furthermore, the program's exit code must be
799b89a7cc2SEnji Cooper    expected_exit_code.
800b89a7cc2SEnji Cooper
801b89a7cc2SEnji Cooper    Args:
802b89a7cc2SEnji Cooper      gtest_prog_name: Google Test binary name.
803b89a7cc2SEnji Cooper      expected: expected output.
804b89a7cc2SEnji Cooper      expected_exit_code: program's exit code.
805b89a7cc2SEnji Cooper      extra_args: extra arguments to binary invocation.
806b89a7cc2SEnji Cooper    """
807b89a7cc2SEnji Cooper
80828f6c2f2SEnji Cooper    actual = self._GetJsonOutput(
80928f6c2f2SEnji Cooper        gtest_prog_name, extra_args or [], expected_exit_code
81028f6c2f2SEnji Cooper    )
811b89a7cc2SEnji Cooper    self.assertEqual(expected, gtest_json_test_utils.normalize(actual))
812b89a7cc2SEnji Cooper
813b89a7cc2SEnji Cooper
814b89a7cc2SEnji Cooperif __name__ == '__main__':
815b89a7cc2SEnji Cooper  if NO_STACKTRACE_SUPPORT_FLAG in sys.argv:
816b89a7cc2SEnji Cooper    # unittest.main() can't handle unknown flags
817b89a7cc2SEnji Cooper    sys.argv.remove(NO_STACKTRACE_SUPPORT_FLAG)
818b89a7cc2SEnji Cooper
819b89a7cc2SEnji Cooper  os.environ['GTEST_STACK_TRACE_DEPTH'] = '1'
820b89a7cc2SEnji Cooper  gtest_test_utils.Main()
821