blob: 8c043b709dfd1eb88dfeb15a7f65bc223b0290fc [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001#
2# BitBake Tests for the Data Store (data.py/data_smart.py)
3#
4# Copyright (C) 2010 Chris Larson
5# Copyright (C) 2012 Richard Purdie
6#
Brad Bishopc342db32019-05-15 21:57:59 -04007# SPDX-License-Identifier: GPL-2.0-only
Patrick Williamsc124f4f2015-09-15 14:41:29 -05008#
9
10import unittest
11import bb
12import bb.data
13import bb.parse
14import logging
Andrew Geisslerc9f78652020-09-18 14:11:35 -050015import os
Patrick Williamsc124f4f2015-09-15 14:41:29 -050016
17class LogRecord():
18 def __enter__(self):
19 logs = []
20 class LogHandler(logging.Handler):
21 def emit(self, record):
22 logs.append(record)
23 logger = logging.getLogger("BitBake")
24 handler = LogHandler()
25 self.handler = handler
26 logger.addHandler(handler)
27 return logs
28 def __exit__(self, type, value, traceback):
29 logger = logging.getLogger("BitBake")
30 logger.removeHandler(self.handler)
31 return
32
33def logContains(item, logs):
34 for l in logs:
35 m = l.getMessage()
36 if item in m:
37 return True
38 return False
39
40class DataExpansions(unittest.TestCase):
41 def setUp(self):
42 self.d = bb.data.init()
43 self.d["foo"] = "value_of_foo"
44 self.d["bar"] = "value_of_bar"
45 self.d["value_of_foo"] = "value_of_'value_of_foo'"
46
47 def test_one_var(self):
48 val = self.d.expand("${foo}")
49 self.assertEqual(str(val), "value_of_foo")
50
51 def test_indirect_one_var(self):
52 val = self.d.expand("${${foo}}")
53 self.assertEqual(str(val), "value_of_'value_of_foo'")
54
55 def test_indirect_and_another(self):
56 val = self.d.expand("${${foo}} ${bar}")
57 self.assertEqual(str(val), "value_of_'value_of_foo' value_of_bar")
58
59 def test_python_snippet(self):
60 val = self.d.expand("${@5*12}")
61 self.assertEqual(str(val), "60")
62
Patrick Williams7784c422022-11-17 07:29:11 -060063 def test_python_snippet_w_dict(self):
64 val = self.d.expand("${@{ 'green': 1, 'blue': 2 }['green']}")
65 self.assertEqual(str(val), "1")
66
67 def test_python_unexpanded_multi(self):
68 self.d.setVar("bar", "${unsetvar}")
69 val = self.d.expand("${@2*2},${foo},${@d.getVar('foo') + ' ${bar}'},${foo}")
70 self.assertEqual(str(val), "4,value_of_foo,${@d.getVar('foo') + ' ${unsetvar}'},value_of_foo")
71
Patrick Williamsc124f4f2015-09-15 14:41:29 -050072 def test_expand_in_python_snippet(self):
73 val = self.d.expand("${@'boo ' + '${foo}'}")
74 self.assertEqual(str(val), "boo value_of_foo")
75
76 def test_python_snippet_getvar(self):
Brad Bishop6e60e8b2018-02-01 10:27:11 -050077 val = self.d.expand("${@d.getVar('foo') + ' ${bar}'}")
Patrick Williamsc124f4f2015-09-15 14:41:29 -050078 self.assertEqual(str(val), "value_of_foo value_of_bar")
79
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050080 def test_python_unexpanded(self):
81 self.d.setVar("bar", "${unsetvar}")
Brad Bishop6e60e8b2018-02-01 10:27:11 -050082 val = self.d.expand("${@d.getVar('foo') + ' ${bar}'}")
83 self.assertEqual(str(val), "${@d.getVar('foo') + ' ${unsetvar}'}")
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050084
Patrick Williamsc124f4f2015-09-15 14:41:29 -050085 def test_python_snippet_syntax_error(self):
86 self.d.setVar("FOO", "${@foo = 5}")
87 self.assertRaises(bb.data_smart.ExpansionError, self.d.getVar, "FOO", True)
88
89 def test_python_snippet_runtime_error(self):
90 self.d.setVar("FOO", "${@int('test')}")
91 self.assertRaises(bb.data_smart.ExpansionError, self.d.getVar, "FOO", True)
92
93 def test_python_snippet_error_path(self):
94 self.d.setVar("FOO", "foo value ${BAR}")
95 self.d.setVar("BAR", "bar value ${@int('test')}")
96 self.assertRaises(bb.data_smart.ExpansionError, self.d.getVar, "FOO", True)
97
98 def test_value_containing_value(self):
Brad Bishop6e60e8b2018-02-01 10:27:11 -050099 val = self.d.expand("${@d.getVar('foo') + ' ${bar}'}")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500100 self.assertEqual(str(val), "value_of_foo value_of_bar")
101
102 def test_reference_undefined_var(self):
103 val = self.d.expand("${undefinedvar} meh")
104 self.assertEqual(str(val), "${undefinedvar} meh")
105
106 def test_double_reference(self):
107 self.d.setVar("BAR", "bar value")
108 self.d.setVar("FOO", "${BAR} foo ${BAR}")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500109 val = self.d.getVar("FOO")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500110 self.assertEqual(str(val), "bar value foo bar value")
111
112 def test_direct_recursion(self):
113 self.d.setVar("FOO", "${FOO}")
114 self.assertRaises(bb.data_smart.ExpansionError, self.d.getVar, "FOO", True)
115
116 def test_indirect_recursion(self):
117 self.d.setVar("FOO", "${BAR}")
118 self.d.setVar("BAR", "${BAZ}")
119 self.d.setVar("BAZ", "${FOO}")
120 self.assertRaises(bb.data_smart.ExpansionError, self.d.getVar, "FOO", True)
121
122 def test_recursion_exception(self):
123 self.d.setVar("FOO", "${BAR}")
124 self.d.setVar("BAR", "${${@'FOO'}}")
125 self.assertRaises(bb.data_smart.ExpansionError, self.d.getVar, "FOO", True)
126
127 def test_incomplete_varexp_single_quotes(self):
128 self.d.setVar("FOO", "sed -i -e 's:IP{:I${:g' $pc")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500129 val = self.d.getVar("FOO")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500130 self.assertEqual(str(val), "sed -i -e 's:IP{:I${:g' $pc")
131
132 def test_nonstring(self):
133 self.d.setVar("TEST", 5)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500134 val = self.d.getVar("TEST")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500135 self.assertEqual(str(val), "5")
136
137 def test_rename(self):
138 self.d.renameVar("foo", "newfoo")
139 self.assertEqual(self.d.getVar("newfoo", False), "value_of_foo")
140 self.assertEqual(self.d.getVar("foo", False), None)
141
142 def test_deletion(self):
143 self.d.delVar("foo")
144 self.assertEqual(self.d.getVar("foo", False), None)
145
146 def test_keys(self):
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600147 keys = list(self.d.keys())
148 self.assertCountEqual(keys, ['value_of_foo', 'foo', 'bar'])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500149
150 def test_keys_deletion(self):
151 newd = bb.data.createCopy(self.d)
152 newd.delVar("bar")
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600153 keys = list(newd.keys())
154 self.assertCountEqual(keys, ['value_of_foo', 'foo'])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500155
156class TestNestedExpansions(unittest.TestCase):
157 def setUp(self):
158 self.d = bb.data.init()
159 self.d["foo"] = "foo"
160 self.d["bar"] = "bar"
161 self.d["value_of_foobar"] = "187"
162
163 def test_refs(self):
164 val = self.d.expand("${value_of_${foo}${bar}}")
165 self.assertEqual(str(val), "187")
166
167 #def test_python_refs(self):
168 # val = self.d.expand("${@${@3}**2 + ${@4}**2}")
169 # self.assertEqual(str(val), "25")
170
171 def test_ref_in_python_ref(self):
172 val = self.d.expand("${@'${foo}' + 'bar'}")
173 self.assertEqual(str(val), "foobar")
174
175 def test_python_ref_in_ref(self):
176 val = self.d.expand("${${@'f'+'o'+'o'}}")
177 self.assertEqual(str(val), "foo")
178
179 def test_deep_nesting(self):
180 depth = 100
181 val = self.d.expand("${" * depth + "foo" + "}" * depth)
182 self.assertEqual(str(val), "foo")
183
184 #def test_deep_python_nesting(self):
185 # depth = 50
186 # val = self.d.expand("${@" * depth + "1" + "+1}" * depth)
187 # self.assertEqual(str(val), str(depth + 1))
188
189 def test_mixed(self):
190 val = self.d.expand("${value_of_${@('${foo}'+'bar')[0:3]}${${@'BAR'.lower()}}}")
191 self.assertEqual(str(val), "187")
192
193 def test_runtime(self):
194 val = self.d.expand("${${@'value_of' + '_f'+'o'+'o'+'b'+'a'+'r'}}")
195 self.assertEqual(str(val), "187")
196
197class TestMemoize(unittest.TestCase):
198 def test_memoized(self):
199 d = bb.data.init()
200 d.setVar("FOO", "bar")
201 self.assertTrue(d.getVar("FOO", False) is d.getVar("FOO", False))
202
203 def test_not_memoized(self):
204 d1 = bb.data.init()
205 d2 = bb.data.init()
206 d1.setVar("FOO", "bar")
207 d2.setVar("FOO", "bar2")
208 self.assertTrue(d1.getVar("FOO", False) is not d2.getVar("FOO", False))
209
210 def test_changed_after_memoized(self):
211 d = bb.data.init()
212 d.setVar("foo", "value of foo")
213 self.assertEqual(str(d.getVar("foo", False)), "value of foo")
214 d.setVar("foo", "second value of foo")
215 self.assertEqual(str(d.getVar("foo", False)), "second value of foo")
216
217 def test_same_value(self):
218 d = bb.data.init()
219 d.setVar("foo", "value of")
220 d.setVar("bar", "value of")
221 self.assertEqual(d.getVar("foo", False),
222 d.getVar("bar", False))
223
224class TestConcat(unittest.TestCase):
225 def setUp(self):
226 self.d = bb.data.init()
227 self.d.setVar("FOO", "foo")
228 self.d.setVar("VAL", "val")
229 self.d.setVar("BAR", "bar")
230
231 def test_prepend(self):
232 self.d.setVar("TEST", "${VAL}")
233 self.d.prependVar("TEST", "${FOO}:")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500234 self.assertEqual(self.d.getVar("TEST"), "foo:val")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500235
236 def test_append(self):
237 self.d.setVar("TEST", "${VAL}")
238 self.d.appendVar("TEST", ":${BAR}")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500239 self.assertEqual(self.d.getVar("TEST"), "val:bar")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500240
241 def test_multiple_append(self):
242 self.d.setVar("TEST", "${VAL}")
243 self.d.prependVar("TEST", "${FOO}:")
244 self.d.appendVar("TEST", ":val2")
245 self.d.appendVar("TEST", ":${BAR}")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500246 self.assertEqual(self.d.getVar("TEST"), "foo:val:val2:bar")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500247
248class TestConcatOverride(unittest.TestCase):
249 def setUp(self):
250 self.d = bb.data.init()
251 self.d.setVar("FOO", "foo")
252 self.d.setVar("VAL", "val")
253 self.d.setVar("BAR", "bar")
254
255 def test_prepend(self):
256 self.d.setVar("TEST", "${VAL}")
Patrick Williams213cb262021-08-07 19:21:33 -0500257 self.d.setVar("TEST:prepend", "${FOO}:")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500258 self.assertEqual(self.d.getVar("TEST"), "foo:val")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500259
260 def test_append(self):
261 self.d.setVar("TEST", "${VAL}")
Patrick Williams213cb262021-08-07 19:21:33 -0500262 self.d.setVar("TEST:append", ":${BAR}")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500263 self.assertEqual(self.d.getVar("TEST"), "val:bar")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500264
265 def test_multiple_append(self):
266 self.d.setVar("TEST", "${VAL}")
Patrick Williams213cb262021-08-07 19:21:33 -0500267 self.d.setVar("TEST:prepend", "${FOO}:")
268 self.d.setVar("TEST:append", ":val2")
269 self.d.setVar("TEST:append", ":${BAR}")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500270 self.assertEqual(self.d.getVar("TEST"), "foo:val:val2:bar")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500271
272 def test_append_unset(self):
Patrick Williams213cb262021-08-07 19:21:33 -0500273 self.d.setVar("TEST:prepend", "${FOO}:")
274 self.d.setVar("TEST:append", ":val2")
275 self.d.setVar("TEST:append", ":${BAR}")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500276 self.assertEqual(self.d.getVar("TEST"), "foo::val2:bar")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500277
278 def test_remove(self):
279 self.d.setVar("TEST", "${VAL} ${BAR}")
Patrick Williams213cb262021-08-07 19:21:33 -0500280 self.d.setVar("TEST:remove", "val")
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800281 self.assertEqual(self.d.getVar("TEST"), " bar")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500282
283 def test_remove_cleared(self):
284 self.d.setVar("TEST", "${VAL} ${BAR}")
Patrick Williams213cb262021-08-07 19:21:33 -0500285 self.d.setVar("TEST:remove", "val")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500286 self.d.setVar("TEST", "${VAL} ${BAR}")
287 self.assertEqual(self.d.getVar("TEST"), "val bar")
288
289 # Ensure the value is unchanged if we have an inactive remove override
290 # (including that whitespace is preserved)
291 def test_remove_inactive_override(self):
292 self.d.setVar("TEST", "${VAL} ${BAR} 123")
Patrick Williams213cb262021-08-07 19:21:33 -0500293 self.d.setVar("TEST:remove:inactiveoverride", "val")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500294 self.assertEqual(self.d.getVar("TEST"), "val bar 123")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500295
296 def test_doubleref_remove(self):
297 self.d.setVar("TEST", "${VAL} ${BAR}")
Patrick Williams213cb262021-08-07 19:21:33 -0500298 self.d.setVar("TEST:remove", "val")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500299 self.d.setVar("TEST_TEST", "${TEST} ${TEST}")
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800300 self.assertEqual(self.d.getVar("TEST_TEST"), " bar bar")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500301
302 def test_empty_remove(self):
303 self.d.setVar("TEST", "")
Patrick Williams213cb262021-08-07 19:21:33 -0500304 self.d.setVar("TEST:remove", "val")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500305 self.assertEqual(self.d.getVar("TEST"), "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500306
307 def test_remove_expansion(self):
308 self.d.setVar("BAR", "Z")
309 self.d.setVar("TEST", "${BAR}/X Y")
Patrick Williams213cb262021-08-07 19:21:33 -0500310 self.d.setVar("TEST:remove", "${BAR}/X")
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800311 self.assertEqual(self.d.getVar("TEST"), " Y")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500312
313 def test_remove_expansion_items(self):
314 self.d.setVar("TEST", "A B C D")
315 self.d.setVar("BAR", "B D")
Patrick Williams213cb262021-08-07 19:21:33 -0500316 self.d.setVar("TEST:remove", "${BAR}")
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800317 self.assertEqual(self.d.getVar("TEST"), "A C ")
318
319 def test_remove_preserve_whitespace(self):
320 # When the removal isn't active, the original value should be preserved
321 self.d.setVar("TEST", " A B")
Patrick Williams213cb262021-08-07 19:21:33 -0500322 self.d.setVar("TEST:remove", "C")
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800323 self.assertEqual(self.d.getVar("TEST"), " A B")
324
325 def test_remove_preserve_whitespace2(self):
326 # When the removal is active preserve the whitespace
327 self.d.setVar("TEST", " A B")
Patrick Williams213cb262021-08-07 19:21:33 -0500328 self.d.setVar("TEST:remove", "B")
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800329 self.assertEqual(self.d.getVar("TEST"), " A ")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500330
331class TestOverrides(unittest.TestCase):
332 def setUp(self):
333 self.d = bb.data.init()
334 self.d.setVar("OVERRIDES", "foo:bar:local")
335 self.d.setVar("TEST", "testvalue")
336
337 def test_no_override(self):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500338 self.assertEqual(self.d.getVar("TEST"), "testvalue")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500339
340 def test_one_override(self):
Patrick Williams213cb262021-08-07 19:21:33 -0500341 self.d.setVar("TEST:bar", "testvalue2")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500342 self.assertEqual(self.d.getVar("TEST"), "testvalue2")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500343
344 def test_one_override_unset(self):
Patrick Williams213cb262021-08-07 19:21:33 -0500345 self.d.setVar("TEST2:bar", "testvalue2")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500346
347 self.assertEqual(self.d.getVar("TEST2"), "testvalue2")
Patrick Williams213cb262021-08-07 19:21:33 -0500348 self.assertCountEqual(list(self.d.keys()), ['TEST', 'TEST2', 'OVERRIDES', 'TEST2:bar'])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500349
350 def test_multiple_override(self):
Patrick Williams213cb262021-08-07 19:21:33 -0500351 self.d.setVar("TEST:bar", "testvalue2")
352 self.d.setVar("TEST:local", "testvalue3")
353 self.d.setVar("TEST:foo", "testvalue4")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500354 self.assertEqual(self.d.getVar("TEST"), "testvalue3")
Patrick Williams213cb262021-08-07 19:21:33 -0500355 self.assertCountEqual(list(self.d.keys()), ['TEST', 'TEST:foo', 'OVERRIDES', 'TEST:bar', 'TEST:local'])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500356
357 def test_multiple_combined_overrides(self):
Patrick Williams213cb262021-08-07 19:21:33 -0500358 self.d.setVar("TEST:local:foo:bar", "testvalue3")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500359 self.assertEqual(self.d.getVar("TEST"), "testvalue3")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500360
361 def test_multiple_overrides_unset(self):
Patrick Williams213cb262021-08-07 19:21:33 -0500362 self.d.setVar("TEST2:local:foo:bar", "testvalue3")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500363 self.assertEqual(self.d.getVar("TEST2"), "testvalue3")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500364
365 def test_keyexpansion_override(self):
366 self.d.setVar("LOCAL", "local")
Patrick Williams213cb262021-08-07 19:21:33 -0500367 self.d.setVar("TEST:bar", "testvalue2")
368 self.d.setVar("TEST:${LOCAL}", "testvalue3")
369 self.d.setVar("TEST:foo", "testvalue4")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500370 bb.data.expandKeys(self.d)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500371 self.assertEqual(self.d.getVar("TEST"), "testvalue3")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500372
373 def test_rename_override(self):
Patrick Williams213cb262021-08-07 19:21:33 -0500374 self.d.setVar("ALTERNATIVE:ncurses-tools:class-target", "a")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500375 self.d.setVar("OVERRIDES", "class-target")
Patrick Williams213cb262021-08-07 19:21:33 -0500376 self.d.renameVar("ALTERNATIVE:ncurses-tools", "ALTERNATIVE:lib32-ncurses-tools")
377 self.assertEqual(self.d.getVar("ALTERNATIVE:lib32-ncurses-tools"), "a")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500378
379 def test_underscore_override(self):
Patrick Williams213cb262021-08-07 19:21:33 -0500380 self.d.setVar("TEST:bar", "testvalue2")
381 self.d.setVar("TEST:some_val", "testvalue3")
382 self.d.setVar("TEST:foo", "testvalue4")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500383 self.d.setVar("OVERRIDES", "foo:bar:some_val")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500384 self.assertEqual(self.d.getVar("TEST"), "testvalue3")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500385
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800386 def test_remove_with_override(self):
Patrick Williams213cb262021-08-07 19:21:33 -0500387 self.d.setVar("TEST:bar", "testvalue2")
388 self.d.setVar("TEST:some_val", "testvalue3 testvalue5")
389 self.d.setVar("TEST:some_val:remove", "testvalue3")
390 self.d.setVar("TEST:foo", "testvalue4")
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800391 self.d.setVar("OVERRIDES", "foo:bar:some_val")
392 self.assertEqual(self.d.getVar("TEST"), " testvalue5")
393
Brad Bishop00e122a2019-10-05 11:10:57 -0400394 def test_append_and_override_1(self):
Patrick Williams213cb262021-08-07 19:21:33 -0500395 self.d.setVar("TEST:append", "testvalue2")
396 self.d.setVar("TEST:bar", "testvalue3")
Brad Bishop00e122a2019-10-05 11:10:57 -0400397 self.assertEqual(self.d.getVar("TEST"), "testvalue3testvalue2")
398
399 def test_append_and_override_2(self):
Patrick Williams213cb262021-08-07 19:21:33 -0500400 self.d.setVar("TEST:append:bar", "testvalue2")
Brad Bishop00e122a2019-10-05 11:10:57 -0400401 self.assertEqual(self.d.getVar("TEST"), "testvaluetestvalue2")
402
403 def test_append_and_override_3(self):
Patrick Williams213cb262021-08-07 19:21:33 -0500404 self.d.setVar("TEST:bar:append", "testvalue2")
Brad Bishop00e122a2019-10-05 11:10:57 -0400405 self.assertEqual(self.d.getVar("TEST"), "testvalue2")
406
Brad Bishop19323692019-04-05 15:28:33 -0400407 # Test an override with _<numeric> in it based on a real world OE issue
408 def test_underscore_override(self):
409 self.d.setVar("TARGET_ARCH", "x86_64")
410 self.d.setVar("PN", "test-${TARGET_ARCH}")
411 self.d.setVar("VERSION", "1")
Patrick Williams213cb262021-08-07 19:21:33 -0500412 self.d.setVar("VERSION:pn-test-${TARGET_ARCH}", "2")
Brad Bishop19323692019-04-05 15:28:33 -0400413 self.d.setVar("OVERRIDES", "pn-${PN}")
414 bb.data.expandKeys(self.d)
415 self.assertEqual(self.d.getVar("VERSION"), "2")
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800416
Patrick Williams213cb262021-08-07 19:21:33 -0500417 def test_append_and_unused_override(self):
418 # Had a bug where an unused override append could return "" instead of None
419 self.d.setVar("BAR:append:unusedoverride", "testvalue2")
420 self.assertEqual(self.d.getVar("BAR"), None)
421
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500422class TestKeyExpansion(unittest.TestCase):
423 def setUp(self):
424 self.d = bb.data.init()
425 self.d.setVar("FOO", "foo")
426 self.d.setVar("BAR", "foo")
427
428 def test_keyexpand(self):
429 self.d.setVar("VAL_${FOO}", "A")
430 self.d.setVar("VAL_${BAR}", "B")
431 with LogRecord() as logs:
432 bb.data.expandKeys(self.d)
433 self.assertTrue(logContains("Variable key VAL_${FOO} (A) replaces original key VAL_foo (B)", logs))
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500434 self.assertEqual(self.d.getVar("VAL_foo"), "A")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500435
436class TestFlags(unittest.TestCase):
437 def setUp(self):
438 self.d = bb.data.init()
439 self.d.setVar("foo", "value of foo")
440 self.d.setVarFlag("foo", "flag1", "value of flag1")
441 self.d.setVarFlag("foo", "flag2", "value of flag2")
442
443 def test_setflag(self):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500444 self.assertEqual(self.d.getVarFlag("foo", "flag1", False), "value of flag1")
445 self.assertEqual(self.d.getVarFlag("foo", "flag2", False), "value of flag2")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500446
447 def test_delflag(self):
448 self.d.delVarFlag("foo", "flag2")
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500449 self.assertEqual(self.d.getVarFlag("foo", "flag1", False), "value of flag1")
450 self.assertEqual(self.d.getVarFlag("foo", "flag2", False), None)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500451
452
453class Contains(unittest.TestCase):
454 def setUp(self):
455 self.d = bb.data.init()
456 self.d.setVar("SOMEFLAG", "a b c")
457
458 def test_contains(self):
459 self.assertTrue(bb.utils.contains("SOMEFLAG", "a", True, False, self.d))
460 self.assertTrue(bb.utils.contains("SOMEFLAG", "b", True, False, self.d))
461 self.assertTrue(bb.utils.contains("SOMEFLAG", "c", True, False, self.d))
462
463 self.assertTrue(bb.utils.contains("SOMEFLAG", "a b", True, False, self.d))
464 self.assertTrue(bb.utils.contains("SOMEFLAG", "b c", True, False, self.d))
465 self.assertTrue(bb.utils.contains("SOMEFLAG", "c a", True, False, self.d))
466
467 self.assertTrue(bb.utils.contains("SOMEFLAG", "a b c", True, False, self.d))
468 self.assertTrue(bb.utils.contains("SOMEFLAG", "c b a", True, False, self.d))
469
470 self.assertFalse(bb.utils.contains("SOMEFLAG", "x", True, False, self.d))
471 self.assertFalse(bb.utils.contains("SOMEFLAG", "a x", True, False, self.d))
472 self.assertFalse(bb.utils.contains("SOMEFLAG", "x c b", True, False, self.d))
473 self.assertFalse(bb.utils.contains("SOMEFLAG", "x c b a", True, False, self.d))
474
475 def test_contains_any(self):
476 self.assertTrue(bb.utils.contains_any("SOMEFLAG", "a", True, False, self.d))
477 self.assertTrue(bb.utils.contains_any("SOMEFLAG", "b", True, False, self.d))
478 self.assertTrue(bb.utils.contains_any("SOMEFLAG", "c", True, False, self.d))
479
480 self.assertTrue(bb.utils.contains_any("SOMEFLAG", "a b", True, False, self.d))
481 self.assertTrue(bb.utils.contains_any("SOMEFLAG", "b c", True, False, self.d))
482 self.assertTrue(bb.utils.contains_any("SOMEFLAG", "c a", True, False, self.d))
483
484 self.assertTrue(bb.utils.contains_any("SOMEFLAG", "a x", True, False, self.d))
485 self.assertTrue(bb.utils.contains_any("SOMEFLAG", "x c", True, False, self.d))
486
487 self.assertFalse(bb.utils.contains_any("SOMEFLAG", "x", True, False, self.d))
488 self.assertFalse(bb.utils.contains_any("SOMEFLAG", "x y z", True, False, self.d))
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500489
490
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800491class TaskHash(unittest.TestCase):
492 def test_taskhashes(self):
493 def gettask_bashhash(taskname, d):
Andrew Geissler82c905d2020-04-13 13:39:40 -0500494 tasklist, gendeps, lookupcache = bb.data.generate_dependencies(d, set())
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800495 taskdeps, basehash = bb.data.generate_dependency_hash(tasklist, gendeps, lookupcache, set(), "somefile")
496 bb.warn(str(lookupcache))
Brad Bishop08902b02019-08-20 09:16:51 -0400497 return basehash["somefile:" + taskname]
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800498
499 d = bb.data.init()
500 d.setVar("__BBTASKS", ["mytask"])
501 d.setVar("__exportlist", [])
502 d.setVar("mytask", "${MYCOMMAND}")
503 d.setVar("MYCOMMAND", "${VAR}; foo; bar; exit 0")
504 d.setVar("VAR", "val")
505 orighash = gettask_bashhash("mytask", d)
506
507 # Changing a variable should change the hash
508 d.setVar("VAR", "val2")
509 nexthash = gettask_bashhash("mytask", d)
510 self.assertNotEqual(orighash, nexthash)
511
512 d.setVar("VAR", "val")
513 # Adding an inactive removal shouldn't change the hash
514 d.setVar("BAR", "notbar")
Patrick Williams213cb262021-08-07 19:21:33 -0500515 d.setVar("MYCOMMAND:remove", "${BAR}")
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800516 nexthash = gettask_bashhash("mytask", d)
517 self.assertEqual(orighash, nexthash)
518
519 # Adding an active removal should change the hash
520 d.setVar("BAR", "bar;")
521 nexthash = gettask_bashhash("mytask", d)
522 self.assertNotEqual(orighash, nexthash)
523
524 # Setup an inactive contains()
525 d.setVar("VAR", "${@bb.utils.contains('VAR2', 'A', 'val', '', d)}")
526 orighash = gettask_bashhash("mytask", d)
527
528 # Activate the contains() and the hash should change
529 d.setVar("VAR2", "A")
530 nexthash = gettask_bashhash("mytask", d)
531 self.assertNotEqual(orighash, nexthash)
532
533 # The contains should be inactive but even though VAR2 has a
534 # different value the hash should match the original
535 d.setVar("VAR2", "B")
536 nexthash = gettask_bashhash("mytask", d)
537 self.assertEqual(orighash, nexthash)
538
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500539class Serialize(unittest.TestCase):
540
541 def test_serialize(self):
542 import tempfile
543 import pickle
544 d = bb.data.init()
545 d.enableTracking()
546 d.setVar('HELLO', 'world')
547 d.setVarFlag('HELLO', 'other', 'planet')
548 with tempfile.NamedTemporaryFile(delete=False) as tmpfile:
549 tmpfilename = tmpfile.name
550 pickle.dump(d, tmpfile)
551
552 with open(tmpfilename, 'rb') as f:
553 newd = pickle.load(f)
554
555 os.remove(tmpfilename)
556
557 self.assertEqual(d, newd)
558 self.assertEqual(newd.getVar('HELLO'), 'world')
559 self.assertEqual(newd.getVarFlag('HELLO', 'other'), 'planet')
560
561