blob: a9b0bdb099dba4e6406e58bf182fc96a408f2b63 [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
15
16class LogRecord():
17 def __enter__(self):
18 logs = []
19 class LogHandler(logging.Handler):
20 def emit(self, record):
21 logs.append(record)
22 logger = logging.getLogger("BitBake")
23 handler = LogHandler()
24 self.handler = handler
25 logger.addHandler(handler)
26 return logs
27 def __exit__(self, type, value, traceback):
28 logger = logging.getLogger("BitBake")
29 logger.removeHandler(self.handler)
30 return
31
32def logContains(item, logs):
33 for l in logs:
34 m = l.getMessage()
35 if item in m:
36 return True
37 return False
38
39class DataExpansions(unittest.TestCase):
40 def setUp(self):
41 self.d = bb.data.init()
42 self.d["foo"] = "value_of_foo"
43 self.d["bar"] = "value_of_bar"
44 self.d["value_of_foo"] = "value_of_'value_of_foo'"
45
46 def test_one_var(self):
47 val = self.d.expand("${foo}")
48 self.assertEqual(str(val), "value_of_foo")
49
50 def test_indirect_one_var(self):
51 val = self.d.expand("${${foo}}")
52 self.assertEqual(str(val), "value_of_'value_of_foo'")
53
54 def test_indirect_and_another(self):
55 val = self.d.expand("${${foo}} ${bar}")
56 self.assertEqual(str(val), "value_of_'value_of_foo' value_of_bar")
57
58 def test_python_snippet(self):
59 val = self.d.expand("${@5*12}")
60 self.assertEqual(str(val), "60")
61
62 def test_expand_in_python_snippet(self):
63 val = self.d.expand("${@'boo ' + '${foo}'}")
64 self.assertEqual(str(val), "boo value_of_foo")
65
66 def test_python_snippet_getvar(self):
Brad Bishop6e60e8b2018-02-01 10:27:11 -050067 val = self.d.expand("${@d.getVar('foo') + ' ${bar}'}")
Patrick Williamsc124f4f2015-09-15 14:41:29 -050068 self.assertEqual(str(val), "value_of_foo value_of_bar")
69
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050070 def test_python_unexpanded(self):
71 self.d.setVar("bar", "${unsetvar}")
Brad Bishop6e60e8b2018-02-01 10:27:11 -050072 val = self.d.expand("${@d.getVar('foo') + ' ${bar}'}")
73 self.assertEqual(str(val), "${@d.getVar('foo') + ' ${unsetvar}'}")
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050074
Patrick Williamsc124f4f2015-09-15 14:41:29 -050075 def test_python_snippet_syntax_error(self):
76 self.d.setVar("FOO", "${@foo = 5}")
77 self.assertRaises(bb.data_smart.ExpansionError, self.d.getVar, "FOO", True)
78
79 def test_python_snippet_runtime_error(self):
80 self.d.setVar("FOO", "${@int('test')}")
81 self.assertRaises(bb.data_smart.ExpansionError, self.d.getVar, "FOO", True)
82
83 def test_python_snippet_error_path(self):
84 self.d.setVar("FOO", "foo value ${BAR}")
85 self.d.setVar("BAR", "bar value ${@int('test')}")
86 self.assertRaises(bb.data_smart.ExpansionError, self.d.getVar, "FOO", True)
87
88 def test_value_containing_value(self):
Brad Bishop6e60e8b2018-02-01 10:27:11 -050089 val = self.d.expand("${@d.getVar('foo') + ' ${bar}'}")
Patrick Williamsc124f4f2015-09-15 14:41:29 -050090 self.assertEqual(str(val), "value_of_foo value_of_bar")
91
92 def test_reference_undefined_var(self):
93 val = self.d.expand("${undefinedvar} meh")
94 self.assertEqual(str(val), "${undefinedvar} meh")
95
96 def test_double_reference(self):
97 self.d.setVar("BAR", "bar value")
98 self.d.setVar("FOO", "${BAR} foo ${BAR}")
Brad Bishop6e60e8b2018-02-01 10:27:11 -050099 val = self.d.getVar("FOO")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500100 self.assertEqual(str(val), "bar value foo bar value")
101
102 def test_direct_recursion(self):
103 self.d.setVar("FOO", "${FOO}")
104 self.assertRaises(bb.data_smart.ExpansionError, self.d.getVar, "FOO", True)
105
106 def test_indirect_recursion(self):
107 self.d.setVar("FOO", "${BAR}")
108 self.d.setVar("BAR", "${BAZ}")
109 self.d.setVar("BAZ", "${FOO}")
110 self.assertRaises(bb.data_smart.ExpansionError, self.d.getVar, "FOO", True)
111
112 def test_recursion_exception(self):
113 self.d.setVar("FOO", "${BAR}")
114 self.d.setVar("BAR", "${${@'FOO'}}")
115 self.assertRaises(bb.data_smart.ExpansionError, self.d.getVar, "FOO", True)
116
117 def test_incomplete_varexp_single_quotes(self):
118 self.d.setVar("FOO", "sed -i -e 's:IP{:I${:g' $pc")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500119 val = self.d.getVar("FOO")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500120 self.assertEqual(str(val), "sed -i -e 's:IP{:I${:g' $pc")
121
122 def test_nonstring(self):
123 self.d.setVar("TEST", 5)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500124 val = self.d.getVar("TEST")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500125 self.assertEqual(str(val), "5")
126
127 def test_rename(self):
128 self.d.renameVar("foo", "newfoo")
129 self.assertEqual(self.d.getVar("newfoo", False), "value_of_foo")
130 self.assertEqual(self.d.getVar("foo", False), None)
131
132 def test_deletion(self):
133 self.d.delVar("foo")
134 self.assertEqual(self.d.getVar("foo", False), None)
135
136 def test_keys(self):
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600137 keys = list(self.d.keys())
138 self.assertCountEqual(keys, ['value_of_foo', 'foo', 'bar'])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500139
140 def test_keys_deletion(self):
141 newd = bb.data.createCopy(self.d)
142 newd.delVar("bar")
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600143 keys = list(newd.keys())
144 self.assertCountEqual(keys, ['value_of_foo', 'foo'])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500145
146class TestNestedExpansions(unittest.TestCase):
147 def setUp(self):
148 self.d = bb.data.init()
149 self.d["foo"] = "foo"
150 self.d["bar"] = "bar"
151 self.d["value_of_foobar"] = "187"
152
153 def test_refs(self):
154 val = self.d.expand("${value_of_${foo}${bar}}")
155 self.assertEqual(str(val), "187")
156
157 #def test_python_refs(self):
158 # val = self.d.expand("${@${@3}**2 + ${@4}**2}")
159 # self.assertEqual(str(val), "25")
160
161 def test_ref_in_python_ref(self):
162 val = self.d.expand("${@'${foo}' + 'bar'}")
163 self.assertEqual(str(val), "foobar")
164
165 def test_python_ref_in_ref(self):
166 val = self.d.expand("${${@'f'+'o'+'o'}}")
167 self.assertEqual(str(val), "foo")
168
169 def test_deep_nesting(self):
170 depth = 100
171 val = self.d.expand("${" * depth + "foo" + "}" * depth)
172 self.assertEqual(str(val), "foo")
173
174 #def test_deep_python_nesting(self):
175 # depth = 50
176 # val = self.d.expand("${@" * depth + "1" + "+1}" * depth)
177 # self.assertEqual(str(val), str(depth + 1))
178
179 def test_mixed(self):
180 val = self.d.expand("${value_of_${@('${foo}'+'bar')[0:3]}${${@'BAR'.lower()}}}")
181 self.assertEqual(str(val), "187")
182
183 def test_runtime(self):
184 val = self.d.expand("${${@'value_of' + '_f'+'o'+'o'+'b'+'a'+'r'}}")
185 self.assertEqual(str(val), "187")
186
187class TestMemoize(unittest.TestCase):
188 def test_memoized(self):
189 d = bb.data.init()
190 d.setVar("FOO", "bar")
191 self.assertTrue(d.getVar("FOO", False) is d.getVar("FOO", False))
192
193 def test_not_memoized(self):
194 d1 = bb.data.init()
195 d2 = bb.data.init()
196 d1.setVar("FOO", "bar")
197 d2.setVar("FOO", "bar2")
198 self.assertTrue(d1.getVar("FOO", False) is not d2.getVar("FOO", False))
199
200 def test_changed_after_memoized(self):
201 d = bb.data.init()
202 d.setVar("foo", "value of foo")
203 self.assertEqual(str(d.getVar("foo", False)), "value of foo")
204 d.setVar("foo", "second value of foo")
205 self.assertEqual(str(d.getVar("foo", False)), "second value of foo")
206
207 def test_same_value(self):
208 d = bb.data.init()
209 d.setVar("foo", "value of")
210 d.setVar("bar", "value of")
211 self.assertEqual(d.getVar("foo", False),
212 d.getVar("bar", False))
213
214class TestConcat(unittest.TestCase):
215 def setUp(self):
216 self.d = bb.data.init()
217 self.d.setVar("FOO", "foo")
218 self.d.setVar("VAL", "val")
219 self.d.setVar("BAR", "bar")
220
221 def test_prepend(self):
222 self.d.setVar("TEST", "${VAL}")
223 self.d.prependVar("TEST", "${FOO}:")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500224 self.assertEqual(self.d.getVar("TEST"), "foo:val")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500225
226 def test_append(self):
227 self.d.setVar("TEST", "${VAL}")
228 self.d.appendVar("TEST", ":${BAR}")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500229 self.assertEqual(self.d.getVar("TEST"), "val:bar")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500230
231 def test_multiple_append(self):
232 self.d.setVar("TEST", "${VAL}")
233 self.d.prependVar("TEST", "${FOO}:")
234 self.d.appendVar("TEST", ":val2")
235 self.d.appendVar("TEST", ":${BAR}")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500236 self.assertEqual(self.d.getVar("TEST"), "foo:val:val2:bar")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500237
238class TestConcatOverride(unittest.TestCase):
239 def setUp(self):
240 self.d = bb.data.init()
241 self.d.setVar("FOO", "foo")
242 self.d.setVar("VAL", "val")
243 self.d.setVar("BAR", "bar")
244
245 def test_prepend(self):
246 self.d.setVar("TEST", "${VAL}")
247 self.d.setVar("TEST_prepend", "${FOO}:")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500248 self.assertEqual(self.d.getVar("TEST"), "foo:val")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500249
250 def test_append(self):
251 self.d.setVar("TEST", "${VAL}")
252 self.d.setVar("TEST_append", ":${BAR}")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500253 self.assertEqual(self.d.getVar("TEST"), "val:bar")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500254
255 def test_multiple_append(self):
256 self.d.setVar("TEST", "${VAL}")
257 self.d.setVar("TEST_prepend", "${FOO}:")
258 self.d.setVar("TEST_append", ":val2")
259 self.d.setVar("TEST_append", ":${BAR}")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500260 self.assertEqual(self.d.getVar("TEST"), "foo:val:val2:bar")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500261
262 def test_append_unset(self):
263 self.d.setVar("TEST_prepend", "${FOO}:")
264 self.d.setVar("TEST_append", ":val2")
265 self.d.setVar("TEST_append", ":${BAR}")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500266 self.assertEqual(self.d.getVar("TEST"), "foo::val2:bar")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500267
268 def test_remove(self):
269 self.d.setVar("TEST", "${VAL} ${BAR}")
270 self.d.setVar("TEST_remove", "val")
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800271 self.assertEqual(self.d.getVar("TEST"), " bar")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500272
273 def test_remove_cleared(self):
274 self.d.setVar("TEST", "${VAL} ${BAR}")
275 self.d.setVar("TEST_remove", "val")
276 self.d.setVar("TEST", "${VAL} ${BAR}")
277 self.assertEqual(self.d.getVar("TEST"), "val bar")
278
279 # Ensure the value is unchanged if we have an inactive remove override
280 # (including that whitespace is preserved)
281 def test_remove_inactive_override(self):
282 self.d.setVar("TEST", "${VAL} ${BAR} 123")
283 self.d.setVar("TEST_remove_inactiveoverride", "val")
284 self.assertEqual(self.d.getVar("TEST"), "val bar 123")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500285
286 def test_doubleref_remove(self):
287 self.d.setVar("TEST", "${VAL} ${BAR}")
288 self.d.setVar("TEST_remove", "val")
289 self.d.setVar("TEST_TEST", "${TEST} ${TEST}")
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800290 self.assertEqual(self.d.getVar("TEST_TEST"), " bar bar")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500291
292 def test_empty_remove(self):
293 self.d.setVar("TEST", "")
294 self.d.setVar("TEST_remove", "val")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500295 self.assertEqual(self.d.getVar("TEST"), "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500296
297 def test_remove_expansion(self):
298 self.d.setVar("BAR", "Z")
299 self.d.setVar("TEST", "${BAR}/X Y")
300 self.d.setVar("TEST_remove", "${BAR}/X")
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800301 self.assertEqual(self.d.getVar("TEST"), " Y")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500302
303 def test_remove_expansion_items(self):
304 self.d.setVar("TEST", "A B C D")
305 self.d.setVar("BAR", "B D")
306 self.d.setVar("TEST_remove", "${BAR}")
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800307 self.assertEqual(self.d.getVar("TEST"), "A C ")
308
309 def test_remove_preserve_whitespace(self):
310 # When the removal isn't active, the original value should be preserved
311 self.d.setVar("TEST", " A B")
312 self.d.setVar("TEST_remove", "C")
313 self.assertEqual(self.d.getVar("TEST"), " A B")
314
315 def test_remove_preserve_whitespace2(self):
316 # When the removal is active preserve the whitespace
317 self.d.setVar("TEST", " A B")
318 self.d.setVar("TEST_remove", "B")
319 self.assertEqual(self.d.getVar("TEST"), " A ")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500320
321class TestOverrides(unittest.TestCase):
322 def setUp(self):
323 self.d = bb.data.init()
324 self.d.setVar("OVERRIDES", "foo:bar:local")
325 self.d.setVar("TEST", "testvalue")
326
327 def test_no_override(self):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500328 self.assertEqual(self.d.getVar("TEST"), "testvalue")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500329
330 def test_one_override(self):
331 self.d.setVar("TEST_bar", "testvalue2")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500332 self.assertEqual(self.d.getVar("TEST"), "testvalue2")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500333
334 def test_one_override_unset(self):
335 self.d.setVar("TEST2_bar", "testvalue2")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500336
337 self.assertEqual(self.d.getVar("TEST2"), "testvalue2")
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600338 self.assertCountEqual(list(self.d.keys()), ['TEST', 'TEST2', 'OVERRIDES', 'TEST2_bar'])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500339
340 def test_multiple_override(self):
341 self.d.setVar("TEST_bar", "testvalue2")
342 self.d.setVar("TEST_local", "testvalue3")
343 self.d.setVar("TEST_foo", "testvalue4")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500344 self.assertEqual(self.d.getVar("TEST"), "testvalue3")
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600345 self.assertCountEqual(list(self.d.keys()), ['TEST', 'TEST_foo', 'OVERRIDES', 'TEST_bar', 'TEST_local'])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500346
347 def test_multiple_combined_overrides(self):
348 self.d.setVar("TEST_local_foo_bar", "testvalue3")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500349 self.assertEqual(self.d.getVar("TEST"), "testvalue3")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500350
351 def test_multiple_overrides_unset(self):
352 self.d.setVar("TEST2_local_foo_bar", "testvalue3")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500353 self.assertEqual(self.d.getVar("TEST2"), "testvalue3")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500354
355 def test_keyexpansion_override(self):
356 self.d.setVar("LOCAL", "local")
357 self.d.setVar("TEST_bar", "testvalue2")
358 self.d.setVar("TEST_${LOCAL}", "testvalue3")
359 self.d.setVar("TEST_foo", "testvalue4")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500360 bb.data.expandKeys(self.d)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500361 self.assertEqual(self.d.getVar("TEST"), "testvalue3")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500362
363 def test_rename_override(self):
364 self.d.setVar("ALTERNATIVE_ncurses-tools_class-target", "a")
365 self.d.setVar("OVERRIDES", "class-target")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500366 self.d.renameVar("ALTERNATIVE_ncurses-tools", "ALTERNATIVE_lib32-ncurses-tools")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500367 self.assertEqual(self.d.getVar("ALTERNATIVE_lib32-ncurses-tools"), "a")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500368
369 def test_underscore_override(self):
370 self.d.setVar("TEST_bar", "testvalue2")
371 self.d.setVar("TEST_some_val", "testvalue3")
372 self.d.setVar("TEST_foo", "testvalue4")
373 self.d.setVar("OVERRIDES", "foo:bar:some_val")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500374 self.assertEqual(self.d.getVar("TEST"), "testvalue3")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500375
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800376 def test_remove_with_override(self):
377 self.d.setVar("TEST_bar", "testvalue2")
378 self.d.setVar("TEST_some_val", "testvalue3 testvalue5")
379 self.d.setVar("TEST_some_val_remove", "testvalue3")
380 self.d.setVar("TEST_foo", "testvalue4")
381 self.d.setVar("OVERRIDES", "foo:bar:some_val")
382 self.assertEqual(self.d.getVar("TEST"), " testvalue5")
383
Brad Bishop19323692019-04-05 15:28:33 -0400384 # Test an override with _<numeric> in it based on a real world OE issue
385 def test_underscore_override(self):
386 self.d.setVar("TARGET_ARCH", "x86_64")
387 self.d.setVar("PN", "test-${TARGET_ARCH}")
388 self.d.setVar("VERSION", "1")
389 self.d.setVar("VERSION_pn-test-${TARGET_ARCH}", "2")
390 self.d.setVar("OVERRIDES", "pn-${PN}")
391 bb.data.expandKeys(self.d)
392 self.assertEqual(self.d.getVar("VERSION"), "2")
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800393
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500394class TestKeyExpansion(unittest.TestCase):
395 def setUp(self):
396 self.d = bb.data.init()
397 self.d.setVar("FOO", "foo")
398 self.d.setVar("BAR", "foo")
399
400 def test_keyexpand(self):
401 self.d.setVar("VAL_${FOO}", "A")
402 self.d.setVar("VAL_${BAR}", "B")
403 with LogRecord() as logs:
404 bb.data.expandKeys(self.d)
405 self.assertTrue(logContains("Variable key VAL_${FOO} (A) replaces original key VAL_foo (B)", logs))
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500406 self.assertEqual(self.d.getVar("VAL_foo"), "A")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500407
408class TestFlags(unittest.TestCase):
409 def setUp(self):
410 self.d = bb.data.init()
411 self.d.setVar("foo", "value of foo")
412 self.d.setVarFlag("foo", "flag1", "value of flag1")
413 self.d.setVarFlag("foo", "flag2", "value of flag2")
414
415 def test_setflag(self):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500416 self.assertEqual(self.d.getVarFlag("foo", "flag1", False), "value of flag1")
417 self.assertEqual(self.d.getVarFlag("foo", "flag2", False), "value of flag2")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500418
419 def test_delflag(self):
420 self.d.delVarFlag("foo", "flag2")
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500421 self.assertEqual(self.d.getVarFlag("foo", "flag1", False), "value of flag1")
422 self.assertEqual(self.d.getVarFlag("foo", "flag2", False), None)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500423
424
425class Contains(unittest.TestCase):
426 def setUp(self):
427 self.d = bb.data.init()
428 self.d.setVar("SOMEFLAG", "a b c")
429
430 def test_contains(self):
431 self.assertTrue(bb.utils.contains("SOMEFLAG", "a", True, False, self.d))
432 self.assertTrue(bb.utils.contains("SOMEFLAG", "b", True, False, self.d))
433 self.assertTrue(bb.utils.contains("SOMEFLAG", "c", True, False, self.d))
434
435 self.assertTrue(bb.utils.contains("SOMEFLAG", "a b", True, False, self.d))
436 self.assertTrue(bb.utils.contains("SOMEFLAG", "b c", True, False, self.d))
437 self.assertTrue(bb.utils.contains("SOMEFLAG", "c a", True, False, self.d))
438
439 self.assertTrue(bb.utils.contains("SOMEFLAG", "a b c", True, False, self.d))
440 self.assertTrue(bb.utils.contains("SOMEFLAG", "c b a", True, False, self.d))
441
442 self.assertFalse(bb.utils.contains("SOMEFLAG", "x", True, False, self.d))
443 self.assertFalse(bb.utils.contains("SOMEFLAG", "a x", True, False, self.d))
444 self.assertFalse(bb.utils.contains("SOMEFLAG", "x c b", True, False, self.d))
445 self.assertFalse(bb.utils.contains("SOMEFLAG", "x c b a", True, False, self.d))
446
447 def test_contains_any(self):
448 self.assertTrue(bb.utils.contains_any("SOMEFLAG", "a", True, False, self.d))
449 self.assertTrue(bb.utils.contains_any("SOMEFLAG", "b", True, False, self.d))
450 self.assertTrue(bb.utils.contains_any("SOMEFLAG", "c", True, False, self.d))
451
452 self.assertTrue(bb.utils.contains_any("SOMEFLAG", "a b", True, False, self.d))
453 self.assertTrue(bb.utils.contains_any("SOMEFLAG", "b c", True, False, self.d))
454 self.assertTrue(bb.utils.contains_any("SOMEFLAG", "c a", True, False, self.d))
455
456 self.assertTrue(bb.utils.contains_any("SOMEFLAG", "a x", True, False, self.d))
457 self.assertTrue(bb.utils.contains_any("SOMEFLAG", "x c", True, False, self.d))
458
459 self.assertFalse(bb.utils.contains_any("SOMEFLAG", "x", True, False, self.d))
460 self.assertFalse(bb.utils.contains_any("SOMEFLAG", "x y z", True, False, self.d))
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500461
462
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800463class TaskHash(unittest.TestCase):
464 def test_taskhashes(self):
465 def gettask_bashhash(taskname, d):
466 tasklist, gendeps, lookupcache = bb.data.generate_dependencies(d)
467 taskdeps, basehash = bb.data.generate_dependency_hash(tasklist, gendeps, lookupcache, set(), "somefile")
468 bb.warn(str(lookupcache))
Brad Bishop08902b02019-08-20 09:16:51 -0400469 return basehash["somefile:" + taskname]
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800470
471 d = bb.data.init()
472 d.setVar("__BBTASKS", ["mytask"])
473 d.setVar("__exportlist", [])
474 d.setVar("mytask", "${MYCOMMAND}")
475 d.setVar("MYCOMMAND", "${VAR}; foo; bar; exit 0")
476 d.setVar("VAR", "val")
477 orighash = gettask_bashhash("mytask", d)
478
479 # Changing a variable should change the hash
480 d.setVar("VAR", "val2")
481 nexthash = gettask_bashhash("mytask", d)
482 self.assertNotEqual(orighash, nexthash)
483
484 d.setVar("VAR", "val")
485 # Adding an inactive removal shouldn't change the hash
486 d.setVar("BAR", "notbar")
487 d.setVar("MYCOMMAND_remove", "${BAR}")
488 nexthash = gettask_bashhash("mytask", d)
489 self.assertEqual(orighash, nexthash)
490
491 # Adding an active removal should change the hash
492 d.setVar("BAR", "bar;")
493 nexthash = gettask_bashhash("mytask", d)
494 self.assertNotEqual(orighash, nexthash)
495
496 # Setup an inactive contains()
497 d.setVar("VAR", "${@bb.utils.contains('VAR2', 'A', 'val', '', d)}")
498 orighash = gettask_bashhash("mytask", d)
499
500 # Activate the contains() and the hash should change
501 d.setVar("VAR2", "A")
502 nexthash = gettask_bashhash("mytask", d)
503 self.assertNotEqual(orighash, nexthash)
504
505 # The contains should be inactive but even though VAR2 has a
506 # different value the hash should match the original
507 d.setVar("VAR2", "B")
508 nexthash = gettask_bashhash("mytask", d)
509 self.assertEqual(orighash, nexthash)
510
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500511class Serialize(unittest.TestCase):
512
513 def test_serialize(self):
514 import tempfile
515 import pickle
516 d = bb.data.init()
517 d.enableTracking()
518 d.setVar('HELLO', 'world')
519 d.setVarFlag('HELLO', 'other', 'planet')
520 with tempfile.NamedTemporaryFile(delete=False) as tmpfile:
521 tmpfilename = tmpfile.name
522 pickle.dump(d, tmpfile)
523
524 with open(tmpfilename, 'rb') as f:
525 newd = pickle.load(f)
526
527 os.remove(tmpfilename)
528
529 self.assertEqual(d, newd)
530 self.assertEqual(newd.getVar('HELLO'), 'world')
531 self.assertEqual(newd.getVarFlag('HELLO', 'other'), 'planet')
532
533
534# Remote datastore tests
535# These really only test the interface, since in actual usage we have a
536# tinfoil connector that does everything over RPC, and this doesn't test
537# that.
538
539class TestConnector:
540 d = None
541 def __init__(self, d):
542 self.d = d
543 def getVar(self, name):
544 return self.d._findVar(name)
545 def getKeys(self):
546 return set(self.d.keys())
547 def getVarHistory(self, name):
548 return self.d.varhistory.variable(name)
549 def expandPythonRef(self, varname, expr, d):
550 localdata = self.d.createCopy()
551 for key in d.localkeys():
552 localdata.setVar(d.getVar(key))
553 varparse = bb.data_smart.VariableParse(varname, localdata)
554 return varparse.python_sub(expr)
555 def setVar(self, name, value):
556 self.d.setVar(name, value)
557 def setVarFlag(self, name, flag, value):
558 self.d.setVarFlag(name, flag, value)
559 def delVar(self, name):
560 self.d.delVar(name)
561 return False
562 def delVarFlag(self, name, flag):
563 self.d.delVarFlag(name, flag)
564 return False
565 def renameVar(self, name, newname):
566 self.d.renameVar(name, newname)
567 return False
568
569class Remote(unittest.TestCase):
570 def test_remote(self):
571
572 d1 = bb.data.init()
573 d1.enableTracking()
574 d2 = bb.data.init()
575 d2.enableTracking()
576 connector = TestConnector(d1)
577
578 d2.setVar('_remote_data', connector)
579
580 d1.setVar('HELLO', 'world')
581 d1.setVarFlag('OTHER', 'flagname', 'flagvalue')
582 self.assertEqual(d2.getVar('HELLO'), 'world')
583 self.assertEqual(d2.expand('${HELLO}'), 'world')
584 self.assertEqual(d2.expand('${@d.getVar("HELLO")}'), 'world')
585 self.assertIn('flagname', d2.getVarFlags('OTHER'))
586 self.assertEqual(d2.getVarFlag('OTHER', 'flagname'), 'flagvalue')
587 self.assertEqual(d1.varhistory.variable('HELLO'), d2.varhistory.variable('HELLO'))
588 # Test setVar on client side affects server
589 d2.setVar('HELLO', 'other-world')
590 self.assertEqual(d1.getVar('HELLO'), 'other-world')
591 # Test setVarFlag on client side affects server
592 d2.setVarFlag('HELLO', 'flagname', 'flagvalue')
593 self.assertEqual(d1.getVarFlag('HELLO', 'flagname'), 'flagvalue')
594 # Test client side data is incorporated in python expansion (which is done on server)
595 d2.setVar('FOO', 'bar')
596 self.assertEqual(d2.expand('${@d.getVar("FOO")}'), 'bar')
597 # Test overrides work
598 d1.setVar('FOO_test', 'baz')
599 d1.appendVar('OVERRIDES', ':test')
600 self.assertEqual(d2.getVar('FOO'), 'baz')
601
602
603# Remote equivalents of local test classes
604# Note that these aren't perfect since we only test in one direction
605
606class RemoteDataExpansions(DataExpansions):
607 def setUp(self):
608 self.d1 = bb.data.init()
609 self.d = bb.data.init()
610 self.d1["foo"] = "value_of_foo"
611 self.d1["bar"] = "value_of_bar"
612 self.d1["value_of_foo"] = "value_of_'value_of_foo'"
613 connector = TestConnector(self.d1)
614 self.d.setVar('_remote_data', connector)
615
616class TestRemoteNestedExpansions(TestNestedExpansions):
617 def setUp(self):
618 self.d1 = bb.data.init()
619 self.d = bb.data.init()
620 self.d1["foo"] = "foo"
621 self.d1["bar"] = "bar"
622 self.d1["value_of_foobar"] = "187"
623 connector = TestConnector(self.d1)
624 self.d.setVar('_remote_data', connector)
625
626class TestRemoteConcat(TestConcat):
627 def setUp(self):
628 self.d1 = bb.data.init()
629 self.d = bb.data.init()
630 self.d1.setVar("FOO", "foo")
631 self.d1.setVar("VAL", "val")
632 self.d1.setVar("BAR", "bar")
633 connector = TestConnector(self.d1)
634 self.d.setVar('_remote_data', connector)
635
636class TestRemoteConcatOverride(TestConcatOverride):
637 def setUp(self):
638 self.d1 = bb.data.init()
639 self.d = bb.data.init()
640 self.d1.setVar("FOO", "foo")
641 self.d1.setVar("VAL", "val")
642 self.d1.setVar("BAR", "bar")
643 connector = TestConnector(self.d1)
644 self.d.setVar('_remote_data', connector)
645
646class TestRemoteOverrides(TestOverrides):
647 def setUp(self):
648 self.d1 = bb.data.init()
649 self.d = bb.data.init()
650 self.d1.setVar("OVERRIDES", "foo:bar:local")
651 self.d1.setVar("TEST", "testvalue")
652 connector = TestConnector(self.d1)
653 self.d.setVar('_remote_data', connector)
654
655class TestRemoteKeyExpansion(TestKeyExpansion):
656 def setUp(self):
657 self.d1 = bb.data.init()
658 self.d = bb.data.init()
659 self.d1.setVar("FOO", "foo")
660 self.d1.setVar("BAR", "foo")
661 connector = TestConnector(self.d1)
662 self.d.setVar('_remote_data', connector)
663
664class TestRemoteFlags(TestFlags):
665 def setUp(self):
666 self.d1 = bb.data.init()
667 self.d = bb.data.init()
668 self.d1.setVar("foo", "value of foo")
669 self.d1.setVarFlag("foo", "flag1", "value of flag1")
670 self.d1.setVarFlag("foo", "flag2", "value of flag2")
671 connector = TestConnector(self.d1)
672 self.d.setVar('_remote_data', connector)