blob: db3e2010a92df29f3df58062e8d3e59202fc8616 [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001# ex:ts=4:sw=4:sts=4:et
2# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
3#
4# BitBake Tests for the Data Store (data.py/data_smart.py)
5#
6# Copyright (C) 2010 Chris Larson
7# Copyright (C) 2012 Richard Purdie
8#
9# This program is free software; you can redistribute it and/or modify
10# it under the terms of the GNU General Public License version 2 as
11# published by the Free Software Foundation.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License along
19# with this program; if not, write to the Free Software Foundation, Inc.,
20# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21#
22
23import unittest
24import bb
25import bb.data
26import bb.parse
27import logging
28
29class LogRecord():
30 def __enter__(self):
31 logs = []
32 class LogHandler(logging.Handler):
33 def emit(self, record):
34 logs.append(record)
35 logger = logging.getLogger("BitBake")
36 handler = LogHandler()
37 self.handler = handler
38 logger.addHandler(handler)
39 return logs
40 def __exit__(self, type, value, traceback):
41 logger = logging.getLogger("BitBake")
42 logger.removeHandler(self.handler)
43 return
44
45def logContains(item, logs):
46 for l in logs:
47 m = l.getMessage()
48 if item in m:
49 return True
50 return False
51
52class DataExpansions(unittest.TestCase):
53 def setUp(self):
54 self.d = bb.data.init()
55 self.d["foo"] = "value_of_foo"
56 self.d["bar"] = "value_of_bar"
57 self.d["value_of_foo"] = "value_of_'value_of_foo'"
58
59 def test_one_var(self):
60 val = self.d.expand("${foo}")
61 self.assertEqual(str(val), "value_of_foo")
62
63 def test_indirect_one_var(self):
64 val = self.d.expand("${${foo}}")
65 self.assertEqual(str(val), "value_of_'value_of_foo'")
66
67 def test_indirect_and_another(self):
68 val = self.d.expand("${${foo}} ${bar}")
69 self.assertEqual(str(val), "value_of_'value_of_foo' value_of_bar")
70
71 def test_python_snippet(self):
72 val = self.d.expand("${@5*12}")
73 self.assertEqual(str(val), "60")
74
75 def test_expand_in_python_snippet(self):
76 val = self.d.expand("${@'boo ' + '${foo}'}")
77 self.assertEqual(str(val), "boo value_of_foo")
78
79 def test_python_snippet_getvar(self):
Brad Bishop6e60e8b2018-02-01 10:27:11 -050080 val = self.d.expand("${@d.getVar('foo') + ' ${bar}'}")
Patrick Williamsc124f4f2015-09-15 14:41:29 -050081 self.assertEqual(str(val), "value_of_foo value_of_bar")
82
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050083 def test_python_unexpanded(self):
84 self.d.setVar("bar", "${unsetvar}")
Brad Bishop6e60e8b2018-02-01 10:27:11 -050085 val = self.d.expand("${@d.getVar('foo') + ' ${bar}'}")
86 self.assertEqual(str(val), "${@d.getVar('foo') + ' ${unsetvar}'}")
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050087
Patrick Williamsc124f4f2015-09-15 14:41:29 -050088 def test_python_snippet_syntax_error(self):
89 self.d.setVar("FOO", "${@foo = 5}")
90 self.assertRaises(bb.data_smart.ExpansionError, self.d.getVar, "FOO", True)
91
92 def test_python_snippet_runtime_error(self):
93 self.d.setVar("FOO", "${@int('test')}")
94 self.assertRaises(bb.data_smart.ExpansionError, self.d.getVar, "FOO", True)
95
96 def test_python_snippet_error_path(self):
97 self.d.setVar("FOO", "foo value ${BAR}")
98 self.d.setVar("BAR", "bar value ${@int('test')}")
99 self.assertRaises(bb.data_smart.ExpansionError, self.d.getVar, "FOO", True)
100
101 def test_value_containing_value(self):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500102 val = self.d.expand("${@d.getVar('foo') + ' ${bar}'}")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500103 self.assertEqual(str(val), "value_of_foo value_of_bar")
104
105 def test_reference_undefined_var(self):
106 val = self.d.expand("${undefinedvar} meh")
107 self.assertEqual(str(val), "${undefinedvar} meh")
108
109 def test_double_reference(self):
110 self.d.setVar("BAR", "bar value")
111 self.d.setVar("FOO", "${BAR} foo ${BAR}")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500112 val = self.d.getVar("FOO")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500113 self.assertEqual(str(val), "bar value foo bar value")
114
115 def test_direct_recursion(self):
116 self.d.setVar("FOO", "${FOO}")
117 self.assertRaises(bb.data_smart.ExpansionError, self.d.getVar, "FOO", True)
118
119 def test_indirect_recursion(self):
120 self.d.setVar("FOO", "${BAR}")
121 self.d.setVar("BAR", "${BAZ}")
122 self.d.setVar("BAZ", "${FOO}")
123 self.assertRaises(bb.data_smart.ExpansionError, self.d.getVar, "FOO", True)
124
125 def test_recursion_exception(self):
126 self.d.setVar("FOO", "${BAR}")
127 self.d.setVar("BAR", "${${@'FOO'}}")
128 self.assertRaises(bb.data_smart.ExpansionError, self.d.getVar, "FOO", True)
129
130 def test_incomplete_varexp_single_quotes(self):
131 self.d.setVar("FOO", "sed -i -e 's:IP{:I${:g' $pc")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500132 val = self.d.getVar("FOO")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500133 self.assertEqual(str(val), "sed -i -e 's:IP{:I${:g' $pc")
134
135 def test_nonstring(self):
136 self.d.setVar("TEST", 5)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500137 val = self.d.getVar("TEST")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500138 self.assertEqual(str(val), "5")
139
140 def test_rename(self):
141 self.d.renameVar("foo", "newfoo")
142 self.assertEqual(self.d.getVar("newfoo", False), "value_of_foo")
143 self.assertEqual(self.d.getVar("foo", False), None)
144
145 def test_deletion(self):
146 self.d.delVar("foo")
147 self.assertEqual(self.d.getVar("foo", False), None)
148
149 def test_keys(self):
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600150 keys = list(self.d.keys())
151 self.assertCountEqual(keys, ['value_of_foo', 'foo', 'bar'])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500152
153 def test_keys_deletion(self):
154 newd = bb.data.createCopy(self.d)
155 newd.delVar("bar")
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600156 keys = list(newd.keys())
157 self.assertCountEqual(keys, ['value_of_foo', 'foo'])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500158
159class TestNestedExpansions(unittest.TestCase):
160 def setUp(self):
161 self.d = bb.data.init()
162 self.d["foo"] = "foo"
163 self.d["bar"] = "bar"
164 self.d["value_of_foobar"] = "187"
165
166 def test_refs(self):
167 val = self.d.expand("${value_of_${foo}${bar}}")
168 self.assertEqual(str(val), "187")
169
170 #def test_python_refs(self):
171 # val = self.d.expand("${@${@3}**2 + ${@4}**2}")
172 # self.assertEqual(str(val), "25")
173
174 def test_ref_in_python_ref(self):
175 val = self.d.expand("${@'${foo}' + 'bar'}")
176 self.assertEqual(str(val), "foobar")
177
178 def test_python_ref_in_ref(self):
179 val = self.d.expand("${${@'f'+'o'+'o'}}")
180 self.assertEqual(str(val), "foo")
181
182 def test_deep_nesting(self):
183 depth = 100
184 val = self.d.expand("${" * depth + "foo" + "}" * depth)
185 self.assertEqual(str(val), "foo")
186
187 #def test_deep_python_nesting(self):
188 # depth = 50
189 # val = self.d.expand("${@" * depth + "1" + "+1}" * depth)
190 # self.assertEqual(str(val), str(depth + 1))
191
192 def test_mixed(self):
193 val = self.d.expand("${value_of_${@('${foo}'+'bar')[0:3]}${${@'BAR'.lower()}}}")
194 self.assertEqual(str(val), "187")
195
196 def test_runtime(self):
197 val = self.d.expand("${${@'value_of' + '_f'+'o'+'o'+'b'+'a'+'r'}}")
198 self.assertEqual(str(val), "187")
199
200class TestMemoize(unittest.TestCase):
201 def test_memoized(self):
202 d = bb.data.init()
203 d.setVar("FOO", "bar")
204 self.assertTrue(d.getVar("FOO", False) is d.getVar("FOO", False))
205
206 def test_not_memoized(self):
207 d1 = bb.data.init()
208 d2 = bb.data.init()
209 d1.setVar("FOO", "bar")
210 d2.setVar("FOO", "bar2")
211 self.assertTrue(d1.getVar("FOO", False) is not d2.getVar("FOO", False))
212
213 def test_changed_after_memoized(self):
214 d = bb.data.init()
215 d.setVar("foo", "value of foo")
216 self.assertEqual(str(d.getVar("foo", False)), "value of foo")
217 d.setVar("foo", "second value of foo")
218 self.assertEqual(str(d.getVar("foo", False)), "second value of foo")
219
220 def test_same_value(self):
221 d = bb.data.init()
222 d.setVar("foo", "value of")
223 d.setVar("bar", "value of")
224 self.assertEqual(d.getVar("foo", False),
225 d.getVar("bar", False))
226
227class TestConcat(unittest.TestCase):
228 def setUp(self):
229 self.d = bb.data.init()
230 self.d.setVar("FOO", "foo")
231 self.d.setVar("VAL", "val")
232 self.d.setVar("BAR", "bar")
233
234 def test_prepend(self):
235 self.d.setVar("TEST", "${VAL}")
236 self.d.prependVar("TEST", "${FOO}:")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500237 self.assertEqual(self.d.getVar("TEST"), "foo:val")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500238
239 def test_append(self):
240 self.d.setVar("TEST", "${VAL}")
241 self.d.appendVar("TEST", ":${BAR}")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500242 self.assertEqual(self.d.getVar("TEST"), "val:bar")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500243
244 def test_multiple_append(self):
245 self.d.setVar("TEST", "${VAL}")
246 self.d.prependVar("TEST", "${FOO}:")
247 self.d.appendVar("TEST", ":val2")
248 self.d.appendVar("TEST", ":${BAR}")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500249 self.assertEqual(self.d.getVar("TEST"), "foo:val:val2:bar")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500250
251class TestConcatOverride(unittest.TestCase):
252 def setUp(self):
253 self.d = bb.data.init()
254 self.d.setVar("FOO", "foo")
255 self.d.setVar("VAL", "val")
256 self.d.setVar("BAR", "bar")
257
258 def test_prepend(self):
259 self.d.setVar("TEST", "${VAL}")
260 self.d.setVar("TEST_prepend", "${FOO}:")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500261 self.assertEqual(self.d.getVar("TEST"), "foo:val")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500262
263 def test_append(self):
264 self.d.setVar("TEST", "${VAL}")
265 self.d.setVar("TEST_append", ":${BAR}")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500266 self.assertEqual(self.d.getVar("TEST"), "val:bar")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500267
268 def test_multiple_append(self):
269 self.d.setVar("TEST", "${VAL}")
270 self.d.setVar("TEST_prepend", "${FOO}:")
271 self.d.setVar("TEST_append", ":val2")
272 self.d.setVar("TEST_append", ":${BAR}")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500273 self.assertEqual(self.d.getVar("TEST"), "foo:val:val2:bar")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500274
275 def test_append_unset(self):
276 self.d.setVar("TEST_prepend", "${FOO}:")
277 self.d.setVar("TEST_append", ":val2")
278 self.d.setVar("TEST_append", ":${BAR}")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500279 self.assertEqual(self.d.getVar("TEST"), "foo::val2:bar")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500280
281 def test_remove(self):
282 self.d.setVar("TEST", "${VAL} ${BAR}")
283 self.d.setVar("TEST_remove", "val")
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800284 self.assertEqual(self.d.getVar("TEST"), " bar")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500285
286 def test_remove_cleared(self):
287 self.d.setVar("TEST", "${VAL} ${BAR}")
288 self.d.setVar("TEST_remove", "val")
289 self.d.setVar("TEST", "${VAL} ${BAR}")
290 self.assertEqual(self.d.getVar("TEST"), "val bar")
291
292 # Ensure the value is unchanged if we have an inactive remove override
293 # (including that whitespace is preserved)
294 def test_remove_inactive_override(self):
295 self.d.setVar("TEST", "${VAL} ${BAR} 123")
296 self.d.setVar("TEST_remove_inactiveoverride", "val")
297 self.assertEqual(self.d.getVar("TEST"), "val bar 123")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500298
299 def test_doubleref_remove(self):
300 self.d.setVar("TEST", "${VAL} ${BAR}")
301 self.d.setVar("TEST_remove", "val")
302 self.d.setVar("TEST_TEST", "${TEST} ${TEST}")
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800303 self.assertEqual(self.d.getVar("TEST_TEST"), " bar bar")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500304
305 def test_empty_remove(self):
306 self.d.setVar("TEST", "")
307 self.d.setVar("TEST_remove", "val")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500308 self.assertEqual(self.d.getVar("TEST"), "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500309
310 def test_remove_expansion(self):
311 self.d.setVar("BAR", "Z")
312 self.d.setVar("TEST", "${BAR}/X Y")
313 self.d.setVar("TEST_remove", "${BAR}/X")
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800314 self.assertEqual(self.d.getVar("TEST"), " Y")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500315
316 def test_remove_expansion_items(self):
317 self.d.setVar("TEST", "A B C D")
318 self.d.setVar("BAR", "B D")
319 self.d.setVar("TEST_remove", "${BAR}")
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800320 self.assertEqual(self.d.getVar("TEST"), "A C ")
321
322 def test_remove_preserve_whitespace(self):
323 # When the removal isn't active, the original value should be preserved
324 self.d.setVar("TEST", " A B")
325 self.d.setVar("TEST_remove", "C")
326 self.assertEqual(self.d.getVar("TEST"), " A B")
327
328 def test_remove_preserve_whitespace2(self):
329 # When the removal is active preserve the whitespace
330 self.d.setVar("TEST", " A B")
331 self.d.setVar("TEST_remove", "B")
332 self.assertEqual(self.d.getVar("TEST"), " A ")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500333
334class TestOverrides(unittest.TestCase):
335 def setUp(self):
336 self.d = bb.data.init()
337 self.d.setVar("OVERRIDES", "foo:bar:local")
338 self.d.setVar("TEST", "testvalue")
339
340 def test_no_override(self):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500341 self.assertEqual(self.d.getVar("TEST"), "testvalue")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500342
343 def test_one_override(self):
344 self.d.setVar("TEST_bar", "testvalue2")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500345 self.assertEqual(self.d.getVar("TEST"), "testvalue2")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500346
347 def test_one_override_unset(self):
348 self.d.setVar("TEST2_bar", "testvalue2")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500349
350 self.assertEqual(self.d.getVar("TEST2"), "testvalue2")
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600351 self.assertCountEqual(list(self.d.keys()), ['TEST', 'TEST2', 'OVERRIDES', 'TEST2_bar'])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500352
353 def test_multiple_override(self):
354 self.d.setVar("TEST_bar", "testvalue2")
355 self.d.setVar("TEST_local", "testvalue3")
356 self.d.setVar("TEST_foo", "testvalue4")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500357 self.assertEqual(self.d.getVar("TEST"), "testvalue3")
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600358 self.assertCountEqual(list(self.d.keys()), ['TEST', 'TEST_foo', 'OVERRIDES', 'TEST_bar', 'TEST_local'])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500359
360 def test_multiple_combined_overrides(self):
361 self.d.setVar("TEST_local_foo_bar", "testvalue3")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500362 self.assertEqual(self.d.getVar("TEST"), "testvalue3")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500363
364 def test_multiple_overrides_unset(self):
365 self.d.setVar("TEST2_local_foo_bar", "testvalue3")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500366 self.assertEqual(self.d.getVar("TEST2"), "testvalue3")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500367
368 def test_keyexpansion_override(self):
369 self.d.setVar("LOCAL", "local")
370 self.d.setVar("TEST_bar", "testvalue2")
371 self.d.setVar("TEST_${LOCAL}", "testvalue3")
372 self.d.setVar("TEST_foo", "testvalue4")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500373 bb.data.expandKeys(self.d)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500374 self.assertEqual(self.d.getVar("TEST"), "testvalue3")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500375
376 def test_rename_override(self):
377 self.d.setVar("ALTERNATIVE_ncurses-tools_class-target", "a")
378 self.d.setVar("OVERRIDES", "class-target")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500379 self.d.renameVar("ALTERNATIVE_ncurses-tools", "ALTERNATIVE_lib32-ncurses-tools")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500380 self.assertEqual(self.d.getVar("ALTERNATIVE_lib32-ncurses-tools"), "a")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500381
382 def test_underscore_override(self):
383 self.d.setVar("TEST_bar", "testvalue2")
384 self.d.setVar("TEST_some_val", "testvalue3")
385 self.d.setVar("TEST_foo", "testvalue4")
386 self.d.setVar("OVERRIDES", "foo:bar:some_val")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500387 self.assertEqual(self.d.getVar("TEST"), "testvalue3")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500388
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800389 def test_remove_with_override(self):
390 self.d.setVar("TEST_bar", "testvalue2")
391 self.d.setVar("TEST_some_val", "testvalue3 testvalue5")
392 self.d.setVar("TEST_some_val_remove", "testvalue3")
393 self.d.setVar("TEST_foo", "testvalue4")
394 self.d.setVar("OVERRIDES", "foo:bar:some_val")
395 self.assertEqual(self.d.getVar("TEST"), " testvalue5")
396
397
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500398class TestKeyExpansion(unittest.TestCase):
399 def setUp(self):
400 self.d = bb.data.init()
401 self.d.setVar("FOO", "foo")
402 self.d.setVar("BAR", "foo")
403
404 def test_keyexpand(self):
405 self.d.setVar("VAL_${FOO}", "A")
406 self.d.setVar("VAL_${BAR}", "B")
407 with LogRecord() as logs:
408 bb.data.expandKeys(self.d)
409 self.assertTrue(logContains("Variable key VAL_${FOO} (A) replaces original key VAL_foo (B)", logs))
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500410 self.assertEqual(self.d.getVar("VAL_foo"), "A")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500411
412class TestFlags(unittest.TestCase):
413 def setUp(self):
414 self.d = bb.data.init()
415 self.d.setVar("foo", "value of foo")
416 self.d.setVarFlag("foo", "flag1", "value of flag1")
417 self.d.setVarFlag("foo", "flag2", "value of flag2")
418
419 def test_setflag(self):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500420 self.assertEqual(self.d.getVarFlag("foo", "flag1", False), "value of flag1")
421 self.assertEqual(self.d.getVarFlag("foo", "flag2", False), "value of flag2")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500422
423 def test_delflag(self):
424 self.d.delVarFlag("foo", "flag2")
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500425 self.assertEqual(self.d.getVarFlag("foo", "flag1", False), "value of flag1")
426 self.assertEqual(self.d.getVarFlag("foo", "flag2", False), None)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500427
428
429class Contains(unittest.TestCase):
430 def setUp(self):
431 self.d = bb.data.init()
432 self.d.setVar("SOMEFLAG", "a b c")
433
434 def test_contains(self):
435 self.assertTrue(bb.utils.contains("SOMEFLAG", "a", True, False, self.d))
436 self.assertTrue(bb.utils.contains("SOMEFLAG", "b", True, False, self.d))
437 self.assertTrue(bb.utils.contains("SOMEFLAG", "c", True, False, self.d))
438
439 self.assertTrue(bb.utils.contains("SOMEFLAG", "a b", True, False, self.d))
440 self.assertTrue(bb.utils.contains("SOMEFLAG", "b c", True, False, self.d))
441 self.assertTrue(bb.utils.contains("SOMEFLAG", "c a", True, False, self.d))
442
443 self.assertTrue(bb.utils.contains("SOMEFLAG", "a b c", True, False, self.d))
444 self.assertTrue(bb.utils.contains("SOMEFLAG", "c b a", True, False, self.d))
445
446 self.assertFalse(bb.utils.contains("SOMEFLAG", "x", True, False, self.d))
447 self.assertFalse(bb.utils.contains("SOMEFLAG", "a x", True, False, self.d))
448 self.assertFalse(bb.utils.contains("SOMEFLAG", "x c b", True, False, self.d))
449 self.assertFalse(bb.utils.contains("SOMEFLAG", "x c b a", True, False, self.d))
450
451 def test_contains_any(self):
452 self.assertTrue(bb.utils.contains_any("SOMEFLAG", "a", True, False, self.d))
453 self.assertTrue(bb.utils.contains_any("SOMEFLAG", "b", True, False, self.d))
454 self.assertTrue(bb.utils.contains_any("SOMEFLAG", "c", True, False, self.d))
455
456 self.assertTrue(bb.utils.contains_any("SOMEFLAG", "a b", True, False, self.d))
457 self.assertTrue(bb.utils.contains_any("SOMEFLAG", "b c", True, False, self.d))
458 self.assertTrue(bb.utils.contains_any("SOMEFLAG", "c a", True, False, self.d))
459
460 self.assertTrue(bb.utils.contains_any("SOMEFLAG", "a x", True, False, self.d))
461 self.assertTrue(bb.utils.contains_any("SOMEFLAG", "x c", True, False, self.d))
462
463 self.assertFalse(bb.utils.contains_any("SOMEFLAG", "x", True, False, self.d))
464 self.assertFalse(bb.utils.contains_any("SOMEFLAG", "x y z", True, False, self.d))
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500465
466
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800467class TaskHash(unittest.TestCase):
468 def test_taskhashes(self):
469 def gettask_bashhash(taskname, d):
470 tasklist, gendeps, lookupcache = bb.data.generate_dependencies(d)
471 taskdeps, basehash = bb.data.generate_dependency_hash(tasklist, gendeps, lookupcache, set(), "somefile")
472 bb.warn(str(lookupcache))
473 return basehash["somefile." + taskname]
474
475 d = bb.data.init()
476 d.setVar("__BBTASKS", ["mytask"])
477 d.setVar("__exportlist", [])
478 d.setVar("mytask", "${MYCOMMAND}")
479 d.setVar("MYCOMMAND", "${VAR}; foo; bar; exit 0")
480 d.setVar("VAR", "val")
481 orighash = gettask_bashhash("mytask", d)
482
483 # Changing a variable should change the hash
484 d.setVar("VAR", "val2")
485 nexthash = gettask_bashhash("mytask", d)
486 self.assertNotEqual(orighash, nexthash)
487
488 d.setVar("VAR", "val")
489 # Adding an inactive removal shouldn't change the hash
490 d.setVar("BAR", "notbar")
491 d.setVar("MYCOMMAND_remove", "${BAR}")
492 nexthash = gettask_bashhash("mytask", d)
493 self.assertEqual(orighash, nexthash)
494
495 # Adding an active removal should change the hash
496 d.setVar("BAR", "bar;")
497 nexthash = gettask_bashhash("mytask", d)
498 self.assertNotEqual(orighash, nexthash)
499
500 # Setup an inactive contains()
501 d.setVar("VAR", "${@bb.utils.contains('VAR2', 'A', 'val', '', d)}")
502 orighash = gettask_bashhash("mytask", d)
503
504 # Activate the contains() and the hash should change
505 d.setVar("VAR2", "A")
506 nexthash = gettask_bashhash("mytask", d)
507 self.assertNotEqual(orighash, nexthash)
508
509 # The contains should be inactive but even though VAR2 has a
510 # different value the hash should match the original
511 d.setVar("VAR2", "B")
512 nexthash = gettask_bashhash("mytask", d)
513 self.assertEqual(orighash, nexthash)
514
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500515class Serialize(unittest.TestCase):
516
517 def test_serialize(self):
518 import tempfile
519 import pickle
520 d = bb.data.init()
521 d.enableTracking()
522 d.setVar('HELLO', 'world')
523 d.setVarFlag('HELLO', 'other', 'planet')
524 with tempfile.NamedTemporaryFile(delete=False) as tmpfile:
525 tmpfilename = tmpfile.name
526 pickle.dump(d, tmpfile)
527
528 with open(tmpfilename, 'rb') as f:
529 newd = pickle.load(f)
530
531 os.remove(tmpfilename)
532
533 self.assertEqual(d, newd)
534 self.assertEqual(newd.getVar('HELLO'), 'world')
535 self.assertEqual(newd.getVarFlag('HELLO', 'other'), 'planet')
536
537
538# Remote datastore tests
539# These really only test the interface, since in actual usage we have a
540# tinfoil connector that does everything over RPC, and this doesn't test
541# that.
542
543class TestConnector:
544 d = None
545 def __init__(self, d):
546 self.d = d
547 def getVar(self, name):
548 return self.d._findVar(name)
549 def getKeys(self):
550 return set(self.d.keys())
551 def getVarHistory(self, name):
552 return self.d.varhistory.variable(name)
553 def expandPythonRef(self, varname, expr, d):
554 localdata = self.d.createCopy()
555 for key in d.localkeys():
556 localdata.setVar(d.getVar(key))
557 varparse = bb.data_smart.VariableParse(varname, localdata)
558 return varparse.python_sub(expr)
559 def setVar(self, name, value):
560 self.d.setVar(name, value)
561 def setVarFlag(self, name, flag, value):
562 self.d.setVarFlag(name, flag, value)
563 def delVar(self, name):
564 self.d.delVar(name)
565 return False
566 def delVarFlag(self, name, flag):
567 self.d.delVarFlag(name, flag)
568 return False
569 def renameVar(self, name, newname):
570 self.d.renameVar(name, newname)
571 return False
572
573class Remote(unittest.TestCase):
574 def test_remote(self):
575
576 d1 = bb.data.init()
577 d1.enableTracking()
578 d2 = bb.data.init()
579 d2.enableTracking()
580 connector = TestConnector(d1)
581
582 d2.setVar('_remote_data', connector)
583
584 d1.setVar('HELLO', 'world')
585 d1.setVarFlag('OTHER', 'flagname', 'flagvalue')
586 self.assertEqual(d2.getVar('HELLO'), 'world')
587 self.assertEqual(d2.expand('${HELLO}'), 'world')
588 self.assertEqual(d2.expand('${@d.getVar("HELLO")}'), 'world')
589 self.assertIn('flagname', d2.getVarFlags('OTHER'))
590 self.assertEqual(d2.getVarFlag('OTHER', 'flagname'), 'flagvalue')
591 self.assertEqual(d1.varhistory.variable('HELLO'), d2.varhistory.variable('HELLO'))
592 # Test setVar on client side affects server
593 d2.setVar('HELLO', 'other-world')
594 self.assertEqual(d1.getVar('HELLO'), 'other-world')
595 # Test setVarFlag on client side affects server
596 d2.setVarFlag('HELLO', 'flagname', 'flagvalue')
597 self.assertEqual(d1.getVarFlag('HELLO', 'flagname'), 'flagvalue')
598 # Test client side data is incorporated in python expansion (which is done on server)
599 d2.setVar('FOO', 'bar')
600 self.assertEqual(d2.expand('${@d.getVar("FOO")}'), 'bar')
601 # Test overrides work
602 d1.setVar('FOO_test', 'baz')
603 d1.appendVar('OVERRIDES', ':test')
604 self.assertEqual(d2.getVar('FOO'), 'baz')
605
606
607# Remote equivalents of local test classes
608# Note that these aren't perfect since we only test in one direction
609
610class RemoteDataExpansions(DataExpansions):
611 def setUp(self):
612 self.d1 = bb.data.init()
613 self.d = bb.data.init()
614 self.d1["foo"] = "value_of_foo"
615 self.d1["bar"] = "value_of_bar"
616 self.d1["value_of_foo"] = "value_of_'value_of_foo'"
617 connector = TestConnector(self.d1)
618 self.d.setVar('_remote_data', connector)
619
620class TestRemoteNestedExpansions(TestNestedExpansions):
621 def setUp(self):
622 self.d1 = bb.data.init()
623 self.d = bb.data.init()
624 self.d1["foo"] = "foo"
625 self.d1["bar"] = "bar"
626 self.d1["value_of_foobar"] = "187"
627 connector = TestConnector(self.d1)
628 self.d.setVar('_remote_data', connector)
629
630class TestRemoteConcat(TestConcat):
631 def setUp(self):
632 self.d1 = bb.data.init()
633 self.d = bb.data.init()
634 self.d1.setVar("FOO", "foo")
635 self.d1.setVar("VAL", "val")
636 self.d1.setVar("BAR", "bar")
637 connector = TestConnector(self.d1)
638 self.d.setVar('_remote_data', connector)
639
640class TestRemoteConcatOverride(TestConcatOverride):
641 def setUp(self):
642 self.d1 = bb.data.init()
643 self.d = bb.data.init()
644 self.d1.setVar("FOO", "foo")
645 self.d1.setVar("VAL", "val")
646 self.d1.setVar("BAR", "bar")
647 connector = TestConnector(self.d1)
648 self.d.setVar('_remote_data', connector)
649
650class TestRemoteOverrides(TestOverrides):
651 def setUp(self):
652 self.d1 = bb.data.init()
653 self.d = bb.data.init()
654 self.d1.setVar("OVERRIDES", "foo:bar:local")
655 self.d1.setVar("TEST", "testvalue")
656 connector = TestConnector(self.d1)
657 self.d.setVar('_remote_data', connector)
658
659class TestRemoteKeyExpansion(TestKeyExpansion):
660 def setUp(self):
661 self.d1 = bb.data.init()
662 self.d = bb.data.init()
663 self.d1.setVar("FOO", "foo")
664 self.d1.setVar("BAR", "foo")
665 connector = TestConnector(self.d1)
666 self.d.setVar('_remote_data', connector)
667
668class TestRemoteFlags(TestFlags):
669 def setUp(self):
670 self.d1 = bb.data.init()
671 self.d = bb.data.init()
672 self.d1.setVar("foo", "value of foo")
673 self.d1.setVarFlag("foo", "flag1", "value of flag1")
674 self.d1.setVarFlag("foo", "flag2", "value of flag2")
675 connector = TestConnector(self.d1)
676 self.d.setVar('_remote_data', connector)