brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.1 KiB · a3fa62e Raw
388 lines · python
1# RUN: %{python} %s2#3# END.4 5 6import os.path7import platform8import unittest9 10import lit.discovery11import lit.LitConfig12import lit.Test as Test13from lit.TestRunner import (14    ParserKind,15    IntegratedTestKeywordParser,16    parseIntegratedTestScript,17)18 19 20class TestIntegratedTestKeywordParser(unittest.TestCase):21    inputTestCase = None22 23    @staticmethod24    def load_keyword_parser_lit_tests():25        """26        Create and load the LIT test suite and test objects used by27        TestIntegratedTestKeywordParser28        """29        # Create the global config object.30        lit_config = lit.LitConfig.LitConfig(31            progname="lit",32            path=[],33            diagnostic_level="note",34            useValgrind=False,35            valgrindLeakCheck=False,36            valgrindArgs=[],37            noExecute=False,38            debug=False,39            isWindows=(platform.system() == "Windows"),40            order="smart",41            params={},42        )43        TestIntegratedTestKeywordParser.litConfig = lit_config44        # Perform test discovery.45        test_path = os.path.dirname(os.path.dirname(__file__))46        inputs = [os.path.join(test_path, "Inputs/testrunner-custom-parsers/")]47        assert os.path.isdir(inputs[0])48        tests = lit.discovery.find_tests_for_inputs(lit_config, inputs)49        assert len(tests) == 1 and "there should only be one test"50        TestIntegratedTestKeywordParser.inputTestCase = tests[0]51 52    @staticmethod53    def make_parsers():54        def custom_parse(line_number, line, output):55            if output is None:56                output = []57            output += [part for part in line.split(" ") if part.strip()]58            return output59 60        return [61            IntegratedTestKeywordParser("MY_TAG.", ParserKind.TAG),62            IntegratedTestKeywordParser("MY_DNE_TAG.", ParserKind.TAG),63            IntegratedTestKeywordParser("MY_LIST:", ParserKind.LIST),64            IntegratedTestKeywordParser("MY_SPACE_LIST:", ParserKind.SPACE_LIST),65            IntegratedTestKeywordParser("MY_BOOL:", ParserKind.BOOLEAN_EXPR),66            IntegratedTestKeywordParser("MY_INT:", ParserKind.INTEGER),67            IntegratedTestKeywordParser("MY_RUN:", ParserKind.COMMAND),68            IntegratedTestKeywordParser("MY_CUSTOM:", ParserKind.CUSTOM, custom_parse),69            IntegratedTestKeywordParser("MY_DEFINE:", ParserKind.DEFINE),70            IntegratedTestKeywordParser("MY_REDEFINE:", ParserKind.REDEFINE),71        ]72 73    @staticmethod74    def get_parser(parser_list, keyword):75        for p in parser_list:76            if p.keyword == keyword:77                return p78        assert False and "parser not found"79 80    @staticmethod81    def parse_test(parser_list, allow_result=False):82        script = parseIntegratedTestScript(83            TestIntegratedTestKeywordParser.inputTestCase,84            additional_parsers=parser_list,85            require_script=False,86        )87        if isinstance(script, lit.Test.Result):88            assert allow_result89        else:90            assert isinstance(script, list)91            assert len(script) == 092        return script93 94    def test_tags(self):95        parsers = self.make_parsers()96        self.parse_test(parsers)97        tag_parser = self.get_parser(parsers, "MY_TAG.")98        dne_tag_parser = self.get_parser(parsers, "MY_DNE_TAG.")99        self.assertTrue(tag_parser.getValue())100        self.assertFalse(dne_tag_parser.getValue())101 102    def test_lists(self):103        parsers = self.make_parsers()104        self.parse_test(parsers)105        list_parser = self.get_parser(parsers, "MY_LIST:")106        self.assertEqual(list_parser.getValue(), ["one", "two", "three", "four"])107 108    def test_space_lists(self):109        parsers = self.make_parsers()110        self.parse_test(parsers)111        space_list_parser = self.get_parser(parsers, "MY_SPACE_LIST:")112        self.assertEqual(113            space_list_parser.getValue(),114            [115                "orange",116                "tabby",117                "tortie",118                "tuxedo",119                "void",120                "multiple",121                "spaces",122                "cute,",123                "fluffy,",124                "kittens",125            ],126        )127 128    def test_commands(self):129        parsers = self.make_parsers()130        self.parse_test(parsers)131        cmd_parser = self.get_parser(parsers, "MY_RUN:")132        value = cmd_parser.getValue()133        self.assertEqual(len(value), 2)  # there are only two run lines134        self.assertEqual(value[0].command.strip(), "%dbg(MY_RUN: at line 4)  baz")135        self.assertEqual(value[1].command.strip(), "%dbg(MY_RUN: at line 12)  foo  bar")136 137    def test_boolean(self):138        parsers = self.make_parsers()139        self.parse_test(parsers)140        bool_parser = self.get_parser(parsers, "MY_BOOL:")141        value = bool_parser.getValue()142        self.assertEqual(len(value), 2)  # there are only two run lines143        self.assertEqual(value[0].strip(), "a && (b)")144        self.assertEqual(value[1].strip(), "d")145 146    def test_integer(self):147        parsers = self.make_parsers()148        self.parse_test(parsers)149        int_parser = self.get_parser(parsers, "MY_INT:")150        value = int_parser.getValue()151        self.assertEqual(len(value), 2)  # there are only two MY_INT: lines152        self.assertEqual(type(value[0]), int)153        self.assertEqual(value[0], 4)154        self.assertEqual(type(value[1]), int)155        self.assertEqual(value[1], 6)156 157    def test_bad_parser_type(self):158        parsers = self.make_parsers() + ["BAD_PARSER_TYPE"]159        script = self.parse_test(parsers, allow_result=True)160        self.assertTrue(isinstance(script, lit.Test.Result))161        self.assertEqual(script.code, lit.Test.UNRESOLVED)162        self.assertEqual(163            "Additional parser must be an instance of " "IntegratedTestKeywordParser",164            script.output,165        )166 167    def test_duplicate_keyword(self):168        parsers = self.make_parsers() + [169            IntegratedTestKeywordParser("KEY:", ParserKind.BOOLEAN_EXPR),170            IntegratedTestKeywordParser("KEY:", ParserKind.BOOLEAN_EXPR),171        ]172        script = self.parse_test(parsers, allow_result=True)173        self.assertTrue(isinstance(script, lit.Test.Result))174        self.assertEqual(script.code, lit.Test.UNRESOLVED)175        self.assertEqual("Parser for keyword 'KEY:' already exists", script.output)176 177    def test_boolean_unterminated(self):178        parsers = self.make_parsers() + [179            IntegratedTestKeywordParser(180                "MY_BOOL_UNTERMINATED:", ParserKind.BOOLEAN_EXPR181            )182        ]183        script = self.parse_test(parsers, allow_result=True)184        self.assertTrue(isinstance(script, lit.Test.Result))185        self.assertEqual(script.code, lit.Test.UNRESOLVED)186        self.assertEqual(187            "Test has unterminated 'MY_BOOL_UNTERMINATED:' lines " "(with '\\')",188            script.output,189        )190 191    def test_custom(self):192        parsers = self.make_parsers()193        self.parse_test(parsers)194        custom_parser = self.get_parser(parsers, "MY_CUSTOM:")195        value = custom_parser.getValue()196        self.assertEqual(value, ["a", "b", "c"])197 198    def test_defines(self):199        parsers = self.make_parsers()200        self.parse_test(parsers)201        cmd_parser = self.get_parser(parsers, "MY_DEFINE:")202        value = cmd_parser.getValue()203        self.assertEqual(len(value), 1)  # there's only one MY_DEFINE directive204        self.assertEqual(value[0].new_subst, True)205        self.assertEqual(value[0].name, "%{name}")206        self.assertEqual(value[0].value, "value one")207 208    def test_redefines(self):209        parsers = self.make_parsers()210        self.parse_test(parsers)211        cmd_parser = self.get_parser(parsers, "MY_REDEFINE:")212        value = cmd_parser.getValue()213        self.assertEqual(len(value), 1)  # there's only one MY_REDEFINE directive214        self.assertEqual(value[0].new_subst, False)215        self.assertEqual(value[0].name, "%{name}")216        self.assertEqual(value[0].value, "value two")217 218    def test_bad_keywords(self):219        def custom_parse(line_number, line, output):220            return output221 222        try:223            IntegratedTestKeywordParser("TAG_NO_SUFFIX", ParserKind.TAG),224            self.fail("TAG_NO_SUFFIX failed to raise an exception")225        except ValueError as e:226            pass227        except BaseException as e:228            self.fail("TAG_NO_SUFFIX raised the wrong exception: %r" % e)229 230        try:231            IntegratedTestKeywordParser("TAG_WITH_COLON:", ParserKind.TAG),232            self.fail("TAG_WITH_COLON: failed to raise an exception")233        except ValueError as e:234            pass235        except BaseException as e:236            self.fail("TAG_WITH_COLON: raised the wrong exception: %r" % e)237 238        try:239            IntegratedTestKeywordParser("LIST_WITH_DOT.", ParserKind.LIST),240            self.fail("LIST_WITH_DOT. failed to raise an exception")241        except ValueError as e:242            pass243        except BaseException as e:244            self.fail("LIST_WITH_DOT. raised the wrong exception: %r" % e)245 246        try:247            IntegratedTestKeywordParser("SPACE_LIST_WITH_DOT.", ParserKind.SPACE_LIST),248            self.fail("SPACE_LIST_WITH_DOT. failed to raise an exception")249        except ValueError as e:250            pass251        except BaseException as e:252            self.fail("SPACE_LIST_WITH_DOT. raised the wrong exception: %r" % e)253 254        try:255            IntegratedTestKeywordParser(256                "CUSTOM_NO_SUFFIX", ParserKind.CUSTOM, custom_parse257            ),258            self.fail("CUSTOM_NO_SUFFIX failed to raise an exception")259        except ValueError as e:260            pass261        except BaseException as e:262            self.fail("CUSTOM_NO_SUFFIX raised the wrong exception: %r" % e)263 264        # Both '.' and ':' are allowed for CUSTOM keywords.265        try:266            IntegratedTestKeywordParser(267                "CUSTOM_WITH_DOT.", ParserKind.CUSTOM, custom_parse268            ),269        except BaseException as e:270            self.fail("CUSTOM_WITH_DOT. raised an exception: %r" % e)271        try:272            IntegratedTestKeywordParser(273                "CUSTOM_WITH_COLON:", ParserKind.CUSTOM, custom_parse274            ),275        except BaseException as e:276            self.fail("CUSTOM_WITH_COLON: raised an exception: %r" % e)277 278        try:279            IntegratedTestKeywordParser("CUSTOM_NO_PARSER:", ParserKind.CUSTOM),280            self.fail("CUSTOM_NO_PARSER: failed to raise an exception")281        except ValueError as e:282            pass283        except BaseException as e:284            self.fail("CUSTOM_NO_PARSER: raised the wrong exception: %r" % e)285 286 287class TestApplySubtitutions(unittest.TestCase):288    def test_simple(self):289        script = ["echo %bar"]290        substitutions = [("%bar", "hello")]291        result = lit.TestRunner.applySubstitutions(script, substitutions)292        self.assertEqual(result, ["echo hello"])293 294    def test_multiple_substitutions(self):295        script = ["echo %bar %baz"]296        substitutions = [297            ("%bar", "hello"),298            ("%baz", "world"),299            ("%useless", "shouldnt expand"),300        ]301        result = lit.TestRunner.applySubstitutions(script, substitutions)302        self.assertEqual(result, ["echo hello world"])303 304    def test_multiple_script_lines(self):305        script = ["%cxx %compile_flags -c -o %t.o", "%cxx %link_flags %t.o -o %t.exe"]306        substitutions = [307            ("%cxx", "clang++"),308            ("%compile_flags", "-std=c++11 -O3"),309            ("%link_flags", "-lc++"),310        ]311        result = lit.TestRunner.applySubstitutions(script, substitutions)312        self.assertEqual(313            result,314            ["clang++ -std=c++11 -O3 -c -o %t.o", "clang++ -lc++ %t.o -o %t.exe"],315        )316 317    def test_recursive_substitution_real(self):318        script = ["%build %s"]319        substitutions = [320            ("%cxx", "clang++"),321            ("%compile_flags", "-std=c++11 -O3"),322            ("%link_flags", "-lc++"),323            ("%build", "%cxx %compile_flags %link_flags %s -o %t.exe"),324        ]325        result = lit.TestRunner.applySubstitutions(326            script, substitutions, recursion_limit=3327        )328        self.assertEqual(result, ["clang++ -std=c++11 -O3 -lc++ %s -o %t.exe %s"])329 330    def test_recursive_substitution_limit(self):331        script = ["%rec5"]332        # Make sure the substitutions are not in an order where the global333        # substitution would appear to be recursive just because they are334        # processed in the right order.335        substitutions = [336            ("%rec1", "STOP"),337            ("%rec2", "%rec1"),338            ("%rec3", "%rec2"),339            ("%rec4", "%rec3"),340            ("%rec5", "%rec4"),341        ]342        for limit in [5, 6, 7]:343            result = lit.TestRunner.applySubstitutions(344                script, substitutions, recursion_limit=limit345            )346            self.assertEqual(result, ["STOP"])347 348    def test_recursive_substitution_limit_exceeded(self):349        script = ["%rec5"]350        substitutions = [351            ("%rec1", "STOP"),352            ("%rec2", "%rec1"),353            ("%rec3", "%rec2"),354            ("%rec4", "%rec3"),355            ("%rec5", "%rec4"),356        ]357        for limit in [0, 1, 2, 3, 4]:358            try:359                lit.TestRunner.applySubstitutions(360                    script, substitutions, recursion_limit=limit361                )362                self.fail("applySubstitutions should have raised an exception")363            except ValueError:364                pass365 366    def test_recursive_substitution_invalid_value(self):367        script = ["%rec5"]368        substitutions = [369            ("%rec1", "STOP"),370            ("%rec2", "%rec1"),371            ("%rec3", "%rec2"),372            ("%rec4", "%rec3"),373            ("%rec5", "%rec4"),374        ]375        for limit in [-1, -2, -3, "foo"]:376            try:377                lit.TestRunner.applySubstitutions(378                    script, substitutions, recursion_limit=limit379                )380                self.fail("applySubstitutions should have raised an exception")381            except AssertionError:382                pass383 384 385if __name__ == "__main__":386    TestIntegratedTestKeywordParser.load_keyword_parser_lit_tests()387    unittest.main(verbosity=2)388