xref: /OK3568_Linux_fs/yocto/poky/bitbake/lib/bb/tests/parse.py (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun#
2*4882a593Smuzhiyun# BitBake Test for lib/bb/parse/
3*4882a593Smuzhiyun#
4*4882a593Smuzhiyun# Copyright (C) 2015 Richard Purdie
5*4882a593Smuzhiyun#
6*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0-only
7*4882a593Smuzhiyun#
8*4882a593Smuzhiyun
9*4882a593Smuzhiyunimport unittest
10*4882a593Smuzhiyunimport tempfile
11*4882a593Smuzhiyunimport logging
12*4882a593Smuzhiyunimport bb
13*4882a593Smuzhiyunimport os
14*4882a593Smuzhiyun
15*4882a593Smuzhiyunlogger = logging.getLogger('BitBake.TestParse')
16*4882a593Smuzhiyun
17*4882a593Smuzhiyunimport bb.parse
18*4882a593Smuzhiyunimport bb.data
19*4882a593Smuzhiyunimport bb.siggen
20*4882a593Smuzhiyun
21*4882a593Smuzhiyunclass ParseTest(unittest.TestCase):
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun    testfile = """
24*4882a593SmuzhiyunA = "1"
25*4882a593SmuzhiyunB = "2"
26*4882a593Smuzhiyundo_install() {
27*4882a593Smuzhiyun	echo "hello"
28*4882a593Smuzhiyun}
29*4882a593Smuzhiyun
30*4882a593SmuzhiyunC = "3"
31*4882a593Smuzhiyun"""
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun    def setUp(self):
34*4882a593Smuzhiyun        self.origdir = os.getcwd()
35*4882a593Smuzhiyun        self.d = bb.data.init()
36*4882a593Smuzhiyun        bb.parse.siggen = bb.siggen.init(self.d)
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun    def tearDown(self):
39*4882a593Smuzhiyun        os.chdir(self.origdir)
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun    def parsehelper(self, content, suffix = ".bb"):
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun        f = tempfile.NamedTemporaryFile(suffix = suffix)
44*4882a593Smuzhiyun        f.write(bytes(content, "utf-8"))
45*4882a593Smuzhiyun        f.flush()
46*4882a593Smuzhiyun        os.chdir(os.path.dirname(f.name))
47*4882a593Smuzhiyun        return f
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun    def test_parse_simple(self):
50*4882a593Smuzhiyun        f = self.parsehelper(self.testfile)
51*4882a593Smuzhiyun        d = bb.parse.handle(f.name, self.d)['']
52*4882a593Smuzhiyun        self.assertEqual(d.getVar("A"), "1")
53*4882a593Smuzhiyun        self.assertEqual(d.getVar("B"), "2")
54*4882a593Smuzhiyun        self.assertEqual(d.getVar("C"), "3")
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun    def test_parse_incomplete_function(self):
57*4882a593Smuzhiyun        testfileB = self.testfile.replace("}", "")
58*4882a593Smuzhiyun        f = self.parsehelper(testfileB)
59*4882a593Smuzhiyun        with self.assertRaises(bb.parse.ParseError):
60*4882a593Smuzhiyun            d = bb.parse.handle(f.name, self.d)['']
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun    unsettest = """
63*4882a593SmuzhiyunA = "1"
64*4882a593SmuzhiyunB = "2"
65*4882a593SmuzhiyunB[flag] = "3"
66*4882a593Smuzhiyun
67*4882a593Smuzhiyununset A
68*4882a593Smuzhiyununset B[flag]
69*4882a593Smuzhiyun"""
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun    def test_parse_unset(self):
72*4882a593Smuzhiyun        f = self.parsehelper(self.unsettest)
73*4882a593Smuzhiyun        d = bb.parse.handle(f.name, self.d)['']
74*4882a593Smuzhiyun        self.assertEqual(d.getVar("A"), None)
75*4882a593Smuzhiyun        self.assertEqual(d.getVarFlag("A","flag"), None)
76*4882a593Smuzhiyun        self.assertEqual(d.getVar("B"), "2")
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun    exporttest = """
79*4882a593SmuzhiyunA = "a"
80*4882a593Smuzhiyunexport B = "b"
81*4882a593Smuzhiyunexport C
82*4882a593SmuzhiyunexportD = "d"
83*4882a593Smuzhiyun"""
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun    def test_parse_exports(self):
86*4882a593Smuzhiyun        f = self.parsehelper(self.exporttest)
87*4882a593Smuzhiyun        d = bb.parse.handle(f.name, self.d)['']
88*4882a593Smuzhiyun        self.assertEqual(d.getVar("A"), "a")
89*4882a593Smuzhiyun        self.assertIsNone(d.getVarFlag("A", "export"))
90*4882a593Smuzhiyun        self.assertEqual(d.getVar("B"), "b")
91*4882a593Smuzhiyun        self.assertEqual(d.getVarFlag("B", "export"), 1)
92*4882a593Smuzhiyun        self.assertIsNone(d.getVar("C"))
93*4882a593Smuzhiyun        self.assertEqual(d.getVarFlag("C", "export"), 1)
94*4882a593Smuzhiyun        self.assertIsNone(d.getVar("D"))
95*4882a593Smuzhiyun        self.assertIsNone(d.getVarFlag("D", "export"))
96*4882a593Smuzhiyun        self.assertEqual(d.getVar("exportD"), "d")
97*4882a593Smuzhiyun        self.assertIsNone(d.getVarFlag("exportD", "export"))
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun    overridetest = """
101*4882a593SmuzhiyunRRECOMMENDS:${PN} = "a"
102*4882a593SmuzhiyunRRECOMMENDS:${PN}:libc = "b"
103*4882a593SmuzhiyunOVERRIDES = "libc:${PN}"
104*4882a593SmuzhiyunPN = "gtk+"
105*4882a593Smuzhiyun"""
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun    def test_parse_overrides(self):
108*4882a593Smuzhiyun        f = self.parsehelper(self.overridetest)
109*4882a593Smuzhiyun        d = bb.parse.handle(f.name, self.d)['']
110*4882a593Smuzhiyun        self.assertEqual(d.getVar("RRECOMMENDS"), "b")
111*4882a593Smuzhiyun        bb.data.expandKeys(d)
112*4882a593Smuzhiyun        self.assertEqual(d.getVar("RRECOMMENDS"), "b")
113*4882a593Smuzhiyun        d.setVar("RRECOMMENDS:gtk+", "c")
114*4882a593Smuzhiyun        self.assertEqual(d.getVar("RRECOMMENDS"), "c")
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun    overridetest2 = """
117*4882a593SmuzhiyunEXTRA_OECONF = ""
118*4882a593SmuzhiyunEXTRA_OECONF:class-target = "b"
119*4882a593SmuzhiyunEXTRA_OECONF:append = " c"
120*4882a593Smuzhiyun"""
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun    def test_parse_overrides2(self):
123*4882a593Smuzhiyun        f = self.parsehelper(self.overridetest2)
124*4882a593Smuzhiyun        d = bb.parse.handle(f.name, self.d)['']
125*4882a593Smuzhiyun        d.appendVar("EXTRA_OECONF", " d")
126*4882a593Smuzhiyun        d.setVar("OVERRIDES", "class-target")
127*4882a593Smuzhiyun        self.assertEqual(d.getVar("EXTRA_OECONF"), "b c d")
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun    overridetest3 = """
130*4882a593SmuzhiyunDESCRIPTION = "A"
131*4882a593SmuzhiyunDESCRIPTION:${PN}-dev = "${DESCRIPTION} B"
132*4882a593SmuzhiyunPN = "bc"
133*4882a593Smuzhiyun"""
134*4882a593Smuzhiyun
135*4882a593Smuzhiyun    def test_parse_combinations(self):
136*4882a593Smuzhiyun        f = self.parsehelper(self.overridetest3)
137*4882a593Smuzhiyun        d = bb.parse.handle(f.name, self.d)['']
138*4882a593Smuzhiyun        bb.data.expandKeys(d)
139*4882a593Smuzhiyun        self.assertEqual(d.getVar("DESCRIPTION:bc-dev"), "A B")
140*4882a593Smuzhiyun        d.setVar("DESCRIPTION", "E")
141*4882a593Smuzhiyun        d.setVar("DESCRIPTION:bc-dev", "C D")
142*4882a593Smuzhiyun        d.setVar("OVERRIDES", "bc-dev")
143*4882a593Smuzhiyun        self.assertEqual(d.getVar("DESCRIPTION"), "C D")
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun
146*4882a593Smuzhiyun    classextend = """
147*4882a593SmuzhiyunVAR_var:override1 = "B"
148*4882a593SmuzhiyunEXTRA = ":override1"
149*4882a593SmuzhiyunOVERRIDES = "nothing${EXTRA}"
150*4882a593Smuzhiyun
151*4882a593SmuzhiyunBBCLASSEXTEND = "###CLASS###"
152*4882a593Smuzhiyun"""
153*4882a593Smuzhiyun    classextend_bbclass = """
154*4882a593SmuzhiyunEXTRA = ""
155*4882a593Smuzhiyunpython () {
156*4882a593Smuzhiyun    d.renameVar("VAR_var", "VAR_var2")
157*4882a593Smuzhiyun}
158*4882a593Smuzhiyun"""
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun    #
161*4882a593Smuzhiyun    # Test based upon a real world data corruption issue. One
162*4882a593Smuzhiyun    # data store changing a variable poked through into a different data
163*4882a593Smuzhiyun    # store. This test case replicates that issue where the value 'B' would
164*4882a593Smuzhiyun    # become unset/disappear.
165*4882a593Smuzhiyun    #
166*4882a593Smuzhiyun    def test_parse_classextend_contamination(self):
167*4882a593Smuzhiyun        cls = self.parsehelper(self.classextend_bbclass, suffix=".bbclass")
168*4882a593Smuzhiyun        #clsname = os.path.basename(cls.name).replace(".bbclass", "")
169*4882a593Smuzhiyun        self.classextend = self.classextend.replace("###CLASS###", cls.name)
170*4882a593Smuzhiyun        f = self.parsehelper(self.classextend)
171*4882a593Smuzhiyun        alldata = bb.parse.handle(f.name, self.d)
172*4882a593Smuzhiyun        d1 = alldata['']
173*4882a593Smuzhiyun        d2 = alldata[cls.name]
174*4882a593Smuzhiyun        self.assertEqual(d1.getVar("VAR_var"), "B")
175*4882a593Smuzhiyun        self.assertEqual(d2.getVar("VAR_var"), None)
176*4882a593Smuzhiyun
177*4882a593Smuzhiyun    addtask_deltask = """
178*4882a593Smuzhiyunaddtask do_patch after do_foo after do_unpack before do_configure before do_compile
179*4882a593Smuzhiyunaddtask do_fetch do_patch
180*4882a593Smuzhiyun
181*4882a593SmuzhiyunMYVAR = "do_patch"
182*4882a593SmuzhiyunEMPTYVAR = ""
183*4882a593Smuzhiyundeltask do_fetch ${MYVAR} ${EMPTYVAR}
184*4882a593Smuzhiyundeltask ${EMPTYVAR}
185*4882a593Smuzhiyun"""
186*4882a593Smuzhiyun    def test_parse_addtask_deltask(self):
187*4882a593Smuzhiyun        import sys
188*4882a593Smuzhiyun        f = self.parsehelper(self.addtask_deltask)
189*4882a593Smuzhiyun        d = bb.parse.handle(f.name, self.d)['']
190*4882a593Smuzhiyun
191*4882a593Smuzhiyun        stdout = sys.stdout.getvalue()
192*4882a593Smuzhiyun        self.assertTrue("addtask contained multiple 'before' keywords" in stdout)
193*4882a593Smuzhiyun        self.assertTrue("addtask contained multiple 'after' keywords" in stdout)
194*4882a593Smuzhiyun        self.assertTrue('addtask ignored: " do_patch"' in stdout)
195*4882a593Smuzhiyun        #self.assertTrue('dependent task do_foo for do_patch does not exist' in stdout)
196*4882a593Smuzhiyun
197*4882a593Smuzhiyun    broken_multiline_comment = """
198*4882a593Smuzhiyun# First line of comment \\
199*4882a593Smuzhiyun# Second line of comment \\
200*4882a593Smuzhiyun
201*4882a593Smuzhiyun"""
202*4882a593Smuzhiyun    def test_parse_broken_multiline_comment(self):
203*4882a593Smuzhiyun        f = self.parsehelper(self.broken_multiline_comment)
204*4882a593Smuzhiyun        with self.assertRaises(bb.BBHandledException):
205*4882a593Smuzhiyun            d = bb.parse.handle(f.name, self.d)['']
206*4882a593Smuzhiyun
207*4882a593Smuzhiyun
208*4882a593Smuzhiyun    comment_in_var = """
209*4882a593SmuzhiyunVAR = " \\
210*4882a593Smuzhiyun    SOMEVAL \\
211*4882a593Smuzhiyun#   some comment \\
212*4882a593Smuzhiyun    SOMEOTHERVAL \\
213*4882a593Smuzhiyun"
214*4882a593Smuzhiyun"""
215*4882a593Smuzhiyun    def test_parse_comment_in_var(self):
216*4882a593Smuzhiyun        f = self.parsehelper(self.comment_in_var)
217*4882a593Smuzhiyun        with self.assertRaises(bb.BBHandledException):
218*4882a593Smuzhiyun            d = bb.parse.handle(f.name, self.d)['']
219*4882a593Smuzhiyun
220