summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/bb/tests
diff options
context:
space:
mode:
authorPaul Eggleton <paul.eggleton@linux.intel.com>2015-05-18 16:08:36 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2015-05-19 11:58:45 +0100
commitaefc80c02ed6d4de5768723d86ce80520387e1d3 (patch)
tree9606d0ddd49051ed0f83193c78ce5005225c89c4 /bitbake/lib/bb/tests
parentba0546bfaf23aa5ba1033e348a0a1addf0623abb (diff)
downloadpoky-aefc80c02ed6d4de5768723d86ce80520387e1d3.tar.gz
bitbake: lib/bb/utils: fix and extend edit_metadata_file()
Fix several bugs and add some useful enhancements to make this into a more generic metadata editing function: * Support modifying function values (name must be specified ending with "()") * Support dropping values by returning None as the new value * Split out edit_metadata() function to provide same functionality on a list/iterable * Pass operation to callback and allow function to return them * Pass current output lines to callback so they can be modified * Fix handling of single-quoted values * Handle :=, =+, .=, and =. operators * Support arbitrary indent string * Support indenting by length of assignment (by specifying -1) * Fix typo in variablename - intentspc -> indentspc * Expand function docstring to cover arguments / usage * Add a parameter to enable matching names with overrides applied * Add some bitbake-selftest tests Note that this does change the expected signature of the callback function. The only known caller is in lib/bb/utils.py itself; I doubt anyone else has made extensive use of this function yet. (Bitbake rev: 20059e4d5ab9bf0f32c781ccb208da3c95818018) Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib/bb/tests')
-rw-r--r--bitbake/lib/bb/tests/utils.py271
1 files changed, 271 insertions, 0 deletions
diff --git a/bitbake/lib/bb/tests/utils.py b/bitbake/lib/bb/tests/utils.py
index 6e09858e51..9171509a62 100644
--- a/bitbake/lib/bb/tests/utils.py
+++ b/bitbake/lib/bb/tests/utils.py
@@ -22,6 +22,7 @@
22import unittest 22import unittest
23import bb 23import bb
24import os 24import os
25import tempfile
25 26
26class VerCmpString(unittest.TestCase): 27class VerCmpString(unittest.TestCase):
27 28
@@ -105,3 +106,273 @@ class Path(unittest.TestCase):
105 for arg1, correctresult in checkitems: 106 for arg1, correctresult in checkitems:
106 result = bb.utils._check_unsafe_delete_path(arg1) 107 result = bb.utils._check_unsafe_delete_path(arg1)
107 self.assertEqual(result, correctresult, '_check_unsafe_delete_path("%s") != %s' % (arg1, correctresult)) 108 self.assertEqual(result, correctresult, '_check_unsafe_delete_path("%s") != %s' % (arg1, correctresult))
109
110
111class EditMetadataFile(unittest.TestCase):
112 _origfile = """
113# A comment
114HELLO = "oldvalue"
115
116THIS = "that"
117
118# Another comment
119NOCHANGE = "samevalue"
120OTHER = 'anothervalue'
121
122MULTILINE = "a1 \\
123 a2 \\
124 a3"
125
126MULTILINE2 := " \\
127 b1 \\
128 b2 \\
129 b3 \\
130 "
131
132
133MULTILINE3 = " \\
134 c1 \\
135 c2 \\
136 c3 \\
137"
138
139do_functionname() {
140 command1 ${VAL1} ${VAL2}
141 command2 ${VAL3} ${VAL4}
142}
143"""
144 def _testeditfile(self, varvalues, compareto, dummyvars=None):
145 if dummyvars is None:
146 dummyvars = []
147 with tempfile.NamedTemporaryFile('w', delete=False) as tf:
148 tf.write(self._origfile)
149 tf.close()
150 try:
151 varcalls = []
152 def handle_file(varname, origvalue, op, newlines):
153 self.assertIn(varname, varvalues, 'Callback called for variable %s not in the list!' % varname)
154 self.assertNotIn(varname, dummyvars, 'Callback called for variable %s in dummy list!' % varname)
155 varcalls.append(varname)
156 return varvalues[varname]
157
158 bb.utils.edit_metadata_file(tf.name, varvalues.keys(), handle_file)
159 with open(tf.name) as f:
160 modfile = f.readlines()
161 # Ensure the output matches the expected output
162 self.assertEqual(compareto.splitlines(True), modfile)
163 # Ensure the callback function was called for every variable we asked for
164 # (plus allow testing behaviour when a requested variable is not present)
165 self.assertEqual(sorted(varvalues.keys()), sorted(varcalls + dummyvars))
166 finally:
167 os.remove(tf.name)
168
169
170 def test_edit_metadata_file_nochange(self):
171 # Test file doesn't get modified with nothing to do
172 self._testeditfile({}, self._origfile)
173 # Test file doesn't get modified with only dummy variables
174 self._testeditfile({'DUMMY1': ('should_not_set', None, 0, True),
175 'DUMMY2': ('should_not_set_again', None, 0, True)}, self._origfile, dummyvars=['DUMMY1', 'DUMMY2'])
176 # Test file doesn't get modified with some the same values
177 self._testeditfile({'THIS': ('that', None, 0, True),
178 'OTHER': ('anothervalue', None, 0, True),
179 'MULTILINE3': (' c1 c2 c3', None, 4, False)}, self._origfile)
180
181 def test_edit_metadata_file_1(self):
182
183 newfile1 = """
184# A comment
185HELLO = "newvalue"
186
187THIS = "that"
188
189# Another comment
190NOCHANGE = "samevalue"
191OTHER = 'anothervalue'
192
193MULTILINE = "a1 \\
194 a2 \\
195 a3"
196
197MULTILINE2 := " \\
198 b1 \\
199 b2 \\
200 b3 \\
201 "
202
203
204MULTILINE3 = " \\
205 c1 \\
206 c2 \\
207 c3 \\
208"
209
210do_functionname() {
211 command1 ${VAL1} ${VAL2}
212 command2 ${VAL3} ${VAL4}
213}
214"""
215 self._testeditfile({'HELLO': ('newvalue', None, 4, True)}, newfile1)
216
217
218 def test_edit_metadata_file_2(self):
219
220 newfile2 = """
221# A comment
222HELLO = "oldvalue"
223
224THIS = "that"
225
226# Another comment
227NOCHANGE = "samevalue"
228OTHER = 'anothervalue'
229
230MULTILINE = " \\
231 d1 \\
232 d2 \\
233 d3 \\
234 "
235
236MULTILINE2 := " \\
237 b1 \\
238 b2 \\
239 b3 \\
240 "
241
242
243MULTILINE3 = "nowsingle"
244
245do_functionname() {
246 command1 ${VAL1} ${VAL2}
247 command2 ${VAL3} ${VAL4}
248}
249"""
250 self._testeditfile({'MULTILINE': (['d1','d2','d3'], None, 4, False),
251 'MULTILINE3': ('nowsingle', None, 4, True),
252 'NOTPRESENT': (['a', 'b'], None, 4, False)}, newfile2, dummyvars=['NOTPRESENT'])
253
254
255 def test_edit_metadata_file_3(self):
256
257 newfile3 = """
258# A comment
259HELLO = "oldvalue"
260
261# Another comment
262NOCHANGE = "samevalue"
263OTHER = "yetanothervalue"
264
265MULTILINE = "e1 \\
266 e2 \\
267 e3 \\
268 "
269
270MULTILINE2 := "f1 \\
271\tf2 \\
272\t"
273
274
275MULTILINE3 = " \\
276 c1 \\
277 c2 \\
278 c3 \\
279"
280
281do_functionname() {
282 othercommand_one a b c
283 othercommand_two d e f
284}
285"""
286
287 self._testeditfile({'do_functionname()': (['othercommand_one a b c', 'othercommand_two d e f'], None, 4, False),
288 'MULTILINE2': (['f1', 'f2'], None, '\t', True),
289 'MULTILINE': (['e1', 'e2', 'e3'], None, -1, True),
290 'THIS': (None, None, 0, False),
291 'OTHER': ('yetanothervalue', None, 0, True)}, newfile3)
292
293
294 def test_edit_metadata_file_4(self):
295
296 newfile4 = """
297# A comment
298HELLO = "oldvalue"
299
300THIS = "that"
301
302# Another comment
303OTHER = 'anothervalue'
304
305MULTILINE = "a1 \\
306 a2 \\
307 a3"
308
309MULTILINE2 := " \\
310 b1 \\
311 b2 \\
312 b3 \\
313 "
314
315
316"""
317
318 self._testeditfile({'NOCHANGE': (None, None, 0, False),
319 'MULTILINE3': (None, None, 0, False),
320 'THIS': ('that', None, 0, False),
321 'do_functionname()': (None, None, 0, False)}, newfile4)
322
323
324 def test_edit_metadata(self):
325 newfile5 = """
326# A comment
327HELLO = "hithere"
328
329# A new comment
330THIS += "that"
331
332# Another comment
333NOCHANGE = "samevalue"
334OTHER = 'anothervalue'
335
336MULTILINE = "a1 \\
337 a2 \\
338 a3"
339
340MULTILINE2 := " \\
341 b1 \\
342 b2 \\
343 b3 \\
344 "
345
346
347MULTILINE3 = " \\
348 c1 \\
349 c2 \\
350 c3 \\
351"
352
353NEWVAR = "value"
354
355do_functionname() {
356 command1 ${VAL1} ${VAL2}
357 command2 ${VAL3} ${VAL4}
358}
359"""
360
361
362 def handle_var(varname, origvalue, op, newlines):
363 if varname == 'THIS':
364 newlines.append('# A new comment\n')
365 elif varname == 'do_functionname()':
366 newlines.append('NEWVAR = "value"\n')
367 newlines.append('\n')
368 valueitem = varvalues.get(varname, None)
369 if valueitem:
370 return valueitem
371 else:
372 return (origvalue, op, 0, True)
373
374 varvalues = {'HELLO': ('hithere', None, 0, True), 'THIS': ('that', '+=', 0, True)}
375 varlist = ['HELLO', 'THIS', 'do_functionname()']
376 (updated, newlines) = bb.utils.edit_metadata(self._origfile.splitlines(True), varlist, handle_var)
377 self.assertTrue(updated, 'List should be updated but isn\'t')
378 self.assertEqual(newlines, newfile5.splitlines(True))