diff options
Diffstat (limited to 'bitbake/lib/bb/tests/parse.py')
-rw-r--r-- | bitbake/lib/bb/tests/parse.py | 303 |
1 files changed, 286 insertions, 17 deletions
diff --git a/bitbake/lib/bb/tests/parse.py b/bitbake/lib/bb/tests/parse.py index 9e21e18425..e3cba67ad4 100644 --- a/bitbake/lib/bb/tests/parse.py +++ b/bitbake/lib/bb/tests/parse.py | |||
@@ -75,6 +75,59 @@ unset B[flag] | |||
75 | self.assertEqual(d.getVarFlag("A","flag"), None) | 75 | self.assertEqual(d.getVarFlag("A","flag"), None) |
76 | self.assertEqual(d.getVar("B"), "2") | 76 | self.assertEqual(d.getVar("B"), "2") |
77 | 77 | ||
78 | defaulttest = """ | ||
79 | A = "set value" | ||
80 | A ??= "default value" | ||
81 | |||
82 | A[flag_set_vs_question] = "set flag" | ||
83 | A[flag_set_vs_question] ?= "question flag" | ||
84 | |||
85 | A[flag_set_vs_default] = "set flag" | ||
86 | A[flag_set_vs_default] ??= "default flag" | ||
87 | |||
88 | A[flag_question] ?= "question flag" | ||
89 | |||
90 | A[flag_default] ??= "default flag" | ||
91 | |||
92 | A[flag_question_vs_default] ?= "question flag" | ||
93 | A[flag_question_vs_default] ??= "default flag" | ||
94 | |||
95 | A[flag_default_vs_question] ??= "default flag" | ||
96 | A[flag_default_vs_question] ?= "question flag" | ||
97 | |||
98 | A[flag_set_question_default] = "set flag" | ||
99 | A[flag_set_question_default] ?= "question flag" | ||
100 | A[flag_set_question_default] ??= "default flag" | ||
101 | |||
102 | A[flag_set_default_question] = "set flag" | ||
103 | A[flag_set_default_question] ??= "default flag" | ||
104 | A[flag_set_default_question] ?= "question flag" | ||
105 | |||
106 | A[flag_set_twice] = "set flag first" | ||
107 | A[flag_set_twice] = "set flag second" | ||
108 | |||
109 | A[flag_question_twice] ?= "question flag first" | ||
110 | A[flag_question_twice] ?= "question flag second" | ||
111 | |||
112 | A[flag_default_twice] ??= "default flag first" | ||
113 | A[flag_default_twice] ??= "default flag second" | ||
114 | """ | ||
115 | def test_parse_defaulttest(self): | ||
116 | f = self.parsehelper(self.defaulttest) | ||
117 | d = bb.parse.handle(f.name, self.d)[''] | ||
118 | self.assertEqual(d.getVar("A"), "set value") | ||
119 | self.assertEqual(d.getVarFlag("A","flag_set_vs_question"), "set flag") | ||
120 | self.assertEqual(d.getVarFlag("A","flag_set_vs_default"), "set flag") | ||
121 | self.assertEqual(d.getVarFlag("A","flag_question"), "question flag") | ||
122 | self.assertEqual(d.getVarFlag("A","flag_default"), "default flag") | ||
123 | self.assertEqual(d.getVarFlag("A","flag_question_vs_default"), "question flag") | ||
124 | self.assertEqual(d.getVarFlag("A","flag_default_vs_question"), "question flag") | ||
125 | self.assertEqual(d.getVarFlag("A","flag_set_question_default"), "set flag") | ||
126 | self.assertEqual(d.getVarFlag("A","flag_set_default_question"), "set flag") | ||
127 | self.assertEqual(d.getVarFlag("A","flag_set_twice"), "set flag second") | ||
128 | self.assertEqual(d.getVarFlag("A","flag_question_twice"), "question flag first") | ||
129 | self.assertEqual(d.getVarFlag("A","flag_default_twice"), "default flag second") | ||
130 | |||
78 | exporttest = """ | 131 | exporttest = """ |
79 | A = "a" | 132 | A = "a" |
80 | export B = "b" | 133 | export B = "b" |
@@ -98,8 +151,8 @@ exportD = "d" | |||
98 | 151 | ||
99 | 152 | ||
100 | overridetest = """ | 153 | overridetest = """ |
101 | RRECOMMENDS_${PN} = "a" | 154 | RRECOMMENDS:${PN} = "a" |
102 | RRECOMMENDS_${PN}_libc = "b" | 155 | RRECOMMENDS:${PN}:libc = "b" |
103 | OVERRIDES = "libc:${PN}" | 156 | OVERRIDES = "libc:${PN}" |
104 | PN = "gtk+" | 157 | PN = "gtk+" |
105 | """ | 158 | """ |
@@ -110,16 +163,16 @@ PN = "gtk+" | |||
110 | self.assertEqual(d.getVar("RRECOMMENDS"), "b") | 163 | self.assertEqual(d.getVar("RRECOMMENDS"), "b") |
111 | bb.data.expandKeys(d) | 164 | bb.data.expandKeys(d) |
112 | self.assertEqual(d.getVar("RRECOMMENDS"), "b") | 165 | self.assertEqual(d.getVar("RRECOMMENDS"), "b") |
113 | d.setVar("RRECOMMENDS_gtk+", "c") | 166 | d.setVar("RRECOMMENDS:gtk+", "c") |
114 | self.assertEqual(d.getVar("RRECOMMENDS"), "c") | 167 | self.assertEqual(d.getVar("RRECOMMENDS"), "c") |
115 | 168 | ||
116 | overridetest2 = """ | 169 | overridetest2 = """ |
117 | EXTRA_OECONF = "" | 170 | EXTRA_OECONF = "" |
118 | EXTRA_OECONF_class-target = "b" | 171 | EXTRA_OECONF:class-target = "b" |
119 | EXTRA_OECONF_append = " c" | 172 | EXTRA_OECONF:append = " c" |
120 | """ | 173 | """ |
121 | 174 | ||
122 | def test_parse_overrides(self): | 175 | def test_parse_overrides2(self): |
123 | f = self.parsehelper(self.overridetest2) | 176 | f = self.parsehelper(self.overridetest2) |
124 | d = bb.parse.handle(f.name, self.d)[''] | 177 | d = bb.parse.handle(f.name, self.d)[''] |
125 | d.appendVar("EXTRA_OECONF", " d") | 178 | d.appendVar("EXTRA_OECONF", " d") |
@@ -128,7 +181,7 @@ EXTRA_OECONF_append = " c" | |||
128 | 181 | ||
129 | overridetest3 = """ | 182 | overridetest3 = """ |
130 | DESCRIPTION = "A" | 183 | DESCRIPTION = "A" |
131 | DESCRIPTION_${PN}-dev = "${DESCRIPTION} B" | 184 | DESCRIPTION:${PN}-dev = "${DESCRIPTION} B" |
132 | PN = "bc" | 185 | PN = "bc" |
133 | """ | 186 | """ |
134 | 187 | ||
@@ -136,15 +189,15 @@ PN = "bc" | |||
136 | f = self.parsehelper(self.overridetest3) | 189 | f = self.parsehelper(self.overridetest3) |
137 | d = bb.parse.handle(f.name, self.d)[''] | 190 | d = bb.parse.handle(f.name, self.d)[''] |
138 | bb.data.expandKeys(d) | 191 | bb.data.expandKeys(d) |
139 | self.assertEqual(d.getVar("DESCRIPTION_bc-dev"), "A B") | 192 | self.assertEqual(d.getVar("DESCRIPTION:bc-dev"), "A B") |
140 | d.setVar("DESCRIPTION", "E") | 193 | d.setVar("DESCRIPTION", "E") |
141 | d.setVar("DESCRIPTION_bc-dev", "C D") | 194 | d.setVar("DESCRIPTION:bc-dev", "C D") |
142 | d.setVar("OVERRIDES", "bc-dev") | 195 | d.setVar("OVERRIDES", "bc-dev") |
143 | self.assertEqual(d.getVar("DESCRIPTION"), "C D") | 196 | self.assertEqual(d.getVar("DESCRIPTION"), "C D") |
144 | 197 | ||
145 | 198 | ||
146 | classextend = """ | 199 | classextend = """ |
147 | VAR_var_override1 = "B" | 200 | VAR_var:override1 = "B" |
148 | EXTRA = ":override1" | 201 | EXTRA = ":override1" |
149 | OVERRIDES = "nothing${EXTRA}" | 202 | OVERRIDES = "nothing${EXTRA}" |
150 | 203 | ||
@@ -164,6 +217,7 @@ python () { | |||
164 | # become unset/disappear. | 217 | # become unset/disappear. |
165 | # | 218 | # |
166 | def test_parse_classextend_contamination(self): | 219 | def test_parse_classextend_contamination(self): |
220 | self.d.setVar("__bbclasstype", "recipe") | ||
167 | cls = self.parsehelper(self.classextend_bbclass, suffix=".bbclass") | 221 | cls = self.parsehelper(self.classextend_bbclass, suffix=".bbclass") |
168 | #clsname = os.path.basename(cls.name).replace(".bbclass", "") | 222 | #clsname = os.path.basename(cls.name).replace(".bbclass", "") |
169 | self.classextend = self.classextend.replace("###CLASS###", cls.name) | 223 | self.classextend = self.classextend.replace("###CLASS###", cls.name) |
@@ -176,7 +230,19 @@ python () { | |||
176 | 230 | ||
177 | addtask_deltask = """ | 231 | addtask_deltask = """ |
178 | addtask do_patch after do_foo after do_unpack before do_configure before do_compile | 232 | addtask do_patch after do_foo after do_unpack before do_configure before do_compile |
179 | addtask do_fetch do_patch | 233 | addtask do_fetch2 do_patch2 |
234 | |||
235 | addtask do_myplaintask | ||
236 | addtask do_myplaintask2 | ||
237 | deltask do_myplaintask2 | ||
238 | addtask do_mytask# comment | ||
239 | addtask do_mytask2 # comment2 | ||
240 | addtask do_mytask3 | ||
241 | deltask do_mytask3# comment | ||
242 | deltask do_mytask4 # comment2 | ||
243 | |||
244 | # Ensure a missing task prefix on after works | ||
245 | addtask do_mytask5 after mytask | ||
180 | 246 | ||
181 | MYVAR = "do_patch" | 247 | MYVAR = "do_patch" |
182 | EMPTYVAR = "" | 248 | EMPTYVAR = "" |
@@ -184,13 +250,216 @@ deltask do_fetch ${MYVAR} ${EMPTYVAR} | |||
184 | deltask ${EMPTYVAR} | 250 | deltask ${EMPTYVAR} |
185 | """ | 251 | """ |
186 | def test_parse_addtask_deltask(self): | 252 | def test_parse_addtask_deltask(self): |
187 | import sys | 253 | |
188 | f = self.parsehelper(self.addtask_deltask) | 254 | f = self.parsehelper(self.addtask_deltask) |
189 | d = bb.parse.handle(f.name, self.d)[''] | 255 | d = bb.parse.handle(f.name, self.d)[''] |
190 | 256 | ||
191 | stdout = sys.stdout.getvalue() | 257 | self.assertSequenceEqual(['do_fetch2', 'do_patch2', 'do_myplaintask', 'do_mytask', 'do_mytask2', 'do_mytask5'], bb.build.listtasks(d)) |
192 | self.assertTrue("addtask contained multiple 'before' keywords" in stdout) | 258 | self.assertEqual(['do_mytask'], d.getVarFlag("do_mytask5", "deps")) |
193 | self.assertTrue("addtask contained multiple 'after' keywords" in stdout) | 259 | |
194 | self.assertTrue('addtask ignored: " do_patch"' in stdout) | 260 | broken_multiline_comment = """ |
195 | #self.assertTrue('dependent task do_foo for do_patch does not exist' in stdout) | 261 | # First line of comment \\ |
262 | # Second line of comment \\ | ||
263 | |||
264 | """ | ||
265 | def test_parse_broken_multiline_comment(self): | ||
266 | f = self.parsehelper(self.broken_multiline_comment) | ||
267 | with self.assertRaises(bb.BBHandledException): | ||
268 | d = bb.parse.handle(f.name, self.d)[''] | ||
269 | |||
270 | |||
271 | comment_in_var = """ | ||
272 | VAR = " \\ | ||
273 | SOMEVAL \\ | ||
274 | # some comment \\ | ||
275 | SOMEOTHERVAL \\ | ||
276 | " | ||
277 | """ | ||
278 | def test_parse_comment_in_var(self): | ||
279 | f = self.parsehelper(self.comment_in_var) | ||
280 | with self.assertRaises(bb.BBHandledException): | ||
281 | d = bb.parse.handle(f.name, self.d)[''] | ||
282 | |||
283 | |||
284 | at_sign_in_var_flag = """ | ||
285 | A[flag@.service] = "nonet" | ||
286 | B[flag@.target] = "ntb" | ||
287 | C[f] = "flag" | ||
196 | 288 | ||
289 | unset A[flag@.service] | ||
290 | """ | ||
291 | def test_parse_at_sign_in_var_flag(self): | ||
292 | f = self.parsehelper(self.at_sign_in_var_flag) | ||
293 | d = bb.parse.handle(f.name, self.d)[''] | ||
294 | self.assertEqual(d.getVar("A"), None) | ||
295 | self.assertEqual(d.getVar("B"), None) | ||
296 | self.assertEqual(d.getVarFlag("A","flag@.service"), None) | ||
297 | self.assertEqual(d.getVarFlag("B","flag@.target"), "ntb") | ||
298 | self.assertEqual(d.getVarFlag("C","f"), "flag") | ||
299 | |||
300 | def test_parse_invalid_at_sign_in_var_flag(self): | ||
301 | invalid_at_sign = self.at_sign_in_var_flag.replace("B[f", "B[@f") | ||
302 | f = self.parsehelper(invalid_at_sign) | ||
303 | with self.assertRaises(bb.parse.ParseError): | ||
304 | d = bb.parse.handle(f.name, self.d)[''] | ||
305 | |||
306 | export_function_recipe = """ | ||
307 | inherit someclass | ||
308 | """ | ||
309 | |||
310 | export_function_recipe2 = """ | ||
311 | inherit someclass | ||
312 | |||
313 | do_compile () { | ||
314 | false | ||
315 | } | ||
316 | |||
317 | python do_compilepython () { | ||
318 | bb.note("Something else") | ||
319 | } | ||
320 | |||
321 | """ | ||
322 | export_function_class = """ | ||
323 | someclass_do_compile() { | ||
324 | true | ||
325 | } | ||
326 | |||
327 | python someclass_do_compilepython () { | ||
328 | bb.note("Something") | ||
329 | } | ||
330 | |||
331 | EXPORT_FUNCTIONS do_compile do_compilepython | ||
332 | """ | ||
333 | |||
334 | export_function_class2 = """ | ||
335 | secondclass_do_compile() { | ||
336 | true | ||
337 | } | ||
338 | |||
339 | python secondclass_do_compilepython () { | ||
340 | bb.note("Something") | ||
341 | } | ||
342 | |||
343 | EXPORT_FUNCTIONS do_compile do_compilepython | ||
344 | """ | ||
345 | |||
346 | def test_parse_export_functions(self): | ||
347 | def check_function_flags(d): | ||
348 | self.assertEqual(d.getVarFlag("do_compile", "func"), 1) | ||
349 | self.assertEqual(d.getVarFlag("do_compilepython", "func"), 1) | ||
350 | self.assertEqual(d.getVarFlag("do_compile", "python"), None) | ||
351 | self.assertEqual(d.getVarFlag("do_compilepython", "python"), "1") | ||
352 | |||
353 | with tempfile.TemporaryDirectory() as tempdir: | ||
354 | self.d.setVar("__bbclasstype", "recipe") | ||
355 | recipename = tempdir + "/recipe.bb" | ||
356 | os.makedirs(tempdir + "/classes") | ||
357 | with open(tempdir + "/classes/someclass.bbclass", "w") as f: | ||
358 | f.write(self.export_function_class) | ||
359 | f.flush() | ||
360 | with open(tempdir + "/classes/secondclass.bbclass", "w") as f: | ||
361 | f.write(self.export_function_class2) | ||
362 | f.flush() | ||
363 | |||
364 | with open(recipename, "w") as f: | ||
365 | f.write(self.export_function_recipe) | ||
366 | f.flush() | ||
367 | os.chdir(tempdir) | ||
368 | d = bb.parse.handle(recipename, bb.data.createCopy(self.d))[''] | ||
369 | self.assertIn("someclass_do_compile", d.getVar("do_compile")) | ||
370 | self.assertIn("someclass_do_compilepython", d.getVar("do_compilepython")) | ||
371 | check_function_flags(d) | ||
372 | |||
373 | recipename2 = tempdir + "/recipe2.bb" | ||
374 | with open(recipename2, "w") as f: | ||
375 | f.write(self.export_function_recipe2) | ||
376 | f.flush() | ||
377 | |||
378 | d = bb.parse.handle(recipename2, bb.data.createCopy(self.d))[''] | ||
379 | self.assertNotIn("someclass_do_compile", d.getVar("do_compile")) | ||
380 | self.assertNotIn("someclass_do_compilepython", d.getVar("do_compilepython")) | ||
381 | self.assertIn("false", d.getVar("do_compile")) | ||
382 | self.assertIn("else", d.getVar("do_compilepython")) | ||
383 | check_function_flags(d) | ||
384 | |||
385 | with open(recipename, "a+") as f: | ||
386 | f.write("\ninherit secondclass\n") | ||
387 | f.flush() | ||
388 | with open(recipename2, "a+") as f: | ||
389 | f.write("\ninherit secondclass\n") | ||
390 | f.flush() | ||
391 | |||
392 | d = bb.parse.handle(recipename, bb.data.createCopy(self.d))[''] | ||
393 | self.assertIn("secondclass_do_compile", d.getVar("do_compile")) | ||
394 | self.assertIn("secondclass_do_compilepython", d.getVar("do_compilepython")) | ||
395 | check_function_flags(d) | ||
396 | |||
397 | d = bb.parse.handle(recipename2, bb.data.createCopy(self.d))[''] | ||
398 | self.assertNotIn("someclass_do_compile", d.getVar("do_compile")) | ||
399 | self.assertNotIn("someclass_do_compilepython", d.getVar("do_compilepython")) | ||
400 | self.assertIn("false", d.getVar("do_compile")) | ||
401 | self.assertIn("else", d.getVar("do_compilepython")) | ||
402 | check_function_flags(d) | ||
403 | |||
404 | export_function_unclosed_tab = """ | ||
405 | do_compile () { | ||
406 | bb.note("Something") | ||
407 | \t} | ||
408 | """ | ||
409 | export_function_unclosed_space = """ | ||
410 | do_compile () { | ||
411 | bb.note("Something") | ||
412 | } | ||
413 | """ | ||
414 | export_function_residue = """ | ||
415 | do_compile () { | ||
416 | bb.note("Something") | ||
417 | } | ||
418 | |||
419 | include \\ | ||
420 | """ | ||
421 | |||
422 | def test_unclosed_functions(self): | ||
423 | def test_helper(content, expected_error): | ||
424 | with tempfile.TemporaryDirectory() as tempdir: | ||
425 | recipename = tempdir + "/recipe_unclosed.bb" | ||
426 | with open(recipename, "w") as f: | ||
427 | f.write(content) | ||
428 | f.flush() | ||
429 | os.chdir(tempdir) | ||
430 | with self.assertRaises(bb.parse.ParseError) as error: | ||
431 | bb.parse.handle(recipename, bb.data.createCopy(self.d)) | ||
432 | self.assertIn(expected_error, str(error.exception)) | ||
433 | |||
434 | with tempfile.TemporaryDirectory() as tempdir: | ||
435 | test_helper(self.export_function_unclosed_tab, "Unparsed lines from unclosed function") | ||
436 | test_helper(self.export_function_unclosed_space, "Unparsed lines from unclosed function") | ||
437 | test_helper(self.export_function_residue, "Unparsed lines") | ||
438 | |||
439 | recipename_closed = tempdir + "/recipe_closed.bb" | ||
440 | with open(recipename_closed, "w") as in_file: | ||
441 | lines = self.export_function_unclosed_tab.split("\n") | ||
442 | lines[3] = "}" | ||
443 | in_file.write("\n".join(lines)) | ||
444 | in_file.flush() | ||
445 | bb.parse.handle(recipename_closed, bb.data.createCopy(self.d)) | ||
446 | |||
447 | special_character_assignment = """ | ||
448 | A+="a" | ||
449 | A+ = "b" | ||
450 | + = "c" | ||
451 | """ | ||
452 | ambigous_assignment = """ | ||
453 | += "d" | ||
454 | """ | ||
455 | def test_parse_special_character_assignment(self): | ||
456 | f = self.parsehelper(self.special_character_assignment) | ||
457 | d = bb.parse.handle(f.name, self.d)[''] | ||
458 | self.assertEqual(d.getVar("A"), " a") | ||
459 | self.assertEqual(d.getVar("A+"), "b") | ||
460 | self.assertEqual(d.getVar("+"), "c") | ||
461 | |||
462 | f = self.parsehelper(self.ambigous_assignment) | ||
463 | with self.assertRaises(bb.parse.ParseError) as error: | ||
464 | bb.parse.handle(f.name, self.d) | ||
465 | self.assertIn("Empty variable name in assignment", str(error.exception)) | ||