blob: 3e49984c93f8ca8608f45d1960675fc7defe26e7 [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 Bishop00e122a2019-10-05 11:10:57 -0400384 def test_append_and_override_1(self):
385 self.d.setVar("TEST_append", "testvalue2")
386 self.d.setVar("TEST_bar", "testvalue3")
387 self.assertEqual(self.d.getVar("TEST"), "testvalue3testvalue2")
388
389 def test_append_and_override_2(self):
390 self.d.setVar("TEST_append_bar", "testvalue2")
391 self.assertEqual(self.d.getVar("TEST"), "testvaluetestvalue2")
392
393 def test_append_and_override_3(self):
394 self.d.setVar("TEST_bar_append", "testvalue2")
395 self.assertEqual(self.d.getVar("TEST"), "testvalue2")
396
Brad Bishop19323692019-04-05 15:28:33 -0400397 # Test an override with _<numeric> in it based on a real world OE issue
398 def test_underscore_override(self):
399 self.d.setVar("TARGET_ARCH", "x86_64")
400 self.d.setVar("PN", "test-${TARGET_ARCH}")
401 self.d.setVar("VERSION", "1")
402 self.d.setVar("VERSION_pn-test-${TARGET_ARCH}", "2")
403 self.d.setVar("OVERRIDES", "pn-${PN}")
404 bb.data.expandKeys(self.d)
405 self.assertEqual(self.d.getVar("VERSION"), "2")
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800406
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500407class TestKeyExpansion(unittest.TestCase):
408 def setUp(self):
409 self.d = bb.data.init()
410 self.d.setVar("FOO", "foo")
411 self.d.setVar("BAR", "foo")
412
413 def test_keyexpand(self):
414 self.d.setVar("VAL_${FOO}", "A")
415 self.d.setVar("VAL_${BAR}", "B")
416 with LogRecord() as logs:
417 bb.data.expandKeys(self.d)
418 self.assertTrue(logContains("Variable key VAL_${FOO} (A) replaces original key VAL_foo (B)", logs))
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500419 self.assertEqual(self.d.getVar("VAL_foo"), "A")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500420
421class TestFlags(unittest.TestCase):
422 def setUp(self):
423 self.d = bb.data.init()
424 self.d.setVar("foo", "value of foo")
425 self.d.setVarFlag("foo", "flag1", "value of flag1")
426 self.d.setVarFlag("foo", "flag2", "value of flag2")
427
428 def test_setflag(self):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500429 self.assertEqual(self.d.getVarFlag("foo", "flag1", False), "value of flag1")
430 self.assertEqual(self.d.getVarFlag("foo", "flag2", False), "value of flag2")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500431
432 def test_delflag(self):
433 self.d.delVarFlag("foo", "flag2")
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500434 self.assertEqual(self.d.getVarFlag("foo", "flag1", False), "value of flag1")
435 self.assertEqual(self.d.getVarFlag("foo", "flag2", False), None)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500436
437
438class Contains(unittest.TestCase):
439 def setUp(self):
440 self.d = bb.data.init()
441 self.d.setVar("SOMEFLAG", "a b c")
442
443 def test_contains(self):
444 self.assertTrue(bb.utils.contains("SOMEFLAG", "a", True, False, self.d))
445 self.assertTrue(bb.utils.contains("SOMEFLAG", "b", True, False, self.d))
446 self.assertTrue(bb.utils.contains("SOMEFLAG", "c", True, False, self.d))
447
448 self.assertTrue(bb.utils.contains("SOMEFLAG", "a b", True, False, self.d))
449 self.assertTrue(bb.utils.contains("SOMEFLAG", "b c", True, False, self.d))
450 self.assertTrue(bb.utils.contains("SOMEFLAG", "c a", True, False, self.d))
451
452 self.assertTrue(bb.utils.contains("SOMEFLAG", "a b c", True, False, self.d))
453 self.assertTrue(bb.utils.contains("SOMEFLAG", "c b a", True, False, self.d))
454
455 self.assertFalse(bb.utils.contains("SOMEFLAG", "x", True, False, self.d))
456 self.assertFalse(bb.utils.contains("SOMEFLAG", "a x", True, False, self.d))
457 self.assertFalse(bb.utils.contains("SOMEFLAG", "x c b", True, False, self.d))
458 self.assertFalse(bb.utils.contains("SOMEFLAG", "x c b a", True, False, self.d))
459
460 def test_contains_any(self):
461 self.assertTrue(bb.utils.contains_any("SOMEFLAG", "a", True, False, self.d))
462 self.assertTrue(bb.utils.contains_any("SOMEFLAG", "b", True, False, self.d))
463 self.assertTrue(bb.utils.contains_any("SOMEFLAG", "c", True, False, self.d))
464
465 self.assertTrue(bb.utils.contains_any("SOMEFLAG", "a b", True, False, self.d))
466 self.assertTrue(bb.utils.contains_any("SOMEFLAG", "b c", True, False, self.d))
467 self.assertTrue(bb.utils.contains_any("SOMEFLAG", "c a", True, False, self.d))
468
469 self.assertTrue(bb.utils.contains_any("SOMEFLAG", "a x", True, False, self.d))
470 self.assertTrue(bb.utils.contains_any("SOMEFLAG", "x c", True, False, self.d))
471
472 self.assertFalse(bb.utils.contains_any("SOMEFLAG", "x", True, False, self.d))
473 self.assertFalse(bb.utils.contains_any("SOMEFLAG", "x y z", True, False, self.d))
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500474
475
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800476class TaskHash(unittest.TestCase):
477 def test_taskhashes(self):
478 def gettask_bashhash(taskname, d):
479 tasklist, gendeps, lookupcache = bb.data.generate_dependencies(d)
480 taskdeps, basehash = bb.data.generate_dependency_hash(tasklist, gendeps, lookupcache, set(), "somefile")
481 bb.warn(str(lookupcache))
Brad Bishop08902b02019-08-20 09:16:51 -0400482 return basehash["somefile:" + taskname]
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800483
484 d = bb.data.init()
485 d.setVar("__BBTASKS", ["mytask"])
486 d.setVar("__exportlist", [])
487 d.setVar("mytask", "${MYCOMMAND}")
488 d.setVar("MYCOMMAND", "${VAR}; foo; bar; exit 0")
489 d.setVar("VAR", "val")
490 orighash = gettask_bashhash("mytask", d)
491
492 # Changing a variable should change the hash
493 d.setVar("VAR", "val2")
494 nexthash = gettask_bashhash("mytask", d)
495 self.assertNotEqual(orighash, nexthash)
496
497 d.setVar("VAR", "val")
498 # Adding an inactive removal shouldn't change the hash
499 d.setVar("BAR", "notbar")
500 d.setVar("MYCOMMAND_remove", "${BAR}")
501 nexthash = gettask_bashhash("mytask", d)
502 self.assertEqual(orighash, nexthash)
503
504 # Adding an active removal should change the hash
505 d.setVar("BAR", "bar;")
506 nexthash = gettask_bashhash("mytask", d)
507 self.assertNotEqual(orighash, nexthash)
508
509 # Setup an inactive contains()
510 d.setVar("VAR", "${@bb.utils.contains('VAR2', 'A', 'val', '', d)}")
511 orighash = gettask_bashhash("mytask", d)
512
513 # Activate the contains() and the hash should change
514 d.setVar("VAR2", "A")
515 nexthash = gettask_bashhash("mytask", d)
516 self.assertNotEqual(orighash, nexthash)
517
518 # The contains should be inactive but even though VAR2 has a
519 # different value the hash should match the original
520 d.setVar("VAR2", "B")
521 nexthash = gettask_bashhash("mytask", d)
522 self.assertEqual(orighash, nexthash)
523
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500524class Serialize(unittest.TestCase):
525
526 def test_serialize(self):
527 import tempfile
528 import pickle
529 d = bb.data.init()
530 d.enableTracking()
531 d.setVar('HELLO', 'world')
532 d.setVarFlag('HELLO', 'other', 'planet')
533 with tempfile.NamedTemporaryFile(delete=False) as tmpfile:
534 tmpfilename = tmpfile.name
535 pickle.dump(d, tmpfile)
536
537 with open(tmpfilename, 'rb') as f:
538 newd = pickle.load(f)
539
540 os.remove(tmpfilename)
541
542 self.assertEqual(d, newd)
543 self.assertEqual(newd.getVar('HELLO'), 'world')
544 self.assertEqual(newd.getVarFlag('HELLO', 'other'), 'planet')
545
546
547# Remote datastore tests
548# These really only test the interface, since in actual usage we have a
549# tinfoil connector that does everything over RPC, and this doesn't test
550# that.
551
552class TestConnector:
553 d = None
554 def __init__(self, d):
555 self.d = d
556 def getVar(self, name):
557 return self.d._findVar(name)
558 def getKeys(self):
559 return set(self.d.keys())
560 def getVarHistory(self, name):
561 return self.d.varhistory.variable(name)
562 def expandPythonRef(self, varname, expr, d):
563 localdata = self.d.createCopy()
564 for key in d.localkeys():
565 localdata.setVar(d.getVar(key))
566 varparse = bb.data_smart.VariableParse(varname, localdata)
567 return varparse.python_sub(expr)
568 def setVar(self, name, value):
569 self.d.setVar(name, value)
570 def setVarFlag(self, name, flag, value):
571 self.d.setVarFlag(name, flag, value)
572 def delVar(self, name):
573 self.d.delVar(name)
574 return False
575 def delVarFlag(self, name, flag):
576 self.d.delVarFlag(name, flag)
577 return False
578 def renameVar(self, name, newname):
579 self.d.renameVar(name, newname)
580 return False
581
582class Remote(unittest.TestCase):
583 def test_remote(self):
584
585 d1 = bb.data.init()
586 d1.enableTracking()
587 d2 = bb.data.init()
588 d2.enableTracking()
589 connector = TestConnector(d1)
590
591 d2.setVar('_remote_data', connector)
592
593 d1.setVar('HELLO', 'world')
594 d1.setVarFlag('OTHER', 'flagname', 'flagvalue')
595 self.assertEqual(d2.getVar('HELLO'), 'world')
596 self.assertEqual(d2.expand('${HELLO}'), 'world')
597 self.assertEqual(d2.expand('${@d.getVar("HELLO")}'), 'world')
598 self.assertIn('flagname', d2.getVarFlags('OTHER'))
599 self.assertEqual(d2.getVarFlag('OTHER', 'flagname'), 'flagvalue')
600 self.assertEqual(d1.varhistory.variable('HELLO'), d2.varhistory.variable('HELLO'))
601 # Test setVar on client side affects server
602 d2.setVar('HELLO', 'other-world')
603 self.assertEqual(d1.getVar('HELLO'), 'other-world')
604 # Test setVarFlag on client side affects server
605 d2.setVarFlag('HELLO', 'flagname', 'flagvalue')
606 self.assertEqual(d1.getVarFlag('HELLO', 'flagname'), 'flagvalue')
607 # Test client side data is incorporated in python expansion (which is done on server)
608 d2.setVar('FOO', 'bar')
609 self.assertEqual(d2.expand('${@d.getVar("FOO")}'), 'bar')
610 # Test overrides work
611 d1.setVar('FOO_test', 'baz')
612 d1.appendVar('OVERRIDES', ':test')
613 self.assertEqual(d2.getVar('FOO'), 'baz')
614
615
616# Remote equivalents of local test classes
617# Note that these aren't perfect since we only test in one direction
618
619class RemoteDataExpansions(DataExpansions):
620 def setUp(self):
621 self.d1 = bb.data.init()
622 self.d = bb.data.init()
623 self.d1["foo"] = "value_of_foo"
624 self.d1["bar"] = "value_of_bar"
625 self.d1["value_of_foo"] = "value_of_'value_of_foo'"
626 connector = TestConnector(self.d1)
627 self.d.setVar('_remote_data', connector)
628
629class TestRemoteNestedExpansions(TestNestedExpansions):
630 def setUp(self):
631 self.d1 = bb.data.init()
632 self.d = bb.data.init()
633 self.d1["foo"] = "foo"
634 self.d1["bar"] = "bar"
635 self.d1["value_of_foobar"] = "187"
636 connector = TestConnector(self.d1)
637 self.d.setVar('_remote_data', connector)
638
639class TestRemoteConcat(TestConcat):
640 def setUp(self):
641 self.d1 = bb.data.init()
642 self.d = bb.data.init()
643 self.d1.setVar("FOO", "foo")
644 self.d1.setVar("VAL", "val")
645 self.d1.setVar("BAR", "bar")
646 connector = TestConnector(self.d1)
647 self.d.setVar('_remote_data', connector)
648
649class TestRemoteConcatOverride(TestConcatOverride):
650 def setUp(self):
651 self.d1 = bb.data.init()
652 self.d = bb.data.init()
653 self.d1.setVar("FOO", "foo")
654 self.d1.setVar("VAL", "val")
655 self.d1.setVar("BAR", "bar")
656 connector = TestConnector(self.d1)
657 self.d.setVar('_remote_data', connector)
658
659class TestRemoteOverrides(TestOverrides):
660 def setUp(self):
661 self.d1 = bb.data.init()
662 self.d = bb.data.init()
663 self.d1.setVar("OVERRIDES", "foo:bar:local")
664 self.d1.setVar("TEST", "testvalue")
665 connector = TestConnector(self.d1)
666 self.d.setVar('_remote_data', connector)
667
668class TestRemoteKeyExpansion(TestKeyExpansion):
669 def setUp(self):
670 self.d1 = bb.data.init()
671 self.d = bb.data.init()
672 self.d1.setVar("FOO", "foo")
673 self.d1.setVar("BAR", "foo")
674 connector = TestConnector(self.d1)
675 self.d.setVar('_remote_data', connector)
676
677class TestRemoteFlags(TestFlags):
678 def setUp(self):
679 self.d1 = bb.data.init()
680 self.d = bb.data.init()
681 self.d1.setVar("foo", "value of foo")
682 self.d1.setVarFlag("foo", "flag1", "value of flag1")
683 self.d1.setVarFlag("foo", "flag2", "value of flag2")
684 connector = TestConnector(self.d1)
685 self.d.setVar('_remote_data', connector)