12 import lit
.Test
as Test
13 from lit
.TestRunner
import (
15 IntegratedTestKeywordParser
,
16 parseIntegratedTestScript
,
20 class TestIntegratedTestKeywordParser(unittest
.TestCase
):
24 def load_keyword_parser_lit_tests():
26 Create and load the LIT test suite and test objects used by
27 TestIntegratedTestKeywordParser
29 # Create the global config object.
30 lit_config
= lit
.LitConfig
.LitConfig(
35 valgrindLeakCheck
=False,
39 isWindows
=(platform
.system() == "Windows"),
43 TestIntegratedTestKeywordParser
.litConfig
= lit_config
44 # 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]
54 def custom_parse(line_number
, line
, output
):
57 output
+= [part
for part
in line
.split(" ") if part
.strip()]
61 IntegratedTestKeywordParser("MY_TAG.", ParserKind
.TAG
),
62 IntegratedTestKeywordParser("MY_DNE_TAG.", ParserKind
.TAG
),
63 IntegratedTestKeywordParser("MY_LIST:", ParserKind
.LIST
),
64 IntegratedTestKeywordParser("MY_BOOL:", ParserKind
.BOOLEAN_EXPR
),
65 IntegratedTestKeywordParser("MY_INT:", ParserKind
.INTEGER
),
66 IntegratedTestKeywordParser("MY_RUN:", ParserKind
.COMMAND
),
67 IntegratedTestKeywordParser("MY_CUSTOM:", ParserKind
.CUSTOM
, custom_parse
),
68 IntegratedTestKeywordParser("MY_DEFINE:", ParserKind
.DEFINE
),
69 IntegratedTestKeywordParser("MY_REDEFINE:", ParserKind
.REDEFINE
),
73 def get_parser(parser_list
, keyword
):
75 if p
.keyword
== keyword
:
77 assert False and "parser not found"
80 def parse_test(parser_list
, allow_result
=False):
81 script
= parseIntegratedTestScript(
82 TestIntegratedTestKeywordParser
.inputTestCase
,
83 additional_parsers
=parser_list
,
86 if isinstance(script
, lit
.Test
.Result
):
89 assert isinstance(script
, list)
90 assert len(script
) == 0
94 parsers
= self
.make_parsers()
95 self
.parse_test(parsers
)
96 tag_parser
= self
.get_parser(parsers
, "MY_TAG.")
97 dne_tag_parser
= self
.get_parser(parsers
, "MY_DNE_TAG.")
98 self
.assertTrue(tag_parser
.getValue())
99 self
.assertFalse(dne_tag_parser
.getValue())
101 def test_lists(self
):
102 parsers
= self
.make_parsers()
103 self
.parse_test(parsers
)
104 list_parser
= self
.get_parser(parsers
, "MY_LIST:")
105 self
.assertEqual(list_parser
.getValue(), ["one", "two", "three", "four"])
107 def test_commands(self
):
108 parsers
= self
.make_parsers()
109 self
.parse_test(parsers
)
110 cmd_parser
= self
.get_parser(parsers
, "MY_RUN:")
111 value
= cmd_parser
.getValue()
112 self
.assertEqual(len(value
), 2) # there are only two run lines
113 self
.assertEqual(value
[0].command
.strip(), "%dbg(MY_RUN: at line 4) baz")
114 self
.assertEqual(value
[1].command
.strip(), "%dbg(MY_RUN: at line 7) foo bar")
116 def test_boolean(self
):
117 parsers
= self
.make_parsers()
118 self
.parse_test(parsers
)
119 bool_parser
= self
.get_parser(parsers
, "MY_BOOL:")
120 value
= bool_parser
.getValue()
121 self
.assertEqual(len(value
), 2) # there are only two run lines
122 self
.assertEqual(value
[0].strip(), "a && (b)")
123 self
.assertEqual(value
[1].strip(), "d")
125 def test_integer(self
):
126 parsers
= self
.make_parsers()
127 self
.parse_test(parsers
)
128 int_parser
= self
.get_parser(parsers
, "MY_INT:")
129 value
= int_parser
.getValue()
130 self
.assertEqual(len(value
), 2) # there are only two MY_INT: lines
131 self
.assertEqual(type(value
[0]), int)
132 self
.assertEqual(value
[0], 4)
133 self
.assertEqual(type(value
[1]), int)
134 self
.assertEqual(value
[1], 6)
136 def test_bad_parser_type(self
):
137 parsers
= self
.make_parsers() + ["BAD_PARSER_TYPE"]
138 script
= self
.parse_test(parsers
, allow_result
=True)
139 self
.assertTrue(isinstance(script
, lit
.Test
.Result
))
140 self
.assertEqual(script
.code
, lit
.Test
.UNRESOLVED
)
142 "Additional parser must be an instance of " "IntegratedTestKeywordParser",
146 def test_duplicate_keyword(self
):
147 parsers
= self
.make_parsers() + [
148 IntegratedTestKeywordParser("KEY:", ParserKind
.BOOLEAN_EXPR
),
149 IntegratedTestKeywordParser("KEY:", ParserKind
.BOOLEAN_EXPR
),
151 script
= self
.parse_test(parsers
, allow_result
=True)
152 self
.assertTrue(isinstance(script
, lit
.Test
.Result
))
153 self
.assertEqual(script
.code
, lit
.Test
.UNRESOLVED
)
154 self
.assertEqual("Parser for keyword 'KEY:' already exists", script
.output
)
156 def test_boolean_unterminated(self
):
157 parsers
= self
.make_parsers() + [
158 IntegratedTestKeywordParser(
159 "MY_BOOL_UNTERMINATED:", ParserKind
.BOOLEAN_EXPR
162 script
= self
.parse_test(parsers
, allow_result
=True)
163 self
.assertTrue(isinstance(script
, lit
.Test
.Result
))
164 self
.assertEqual(script
.code
, lit
.Test
.UNRESOLVED
)
166 "Test has unterminated 'MY_BOOL_UNTERMINATED:' lines " "(with '\\')",
170 def test_custom(self
):
171 parsers
= self
.make_parsers()
172 self
.parse_test(parsers
)
173 custom_parser
= self
.get_parser(parsers
, "MY_CUSTOM:")
174 value
= custom_parser
.getValue()
175 self
.assertEqual(value
, ["a", "b", "c"])
177 def test_defines(self
):
178 parsers
= self
.make_parsers()
179 self
.parse_test(parsers
)
180 cmd_parser
= self
.get_parser(parsers
, "MY_DEFINE:")
181 value
= cmd_parser
.getValue()
182 self
.assertEqual(len(value
), 1) # there's only one MY_DEFINE directive
183 self
.assertEqual(value
[0].new_subst
, True)
184 self
.assertEqual(value
[0].name
, "%{name}")
185 self
.assertEqual(value
[0].value
, "value one")
187 def test_redefines(self
):
188 parsers
= self
.make_parsers()
189 self
.parse_test(parsers
)
190 cmd_parser
= self
.get_parser(parsers
, "MY_REDEFINE:")
191 value
= cmd_parser
.getValue()
192 self
.assertEqual(len(value
), 1) # there's only one MY_REDEFINE directive
193 self
.assertEqual(value
[0].new_subst
, False)
194 self
.assertEqual(value
[0].name
, "%{name}")
195 self
.assertEqual(value
[0].value
, "value two")
197 def test_bad_keywords(self
):
198 def custom_parse(line_number
, line
, output
):
202 IntegratedTestKeywordParser("TAG_NO_SUFFIX", ParserKind
.TAG
),
203 self
.fail("TAG_NO_SUFFIX failed to raise an exception")
204 except ValueError as e
:
206 except BaseException
as e
:
207 self
.fail("TAG_NO_SUFFIX raised the wrong exception: %r" % e
)
210 IntegratedTestKeywordParser("TAG_WITH_COLON:", ParserKind
.TAG
),
211 self
.fail("TAG_WITH_COLON: failed to raise an exception")
212 except ValueError as e
:
214 except BaseException
as e
:
215 self
.fail("TAG_WITH_COLON: raised the wrong exception: %r" % e
)
218 IntegratedTestKeywordParser("LIST_WITH_DOT.", ParserKind
.LIST
),
219 self
.fail("LIST_WITH_DOT. failed to raise an exception")
220 except ValueError as e
:
222 except BaseException
as e
:
223 self
.fail("LIST_WITH_DOT. raised the wrong exception: %r" % e
)
226 IntegratedTestKeywordParser(
227 "CUSTOM_NO_SUFFIX", ParserKind
.CUSTOM
, custom_parse
229 self
.fail("CUSTOM_NO_SUFFIX failed to raise an exception")
230 except ValueError as e
:
232 except BaseException
as e
:
233 self
.fail("CUSTOM_NO_SUFFIX raised the wrong exception: %r" % e
)
235 # Both '.' and ':' are allowed for CUSTOM keywords.
237 IntegratedTestKeywordParser(
238 "CUSTOM_WITH_DOT.", ParserKind
.CUSTOM
, custom_parse
240 except BaseException
as e
:
241 self
.fail("CUSTOM_WITH_DOT. raised an exception: %r" % e
)
243 IntegratedTestKeywordParser(
244 "CUSTOM_WITH_COLON:", ParserKind
.CUSTOM
, custom_parse
246 except BaseException
as e
:
247 self
.fail("CUSTOM_WITH_COLON: raised an exception: %r" % e
)
250 IntegratedTestKeywordParser("CUSTOM_NO_PARSER:", ParserKind
.CUSTOM
),
251 self
.fail("CUSTOM_NO_PARSER: failed to raise an exception")
252 except ValueError as e
:
254 except BaseException
as e
:
255 self
.fail("CUSTOM_NO_PARSER: raised the wrong exception: %r" % e
)
258 class TestApplySubtitutions(unittest
.TestCase
):
259 def test_simple(self
):
260 script
= ["echo %bar"]
261 substitutions
= [("%bar", "hello")]
262 result
= lit
.TestRunner
.applySubstitutions(script
, substitutions
)
263 self
.assertEqual(result
, ["echo hello"])
265 def test_multiple_substitutions(self
):
266 script
= ["echo %bar %baz"]
270 ("%useless", "shouldnt expand"),
272 result
= lit
.TestRunner
.applySubstitutions(script
, substitutions
)
273 self
.assertEqual(result
, ["echo hello world"])
275 def test_multiple_script_lines(self
):
276 script
= ["%cxx %compile_flags -c -o %t.o", "%cxx %link_flags %t.o -o %t.exe"]
279 ("%compile_flags", "-std=c++11 -O3"),
280 ("%link_flags", "-lc++"),
282 result
= lit
.TestRunner
.applySubstitutions(script
, substitutions
)
285 ["clang++ -std=c++11 -O3 -c -o %t.o", "clang++ -lc++ %t.o -o %t.exe"],
288 def test_recursive_substitution_real(self
):
289 script
= ["%build %s"]
292 ("%compile_flags", "-std=c++11 -O3"),
293 ("%link_flags", "-lc++"),
294 ("%build", "%cxx %compile_flags %link_flags %s -o %t.exe"),
296 result
= lit
.TestRunner
.applySubstitutions(
297 script
, substitutions
, recursion_limit
=3
299 self
.assertEqual(result
, ["clang++ -std=c++11 -O3 -lc++ %s -o %t.exe %s"])
301 def test_recursive_substitution_limit(self
):
303 # Make sure the substitutions are not in an order where the global
304 # substitution would appear to be recursive just because they are
305 # processed in the right order.
313 for limit
in [5, 6, 7]:
314 result
= lit
.TestRunner
.applySubstitutions(
315 script
, substitutions
, recursion_limit
=limit
317 self
.assertEqual(result
, ["STOP"])
319 def test_recursive_substitution_limit_exceeded(self
):
328 for limit
in [0, 1, 2, 3, 4]:
330 lit
.TestRunner
.applySubstitutions(
331 script
, substitutions
, recursion_limit
=limit
333 self
.fail("applySubstitutions should have raised an exception")
337 def test_recursive_substitution_invalid_value(self
):
346 for limit
in [-1, -2, -3, "foo"]:
348 lit
.TestRunner
.applySubstitutions(
349 script
, substitutions
, recursion_limit
=limit
351 self
.fail("applySubstitutions should have raised an exception")
352 except AssertionError:
356 if __name__
== "__main__":
357 TestIntegratedTestKeywordParser
.load_keyword_parser_lit_tests()
358 unittest
.main(verbosity
=2)