1# Copyright (C) 2012 Google Inc. All rights reserved.
2#
3# Redistribution and use in source and binary forms, with or without
4# modification, are permitted provided that the following conditions are
5# met:
6#
7#     * Redistributions of source code must retain the above copyright
8# notice, this list of conditions and the following disclaimer.
9#     * Redistributions in binary form must reproduce the above
10# copyright notice, this list of conditions and the following disclaimer
11# in the documentation and/or other materials provided with the
12# distribution.
13#     * Neither the name of Google Inc. nor the names of its
14# contributors may be used to endorse or promote products derived from
15# this software without specific prior written permission.
16#
17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29import StringIO
30import optparse
31import unittest
32
33from webkitpy.common.host_mock import MockHost
34from webkitpy.layout_tests import lint_test_expectations
35
36
37class FakePort(object):
38    def __init__(self, host, name, path):
39        self.host = host
40        self.name = name
41        self.path = path
42
43    def test_configuration(self):
44        return None
45
46    def expectations_dict(self):
47        self.host.ports_parsed.append(self.name)
48        return {self.path: ''}
49
50    def bot_expectations(self):
51        return {}
52
53    def skipped_layout_tests(self, _):
54        return set([])
55
56    def all_test_configurations(self):
57        return []
58
59    def configuration_specifier_macros(self):
60        return []
61
62    def get_option(self, _, val):
63        return val
64
65    def path_to_generic_test_expectations_file(self):
66        return ''
67
68class FakeFactory(object):
69    def __init__(self, host, ports):
70        self.host = host
71        self.ports = {}
72        for port in ports:
73            self.ports[port.name] = port
74
75    def get(self, port_name='a', *args, **kwargs):  # pylint: disable=W0613,E0202
76        return self.ports[port_name]
77
78    def all_port_names(self, platform=None):  # pylint: disable=W0613,E0202
79        return sorted(self.ports.keys())
80
81
82class LintTest(unittest.TestCase):
83    def test_all_configurations(self):
84        host = MockHost()
85        host.ports_parsed = []
86        host.port_factory = FakeFactory(host, (FakePort(host, 'a', 'path-to-a'),
87                                               FakePort(host, 'b', 'path-to-b'),
88                                               FakePort(host, 'b-win', 'path-to-b')))
89
90        logging_stream = StringIO.StringIO()
91        options = optparse.Values({'platform': None})
92        logger, handler = lint_test_expectations.set_up_logging(logging_stream)
93        try:
94            res = lint_test_expectations.lint(host, options)
95        finally:
96            lint_test_expectations.tear_down_logging(logger, handler)
97        self.assertEqual(res, 0)
98        self.assertEqual(host.ports_parsed, ['a', 'b', 'b-win'])
99
100    def test_lint_test_files(self):
101        logging_stream = StringIO.StringIO()
102        options = optparse.Values({'platform': 'test-mac-leopard'})
103        host = MockHost()
104
105        # pylint appears to complain incorrectly about the method overrides pylint: disable=E0202,C0322
106        # FIXME: incorrect complaints about spacing pylint: disable=C0322
107        host.port_factory.all_port_names = lambda platform=None: [platform]
108
109        logger, handler = lint_test_expectations.set_up_logging(logging_stream)
110        try:
111            res = lint_test_expectations.lint(host, options)
112            self.assertEqual(res, 0)
113        finally:
114            lint_test_expectations.tear_down_logging(logger, handler)
115
116
117    def test_lint_test_files__errors(self):
118        options = optparse.Values({'platform': 'test', 'debug_rwt_logging': False})
119        host = MockHost()
120
121        # FIXME: incorrect complaints about spacing pylint: disable=C0322
122        port = host.port_factory.get(options.platform, options=options)
123        port.expectations_dict = lambda: {'foo': '-- syntax error1', 'bar': '-- syntax error2'}
124
125        host.port_factory.get = lambda platform, options=None: port
126        host.port_factory.all_port_names = lambda platform=None: [port.name()]
127
128        logging_stream = StringIO.StringIO()
129        logger, handler = lint_test_expectations.set_up_logging(logging_stream)
130        try:
131            res = lint_test_expectations.lint(host, options)
132        finally:
133            lint_test_expectations.tear_down_logging(logger, handler)
134
135        self.assertTrue(res)
136        self.assertIn('foo:1', logging_stream.getvalue())
137        self.assertIn('bar:1', logging_stream.getvalue())
138
139
140class CheckVirtualSuiteTest(unittest.TestCase):
141    def test_check_virtual_test_suites(self):
142        host = MockHost()
143        options = optparse.Values({'platform': 'test', 'debug_rwt_logging': False})
144        orig_get = host.port_factory.get
145        host.port_factory.get = lambda options: orig_get('test', options=options)
146
147        logging_stream = StringIO.StringIO()
148        logger, handler = lint_test_expectations.set_up_logging(logging_stream)
149        try:
150            res = lint_test_expectations.check_virtual_test_suites(host, options)
151            self.assertTrue(res)
152
153            host.filesystem.exists = lambda path: True
154            res = lint_test_expectations.check_virtual_test_suites(host, options)
155            self.assertFalse(res)
156        finally:
157            lint_test_expectations.tear_down_logging(logger, handler)
158
159
160class MainTest(unittest.TestCase):
161    # unused args pylint: disable=W0613
162
163    def setUp(self):
164        self.orig_lint_fn = lint_test_expectations.lint
165        self.orig_check_fn = lint_test_expectations.check_virtual_test_suites
166        lint_test_expectations.check_virtual_test_suites = lambda host, options: False
167
168        self.stdout = StringIO.StringIO()
169        self.stderr = StringIO.StringIO()
170
171    def tearDown(self):
172        lint_test_expectations.lint = self.orig_lint_fn
173        lint_test_expectations.check_virtual_test_suites = self.orig_check_fn
174
175    def test_success(self):
176        lint_test_expectations.lint = lambda host, options: False
177        res = lint_test_expectations.main(['--platform', 'test'], self.stdout, self.stderr)
178        self.assertTrue('Lint succeeded' in self.stderr.getvalue())
179        self.assertEqual(res, 0)
180
181    def test_failure(self):
182        lint_test_expectations.lint = lambda host, options: True
183        res = lint_test_expectations.main(['--platform', 'test'], self.stdout, self.stderr)
184        self.assertTrue('Lint failed' in self.stderr.getvalue())
185        self.assertEqual(res, 1)
186
187    def test_interrupt(self):
188        def interrupting_lint(host, options):
189            raise KeyboardInterrupt
190
191        lint_test_expectations.lint = interrupting_lint
192        res = lint_test_expectations.main([], self.stdout, self.stderr)
193        self.assertEqual(res, lint_test_expectations.INTERRUPTED_EXIT_STATUS)
194
195    def test_exception(self):
196        def exception_raising_lint(host, options):
197            assert False
198        lint_test_expectations.lint = exception_raising_lint
199        res = lint_test_expectations.main([], self.stdout, self.stderr)
200        self.assertEqual(res, lint_test_expectations.EXCEPTIONAL_EXIT_STATUS)
201