xref: /llvm-project/llvm/utils/lit/tests/unit/TestRunner.py (revision f951b0f82dff97f91d9b89c67886740acf3373cd)
1# RUN: %{python} %s
2#
3# END.
4
5
6import os.path
7import platform
8import unittest
9
10import lit.discovery
11import lit.LitConfig
12import lit.Test as Test
13from lit.TestRunner import ParserKind, IntegratedTestKeywordParser, \
14                           parseIntegratedTestScript
15
16
17class TestIntegratedTestKeywordParser(unittest.TestCase):
18    inputTestCase = None
19
20    @staticmethod
21    def load_keyword_parser_lit_tests():
22        """
23        Create and load the LIT test suite and test objects used by
24        TestIntegratedTestKeywordParser
25        """
26        # Create the global config object.
27        lit_config = lit.LitConfig.LitConfig(progname='lit',
28                                             path=[],
29                                             quiet=False,
30                                             useValgrind=False,
31                                             valgrindLeakCheck=False,
32                                             valgrindArgs=[],
33                                             noExecute=False,
34                                             debug=False,
35                                             isWindows=(
36                                               platform.system() == 'Windows'),
37                                             params={})
38        TestIntegratedTestKeywordParser.litConfig = lit_config
39        # Perform test discovery.
40        test_path = os.path.dirname(os.path.dirname(__file__))
41        inputs = [os.path.join(test_path, 'Inputs/testrunner-custom-parsers/')]
42        assert os.path.isdir(inputs[0])
43        tests = lit.discovery.find_tests_for_inputs(lit_config, inputs)
44        assert len(tests) == 1 and "there should only be one test"
45        TestIntegratedTestKeywordParser.inputTestCase = tests[0]
46
47    @staticmethod
48    def make_parsers():
49        def custom_parse(line_number, line, output):
50            if output is None:
51                output = []
52            output += [part for part in line.split(' ') if part.strip()]
53            return output
54
55        return [
56            IntegratedTestKeywordParser("MY_TAG.", ParserKind.TAG),
57            IntegratedTestKeywordParser("MY_DNE_TAG.", ParserKind.TAG),
58            IntegratedTestKeywordParser("MY_LIST:", ParserKind.LIST),
59            IntegratedTestKeywordParser("MY_BOOL:", ParserKind.BOOLEAN_EXPR),
60            IntegratedTestKeywordParser("MY_INT:", ParserKind.INTEGER),
61            IntegratedTestKeywordParser("MY_RUN:", ParserKind.COMMAND),
62            IntegratedTestKeywordParser("MY_CUSTOM:", ParserKind.CUSTOM,
63                                        custom_parse),
64
65        ]
66
67    @staticmethod
68    def get_parser(parser_list, keyword):
69        for p in parser_list:
70            if p.keyword == keyword:
71                return p
72        assert False and "parser not found"
73
74    @staticmethod
75    def parse_test(parser_list):
76        script = parseIntegratedTestScript(
77            TestIntegratedTestKeywordParser.inputTestCase,
78            additional_parsers=parser_list, require_script=False)
79        assert not isinstance(script, lit.Test.Result)
80        assert isinstance(script, list)
81        assert len(script) == 0
82
83    def test_tags(self):
84        parsers = self.make_parsers()
85        self.parse_test(parsers)
86        tag_parser = self.get_parser(parsers, 'MY_TAG.')
87        dne_tag_parser = self.get_parser(parsers, 'MY_DNE_TAG.')
88        self.assertTrue(tag_parser.getValue())
89        self.assertFalse(dne_tag_parser.getValue())
90
91    def test_lists(self):
92        parsers = self.make_parsers()
93        self.parse_test(parsers)
94        list_parser = self.get_parser(parsers, 'MY_LIST:')
95        self.assertEqual(list_parser.getValue(),
96                              ['one', 'two', 'three', 'four'])
97
98    def test_commands(self):
99        parsers = self.make_parsers()
100        self.parse_test(parsers)
101        cmd_parser = self.get_parser(parsers, 'MY_RUN:')
102        value = cmd_parser.getValue()
103        self.assertEqual(len(value), 2)  # there are only two run lines
104        self.assertEqual(value[0].strip(), "%dbg(MY_RUN: at line 4)  baz")
105        self.assertEqual(value[1].strip(), "%dbg(MY_RUN: at line 7)  foo  bar")
106
107    def test_boolean(self):
108        parsers = self.make_parsers()
109        self.parse_test(parsers)
110        bool_parser = self.get_parser(parsers, 'MY_BOOL:')
111        value = bool_parser.getValue()
112        self.assertEqual(len(value), 2)  # there are only two run lines
113        self.assertEqual(value[0].strip(), "a && (b)")
114        self.assertEqual(value[1].strip(), "d")
115
116    def test_integer(self):
117        parsers = self.make_parsers()
118        self.parse_test(parsers)
119        int_parser = self.get_parser(parsers, 'MY_INT:')
120        value = int_parser.getValue()
121        self.assertEqual(len(value), 2)  # there are only two MY_INT: lines
122        self.assertEqual(type(value[0]), int)
123        self.assertEqual(value[0], 4)
124        self.assertEqual(type(value[1]), int)
125        self.assertEqual(value[1], 6)
126
127    def test_boolean_unterminated(self):
128        parsers = self.make_parsers() + \
129            [IntegratedTestKeywordParser("MY_BOOL_UNTERMINATED:", ParserKind.BOOLEAN_EXPR)]
130        try:
131            self.parse_test(parsers)
132            self.fail('expected exception')
133        except ValueError as e:
134            self.assertIn("Test has unterminated MY_BOOL_UNTERMINATED: lines", str(e))
135
136
137    def test_custom(self):
138        parsers = self.make_parsers()
139        self.parse_test(parsers)
140        custom_parser = self.get_parser(parsers, 'MY_CUSTOM:')
141        value = custom_parser.getValue()
142        self.assertEqual(value, ['a', 'b', 'c'])
143
144    def test_bad_keywords(self):
145        def custom_parse(line_number, line, output):
146            return output
147
148        try:
149            IntegratedTestKeywordParser("TAG_NO_SUFFIX", ParserKind.TAG),
150            self.fail("TAG_NO_SUFFIX failed to raise an exception")
151        except ValueError as e:
152            pass
153        except BaseException as e:
154            self.fail("TAG_NO_SUFFIX raised the wrong exception: %r" % e)
155
156        try:
157            IntegratedTestKeywordParser("TAG_WITH_COLON:", ParserKind.TAG),
158            self.fail("TAG_WITH_COLON: failed to raise an exception")
159        except ValueError as e:
160            pass
161        except BaseException as e:
162            self.fail("TAG_WITH_COLON: raised the wrong exception: %r" % e)
163
164        try:
165            IntegratedTestKeywordParser("LIST_WITH_DOT.", ParserKind.LIST),
166            self.fail("LIST_WITH_DOT. failed to raise an exception")
167        except ValueError as e:
168            pass
169        except BaseException as e:
170            self.fail("LIST_WITH_DOT. raised the wrong exception: %r" % e)
171
172        try:
173            IntegratedTestKeywordParser("CUSTOM_NO_SUFFIX",
174                                        ParserKind.CUSTOM, custom_parse),
175            self.fail("CUSTOM_NO_SUFFIX failed to raise an exception")
176        except ValueError as e:
177            pass
178        except BaseException as e:
179            self.fail("CUSTOM_NO_SUFFIX raised the wrong exception: %r" % e)
180
181        # Both '.' and ':' are allowed for CUSTOM keywords.
182        try:
183            IntegratedTestKeywordParser("CUSTOM_WITH_DOT.",
184                                        ParserKind.CUSTOM, custom_parse),
185        except BaseException as e:
186            self.fail("CUSTOM_WITH_DOT. raised an exception: %r" % e)
187        try:
188            IntegratedTestKeywordParser("CUSTOM_WITH_COLON:",
189                                        ParserKind.CUSTOM, custom_parse),
190        except BaseException as e:
191            self.fail("CUSTOM_WITH_COLON: raised an exception: %r" % e)
192
193        try:
194            IntegratedTestKeywordParser("CUSTOM_NO_PARSER:",
195                                        ParserKind.CUSTOM),
196            self.fail("CUSTOM_NO_PARSER: failed to raise an exception")
197        except ValueError as e:
198            pass
199        except BaseException as e:
200            self.fail("CUSTOM_NO_PARSER: raised the wrong exception: %r" % e)
201
202if __name__ == '__main__':
203    TestIntegratedTestKeywordParser.load_keyword_parser_lit_tests()
204    unittest.main(verbosity=2)
205