summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/bb/tests/parse.py
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake/lib/bb/tests/parse.py')
-rw-r--r--bitbake/lib/bb/tests/parse.py303
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 = """
79A = "set value"
80A ??= "default value"
81
82A[flag_set_vs_question] = "set flag"
83A[flag_set_vs_question] ?= "question flag"
84
85A[flag_set_vs_default] = "set flag"
86A[flag_set_vs_default] ??= "default flag"
87
88A[flag_question] ?= "question flag"
89
90A[flag_default] ??= "default flag"
91
92A[flag_question_vs_default] ?= "question flag"
93A[flag_question_vs_default] ??= "default flag"
94
95A[flag_default_vs_question] ??= "default flag"
96A[flag_default_vs_question] ?= "question flag"
97
98A[flag_set_question_default] = "set flag"
99A[flag_set_question_default] ?= "question flag"
100A[flag_set_question_default] ??= "default flag"
101
102A[flag_set_default_question] = "set flag"
103A[flag_set_default_question] ??= "default flag"
104A[flag_set_default_question] ?= "question flag"
105
106A[flag_set_twice] = "set flag first"
107A[flag_set_twice] = "set flag second"
108
109A[flag_question_twice] ?= "question flag first"
110A[flag_question_twice] ?= "question flag second"
111
112A[flag_default_twice] ??= "default flag first"
113A[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 = """
79A = "a" 132A = "a"
80export B = "b" 133export B = "b"
@@ -98,8 +151,8 @@ exportD = "d"
98 151
99 152
100 overridetest = """ 153 overridetest = """
101RRECOMMENDS_${PN} = "a" 154RRECOMMENDS:${PN} = "a"
102RRECOMMENDS_${PN}_libc = "b" 155RRECOMMENDS:${PN}:libc = "b"
103OVERRIDES = "libc:${PN}" 156OVERRIDES = "libc:${PN}"
104PN = "gtk+" 157PN = "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 = """
117EXTRA_OECONF = "" 170EXTRA_OECONF = ""
118EXTRA_OECONF_class-target = "b" 171EXTRA_OECONF:class-target = "b"
119EXTRA_OECONF_append = " c" 172EXTRA_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 = """
130DESCRIPTION = "A" 183DESCRIPTION = "A"
131DESCRIPTION_${PN}-dev = "${DESCRIPTION} B" 184DESCRIPTION:${PN}-dev = "${DESCRIPTION} B"
132PN = "bc" 185PN = "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 = """
147VAR_var_override1 = "B" 200VAR_var:override1 = "B"
148EXTRA = ":override1" 201EXTRA = ":override1"
149OVERRIDES = "nothing${EXTRA}" 202OVERRIDES = "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 = """
178addtask do_patch after do_foo after do_unpack before do_configure before do_compile 232addtask do_patch after do_foo after do_unpack before do_configure before do_compile
179addtask do_fetch do_patch 233addtask do_fetch2 do_patch2
234
235addtask do_myplaintask
236addtask do_myplaintask2
237deltask do_myplaintask2
238addtask do_mytask# comment
239addtask do_mytask2 # comment2
240addtask do_mytask3
241deltask do_mytask3# comment
242deltask do_mytask4 # comment2
243
244# Ensure a missing task prefix on after works
245addtask do_mytask5 after mytask
180 246
181MYVAR = "do_patch" 247MYVAR = "do_patch"
182EMPTYVAR = "" 248EMPTYVAR = ""
@@ -184,13 +250,216 @@ deltask do_fetch ${MYVAR} ${EMPTYVAR}
184deltask ${EMPTYVAR} 250deltask ${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 = """
272VAR = " \\
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 = """
285A[flag@.service] = "nonet"
286B[flag@.target] = "ntb"
287C[f] = "flag"
196 288
289unset 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 = """
307inherit someclass
308"""
309
310 export_function_recipe2 = """
311inherit someclass
312
313do_compile () {
314 false
315}
316
317python do_compilepython () {
318 bb.note("Something else")
319}
320
321"""
322 export_function_class = """
323someclass_do_compile() {
324 true
325}
326
327python someclass_do_compilepython () {
328 bb.note("Something")
329}
330
331EXPORT_FUNCTIONS do_compile do_compilepython
332"""
333
334 export_function_class2 = """
335secondclass_do_compile() {
336 true
337}
338
339python secondclass_do_compilepython () {
340 bb.note("Something")
341}
342
343EXPORT_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 = """
405do_compile () {
406 bb.note("Something")
407\t}
408"""
409 export_function_unclosed_space = """
410do_compile () {
411 bb.note("Something")
412 }
413"""
414 export_function_residue = """
415do_compile () {
416 bb.note("Something")
417}
418
419include \\
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 = """
448A+="a"
449A+ = "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))