• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2# Copyright 2018, Google Inc.
3# All rights reserved.
4#
5# Redistribution and use in source and binary forms, with or without
6# modification, are permitted provided that the following conditions are
7# met:
8#
9#     * Redistributions of source code must retain the above copyright
10# notice, this list of conditions and the following disclaimer.
11#     * Redistributions in binary form must reproduce the above
12# copyright notice, this list of conditions and the following disclaimer
13# in the documentation and/or other materials provided with the
14# distribution.
15#     * Neither the name of Google Inc. nor the names of its
16# contributors may be used to endorse or promote products derived from
17# this software without specific prior written permission.
18#
19# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31"""Unit test for the gtest_json_output module."""
32
33import datetime
34import errno
35import json
36import os
37import re
38import sys
39
40from googletest.test import gtest_json_test_utils
41from googletest.test import gtest_test_utils
42
43GTEST_FILTER_FLAG = '--gtest_filter'
44GTEST_LIST_TESTS_FLAG = '--gtest_list_tests'
45GTEST_OUTPUT_FLAG = '--gtest_output'
46GTEST_DEFAULT_OUTPUT_FILE = 'test_detail.json'
47GTEST_PROGRAM_NAME = 'gtest_xml_output_unittest_'
48
49# The flag indicating stacktraces are not supported
50NO_STACKTRACE_SUPPORT_FLAG = '--no_stacktrace_support'
51
52SUPPORTS_STACK_TRACES = NO_STACKTRACE_SUPPORT_FLAG not in sys.argv
53
54if SUPPORTS_STACK_TRACES:
55  STACK_TRACE_TEMPLATE = '\nStack trace:\n*'
56else:
57  STACK_TRACE_TEMPLATE = '\n'
58
59EXPECTED_NON_EMPTY = {
60    'tests': 26,
61    'failures': 5,
62    'disabled': 2,
63    'errors': 0,
64    'timestamp': '*',
65    'time': '*',
66    'ad_hoc_property': '42',
67    'name': 'AllTests',
68    'testsuites': [
69        {
70            'name': 'SuccessfulTest',
71            'tests': 1,
72            'failures': 0,
73            'disabled': 0,
74            'errors': 0,
75            'time': '*',
76            'timestamp': '*',
77            'testsuite': [{
78                'name': 'Succeeds',
79                'file': 'gtest_xml_output_unittest_.cc',
80                'line': 53,
81                'status': 'RUN',
82                'result': 'COMPLETED',
83                'time': '*',
84                'timestamp': '*',
85                'classname': 'SuccessfulTest',
86            }],
87        },
88        {
89            'name': 'FailedTest',
90            'tests': 1,
91            'failures': 1,
92            'disabled': 0,
93            'errors': 0,
94            'time': '*',
95            'timestamp': '*',
96            'testsuite': [{
97                'name': 'Fails',
98                'file': 'gtest_xml_output_unittest_.cc',
99                'line': 61,
100                'status': 'RUN',
101                'result': 'COMPLETED',
102                'time': '*',
103                'timestamp': '*',
104                'classname': 'FailedTest',
105                'failures': [{
106                    'failure': (
107                        'gtest_xml_output_unittest_.cc:*\n'
108                        'Expected equality of these values:\n'
109                        '  1\n  2'
110                        + STACK_TRACE_TEMPLATE
111                    ),
112                    'type': '',
113                }],
114            }],
115        },
116        {
117            'name': 'DisabledTest',
118            'tests': 1,
119            'failures': 0,
120            'disabled': 1,
121            'errors': 0,
122            'time': '*',
123            'timestamp': '*',
124            'testsuite': [{
125                'name': 'DISABLED_test_not_run',
126                'file': 'gtest_xml_output_unittest_.cc',
127                'line': 68,
128                'status': 'NOTRUN',
129                'result': 'SUPPRESSED',
130                'time': '*',
131                'timestamp': '*',
132                'classname': 'DisabledTest',
133            }],
134        },
135        {
136            'name': 'SkippedTest',
137            'tests': 3,
138            'failures': 1,
139            'disabled': 0,
140            'errors': 0,
141            'time': '*',
142            'timestamp': '*',
143            'testsuite': [
144                {
145                    'name': 'Skipped',
146                    'file': 'gtest_xml_output_unittest_.cc',
147                    'line': 75,
148                    'status': 'RUN',
149                    'result': 'SKIPPED',
150                    'time': '*',
151                    'timestamp': '*',
152                    'classname': 'SkippedTest',
153                    'skipped': [
154                        {'message': 'gtest_xml_output_unittest_.cc:*\n\n'}
155                    ],
156                },
157                {
158                    'name': 'SkippedWithMessage',
159                    'file': 'gtest_xml_output_unittest_.cc',
160                    'line': 79,
161                    'status': 'RUN',
162                    'result': 'SKIPPED',
163                    'time': '*',
164                    'timestamp': '*',
165                    'classname': 'SkippedTest',
166                    'skipped': [{
167                        'message': (
168                            'gtest_xml_output_unittest_.cc:*\n'
169                            'It is good practice to tell why you skip a test.\n'
170                        )
171                    }],
172                },
173                {
174                    'name': 'SkippedAfterFailure',
175                    'file': 'gtest_xml_output_unittest_.cc',
176                    'line': 83,
177                    'status': 'RUN',
178                    'result': 'COMPLETED',
179                    'time': '*',
180                    'timestamp': '*',
181                    'classname': 'SkippedTest',
182                    'failures': [{
183                        'failure': (
184                            'gtest_xml_output_unittest_.cc:*\n'
185                            'Expected equality of these values:\n'
186                            '  1\n  2'
187                            + STACK_TRACE_TEMPLATE
188                        ),
189                        'type': '',
190                    }],
191                    'skipped': [{
192                        'message': (
193                            'gtest_xml_output_unittest_.cc:*\n'
194                            'It is good practice to tell why you skip a test.\n'
195                        )
196                    }],
197                },
198            ],
199        },
200        {
201            'name': 'MixedResultTest',
202            'tests': 3,
203            'failures': 1,
204            'disabled': 1,
205            'errors': 0,
206            'time': '*',
207            'timestamp': '*',
208            'testsuite': [
209                {
210                    'name': 'Succeeds',
211                    'file': 'gtest_xml_output_unittest_.cc',
212                    'line': 88,
213                    'status': 'RUN',
214                    'result': 'COMPLETED',
215                    'time': '*',
216                    'timestamp': '*',
217                    'classname': 'MixedResultTest',
218                },
219                {
220                    'name': 'Fails',
221                    'file': 'gtest_xml_output_unittest_.cc',
222                    'line': 93,
223                    'status': 'RUN',
224                    'result': 'COMPLETED',
225                    'time': '*',
226                    'timestamp': '*',
227                    'classname': 'MixedResultTest',
228                    'failures': [
229                        {
230                            'failure': (
231                                'gtest_xml_output_unittest_.cc:*\n'
232                                'Expected equality of these values:\n'
233                                '  1\n  2'
234                                + STACK_TRACE_TEMPLATE
235                            ),
236                            'type': '',
237                        },
238                        {
239                            'failure': (
240                                'gtest_xml_output_unittest_.cc:*\n'
241                                'Expected equality of these values:\n'
242                                '  2\n  3'
243                                + STACK_TRACE_TEMPLATE
244                            ),
245                            'type': '',
246                        },
247                    ],
248                },
249                {
250                    'name': 'DISABLED_test',
251                    'file': 'gtest_xml_output_unittest_.cc',
252                    'line': 98,
253                    'status': 'NOTRUN',
254                    'result': 'SUPPRESSED',
255                    'time': '*',
256                    'timestamp': '*',
257                    'classname': 'MixedResultTest',
258                },
259            ],
260        },
261        {
262            'name': 'XmlQuotingTest',
263            'tests': 1,
264            'failures': 1,
265            'disabled': 0,
266            'errors': 0,
267            'time': '*',
268            'timestamp': '*',
269            'testsuite': [{
270                'name': 'OutputsCData',
271                'file': 'gtest_xml_output_unittest_.cc',
272                'line': 102,
273                'status': 'RUN',
274                'result': 'COMPLETED',
275                'time': '*',
276                'timestamp': '*',
277                'classname': 'XmlQuotingTest',
278                'failures': [{
279                    'failure': (
280                        'gtest_xml_output_unittest_.cc:*\n'
281                        'Failed\nXML output: <?xml encoding="utf-8">'
282                        '<top><![CDATA[cdata text]]></top>'
283                        + STACK_TRACE_TEMPLATE
284                    ),
285                    'type': '',
286                }],
287            }],
288        },
289        {
290            'name': 'InvalidCharactersTest',
291            'tests': 1,
292            'failures': 1,
293            'disabled': 0,
294            'errors': 0,
295            'time': '*',
296            'timestamp': '*',
297            'testsuite': [{
298                'name': 'InvalidCharactersInMessage',
299                'file': 'gtest_xml_output_unittest_.cc',
300                'line': 109,
301                'status': 'RUN',
302                'result': 'COMPLETED',
303                'time': '*',
304                'timestamp': '*',
305                'classname': 'InvalidCharactersTest',
306                'failures': [{
307                    'failure': (
308                        'gtest_xml_output_unittest_.cc:*\n'
309                        'Failed\nInvalid characters in brackets'
310                        ' [\x01\x02]'
311                        + STACK_TRACE_TEMPLATE
312                    ),
313                    'type': '',
314                }],
315            }],
316        },
317        {
318            'name': 'PropertyRecordingTest',
319            'tests': 4,
320            'failures': 0,
321            'disabled': 0,
322            'errors': 0,
323            'time': '*',
324            'timestamp': '*',
325            'SetUpTestSuite': 'yes',
326            'TearDownTestSuite': 'aye',
327            'testsuite': [
328                {
329                    'name': 'OneProperty',
330                    'file': 'gtest_xml_output_unittest_.cc',
331                    'line': 121,
332                    'status': 'RUN',
333                    'result': 'COMPLETED',
334                    'time': '*',
335                    'timestamp': '*',
336                    'classname': 'PropertyRecordingTest',
337                    'key_1': '1',
338                },
339                {
340                    'name': 'IntValuedProperty',
341                    'file': 'gtest_xml_output_unittest_.cc',
342                    'line': 125,
343                    'status': 'RUN',
344                    'result': 'COMPLETED',
345                    'time': '*',
346                    'timestamp': '*',
347                    'classname': 'PropertyRecordingTest',
348                    'key_int': '1',
349                },
350                {
351                    'name': 'ThreeProperties',
352                    'file': 'gtest_xml_output_unittest_.cc',
353                    'line': 129,
354                    'status': 'RUN',
355                    'result': 'COMPLETED',
356                    'time': '*',
357                    'timestamp': '*',
358                    'classname': 'PropertyRecordingTest',
359                    'key_1': '1',
360                    'key_2': '2',
361                    'key_3': '3',
362                },
363                {
364                    'name': 'TwoValuesForOneKeyUsesLastValue',
365                    'file': 'gtest_xml_output_unittest_.cc',
366                    'line': 135,
367                    'status': 'RUN',
368                    'result': 'COMPLETED',
369                    'time': '*',
370                    'timestamp': '*',
371                    'classname': 'PropertyRecordingTest',
372                    'key_1': '2',
373                },
374            ],
375        },
376        {
377            'name': 'NoFixtureTest',
378            'tests': 3,
379            'failures': 0,
380            'disabled': 0,
381            'errors': 0,
382            'time': '*',
383            'timestamp': '*',
384            'testsuite': [
385                {
386                    'name': 'RecordProperty',
387                    'file': 'gtest_xml_output_unittest_.cc',
388                    'line': 140,
389                    'status': 'RUN',
390                    'result': 'COMPLETED',
391                    'time': '*',
392                    'timestamp': '*',
393                    'classname': 'NoFixtureTest',
394                    'key': '1',
395                },
396                {
397                    'name': 'ExternalUtilityThatCallsRecordIntValuedProperty',
398                    'file': 'gtest_xml_output_unittest_.cc',
399                    'line': 153,
400                    'status': 'RUN',
401                    'result': 'COMPLETED',
402                    'time': '*',
403                    'timestamp': '*',
404                    'classname': 'NoFixtureTest',
405                    'key_for_utility_int': '1',
406                },
407                {
408                    'name': (
409                        'ExternalUtilityThatCallsRecordStringValuedProperty'
410                    ),
411                    'file': 'gtest_xml_output_unittest_.cc',
412                    'line': 157,
413                    'status': 'RUN',
414                    'result': 'COMPLETED',
415                    'time': '*',
416                    'timestamp': '*',
417                    'classname': 'NoFixtureTest',
418                    'key_for_utility_string': '1',
419                },
420            ],
421        },
422        {
423            'name': 'TypedTest/0',
424            'tests': 1,
425            'failures': 0,
426            'disabled': 0,
427            'errors': 0,
428            'time': '*',
429            'timestamp': '*',
430            'testsuite': [{
431                'name': 'HasTypeParamAttribute',
432                'type_param': 'int',
433                'file': 'gtest_xml_output_unittest_.cc',
434                'line': 173,
435                'status': 'RUN',
436                'result': 'COMPLETED',
437                'time': '*',
438                'timestamp': '*',
439                'classname': 'TypedTest/0',
440            }],
441        },
442        {
443            'name': 'TypedTest/1',
444            'tests': 1,
445            'failures': 0,
446            'disabled': 0,
447            'errors': 0,
448            'time': '*',
449            'timestamp': '*',
450            'testsuite': [{
451                'name': 'HasTypeParamAttribute',
452                'type_param': 'long',
453                'file': 'gtest_xml_output_unittest_.cc',
454                'line': 173,
455                'status': 'RUN',
456                'result': 'COMPLETED',
457                'time': '*',
458                'timestamp': '*',
459                'classname': 'TypedTest/1',
460            }],
461        },
462        {
463            'name': 'Single/TypeParameterizedTestSuite/0',
464            'tests': 1,
465            'failures': 0,
466            'disabled': 0,
467            'errors': 0,
468            'time': '*',
469            'timestamp': '*',
470            'testsuite': [{
471                'name': 'HasTypeParamAttribute',
472                'type_param': 'int',
473                'file': 'gtest_xml_output_unittest_.cc',
474                'line': 180,
475                'status': 'RUN',
476                'result': 'COMPLETED',
477                'time': '*',
478                'timestamp': '*',
479                'classname': 'Single/TypeParameterizedTestSuite/0',
480            }],
481        },
482        {
483            'name': 'Single/TypeParameterizedTestSuite/1',
484            'tests': 1,
485            'failures': 0,
486            'disabled': 0,
487            'errors': 0,
488            'time': '*',
489            'timestamp': '*',
490            'testsuite': [{
491                'name': 'HasTypeParamAttribute',
492                'type_param': 'long',
493                'file': 'gtest_xml_output_unittest_.cc',
494                'line': 180,
495                'status': 'RUN',
496                'result': 'COMPLETED',
497                'time': '*',
498                'timestamp': '*',
499                'classname': 'Single/TypeParameterizedTestSuite/1',
500            }],
501        },
502        {
503            'name': 'Single/ValueParamTest',
504            'tests': 4,
505            'failures': 0,
506            'disabled': 0,
507            'errors': 0,
508            'time': '*',
509            'timestamp': '*',
510            'testsuite': [
511                {
512                    'name': 'HasValueParamAttribute/0',
513                    'value_param': '33',
514                    'file': 'gtest_xml_output_unittest_.cc',
515                    'line': 164,
516                    'status': 'RUN',
517                    'result': 'COMPLETED',
518                    'time': '*',
519                    'timestamp': '*',
520                    'classname': 'Single/ValueParamTest',
521                },
522                {
523                    'name': 'HasValueParamAttribute/1',
524                    'value_param': '42',
525                    'file': 'gtest_xml_output_unittest_.cc',
526                    'line': 164,
527                    'status': 'RUN',
528                    'result': 'COMPLETED',
529                    'time': '*',
530                    'timestamp': '*',
531                    'classname': 'Single/ValueParamTest',
532                },
533                {
534                    'name': 'AnotherTestThatHasValueParamAttribute/0',
535                    'value_param': '33',
536                    'file': 'gtest_xml_output_unittest_.cc',
537                    'line': 165,
538                    'status': 'RUN',
539                    'result': 'COMPLETED',
540                    'time': '*',
541                    'timestamp': '*',
542                    'classname': 'Single/ValueParamTest',
543                },
544                {
545                    'name': 'AnotherTestThatHasValueParamAttribute/1',
546                    'value_param': '42',
547                    'file': 'gtest_xml_output_unittest_.cc',
548                    'line': 165,
549                    'status': 'RUN',
550                    'result': 'COMPLETED',
551                    'time': '*',
552                    'timestamp': '*',
553                    'classname': 'Single/ValueParamTest',
554                },
555            ],
556        },
557    ],
558}
559
560EXPECTED_FILTERED = {
561    'tests': 1,
562    'failures': 0,
563    'disabled': 0,
564    'errors': 0,
565    'time': '*',
566    'timestamp': '*',
567    'name': 'AllTests',
568    'ad_hoc_property': '42',
569    'testsuites': [{
570        'name': 'SuccessfulTest',
571        'tests': 1,
572        'failures': 0,
573        'disabled': 0,
574        'errors': 0,
575        'time': '*',
576        'timestamp': '*',
577        'testsuite': [{
578            'name': 'Succeeds',
579            'file': 'gtest_xml_output_unittest_.cc',
580            'line': 53,
581            'status': 'RUN',
582            'result': 'COMPLETED',
583            'time': '*',
584            'timestamp': '*',
585            'classname': 'SuccessfulTest',
586        }],
587    }],
588}
589
590EXPECTED_NO_TEST = {
591    'tests': 0,
592    'failures': 0,
593    'disabled': 0,
594    'errors': 0,
595    'time': '*',
596    'timestamp': '*',
597    'name': 'AllTests',
598    'testsuites': [{
599        'name': 'NonTestSuiteFailure',
600        'tests': 1,
601        'failures': 1,
602        'disabled': 0,
603        'skipped': 0,
604        'errors': 0,
605        'time': '*',
606        'timestamp': '*',
607        'testsuite': [{
608            'name': '',
609            'status': 'RUN',
610            'result': 'COMPLETED',
611            'time': '*',
612            'timestamp': '*',
613            'classname': '',
614            'failures': [{
615                'failure': (
616                    'gtest_no_test_unittest.cc:*\n'
617                    'Expected equality of these values:\n'
618                    '  1\n  2'
619                    + STACK_TRACE_TEMPLATE
620                ),
621                'type': '',
622            }],
623        }],
624    }],
625}
626
627GTEST_PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath(GTEST_PROGRAM_NAME)
628
629SUPPORTS_TYPED_TESTS = (
630    'TypedTest'
631    in gtest_test_utils.Subprocess(
632        [GTEST_PROGRAM_PATH, GTEST_LIST_TESTS_FLAG], capture_stderr=False
633    ).output
634)
635
636
637class GTestJsonOutputUnitTest(gtest_test_utils.TestCase):
638  """Unit test for Google Test's JSON output functionality."""
639
640  # This test currently breaks on platforms that do not support typed and
641  # type-parameterized tests, so we don't run it under them.
642  if SUPPORTS_TYPED_TESTS:
643
644    def testNonEmptyJsonOutput(self):
645      """Verifies JSON output for a Google Test binary with non-empty output.
646
647      Runs a test program that generates a non-empty JSON output, and
648      tests that the JSON output is expected.
649      """
650      self._TestJsonOutput(GTEST_PROGRAM_NAME, EXPECTED_NON_EMPTY, 1)
651
652  def testNoTestJsonOutput(self):
653    """Verifies JSON output for a Google Test binary without actual tests.
654
655    Runs a test program that generates an JSON output for a binary with no
656    tests, and tests that the JSON output is expected.
657    """
658
659    self._TestJsonOutput('gtest_no_test_unittest', EXPECTED_NO_TEST, 0)
660
661  def testTimestampValue(self):
662    """Checks whether the timestamp attribute in the JSON output is valid.
663
664    Runs a test program that generates an empty JSON output, and checks if
665    the timestamp attribute in the testsuites tag is valid.
666    """
667    actual = self._GetJsonOutput('gtest_no_test_unittest', [], 0)
668    date_time_str = actual['timestamp']
669    # datetime.strptime() is only available in Python 2.5+ so we have to
670    # parse the expected datetime manually.
671    match = re.match(r'(\d+)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)', date_time_str)
672    self.assertTrue(
673        re.match,
674        'JSON datettime string %s has incorrect format' % date_time_str,
675    )
676    date_time_from_json = datetime.datetime(
677        year=int(match.group(1)),
678        month=int(match.group(2)),
679        day=int(match.group(3)),
680        hour=int(match.group(4)),
681        minute=int(match.group(5)),
682        second=int(match.group(6)),
683    )
684
685    time_delta = abs(datetime.datetime.now() - date_time_from_json)
686    # timestamp value should be near the current local time
687    self.assertTrue(
688        time_delta < datetime.timedelta(seconds=600),
689        'time_delta is %s' % time_delta,
690    )
691
692  def testDefaultOutputFile(self):
693    """Verifies the default output file name.
694
695    Confirms that Google Test produces an JSON output file with the expected
696    default name if no name is explicitly specified.
697    """
698    output_file = os.path.join(
699        gtest_test_utils.GetTempDir(), GTEST_DEFAULT_OUTPUT_FILE
700    )
701    gtest_prog_path = gtest_test_utils.GetTestExecutablePath(
702        'gtest_no_test_unittest'
703    )
704    try:
705      os.remove(output_file)
706    except OSError:
707      e = sys.exc_info()[1]
708      if e.errno != errno.ENOENT:
709        raise
710
711    p = gtest_test_utils.Subprocess(
712        [gtest_prog_path, '%s=json' % GTEST_OUTPUT_FLAG],
713        working_dir=gtest_test_utils.GetTempDir(),
714    )
715    self.assertTrue(p.exited)
716    self.assertEqual(0, p.exit_code)
717    self.assertTrue(os.path.isfile(output_file))
718
719  def testSuppressedJsonOutput(self):
720    """Verifies that no JSON output is generated.
721
722    Tests that no JSON file is generated if the default JSON listener is
723    shut down before RUN_ALL_TESTS is invoked.
724    """
725
726    json_path = os.path.join(
727        gtest_test_utils.GetTempDir(), GTEST_PROGRAM_NAME + 'out.json'
728    )
729    if os.path.isfile(json_path):
730      os.remove(json_path)
731
732    command = [
733        GTEST_PROGRAM_PATH,
734        '%s=json:%s' % (GTEST_OUTPUT_FLAG, json_path),
735        '--shut_down_xml',
736    ]
737    p = gtest_test_utils.Subprocess(command)
738    if p.terminated_by_signal:
739      # p.signal is available only if p.terminated_by_signal is True.
740      self.assertFalse(
741          p.terminated_by_signal,
742          '%s was killed by signal %d' % (GTEST_PROGRAM_NAME, p.signal),
743      )
744    else:
745      self.assertTrue(p.exited)
746      self.assertEqual(
747          1,
748          p.exit_code,
749          "'%s' exited with code %s, which doesn't match "
750          'the expected exit code %s.' % (command, p.exit_code, 1),
751      )
752
753    self.assertTrue(not os.path.isfile(json_path))
754
755  def testFilteredTestJsonOutput(self):
756    """Verifies JSON output when a filter is applied.
757
758    Runs a test program that executes only some tests and verifies that
759    non-selected tests do not show up in the JSON output.
760    """
761
762    self._TestJsonOutput(
763        GTEST_PROGRAM_NAME,
764        EXPECTED_FILTERED,
765        0,
766        extra_args=['%s=SuccessfulTest.*' % GTEST_FILTER_FLAG],
767    )
768
769  def _GetJsonOutput(self, gtest_prog_name, extra_args, expected_exit_code):
770    """Returns the JSON output generated by running the program gtest_prog_name.
771
772    Furthermore, the program's exit code must be expected_exit_code.
773
774    Args:
775      gtest_prog_name: Google Test binary name.
776      extra_args: extra arguments to binary invocation.
777      expected_exit_code: program's exit code.
778    """
779    json_path = os.path.join(
780        gtest_test_utils.GetTempDir(), gtest_prog_name + 'out.json'
781    )
782    gtest_prog_path = gtest_test_utils.GetTestExecutablePath(gtest_prog_name)
783
784    command = [
785        gtest_prog_path,
786        '%s=json:%s' % (GTEST_OUTPUT_FLAG, json_path),
787    ] + extra_args
788    p = gtest_test_utils.Subprocess(command)
789    if p.terminated_by_signal:
790      self.assertTrue(
791          False, '%s was killed by signal %d' % (gtest_prog_name, p.signal)
792      )
793    else:
794      self.assertTrue(p.exited)
795      self.assertEqual(
796          expected_exit_code,
797          p.exit_code,
798          "'%s' exited with code %s, which doesn't match "
799          'the expected exit code %s.'
800          % (command, p.exit_code, expected_exit_code),
801      )
802    with open(json_path) as f:
803      actual = json.load(f)
804    return actual
805
806  def _TestJsonOutput(
807      self, gtest_prog_name, expected, expected_exit_code, extra_args=None
808  ):
809    """Checks the JSON output generated by the Google Test binary.
810
811    Asserts that the JSON document generated by running the program
812    gtest_prog_name matches expected_json, a string containing another
813    JSON document.  Furthermore, the program's exit code must be
814    expected_exit_code.
815
816    Args:
817      gtest_prog_name: Google Test binary name.
818      expected: expected output.
819      expected_exit_code: program's exit code.
820      extra_args: extra arguments to binary invocation.
821    """
822
823    actual = self._GetJsonOutput(
824        gtest_prog_name, extra_args or [], expected_exit_code
825    )
826    self.assertEqual(expected, gtest_json_test_utils.normalize(actual))
827
828
829if __name__ == '__main__':
830  if NO_STACKTRACE_SUPPORT_FLAG in sys.argv:
831    # unittest.main() can't handle unknown flags
832    sys.argv.remove(NO_STACKTRACE_SUPPORT_FLAG)
833
834  os.environ['GTEST_STACK_TRACE_DEPTH'] = '1'
835  gtest_test_utils.Main()
836