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 json
34import os
35import gtest_json_test_utils
36import gtest_test_utils
37
38GTEST_OUTPUT_SUBDIR = 'json_outfiles'
39GTEST_OUTPUT_1_TEST = 'gtest_xml_outfile1_test_'
40GTEST_OUTPUT_2_TEST = 'gtest_xml_outfile2_test_'
41
42EXPECTED_1 = {
43    u'tests': 1,
44    u'failures': 0,
45    u'disabled': 0,
46    u'errors': 0,
47    u'time': u'*',
48    u'timestamp': u'*',
49    u'name': u'AllTests',
50    u'testsuites': [{
51        u'name': u'PropertyOne',
52        u'tests': 1,
53        u'failures': 0,
54        u'disabled': 0,
55        u'errors': 0,
56        u'time': u'*',
57        u'testsuite': [{
58            u'name': u'TestSomeProperties',
59            u'status': u'RUN',
60            u'time': u'*',
61            u'classname': u'PropertyOne',
62            u'SetUpProp': u'1',
63            u'TestSomeProperty': u'1',
64            u'TearDownProp': u'1',
65        }],
66    }],
67}
68
69EXPECTED_2 = {
70    u'tests': 1,
71    u'failures': 0,
72    u'disabled': 0,
73    u'errors': 0,
74    u'time': u'*',
75    u'timestamp': u'*',
76    u'name': u'AllTests',
77    u'testsuites': [{
78        u'name': u'PropertyTwo',
79        u'tests': 1,
80        u'failures': 0,
81        u'disabled': 0,
82        u'errors': 0,
83        u'time': u'*',
84        u'testsuite': [{
85            u'name': u'TestSomeProperties',
86            u'status': u'RUN',
87            u'time': u'*',
88            u'classname': u'PropertyTwo',
89            u'SetUpProp': u'2',
90            u'TestSomeProperty': u'2',
91            u'TearDownProp': u'2',
92        }],
93    }],
94}
95
96
97class GTestJsonOutFilesTest(gtest_test_utils.TestCase):
98  """Unit test for Google Test's JSON output functionality."""
99
100  def setUp(self):
101    # We want the trailing '/' that the last "" provides in os.path.join, for
102    # telling Google Test to create an output directory instead of a single file
103    # for xml output.
104    self.output_dir_ = os.path.join(gtest_test_utils.GetTempDir(),
105                                    GTEST_OUTPUT_SUBDIR, '')
106    self.DeleteFilesAndDir()
107
108  def tearDown(self):
109    self.DeleteFilesAndDir()
110
111  def DeleteFilesAndDir(self):
112    try:
113      os.remove(os.path.join(self.output_dir_, GTEST_OUTPUT_1_TEST + '.json'))
114    except os.error:
115      pass
116    try:
117      os.remove(os.path.join(self.output_dir_, GTEST_OUTPUT_2_TEST + '.json'))
118    except os.error:
119      pass
120    try:
121      os.rmdir(self.output_dir_)
122    except os.error:
123      pass
124
125  def testOutfile1(self):
126    self._TestOutFile(GTEST_OUTPUT_1_TEST, EXPECTED_1)
127
128  def testOutfile2(self):
129    self._TestOutFile(GTEST_OUTPUT_2_TEST, EXPECTED_2)
130
131  def _TestOutFile(self, test_name, expected):
132    gtest_prog_path = gtest_test_utils.GetTestExecutablePath(test_name)
133    command = [gtest_prog_path, '--gtest_output=json:%s' % self.output_dir_]
134    p = gtest_test_utils.Subprocess(command,
135                                    working_dir=gtest_test_utils.GetTempDir())
136    self.assert_(p.exited)
137    self.assertEquals(0, p.exit_code)
138
139    # FIXME: libtool causes the built test binary to be
140    #   named lt-gtest_xml_outfiles_test_ instead of
141    #   gtest_xml_outfiles_test_.  To account for this possibility, we
142    #   allow both names in the following code.  We should remove this
143    #   when libtool replacement tool is ready.
144    output_file_name1 = test_name + '.json'
145    output_file1 = os.path.join(self.output_dir_, output_file_name1)
146    output_file_name2 = 'lt-' + output_file_name1
147    output_file2 = os.path.join(self.output_dir_, output_file_name2)
148    self.assert_(os.path.isfile(output_file1) or os.path.isfile(output_file2),
149                 output_file1)
150
151    if os.path.isfile(output_file1):
152      with open(output_file1) as f:
153        actual = json.load(f)
154    else:
155      with open(output_file2) as f:
156        actual = json.load(f)
157    self.assertEqual(expected, gtest_json_test_utils.normalize(actual))
158
159
160if __name__ == '__main__':
161  os.environ['GTEST_STACK_TRACE_DEPTH'] = '0'
162  gtest_test_utils.Main()
163