blob: 9171509a6246f7159af0b4b938e23036178d4082 [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 utils.py
5#
6# Copyright (C) 2012 Richard Purdie
7#
8# This program is free software; you can redistribute it and/or modify
9# it under the terms of the GNU General Public License version 2 as
10# published by the Free Software Foundation.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License along
18# with this program; if not, write to the Free Software Foundation, Inc.,
19# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20#
21
22import unittest
23import bb
24import os
25import tempfile
26
27class VerCmpString(unittest.TestCase):
28
29 def test_vercmpstring(self):
30 result = bb.utils.vercmp_string('1', '2')
31 self.assertTrue(result < 0)
32 result = bb.utils.vercmp_string('2', '1')
33 self.assertTrue(result > 0)
34 result = bb.utils.vercmp_string('1', '1.0')
35 self.assertTrue(result < 0)
36 result = bb.utils.vercmp_string('1', '1.1')
37 self.assertTrue(result < 0)
38 result = bb.utils.vercmp_string('1.1', '1_p2')
39 self.assertTrue(result < 0)
40 result = bb.utils.vercmp_string('1.0', '1.0+1.1-beta1')
41 self.assertTrue(result < 0)
42 result = bb.utils.vercmp_string('1.1', '1.0+1.1-beta1')
43 self.assertTrue(result > 0)
44
45 def test_explode_dep_versions(self):
46 correctresult = {"foo" : ["= 1.10"]}
47 result = bb.utils.explode_dep_versions2("foo (= 1.10)")
48 self.assertEqual(result, correctresult)
49 result = bb.utils.explode_dep_versions2("foo (=1.10)")
50 self.assertEqual(result, correctresult)
51 result = bb.utils.explode_dep_versions2("foo ( = 1.10)")
52 self.assertEqual(result, correctresult)
53 result = bb.utils.explode_dep_versions2("foo ( =1.10)")
54 self.assertEqual(result, correctresult)
55 result = bb.utils.explode_dep_versions2("foo ( = 1.10 )")
56 self.assertEqual(result, correctresult)
57 result = bb.utils.explode_dep_versions2("foo ( =1.10 )")
58 self.assertEqual(result, correctresult)
59
60 def test_vercmp_string_op(self):
61 compareops = [('1', '1', '=', True),
62 ('1', '1', '==', True),
63 ('1', '1', '!=', False),
64 ('1', '1', '>', False),
65 ('1', '1', '<', False),
66 ('1', '1', '>=', True),
67 ('1', '1', '<=', True),
68 ('1', '0', '=', False),
69 ('1', '0', '==', False),
70 ('1', '0', '!=', True),
71 ('1', '0', '>', True),
72 ('1', '0', '<', False),
73 ('1', '0', '>>', True),
74 ('1', '0', '<<', False),
75 ('1', '0', '>=', True),
76 ('1', '0', '<=', False),
77 ('0', '1', '=', False),
78 ('0', '1', '==', False),
79 ('0', '1', '!=', True),
80 ('0', '1', '>', False),
81 ('0', '1', '<', True),
82 ('0', '1', '>>', False),
83 ('0', '1', '<<', True),
84 ('0', '1', '>=', False),
85 ('0', '1', '<=', True)]
86
87 for arg1, arg2, op, correctresult in compareops:
88 result = bb.utils.vercmp_string_op(arg1, arg2, op)
89 self.assertEqual(result, correctresult, 'vercmp_string_op("%s", "%s", "%s") != %s' % (arg1, arg2, op, correctresult))
90
91 # Check that clearly invalid operator raises an exception
92 self.assertRaises(bb.utils.VersionStringException, bb.utils.vercmp_string_op, '0', '0', '$')
93
94
95class Path(unittest.TestCase):
96 def test_unsafe_delete_path(self):
97 checkitems = [('/', True),
98 ('//', True),
99 ('///', True),
100 (os.getcwd().count(os.sep) * ('..' + os.sep), True),
101 (os.environ.get('HOME', '/home/test'), True),
102 ('/home/someone', True),
103 ('/home/other/', True),
104 ('/home/other/subdir', False),
105 ('', False)]
106 for arg1, correctresult in checkitems:
107 result = bb.utils._check_unsafe_delete_path(arg1)
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))