xref: /openbmc/openbmc/poky/bitbake/lib/bb/tests/parse.py (revision 595f6308)
1#
2# BitBake Test for lib/bb/parse/
3#
4# Copyright (C) 2015 Richard Purdie
5#
6# SPDX-License-Identifier: GPL-2.0-only
7#
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):
34        self.origdir = os.getcwd()
35        self.d = bb.data.init()
36        bb.parse.siggen = bb.siggen.init(self.d)
37
38    def tearDown(self):
39        os.chdir(self.origdir)
40
41    def parsehelper(self, content, suffix = ".bb"):
42
43        f = tempfile.NamedTemporaryFile(suffix = suffix)
44        f.write(bytes(content, "utf-8"))
45        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)['']
52        self.assertEqual(d.getVar("A"), "1")
53        self.assertEqual(d.getVar("B"), "2")
54        self.assertEqual(d.getVar("C"), "3")
55
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
62    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)['']
74        self.assertEqual(d.getVar("A"), None)
75        self.assertEqual(d.getVarFlag("A","flag"), None)
76        self.assertEqual(d.getVar("B"), "2")
77
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
99
100    overridetest = """
101RRECOMMENDS:${PN} = "a"
102RRECOMMENDS:${PN}:libc = "b"
103OVERRIDES = "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)['']
110        self.assertEqual(d.getVar("RRECOMMENDS"), "b")
111        bb.data.expandKeys(d)
112        self.assertEqual(d.getVar("RRECOMMENDS"), "b")
113        d.setVar("RRECOMMENDS:gtk+", "c")
114        self.assertEqual(d.getVar("RRECOMMENDS"), "c")
115
116    overridetest2 = """
117EXTRA_OECONF = ""
118EXTRA_OECONF:class-target = "b"
119EXTRA_OECONF:append = " c"
120"""
121
122    def test_parse_overrides(self):
123        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")
127        self.assertEqual(d.getVar("EXTRA_OECONF"), "b c d")
128
129    overridetest3 = """
130DESCRIPTION = "A"
131DESCRIPTION:${PN}-dev = "${DESCRIPTION} B"
132PN = "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)
139        self.assertEqual(d.getVar("DESCRIPTION:bc-dev"), "A B")
140        d.setVar("DESCRIPTION", "E")
141        d.setVar("DESCRIPTION:bc-dev", "C D")
142        d.setVar("OVERRIDES", "bc-dev")
143        self.assertEqual(d.getVar("DESCRIPTION"), "C D")
144
145
146    classextend = """
147VAR_var:override1 = "B"
148EXTRA = ":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):
167        cls = self.parsehelper(self.classextend_bbclass, suffix=".bbclass")
168        #clsname = os.path.basename(cls.name).replace(".bbclass", "")
169        self.classextend = self.classextend.replace("###CLASS###", cls.name)
170        f = self.parsehelper(self.classextend)
171        alldata = bb.parse.handle(f.name, self.d)
172        d1 = alldata['']
173        d2 = alldata[cls.name]
174        self.assertEqual(d1.getVar("VAR_var"), "B")
175        self.assertEqual(d2.getVar("VAR_var"), None)
176
177    addtask_deltask = """
178addtask do_patch after do_foo after do_unpack before do_configure before do_compile
179addtask do_fetch do_patch
180
181MYVAR = "do_patch"
182EMPTYVAR = ""
183deltask do_fetch ${MYVAR} ${EMPTYVAR}
184deltask ${EMPTYVAR}
185"""
186    def test_parse_addtask_deltask(self):
187        import sys
188        f = self.parsehelper(self.addtask_deltask)
189        d = bb.parse.handle(f.name, self.d)['']
190
191        stdout = sys.stdout.getvalue()
192        self.assertTrue("addtask contained multiple 'before' keywords" in stdout)
193        self.assertTrue("addtask contained multiple 'after' keywords" in stdout)
194        self.assertTrue('addtask ignored: " do_patch"' in stdout)
195        #self.assertTrue('dependent task do_foo for do_patch does not exist' in stdout)
196
197