blob: cbc7c1ecd4315b69b891564a1a3f111effee455c [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 Williams2a254922023-08-11 09:48:11 -050080 def test_python_snippet_function_reference(self):
81 self.d.setVar("TESTVAL", "testvalue")
82 self.d.setVar("testfunc", 'd.getVar("TESTVAL")')
83 context = bb.utils.get_context()
84 context["testfunc"] = lambda d: d.getVar("TESTVAL")
85 val = self.d.expand("${@testfunc(d)}")
86 self.assertEqual(str(val), "testvalue")
87
88 def test_python_snippet_builtin_metadata(self):
89 self.d.setVar("eval", "INVALID")
90 self.d.expand("${@eval('3')}")
91
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050092 def test_python_unexpanded(self):
93 self.d.setVar("bar", "${unsetvar}")
Brad Bishop6e60e8b2018-02-01 10:27:11 -050094 val = self.d.expand("${@d.getVar('foo') + ' ${bar}'}")
95 self.assertEqual(str(val), "${@d.getVar('foo') + ' ${unsetvar}'}")
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050096
Patrick Williamsc124f4f2015-09-15 14:41:29 -050097 def test_python_snippet_syntax_error(self):
98 self.d.setVar("FOO", "${@foo = 5}")
99 self.assertRaises(bb.data_smart.ExpansionError, self.d.getVar, "FOO", True)
100
101 def test_python_snippet_runtime_error(self):
102 self.d.setVar("FOO", "${@int('test')}")
103 self.assertRaises(bb.data_smart.ExpansionError, self.d.getVar, "FOO", True)
104
105 def test_python_snippet_error_path(self):
106 self.d.setVar("FOO", "foo value ${BAR}")
107 self.d.setVar("BAR", "bar value ${@int('test')}")
108 self.assertRaises(bb.data_smart.ExpansionError, self.d.getVar, "FOO", True)
109
110 def test_value_containing_value(self):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500111 val = self.d.expand("${@d.getVar('foo') + ' ${bar}'}")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500112 self.assertEqual(str(val), "value_of_foo value_of_bar")
113
114 def test_reference_undefined_var(self):
115 val = self.d.expand("${undefinedvar} meh")
116 self.assertEqual(str(val), "${undefinedvar} meh")
117
118 def test_double_reference(self):
119 self.d.setVar("BAR", "bar value")
120 self.d.setVar("FOO", "${BAR} foo ${BAR}")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500121 val = self.d.getVar("FOO")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500122 self.assertEqual(str(val), "bar value foo bar value")
123
124 def test_direct_recursion(self):
125 self.d.setVar("FOO", "${FOO}")
126 self.assertRaises(bb.data_smart.ExpansionError, self.d.getVar, "FOO", True)
127
128 def test_indirect_recursion(self):
129 self.d.setVar("FOO", "${BAR}")
130 self.d.setVar("BAR", "${BAZ}")
131 self.d.setVar("BAZ", "${FOO}")
132 self.assertRaises(bb.data_smart.ExpansionError, self.d.getVar, "FOO", True)
133
134 def test_recursion_exception(self):
135 self.d.setVar("FOO", "${BAR}")
136 self.d.setVar("BAR", "${${@'FOO'}}")
137 self.assertRaises(bb.data_smart.ExpansionError, self.d.getVar, "FOO", True)
138
139 def test_incomplete_varexp_single_quotes(self):
140 self.d.setVar("FOO", "sed -i -e 's:IP{:I${:g' $pc")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500141 val = self.d.getVar("FOO")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500142 self.assertEqual(str(val), "sed -i -e 's:IP{:I${:g' $pc")
143
144 def test_nonstring(self):
145 self.d.setVar("TEST", 5)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500146 val = self.d.getVar("TEST")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500147 self.assertEqual(str(val), "5")
148
149 def test_rename(self):
150 self.d.renameVar("foo", "newfoo")
151 self.assertEqual(self.d.getVar("newfoo", False), "value_of_foo")
152 self.assertEqual(self.d.getVar("foo", False), None)
153
154 def test_deletion(self):
155 self.d.delVar("foo")
156 self.assertEqual(self.d.getVar("foo", False), None)
157
158 def test_keys(self):
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600159 keys = list(self.d.keys())
160 self.assertCountEqual(keys, ['value_of_foo', 'foo', 'bar'])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500161
162 def test_keys_deletion(self):
163 newd = bb.data.createCopy(self.d)
164 newd.delVar("bar")
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600165 keys = list(newd.keys())
166 self.assertCountEqual(keys, ['value_of_foo', 'foo'])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500167
168class TestNestedExpansions(unittest.TestCase):
169 def setUp(self):
170 self.d = bb.data.init()
171 self.d["foo"] = "foo"
172 self.d["bar"] = "bar"
173 self.d["value_of_foobar"] = "187"
174
175 def test_refs(self):
176 val = self.d.expand("${value_of_${foo}${bar}}")
177 self.assertEqual(str(val), "187")
178
179 #def test_python_refs(self):
180 # val = self.d.expand("${@${@3}**2 + ${@4}**2}")
181 # self.assertEqual(str(val), "25")
182
183 def test_ref_in_python_ref(self):
184 val = self.d.expand("${@'${foo}' + 'bar'}")
185 self.assertEqual(str(val), "foobar")
186
187 def test_python_ref_in_ref(self):
188 val = self.d.expand("${${@'f'+'o'+'o'}}")
189 self.assertEqual(str(val), "foo")
190
191 def test_deep_nesting(self):
192 depth = 100
193 val = self.d.expand("${" * depth + "foo" + "}" * depth)
194 self.assertEqual(str(val), "foo")
195
196 #def test_deep_python_nesting(self):
197 # depth = 50
198 # val = self.d.expand("${@" * depth + "1" + "+1}" * depth)
199 # self.assertEqual(str(val), str(depth + 1))
200
201 def test_mixed(self):
202 val = self.d.expand("${value_of_${@('${foo}'+'bar')[0:3]}${${@'BAR'.lower()}}}")
203 self.assertEqual(str(val), "187")
204
205 def test_runtime(self):
206 val = self.d.expand("${${@'value_of' + '_f'+'o'+'o'+'b'+'a'+'r'}}")
207 self.assertEqual(str(val), "187")
208
209class TestMemoize(unittest.TestCase):
210 def test_memoized(self):
211 d = bb.data.init()
212 d.setVar("FOO", "bar")
213 self.assertTrue(d.getVar("FOO", False) is d.getVar("FOO", False))
214
215 def test_not_memoized(self):
216 d1 = bb.data.init()
217 d2 = bb.data.init()
218 d1.setVar("FOO", "bar")
219 d2.setVar("FOO", "bar2")
220 self.assertTrue(d1.getVar("FOO", False) is not d2.getVar("FOO", False))
221
222 def test_changed_after_memoized(self):
223 d = bb.data.init()
224 d.setVar("foo", "value of foo")
225 self.assertEqual(str(d.getVar("foo", False)), "value of foo")
226 d.setVar("foo", "second value of foo")
227 self.assertEqual(str(d.getVar("foo", False)), "second value of foo")
228
229 def test_same_value(self):
230 d = bb.data.init()
231 d.setVar("foo", "value of")
232 d.setVar("bar", "value of")
233 self.assertEqual(d.getVar("foo", False),
234 d.getVar("bar", False))
235
236class TestConcat(unittest.TestCase):
237 def setUp(self):
238 self.d = bb.data.init()
239 self.d.setVar("FOO", "foo")
240 self.d.setVar("VAL", "val")
241 self.d.setVar("BAR", "bar")
242
243 def test_prepend(self):
244 self.d.setVar("TEST", "${VAL}")
245 self.d.prependVar("TEST", "${FOO}:")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500246 self.assertEqual(self.d.getVar("TEST"), "foo:val")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500247
248 def test_append(self):
249 self.d.setVar("TEST", "${VAL}")
250 self.d.appendVar("TEST", ":${BAR}")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500251 self.assertEqual(self.d.getVar("TEST"), "val:bar")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500252
253 def test_multiple_append(self):
254 self.d.setVar("TEST", "${VAL}")
255 self.d.prependVar("TEST", "${FOO}:")
256 self.d.appendVar("TEST", ":val2")
257 self.d.appendVar("TEST", ":${BAR}")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500258 self.assertEqual(self.d.getVar("TEST"), "foo:val:val2:bar")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500259
260class TestConcatOverride(unittest.TestCase):
261 def setUp(self):
262 self.d = bb.data.init()
263 self.d.setVar("FOO", "foo")
264 self.d.setVar("VAL", "val")
265 self.d.setVar("BAR", "bar")
266
267 def test_prepend(self):
268 self.d.setVar("TEST", "${VAL}")
Patrick Williams213cb262021-08-07 19:21:33 -0500269 self.d.setVar("TEST:prepend", "${FOO}:")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500270 self.assertEqual(self.d.getVar("TEST"), "foo:val")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500271
272 def test_append(self):
273 self.d.setVar("TEST", "${VAL}")
Patrick Williams213cb262021-08-07 19:21:33 -0500274 self.d.setVar("TEST:append", ":${BAR}")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500275 self.assertEqual(self.d.getVar("TEST"), "val:bar")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500276
277 def test_multiple_append(self):
278 self.d.setVar("TEST", "${VAL}")
Patrick Williams213cb262021-08-07 19:21:33 -0500279 self.d.setVar("TEST:prepend", "${FOO}:")
280 self.d.setVar("TEST:append", ":val2")
281 self.d.setVar("TEST:append", ":${BAR}")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500282 self.assertEqual(self.d.getVar("TEST"), "foo:val:val2:bar")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500283
284 def test_append_unset(self):
Patrick Williams213cb262021-08-07 19:21:33 -0500285 self.d.setVar("TEST:prepend", "${FOO}:")
286 self.d.setVar("TEST:append", ":val2")
287 self.d.setVar("TEST:append", ":${BAR}")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500288 self.assertEqual(self.d.getVar("TEST"), "foo::val2:bar")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500289
290 def test_remove(self):
291 self.d.setVar("TEST", "${VAL} ${BAR}")
Patrick Williams213cb262021-08-07 19:21:33 -0500292 self.d.setVar("TEST:remove", "val")
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800293 self.assertEqual(self.d.getVar("TEST"), " bar")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500294
295 def test_remove_cleared(self):
296 self.d.setVar("TEST", "${VAL} ${BAR}")
Patrick Williams213cb262021-08-07 19:21:33 -0500297 self.d.setVar("TEST:remove", "val")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500298 self.d.setVar("TEST", "${VAL} ${BAR}")
299 self.assertEqual(self.d.getVar("TEST"), "val bar")
300
301 # Ensure the value is unchanged if we have an inactive remove override
302 # (including that whitespace is preserved)
303 def test_remove_inactive_override(self):
304 self.d.setVar("TEST", "${VAL} ${BAR} 123")
Patrick Williams213cb262021-08-07 19:21:33 -0500305 self.d.setVar("TEST:remove:inactiveoverride", "val")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500306 self.assertEqual(self.d.getVar("TEST"), "val bar 123")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500307
308 def test_doubleref_remove(self):
309 self.d.setVar("TEST", "${VAL} ${BAR}")
Patrick Williams213cb262021-08-07 19:21:33 -0500310 self.d.setVar("TEST:remove", "val")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500311 self.d.setVar("TEST_TEST", "${TEST} ${TEST}")
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800312 self.assertEqual(self.d.getVar("TEST_TEST"), " bar bar")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500313
314 def test_empty_remove(self):
315 self.d.setVar("TEST", "")
Patrick Williams213cb262021-08-07 19:21:33 -0500316 self.d.setVar("TEST:remove", "val")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500317 self.assertEqual(self.d.getVar("TEST"), "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500318
319 def test_remove_expansion(self):
320 self.d.setVar("BAR", "Z")
321 self.d.setVar("TEST", "${BAR}/X Y")
Patrick Williams213cb262021-08-07 19:21:33 -0500322 self.d.setVar("TEST:remove", "${BAR}/X")
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800323 self.assertEqual(self.d.getVar("TEST"), " Y")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500324
325 def test_remove_expansion_items(self):
326 self.d.setVar("TEST", "A B C D")
327 self.d.setVar("BAR", "B D")
Patrick Williams213cb262021-08-07 19:21:33 -0500328 self.d.setVar("TEST:remove", "${BAR}")
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800329 self.assertEqual(self.d.getVar("TEST"), "A C ")
330
331 def test_remove_preserve_whitespace(self):
332 # When the removal isn't active, the original value should be preserved
333 self.d.setVar("TEST", " A B")
Patrick Williams213cb262021-08-07 19:21:33 -0500334 self.d.setVar("TEST:remove", "C")
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800335 self.assertEqual(self.d.getVar("TEST"), " A B")
336
337 def test_remove_preserve_whitespace2(self):
338 # When the removal is active preserve the whitespace
339 self.d.setVar("TEST", " A B")
Patrick Williams213cb262021-08-07 19:21:33 -0500340 self.d.setVar("TEST:remove", "B")
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800341 self.assertEqual(self.d.getVar("TEST"), " A ")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500342
343class TestOverrides(unittest.TestCase):
344 def setUp(self):
345 self.d = bb.data.init()
346 self.d.setVar("OVERRIDES", "foo:bar:local")
347 self.d.setVar("TEST", "testvalue")
348
349 def test_no_override(self):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500350 self.assertEqual(self.d.getVar("TEST"), "testvalue")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500351
352 def test_one_override(self):
Patrick Williams213cb262021-08-07 19:21:33 -0500353 self.d.setVar("TEST:bar", "testvalue2")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500354 self.assertEqual(self.d.getVar("TEST"), "testvalue2")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500355
356 def test_one_override_unset(self):
Patrick Williams213cb262021-08-07 19:21:33 -0500357 self.d.setVar("TEST2:bar", "testvalue2")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500358
359 self.assertEqual(self.d.getVar("TEST2"), "testvalue2")
Patrick Williams213cb262021-08-07 19:21:33 -0500360 self.assertCountEqual(list(self.d.keys()), ['TEST', 'TEST2', 'OVERRIDES', 'TEST2:bar'])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500361
362 def test_multiple_override(self):
Patrick Williams213cb262021-08-07 19:21:33 -0500363 self.d.setVar("TEST:bar", "testvalue2")
364 self.d.setVar("TEST:local", "testvalue3")
365 self.d.setVar("TEST:foo", "testvalue4")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500366 self.assertEqual(self.d.getVar("TEST"), "testvalue3")
Patrick Williams213cb262021-08-07 19:21:33 -0500367 self.assertCountEqual(list(self.d.keys()), ['TEST', 'TEST:foo', 'OVERRIDES', 'TEST:bar', 'TEST:local'])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500368
369 def test_multiple_combined_overrides(self):
Patrick Williams213cb262021-08-07 19:21:33 -0500370 self.d.setVar("TEST:local:foo:bar", "testvalue3")
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_multiple_overrides_unset(self):
Patrick Williams213cb262021-08-07 19:21:33 -0500374 self.d.setVar("TEST2:local:foo:bar", "testvalue3")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500375 self.assertEqual(self.d.getVar("TEST2"), "testvalue3")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500376
377 def test_keyexpansion_override(self):
378 self.d.setVar("LOCAL", "local")
Patrick Williams213cb262021-08-07 19:21:33 -0500379 self.d.setVar("TEST:bar", "testvalue2")
380 self.d.setVar("TEST:${LOCAL}", "testvalue3")
381 self.d.setVar("TEST:foo", "testvalue4")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500382 bb.data.expandKeys(self.d)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500383 self.assertEqual(self.d.getVar("TEST"), "testvalue3")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500384
385 def test_rename_override(self):
Patrick Williams213cb262021-08-07 19:21:33 -0500386 self.d.setVar("ALTERNATIVE:ncurses-tools:class-target", "a")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500387 self.d.setVar("OVERRIDES", "class-target")
Patrick Williams213cb262021-08-07 19:21:33 -0500388 self.d.renameVar("ALTERNATIVE:ncurses-tools", "ALTERNATIVE:lib32-ncurses-tools")
389 self.assertEqual(self.d.getVar("ALTERNATIVE:lib32-ncurses-tools"), "a")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500390
391 def test_underscore_override(self):
Patrick Williams213cb262021-08-07 19:21:33 -0500392 self.d.setVar("TEST:bar", "testvalue2")
393 self.d.setVar("TEST:some_val", "testvalue3")
394 self.d.setVar("TEST:foo", "testvalue4")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500395 self.d.setVar("OVERRIDES", "foo:bar:some_val")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500396 self.assertEqual(self.d.getVar("TEST"), "testvalue3")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500397
Patrick Williamsda295312023-12-05 16:48:56 -0600398 # Test an override with _<numeric> in it based on a real world OE issue
399 def test_underscore_override_2(self):
400 self.d.setVar("TARGET_ARCH", "x86_64")
401 self.d.setVar("PN", "test-${TARGET_ARCH}")
402 self.d.setVar("VERSION", "1")
403 self.d.setVar("VERSION:pn-test-${TARGET_ARCH}", "2")
404 self.d.setVar("OVERRIDES", "pn-${PN}")
405 bb.data.expandKeys(self.d)
406 self.assertEqual(self.d.getVar("VERSION"), "2")
407
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800408 def test_remove_with_override(self):
Patrick Williams213cb262021-08-07 19:21:33 -0500409 self.d.setVar("TEST:bar", "testvalue2")
410 self.d.setVar("TEST:some_val", "testvalue3 testvalue5")
411 self.d.setVar("TEST:some_val:remove", "testvalue3")
412 self.d.setVar("TEST:foo", "testvalue4")
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800413 self.d.setVar("OVERRIDES", "foo:bar:some_val")
414 self.assertEqual(self.d.getVar("TEST"), " testvalue5")
415
Brad Bishop00e122a2019-10-05 11:10:57 -0400416 def test_append_and_override_1(self):
Patrick Williams213cb262021-08-07 19:21:33 -0500417 self.d.setVar("TEST:append", "testvalue2")
418 self.d.setVar("TEST:bar", "testvalue3")
Brad Bishop00e122a2019-10-05 11:10:57 -0400419 self.assertEqual(self.d.getVar("TEST"), "testvalue3testvalue2")
420
421 def test_append_and_override_2(self):
Patrick Williams213cb262021-08-07 19:21:33 -0500422 self.d.setVar("TEST:append:bar", "testvalue2")
Brad Bishop00e122a2019-10-05 11:10:57 -0400423 self.assertEqual(self.d.getVar("TEST"), "testvaluetestvalue2")
424
425 def test_append_and_override_3(self):
Patrick Williams213cb262021-08-07 19:21:33 -0500426 self.d.setVar("TEST:bar:append", "testvalue2")
Brad Bishop00e122a2019-10-05 11:10:57 -0400427 self.assertEqual(self.d.getVar("TEST"), "testvalue2")
428
Patrick Williams213cb262021-08-07 19:21:33 -0500429 def test_append_and_unused_override(self):
430 # Had a bug where an unused override append could return "" instead of None
431 self.d.setVar("BAR:append:unusedoverride", "testvalue2")
432 self.assertEqual(self.d.getVar("BAR"), None)
433
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500434class TestKeyExpansion(unittest.TestCase):
435 def setUp(self):
436 self.d = bb.data.init()
437 self.d.setVar("FOO", "foo")
438 self.d.setVar("BAR", "foo")
439
440 def test_keyexpand(self):
441 self.d.setVar("VAL_${FOO}", "A")
442 self.d.setVar("VAL_${BAR}", "B")
443 with LogRecord() as logs:
444 bb.data.expandKeys(self.d)
445 self.assertTrue(logContains("Variable key VAL_${FOO} (A) replaces original key VAL_foo (B)", logs))
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500446 self.assertEqual(self.d.getVar("VAL_foo"), "A")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500447
448class TestFlags(unittest.TestCase):
449 def setUp(self):
450 self.d = bb.data.init()
451 self.d.setVar("foo", "value of foo")
452 self.d.setVarFlag("foo", "flag1", "value of flag1")
453 self.d.setVarFlag("foo", "flag2", "value of flag2")
454
455 def test_setflag(self):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500456 self.assertEqual(self.d.getVarFlag("foo", "flag1", False), "value of flag1")
457 self.assertEqual(self.d.getVarFlag("foo", "flag2", False), "value of flag2")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500458
459 def test_delflag(self):
460 self.d.delVarFlag("foo", "flag2")
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500461 self.assertEqual(self.d.getVarFlag("foo", "flag1", False), "value of flag1")
462 self.assertEqual(self.d.getVarFlag("foo", "flag2", False), None)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500463
464
465class Contains(unittest.TestCase):
466 def setUp(self):
467 self.d = bb.data.init()
468 self.d.setVar("SOMEFLAG", "a b c")
469
470 def test_contains(self):
471 self.assertTrue(bb.utils.contains("SOMEFLAG", "a", True, False, self.d))
472 self.assertTrue(bb.utils.contains("SOMEFLAG", "b", True, False, self.d))
473 self.assertTrue(bb.utils.contains("SOMEFLAG", "c", True, False, self.d))
474
475 self.assertTrue(bb.utils.contains("SOMEFLAG", "a b", True, False, self.d))
476 self.assertTrue(bb.utils.contains("SOMEFLAG", "b c", True, False, self.d))
477 self.assertTrue(bb.utils.contains("SOMEFLAG", "c a", True, False, self.d))
478
479 self.assertTrue(bb.utils.contains("SOMEFLAG", "a b c", True, False, self.d))
480 self.assertTrue(bb.utils.contains("SOMEFLAG", "c b a", True, False, self.d))
481
482 self.assertFalse(bb.utils.contains("SOMEFLAG", "x", True, False, self.d))
483 self.assertFalse(bb.utils.contains("SOMEFLAG", "a x", True, False, self.d))
484 self.assertFalse(bb.utils.contains("SOMEFLAG", "x c b", True, False, self.d))
485 self.assertFalse(bb.utils.contains("SOMEFLAG", "x c b a", True, False, self.d))
486
487 def test_contains_any(self):
488 self.assertTrue(bb.utils.contains_any("SOMEFLAG", "a", True, False, self.d))
489 self.assertTrue(bb.utils.contains_any("SOMEFLAG", "b", True, False, self.d))
490 self.assertTrue(bb.utils.contains_any("SOMEFLAG", "c", True, False, self.d))
491
492 self.assertTrue(bb.utils.contains_any("SOMEFLAG", "a b", True, False, self.d))
493 self.assertTrue(bb.utils.contains_any("SOMEFLAG", "b c", True, False, self.d))
494 self.assertTrue(bb.utils.contains_any("SOMEFLAG", "c a", True, False, self.d))
495
496 self.assertTrue(bb.utils.contains_any("SOMEFLAG", "a x", True, False, self.d))
497 self.assertTrue(bb.utils.contains_any("SOMEFLAG", "x c", True, False, self.d))
498
499 self.assertFalse(bb.utils.contains_any("SOMEFLAG", "x", True, False, self.d))
500 self.assertFalse(bb.utils.contains_any("SOMEFLAG", "x y z", True, False, self.d))
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500501
502
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800503class TaskHash(unittest.TestCase):
504 def test_taskhashes(self):
505 def gettask_bashhash(taskname, d):
Andrew Geissler82c905d2020-04-13 13:39:40 -0500506 tasklist, gendeps, lookupcache = bb.data.generate_dependencies(d, set())
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800507 taskdeps, basehash = bb.data.generate_dependency_hash(tasklist, gendeps, lookupcache, set(), "somefile")
508 bb.warn(str(lookupcache))
Brad Bishop08902b02019-08-20 09:16:51 -0400509 return basehash["somefile:" + taskname]
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800510
511 d = bb.data.init()
512 d.setVar("__BBTASKS", ["mytask"])
513 d.setVar("__exportlist", [])
514 d.setVar("mytask", "${MYCOMMAND}")
515 d.setVar("MYCOMMAND", "${VAR}; foo; bar; exit 0")
516 d.setVar("VAR", "val")
517 orighash = gettask_bashhash("mytask", d)
518
519 # Changing a variable should change the hash
520 d.setVar("VAR", "val2")
521 nexthash = gettask_bashhash("mytask", d)
522 self.assertNotEqual(orighash, nexthash)
523
524 d.setVar("VAR", "val")
525 # Adding an inactive removal shouldn't change the hash
526 d.setVar("BAR", "notbar")
Patrick Williams213cb262021-08-07 19:21:33 -0500527 d.setVar("MYCOMMAND:remove", "${BAR}")
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800528 nexthash = gettask_bashhash("mytask", d)
529 self.assertEqual(orighash, nexthash)
530
531 # Adding an active removal should change the hash
532 d.setVar("BAR", "bar;")
533 nexthash = gettask_bashhash("mytask", d)
534 self.assertNotEqual(orighash, nexthash)
535
536 # Setup an inactive contains()
537 d.setVar("VAR", "${@bb.utils.contains('VAR2', 'A', 'val', '', d)}")
538 orighash = gettask_bashhash("mytask", d)
539
540 # Activate the contains() and the hash should change
541 d.setVar("VAR2", "A")
542 nexthash = gettask_bashhash("mytask", d)
543 self.assertNotEqual(orighash, nexthash)
544
545 # The contains should be inactive but even though VAR2 has a
546 # different value the hash should match the original
547 d.setVar("VAR2", "B")
548 nexthash = gettask_bashhash("mytask", d)
549 self.assertEqual(orighash, nexthash)
550
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500551class Serialize(unittest.TestCase):
552
553 def test_serialize(self):
554 import tempfile
555 import pickle
556 d = bb.data.init()
557 d.enableTracking()
558 d.setVar('HELLO', 'world')
559 d.setVarFlag('HELLO', 'other', 'planet')
560 with tempfile.NamedTemporaryFile(delete=False) as tmpfile:
561 tmpfilename = tmpfile.name
562 pickle.dump(d, tmpfile)
563
564 with open(tmpfilename, 'rb') as f:
565 newd = pickle.load(f)
566
567 os.remove(tmpfilename)
568
569 self.assertEqual(d, newd)
570 self.assertEqual(newd.getVar('HELLO'), 'world')
571 self.assertEqual(newd.getVarFlag('HELLO', 'other'), 'planet')
572
573