diff options
author | Eric Fiselier <eric@efcs.ca> | 2016-12-05 20:21:21 +0000 |
---|---|---|
committer | Eric Fiselier <eric@efcs.ca> | 2016-12-05 20:21:21 +0000 |
commit | df87d070c917029bd0209408fcfe833d149bcca7 (patch) | |
tree | 5036a58bda62ac62d0dde435b06f0c407af5f513 /llvm/utils/lit/tests/unit/TestRunner.py | |
parent | a8eed310f5defddec84dcf6b9328642a9c3936fd (diff) | |
download | bcm5719-llvm-df87d070c917029bd0209408fcfe833d149bcca7.tar.gz bcm5719-llvm-df87d070c917029bd0209408fcfe833d149bcca7.zip |
[lit] Support custom parsers in parseIntegratedTestScript
Summary:
Libc++ frequently has the need to parse more than just the builtin *test keywords* (`RUN`, `REQUIRES`, `XFAIL`, ect). For example libc++ currently needs a new keyword `MODULES-DEFINES: macro list...`. Instead of re-implementing the script parsing in libc++ this patch allows `parseIntegratedTestScript` to take custom parsers.
This patch introduces a new class `IntegratedTestKeywordParser` which implements the logic to parse/process a test keyword. Parsing of various keyword "kinds" are supported out of the box, including 'TAG', 'COMMAND', and 'LIST', which parse keywords such as `END.`, `RUN:` and `XFAIL:` respectively.
As an example after this change libc++ can implement the `MODULES-DEFINES` simply using:
```
mparser = IntegratedTestKeywordParser('MODULES-DEFINES:', ParserKind.LIST)
parseIntegratedTestScript(test, additional_parsers=[mparser])
macro_list = mparser.getValue()
```
Reviewers: ddunbar, modocache, rnk, danalbert, jroelofs
Subscribers: mgrang, llvm-commits, cfe-commits
Differential Revision: https://reviews.llvm.org/D27005
llvm-svn: 288694
Diffstat (limited to 'llvm/utils/lit/tests/unit/TestRunner.py')
-rw-r--r-- | llvm/utils/lit/tests/unit/TestRunner.py | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/llvm/utils/lit/tests/unit/TestRunner.py b/llvm/utils/lit/tests/unit/TestRunner.py new file mode 100644 index 00000000000..ff11834fed7 --- /dev/null +++ b/llvm/utils/lit/tests/unit/TestRunner.py @@ -0,0 +1,114 @@ +# RUN: %{python} %s +# +# END. + + +import unittest +import platform +import os.path +import tempfile + +import lit +from lit.TestRunner import ParserKind, IntegratedTestKeywordParser, \ + parseIntegratedTestScript + + +class TestIntegratedTestKeywordParser(unittest.TestCase): + inputTestCase = None + + @staticmethod + def load_keyword_parser_lit_tests(): + """ + Create and load the LIT test suite and test objects used by + TestIntegratedTestKeywordParser + """ + # Create the global config object. + lit_config = lit.LitConfig.LitConfig(progname='lit', + path=[], + quiet=False, + useValgrind=False, + valgrindLeakCheck=False, + valgrindArgs=[], + noExecute=False, + debug=False, + isWindows=( + platform.system() == 'Windows'), + params={}) + TestIntegratedTestKeywordParser.litConfig = lit_config + # Perform test discovery. + test_path = os.path.dirname(os.path.dirname(__file__)) + inputs = [os.path.join(test_path, 'Inputs/testrunner-custom-parsers/')] + assert os.path.isdir(inputs[0]) + run = lit.run.Run(lit_config, + lit.discovery.find_tests_for_inputs(lit_config, inputs)) + assert len(run.tests) == 1 and "there should only be one test" + TestIntegratedTestKeywordParser.inputTestCase = run.tests[0] + + @staticmethod + def make_parsers(): + def custom_parse(line_number, line, output): + if output is None: + output = [] + output += [part for part in line.split(' ') if part.strip()] + return output + + return [ + IntegratedTestKeywordParser("MY_TAG.", ParserKind.TAG), + IntegratedTestKeywordParser("MY_DNE_TAG.", ParserKind.TAG), + IntegratedTestKeywordParser("MY_LIST:", ParserKind.LIST), + IntegratedTestKeywordParser("MY_RUN:", ParserKind.COMMAND), + IntegratedTestKeywordParser("MY_CUSTOM:", ParserKind.CUSTOM, + custom_parse) + ] + + @staticmethod + def get_parser(parser_list, keyword): + for p in parser_list: + if p.keyword == keyword: + return p + assert False and "parser not found" + + @staticmethod + def parse_test(parser_list): + script = parseIntegratedTestScript( + TestIntegratedTestKeywordParser.inputTestCase, + additional_parsers=parser_list, require_script=False) + assert not isinstance(script, lit.Test.Result) + assert isinstance(script, list) + assert len(script) == 0 + + def test_tags(self): + parsers = self.make_parsers() + self.parse_test(parsers) + tag_parser = self.get_parser(parsers, 'MY_TAG.') + dne_tag_parser = self.get_parser(parsers, 'MY_DNE_TAG.') + self.assertTrue(tag_parser.getValue()) + self.assertFalse(dne_tag_parser.getValue()) + + def test_lists(self): + parsers = self.make_parsers() + self.parse_test(parsers) + list_parser = self.get_parser(parsers, 'MY_LIST:') + self.assertItemsEqual(list_parser.getValue(), + ['one', 'two', 'three', 'four']) + + def test_commands(self): + parsers = self.make_parsers() + self.parse_test(parsers) + cmd_parser = self.get_parser(parsers, 'MY_RUN:') + value = cmd_parser.getValue() + self.assertEqual(len(value), 2) # there are only two run lines + self.assertEqual(value[0].strip(), 'baz') + self.assertEqual(value[1].strip(), 'foo bar') + + def test_custom(self): + parsers = self.make_parsers() + self.parse_test(parsers) + custom_parser = self.get_parser(parsers, 'MY_CUSTOM:') + value = custom_parser.getValue() + self.assertItemsEqual(value, ['a', 'b', 'c']) + + +if __name__ == '__main__': + TestIntegratedTestKeywordParser.load_keyword_parser_lit_tests() + unittest.main(verbosity=2) |