blob: ee7f2534f156004ec8b70b6791742b67e7bfc063 [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001#
2# BitBake Test for lib/bb/parse/
3#
4# Copyright (C) 2015 Richard Purdie
5#
Brad Bishopc342db32019-05-15 21:57:59 -04006# SPDX-License-Identifier: GPL-2.0-only
Patrick Williamsc124f4f2015-09-15 14:41:29 -05007#
8
9import unittest
10import tempfile
11import logging
12import bb
13import os
14
15logger = logging.getLogger('BitBake.TestParse')
16
17import bb.parse
18import bb.data
19import bb.siggen
20
21class ParseTest(unittest.TestCase):
22
23 testfile = """
24A = "1"
25B = "2"
26do_install() {
27 echo "hello"
28}
29
30C = "3"
31"""
32
33 def setUp(self):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080034 self.origdir = os.getcwd()
Patrick Williamsc124f4f2015-09-15 14:41:29 -050035 self.d = bb.data.init()
36 bb.parse.siggen = bb.siggen.init(self.d)
37
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080038 def tearDown(self):
39 os.chdir(self.origdir)
40
Patrick Williamsc124f4f2015-09-15 14:41:29 -050041 def parsehelper(self, content, suffix = ".bb"):
42
43 f = tempfile.NamedTemporaryFile(suffix = suffix)
Patrick Williamsc0f7c042017-02-23 20:41:17 -060044 f.write(bytes(content, "utf-8"))
Patrick Williamsc124f4f2015-09-15 14:41:29 -050045 f.flush()
46 os.chdir(os.path.dirname(f.name))
47 return f
48
49 def test_parse_simple(self):
50 f = self.parsehelper(self.testfile)
51 d = bb.parse.handle(f.name, self.d)['']
Brad Bishop6e60e8b2018-02-01 10:27:11 -050052 self.assertEqual(d.getVar("A"), "1")
53 self.assertEqual(d.getVar("B"), "2")
54 self.assertEqual(d.getVar("C"), "3")
Patrick Williamsc124f4f2015-09-15 14:41:29 -050055
56 def test_parse_incomplete_function(self):
57 testfileB = self.testfile.replace("}", "")
58 f = self.parsehelper(testfileB)
59 with self.assertRaises(bb.parse.ParseError):
60 d = bb.parse.handle(f.name, self.d)['']
61
Patrick Williamsc0f7c042017-02-23 20:41:17 -060062 unsettest = """
63A = "1"
64B = "2"
65B[flag] = "3"
66
67unset A
68unset B[flag]
69"""
70
71 def test_parse_unset(self):
72 f = self.parsehelper(self.unsettest)
73 d = bb.parse.handle(f.name, self.d)['']
Brad Bishop6e60e8b2018-02-01 10:27:11 -050074 self.assertEqual(d.getVar("A"), None)
75 self.assertEqual(d.getVarFlag("A","flag"), None)
76 self.assertEqual(d.getVar("B"), "2")
Brad Bishopd7bf8c12018-02-25 22:55:05 -050077
78 exporttest = """
79A = "a"
80export B = "b"
81export C
82exportD = "d"
83"""
84
85 def test_parse_exports(self):
86 f = self.parsehelper(self.exporttest)
87 d = bb.parse.handle(f.name, self.d)['']
88 self.assertEqual(d.getVar("A"), "a")
89 self.assertIsNone(d.getVarFlag("A", "export"))
90 self.assertEqual(d.getVar("B"), "b")
91 self.assertEqual(d.getVarFlag("B", "export"), 1)
92 self.assertIsNone(d.getVar("C"))
93 self.assertEqual(d.getVarFlag("C", "export"), 1)
94 self.assertIsNone(d.getVar("D"))
95 self.assertIsNone(d.getVarFlag("D", "export"))
96 self.assertEqual(d.getVar("exportD"), "d")
97 self.assertIsNone(d.getVarFlag("exportD", "export"))
98
Patrick Williamsc0f7c042017-02-23 20:41:17 -060099
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500100 overridetest = """
Patrick Williams213cb262021-08-07 19:21:33 -0500101RRECOMMENDS:${PN} = "a"
102RRECOMMENDS:${PN}:libc = "b"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500103OVERRIDES = "libc:${PN}"
104PN = "gtk+"
105"""
106
107 def test_parse_overrides(self):
108 f = self.parsehelper(self.overridetest)
109 d = bb.parse.handle(f.name, self.d)['']
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500110 self.assertEqual(d.getVar("RRECOMMENDS"), "b")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500111 bb.data.expandKeys(d)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500112 self.assertEqual(d.getVar("RRECOMMENDS"), "b")
Patrick Williams213cb262021-08-07 19:21:33 -0500113 d.setVar("RRECOMMENDS:gtk+", "c")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500114 self.assertEqual(d.getVar("RRECOMMENDS"), "c")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500115
116 overridetest2 = """
117EXTRA_OECONF = ""
Patrick Williams213cb262021-08-07 19:21:33 -0500118EXTRA_OECONF:class-target = "b"
119EXTRA_OECONF:append = " c"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500120"""
121
Patrick Williams03907ee2022-05-01 06:28:52 -0500122 def test_parse_overrides2(self):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500123 f = self.parsehelper(self.overridetest2)
124 d = bb.parse.handle(f.name, self.d)['']
125 d.appendVar("EXTRA_OECONF", " d")
126 d.setVar("OVERRIDES", "class-target")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500127 self.assertEqual(d.getVar("EXTRA_OECONF"), "b c d")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500128
129 overridetest3 = """
130DESCRIPTION = "A"
Patrick Williams213cb262021-08-07 19:21:33 -0500131DESCRIPTION:${PN}-dev = "${DESCRIPTION} B"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500132PN = "bc"
133"""
134
135 def test_parse_combinations(self):
136 f = self.parsehelper(self.overridetest3)
137 d = bb.parse.handle(f.name, self.d)['']
138 bb.data.expandKeys(d)
Patrick Williams213cb262021-08-07 19:21:33 -0500139 self.assertEqual(d.getVar("DESCRIPTION:bc-dev"), "A B")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500140 d.setVar("DESCRIPTION", "E")
Patrick Williams213cb262021-08-07 19:21:33 -0500141 d.setVar("DESCRIPTION:bc-dev", "C D")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500142 d.setVar("OVERRIDES", "bc-dev")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500143 self.assertEqual(d.getVar("DESCRIPTION"), "C D")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500144
145
146 classextend = """
Patrick Williams213cb262021-08-07 19:21:33 -0500147VAR_var:override1 = "B"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500148EXTRA = ":override1"
149OVERRIDES = "nothing${EXTRA}"
150
151BBCLASSEXTEND = "###CLASS###"
152"""
153 classextend_bbclass = """
154EXTRA = ""
155python () {
156 d.renameVar("VAR_var", "VAR_var2")
157}
158"""
159
160 #
161 # Test based upon a real world data corruption issue. One
162 # data store changing a variable poked through into a different data
163 # store. This test case replicates that issue where the value 'B' would
164 # become unset/disappear.
165 #
166 def test_parse_classextend_contamination(self):
Patrick Williams92b42cb2022-09-03 06:53:57 -0500167 self.d.setVar("__bbclasstype", "recipe")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500168 cls = self.parsehelper(self.classextend_bbclass, suffix=".bbclass")
169 #clsname = os.path.basename(cls.name).replace(".bbclass", "")
170 self.classextend = self.classextend.replace("###CLASS###", cls.name)
171 f = self.parsehelper(self.classextend)
172 alldata = bb.parse.handle(f.name, self.d)
173 d1 = alldata['']
174 d2 = alldata[cls.name]
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500175 self.assertEqual(d1.getVar("VAR_var"), "B")
176 self.assertEqual(d2.getVar("VAR_var"), None)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500177
Brad Bishopc342db32019-05-15 21:57:59 -0400178 addtask_deltask = """
179addtask do_patch after do_foo after do_unpack before do_configure before do_compile
180addtask do_fetch do_patch
181
Andrew Geisslerb7d28612020-07-24 16:15:54 -0500182MYVAR = "do_patch"
183EMPTYVAR = ""
184deltask do_fetch ${MYVAR} ${EMPTYVAR}
185deltask ${EMPTYVAR}
Brad Bishopc342db32019-05-15 21:57:59 -0400186"""
187 def test_parse_addtask_deltask(self):
188 import sys
189 f = self.parsehelper(self.addtask_deltask)
190 d = bb.parse.handle(f.name, self.d)['']
191
192 stdout = sys.stdout.getvalue()
193 self.assertTrue("addtask contained multiple 'before' keywords" in stdout)
194 self.assertTrue("addtask contained multiple 'after' keywords" in stdout)
195 self.assertTrue('addtask ignored: " do_patch"' in stdout)
Brad Bishopc342db32019-05-15 21:57:59 -0400196 #self.assertTrue('dependent task do_foo for do_patch does not exist' in stdout)
197
Andrew Geissler615f2f12022-07-15 14:00:58 -0500198 broken_multiline_comment = """
199# First line of comment \\
200# Second line of comment \\
201
202"""
203 def test_parse_broken_multiline_comment(self):
204 f = self.parsehelper(self.broken_multiline_comment)
205 with self.assertRaises(bb.BBHandledException):
206 d = bb.parse.handle(f.name, self.d)['']
207
208
209 comment_in_var = """
210VAR = " \\
211 SOMEVAL \\
212# some comment \\
213 SOMEOTHERVAL \\
214"
215"""
216 def test_parse_comment_in_var(self):
217 f = self.parsehelper(self.comment_in_var)
218 with self.assertRaises(bb.BBHandledException):
219 d = bb.parse.handle(f.name, self.d)['']
220