summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/bb/tests
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake/lib/bb/tests')
-rw-r--r--bitbake/lib/bb/tests/__init__.py0
-rw-r--r--bitbake/lib/bb/tests/codeparser.py375
-rw-r--r--bitbake/lib/bb/tests/cow.py136
-rw-r--r--bitbake/lib/bb/tests/data.py296
-rw-r--r--bitbake/lib/bb/tests/fetch.py562
-rw-r--r--bitbake/lib/bb/tests/utils.py53
6 files changed, 1422 insertions, 0 deletions
diff --git a/bitbake/lib/bb/tests/__init__.py b/bitbake/lib/bb/tests/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/bitbake/lib/bb/tests/__init__.py
diff --git a/bitbake/lib/bb/tests/codeparser.py b/bitbake/lib/bb/tests/codeparser.py
new file mode 100644
index 0000000000..4454bc51ed
--- /dev/null
+++ b/bitbake/lib/bb/tests/codeparser.py
@@ -0,0 +1,375 @@
1# ex:ts=4:sw=4:sts=4:et
2# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
3#
4# BitBake Test for codeparser.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 logging
25import bb
26
27logger = logging.getLogger('BitBake.TestCodeParser')
28
29# bb.data references bb.parse but can't directly import due to circular dependencies.
30# Hack around it for now :(
31import bb.parse
32import bb.data
33
34class ReferenceTest(unittest.TestCase):
35 def setUp(self):
36 self.d = bb.data.init()
37
38 def setEmptyVars(self, varlist):
39 for k in varlist:
40 self.d.setVar(k, "")
41
42 def setValues(self, values):
43 for k, v in values.items():
44 self.d.setVar(k, v)
45
46 def assertReferences(self, refs):
47 self.assertEqual(self.references, refs)
48
49 def assertExecs(self, execs):
50 self.assertEqual(self.execs, execs)
51
52class VariableReferenceTest(ReferenceTest):
53
54 def parseExpression(self, exp):
55 parsedvar = self.d.expandWithRefs(exp, None)
56 self.references = parsedvar.references
57
58 def test_simple_reference(self):
59 self.setEmptyVars(["FOO"])
60 self.parseExpression("${FOO}")
61 self.assertReferences(set(["FOO"]))
62
63 def test_nested_reference(self):
64 self.setEmptyVars(["BAR"])
65 self.d.setVar("FOO", "BAR")
66 self.parseExpression("${${FOO}}")
67 self.assertReferences(set(["FOO", "BAR"]))
68
69 def test_python_reference(self):
70 self.setEmptyVars(["BAR"])
71 self.parseExpression("${@bb.data.getVar('BAR', d, True) + 'foo'}")
72 self.assertReferences(set(["BAR"]))
73
74class ShellReferenceTest(ReferenceTest):
75
76 def parseExpression(self, exp):
77 parsedvar = self.d.expandWithRefs(exp, None)
78 parser = bb.codeparser.ShellParser("ParserTest", logger)
79 parser.parse_shell(parsedvar.value)
80
81 self.references = parsedvar.references
82 self.execs = parser.execs
83
84 def test_quotes_inside_assign(self):
85 self.parseExpression('foo=foo"bar"baz')
86 self.assertReferences(set([]))
87
88 def test_quotes_inside_arg(self):
89 self.parseExpression('sed s#"bar baz"#"alpha beta"#g')
90 self.assertExecs(set(["sed"]))
91
92 def test_arg_continuation(self):
93 self.parseExpression("sed -i -e s,foo,bar,g \\\n *.pc")
94 self.assertExecs(set(["sed"]))
95
96 def test_dollar_in_quoted(self):
97 self.parseExpression('sed -i -e "foo$" *.pc')
98 self.assertExecs(set(["sed"]))
99
100 def test_quotes_inside_arg_continuation(self):
101 self.setEmptyVars(["bindir", "D", "libdir"])
102 self.parseExpression("""
103sed -i -e s#"moc_location=.*$"#"moc_location=${bindir}/moc4"# \\
104-e s#"uic_location=.*$"#"uic_location=${bindir}/uic4"# \\
105${D}${libdir}/pkgconfig/*.pc
106""")
107 self.assertReferences(set(["bindir", "D", "libdir"]))
108
109 def test_assign_subshell_expansion(self):
110 self.parseExpression("foo=$(echo bar)")
111 self.assertExecs(set(["echo"]))
112
113 def test_shell_unexpanded(self):
114 self.setEmptyVars(["QT_BASE_NAME"])
115 self.parseExpression('echo "${QT_BASE_NAME}"')
116 self.assertExecs(set(["echo"]))
117 self.assertReferences(set(["QT_BASE_NAME"]))
118
119 def test_incomplete_varexp_single_quotes(self):
120 self.parseExpression("sed -i -e 's:IP{:I${:g' $pc")
121 self.assertExecs(set(["sed"]))
122
123
124 def test_until(self):
125 self.parseExpression("until false; do echo true; done")
126 self.assertExecs(set(["false", "echo"]))
127 self.assertReferences(set())
128
129 def test_case(self):
130 self.parseExpression("""
131case $foo in
132*)
133bar
134;;
135esac
136""")
137 self.assertExecs(set(["bar"]))
138 self.assertReferences(set())
139
140 def test_assign_exec(self):
141 self.parseExpression("a=b c='foo bar' alpha 1 2 3")
142 self.assertExecs(set(["alpha"]))
143
144 def test_redirect_to_file(self):
145 self.setEmptyVars(["foo"])
146 self.parseExpression("echo foo >${foo}/bar")
147 self.assertExecs(set(["echo"]))
148 self.assertReferences(set(["foo"]))
149
150 def test_heredoc(self):
151 self.setEmptyVars(["theta"])
152 self.parseExpression("""
153cat <<END
154alpha
155beta
156${theta}
157END
158""")
159 self.assertReferences(set(["theta"]))
160
161 def test_redirect_from_heredoc(self):
162 v = ["B", "SHADOW_MAILDIR", "SHADOW_MAILFILE", "SHADOW_UTMPDIR", "SHADOW_LOGDIR", "bindir"]
163 self.setEmptyVars(v)
164 self.parseExpression("""
165cat <<END >${B}/cachedpaths
166shadow_cv_maildir=${SHADOW_MAILDIR}
167shadow_cv_mailfile=${SHADOW_MAILFILE}
168shadow_cv_utmpdir=${SHADOW_UTMPDIR}
169shadow_cv_logdir=${SHADOW_LOGDIR}
170shadow_cv_passwd_dir=${bindir}
171END
172""")
173 self.assertReferences(set(v))
174 self.assertExecs(set(["cat"]))
175
176# def test_incomplete_command_expansion(self):
177# self.assertRaises(reftracker.ShellSyntaxError, reftracker.execs,
178# bbvalue.shparse("cp foo`", self.d), self.d)
179
180# def test_rogue_dollarsign(self):
181# self.setValues({"D" : "/tmp"})
182# self.parseExpression("install -d ${D}$")
183# self.assertReferences(set(["D"]))
184# self.assertExecs(set(["install"]))
185
186
187class PythonReferenceTest(ReferenceTest):
188
189 def setUp(self):
190 self.d = bb.data.init()
191 if hasattr(bb.utils, "_context"):
192 self.context = bb.utils._context
193 else:
194 import __builtin__
195 self.context = __builtin__.__dict__
196
197 def parseExpression(self, exp):
198 parsedvar = self.d.expandWithRefs(exp, None)
199 parser = bb.codeparser.PythonParser("ParserTest", logger)
200 parser.parse_python(parsedvar.value)
201
202 self.references = parsedvar.references | parser.references
203 self.execs = parser.execs
204
205 @staticmethod
206 def indent(value):
207 """Python Snippets have to be indented, python values don't have to
208be. These unit tests are testing snippets."""
209 return " " + value
210
211 def test_getvar_reference(self):
212 self.parseExpression("bb.data.getVar('foo', d, True)")
213 self.assertReferences(set(["foo"]))
214 self.assertExecs(set())
215
216 def test_getvar_computed_reference(self):
217 self.parseExpression("bb.data.getVar('f' + 'o' + 'o', d, True)")
218 self.assertReferences(set())
219 self.assertExecs(set())
220
221 def test_getvar_exec_reference(self):
222 self.parseExpression("eval('bb.data.getVar(\"foo\", d, True)')")
223 self.assertReferences(set())
224 self.assertExecs(set(["eval"]))
225
226 def test_var_reference(self):
227 self.context["foo"] = lambda x: x
228 self.setEmptyVars(["FOO"])
229 self.parseExpression("foo('${FOO}')")
230 self.assertReferences(set(["FOO"]))
231 self.assertExecs(set(["foo"]))
232 del self.context["foo"]
233
234 def test_var_exec(self):
235 for etype in ("func", "task"):
236 self.d.setVar("do_something", "echo 'hi mom! ${FOO}'")
237 self.d.setVarFlag("do_something", etype, True)
238 self.parseExpression("bb.build.exec_func('do_something', d)")
239 self.assertReferences(set([]))
240 self.assertExecs(set(["do_something"]))
241
242 def test_function_reference(self):
243 self.context["testfunc"] = lambda msg: bb.msg.note(1, None, msg)
244 self.d.setVar("FOO", "Hello, World!")
245 self.parseExpression("testfunc('${FOO}')")
246 self.assertReferences(set(["FOO"]))
247 self.assertExecs(set(["testfunc"]))
248 del self.context["testfunc"]
249
250 def test_qualified_function_reference(self):
251 self.parseExpression("time.time()")
252 self.assertExecs(set(["time.time"]))
253
254 def test_qualified_function_reference_2(self):
255 self.parseExpression("os.path.dirname('/foo/bar')")
256 self.assertExecs(set(["os.path.dirname"]))
257
258 def test_qualified_function_reference_nested(self):
259 self.parseExpression("time.strftime('%Y%m%d',time.gmtime())")
260 self.assertExecs(set(["time.strftime", "time.gmtime"]))
261
262 def test_function_reference_chained(self):
263 self.context["testget"] = lambda: "\tstrip me "
264 self.parseExpression("testget().strip()")
265 self.assertExecs(set(["testget"]))
266 del self.context["testget"]
267
268
269class DependencyReferenceTest(ReferenceTest):
270
271 pydata = """
272bb.data.getVar('somevar', d, True)
273def test(d):
274 foo = 'bar %s' % 'foo'
275def test2(d):
276 d.getVar(foo, True)
277 d.getVar('bar', False)
278 test2(d)
279
280def a():
281 \"\"\"some
282 stuff
283 \"\"\"
284 return "heh"
285
286test(d)
287
288bb.data.expand(bb.data.getVar("something", False, d), d)
289bb.data.expand("${inexpand} somethingelse", d)
290bb.data.getVar(a(), d, False)
291"""
292
293 def test_python(self):
294 self.d.setVar("FOO", self.pydata)
295 self.setEmptyVars(["inexpand", "a", "test2", "test"])
296 self.d.setVarFlags("FOO", {"func": True, "python": True})
297
298 deps, values = bb.data.build_dependencies("FOO", set(self.d.keys()), set(), set(), self.d)
299
300 self.assertEquals(deps, set(["somevar", "bar", "something", "inexpand", "test", "test2", "a"]))
301
302
303 shelldata = """
304foo () {
305bar
306}
307{
308echo baz
309$(heh)
310eval `moo`
311}
312a=b
313c=d
314(
315true && false
316test -f foo
317testval=something
318$testval
319) || aiee
320! inverted
321echo ${somevar}
322
323case foo in
324bar)
325echo bar
326;;
327baz)
328echo baz
329;;
330foo*)
331echo foo
332;;
333esac
334"""
335
336 def test_shell(self):
337 execs = ["bar", "echo", "heh", "moo", "true", "aiee"]
338 self.d.setVar("somevar", "heh")
339 self.d.setVar("inverted", "echo inverted...")
340 self.d.setVarFlag("inverted", "func", True)
341 self.d.setVar("FOO", self.shelldata)
342 self.d.setVarFlags("FOO", {"func": True})
343 self.setEmptyVars(execs)
344
345 deps, values = bb.data.build_dependencies("FOO", set(self.d.keys()), set(), set(), self.d)
346
347 self.assertEquals(deps, set(["somevar", "inverted"] + execs))
348
349
350 def test_vardeps(self):
351 self.d.setVar("oe_libinstall", "echo test")
352 self.d.setVar("FOO", "foo=oe_libinstall; eval $foo")
353 self.d.setVarFlag("FOO", "vardeps", "oe_libinstall")
354
355 deps, values = bb.data.build_dependencies("FOO", set(self.d.keys()), set(), set(), self.d)
356
357 self.assertEquals(deps, set(["oe_libinstall"]))
358
359 def test_vardeps_expand(self):
360 self.d.setVar("oe_libinstall", "echo test")
361 self.d.setVar("FOO", "foo=oe_libinstall; eval $foo")
362 self.d.setVarFlag("FOO", "vardeps", "${@'oe_libinstall'}")
363
364 deps, values = bb.data.build_dependencies("FOO", set(self.d.keys()), set(), set(), self.d)
365
366 self.assertEquals(deps, set(["oe_libinstall"]))
367
368 #Currently no wildcard support
369 #def test_vardeps_wildcards(self):
370 # self.d.setVar("oe_libinstall", "echo test")
371 # self.d.setVar("FOO", "foo=oe_libinstall; eval $foo")
372 # self.d.setVarFlag("FOO", "vardeps", "oe_*")
373 # self.assertEquals(deps, set(["oe_libinstall"]))
374
375
diff --git a/bitbake/lib/bb/tests/cow.py b/bitbake/lib/bb/tests/cow.py
new file mode 100644
index 0000000000..35c5841f32
--- /dev/null
+++ b/bitbake/lib/bb/tests/cow.py
@@ -0,0 +1,136 @@
1# 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 Copy-on-Write (cow.py)
5#
6# Copyright 2006 Holger Freyther <freyther@handhelds.org>
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 os
24
25class COWTestCase(unittest.TestCase):
26 """
27 Test case for the COW module from mithro
28 """
29
30 def testGetSet(self):
31 """
32 Test and set
33 """
34 from bb.COW import COWDictBase
35 a = COWDictBase.copy()
36
37 self.assertEquals(False, a.has_key('a'))
38
39 a['a'] = 'a'
40 a['b'] = 'b'
41 self.assertEquals(True, a.has_key('a'))
42 self.assertEquals(True, a.has_key('b'))
43 self.assertEquals('a', a['a'] )
44 self.assertEquals('b', a['b'] )
45
46 def testCopyCopy(self):
47 """
48 Test the copy of copies
49 """
50
51 from bb.COW import COWDictBase
52
53 # create two COW dict 'instances'
54 b = COWDictBase.copy()
55 c = COWDictBase.copy()
56
57 # assign some keys to one instance, some keys to another
58 b['a'] = 10
59 b['c'] = 20
60 c['a'] = 30
61
62 # test separation of the two instances
63 self.assertEquals(False, c.has_key('c'))
64 self.assertEquals(30, c['a'])
65 self.assertEquals(10, b['a'])
66
67 # test copy
68 b_2 = b.copy()
69 c_2 = c.copy()
70
71 self.assertEquals(False, c_2.has_key('c'))
72 self.assertEquals(10, b_2['a'])
73
74 b_2['d'] = 40
75 self.assertEquals(False, c_2.has_key('d'))
76 self.assertEquals(True, b_2.has_key('d'))
77 self.assertEquals(40, b_2['d'])
78 self.assertEquals(False, b.has_key('d'))
79 self.assertEquals(False, c.has_key('d'))
80
81 c_2['d'] = 30
82 self.assertEquals(True, c_2.has_key('d'))
83 self.assertEquals(True, b_2.has_key('d'))
84 self.assertEquals(30, c_2['d'])
85 self.assertEquals(40, b_2['d'])
86 self.assertEquals(False, b.has_key('d'))
87 self.assertEquals(False, c.has_key('d'))
88
89 # test copy of the copy
90 c_3 = c_2.copy()
91 b_3 = b_2.copy()
92 b_3_2 = b_2.copy()
93
94 c_3['e'] = 4711
95 self.assertEquals(4711, c_3['e'])
96 self.assertEquals(False, c_2.has_key('e'))
97 self.assertEquals(False, b_3.has_key('e'))
98 self.assertEquals(False, b_3_2.has_key('e'))
99 self.assertEquals(False, b_2.has_key('e'))
100
101 b_3['e'] = 'viel'
102 self.assertEquals('viel', b_3['e'])
103 self.assertEquals(4711, c_3['e'])
104 self.assertEquals(False, c_2.has_key('e'))
105 self.assertEquals(True, b_3.has_key('e'))
106 self.assertEquals(False, b_3_2.has_key('e'))
107 self.assertEquals(False, b_2.has_key('e'))
108
109 def testCow(self):
110 from bb.COW import COWDictBase
111 c = COWDictBase.copy()
112 c['123'] = 1027
113 c['other'] = 4711
114 c['d'] = { 'abc' : 10, 'bcd' : 20 }
115
116 copy = c.copy()
117
118 self.assertEquals(1027, c['123'])
119 self.assertEquals(4711, c['other'])
120 self.assertEquals({'abc':10, 'bcd':20}, c['d'])
121 self.assertEquals(1027, copy['123'])
122 self.assertEquals(4711, copy['other'])
123 self.assertEquals({'abc':10, 'bcd':20}, copy['d'])
124
125 # cow it now
126 copy['123'] = 1028
127 copy['other'] = 4712
128 copy['d']['abc'] = 20
129
130
131 self.assertEquals(1027, c['123'])
132 self.assertEquals(4711, c['other'])
133 self.assertEquals({'abc':10, 'bcd':20}, c['d'])
134 self.assertEquals(1028, copy['123'])
135 self.assertEquals(4712, copy['other'])
136 self.assertEquals({'abc':20, 'bcd':20}, copy['d'])
diff --git a/bitbake/lib/bb/tests/data.py b/bitbake/lib/bb/tests/data.py
new file mode 100644
index 0000000000..ee66b22e25
--- /dev/null
+++ b/bitbake/lib/bb/tests/data.py
@@ -0,0 +1,296 @@
1# 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
27
28class DataExpansions(unittest.TestCase):
29 def setUp(self):
30 self.d = bb.data.init()
31 self.d["foo"] = "value_of_foo"
32 self.d["bar"] = "value_of_bar"
33 self.d["value_of_foo"] = "value_of_'value_of_foo'"
34
35 def test_one_var(self):
36 val = self.d.expand("${foo}")
37 self.assertEqual(str(val), "value_of_foo")
38
39 def test_indirect_one_var(self):
40 val = self.d.expand("${${foo}}")
41 self.assertEqual(str(val), "value_of_'value_of_foo'")
42
43 def test_indirect_and_another(self):
44 val = self.d.expand("${${foo}} ${bar}")
45 self.assertEqual(str(val), "value_of_'value_of_foo' value_of_bar")
46
47 def test_python_snippet(self):
48 val = self.d.expand("${@5*12}")
49 self.assertEqual(str(val), "60")
50
51 def test_expand_in_python_snippet(self):
52 val = self.d.expand("${@'boo ' + '${foo}'}")
53 self.assertEqual(str(val), "boo value_of_foo")
54
55 def test_python_snippet_getvar(self):
56 val = self.d.expand("${@d.getVar('foo', True) + ' ${bar}'}")
57 self.assertEqual(str(val), "value_of_foo value_of_bar")
58
59 def test_python_snippet_syntax_error(self):
60 self.d.setVar("FOO", "${@foo = 5}")
61 self.assertRaises(bb.data_smart.ExpansionError, self.d.getVar, "FOO", True)
62
63 def test_python_snippet_runtime_error(self):
64 self.d.setVar("FOO", "${@int('test')}")
65 self.assertRaises(bb.data_smart.ExpansionError, self.d.getVar, "FOO", True)
66
67 def test_python_snippet_error_path(self):
68 self.d.setVar("FOO", "foo value ${BAR}")
69 self.d.setVar("BAR", "bar value ${@int('test')}")
70 self.assertRaises(bb.data_smart.ExpansionError, self.d.getVar, "FOO", True)
71
72 def test_value_containing_value(self):
73 val = self.d.expand("${@d.getVar('foo', True) + ' ${bar}'}")
74 self.assertEqual(str(val), "value_of_foo value_of_bar")
75
76 def test_reference_undefined_var(self):
77 val = self.d.expand("${undefinedvar} meh")
78 self.assertEqual(str(val), "${undefinedvar} meh")
79
80 def test_double_reference(self):
81 self.d.setVar("BAR", "bar value")
82 self.d.setVar("FOO", "${BAR} foo ${BAR}")
83 val = self.d.getVar("FOO", True)
84 self.assertEqual(str(val), "bar value foo bar value")
85
86 def test_direct_recursion(self):
87 self.d.setVar("FOO", "${FOO}")
88 self.assertRaises(bb.data_smart.ExpansionError, self.d.getVar, "FOO", True)
89
90 def test_indirect_recursion(self):
91 self.d.setVar("FOO", "${BAR}")
92 self.d.setVar("BAR", "${BAZ}")
93 self.d.setVar("BAZ", "${FOO}")
94 self.assertRaises(bb.data_smart.ExpansionError, self.d.getVar, "FOO", True)
95
96 def test_recursion_exception(self):
97 self.d.setVar("FOO", "${BAR}")
98 self.d.setVar("BAR", "${${@'FOO'}}")
99 self.assertRaises(bb.data_smart.ExpansionError, self.d.getVar, "FOO", True)
100
101 def test_incomplete_varexp_single_quotes(self):
102 self.d.setVar("FOO", "sed -i -e 's:IP{:I${:g' $pc")
103 val = self.d.getVar("FOO", True)
104 self.assertEqual(str(val), "sed -i -e 's:IP{:I${:g' $pc")
105
106 def test_nonstring(self):
107 self.d.setVar("TEST", 5)
108 val = self.d.getVar("TEST", True)
109 self.assertEqual(str(val), "5")
110
111 def test_rename(self):
112 self.d.renameVar("foo", "newfoo")
113 self.assertEqual(self.d.getVar("newfoo"), "value_of_foo")
114 self.assertEqual(self.d.getVar("foo"), None)
115
116 def test_deletion(self):
117 self.d.delVar("foo")
118 self.assertEqual(self.d.getVar("foo"), None)
119
120 def test_keys(self):
121 keys = self.d.keys()
122 self.assertEqual(keys, ['value_of_foo', 'foo', 'bar'])
123
124class TestNestedExpansions(unittest.TestCase):
125 def setUp(self):
126 self.d = bb.data.init()
127 self.d["foo"] = "foo"
128 self.d["bar"] = "bar"
129 self.d["value_of_foobar"] = "187"
130
131 def test_refs(self):
132 val = self.d.expand("${value_of_${foo}${bar}}")
133 self.assertEqual(str(val), "187")
134
135 #def test_python_refs(self):
136 # val = self.d.expand("${@${@3}**2 + ${@4}**2}")
137 # self.assertEqual(str(val), "25")
138
139 def test_ref_in_python_ref(self):
140 val = self.d.expand("${@'${foo}' + 'bar'}")
141 self.assertEqual(str(val), "foobar")
142
143 def test_python_ref_in_ref(self):
144 val = self.d.expand("${${@'f'+'o'+'o'}}")
145 self.assertEqual(str(val), "foo")
146
147 def test_deep_nesting(self):
148 depth = 100
149 val = self.d.expand("${" * depth + "foo" + "}" * depth)
150 self.assertEqual(str(val), "foo")
151
152 #def test_deep_python_nesting(self):
153 # depth = 50
154 # val = self.d.expand("${@" * depth + "1" + "+1}" * depth)
155 # self.assertEqual(str(val), str(depth + 1))
156
157 def test_mixed(self):
158 val = self.d.expand("${value_of_${@('${foo}'+'bar')[0:3]}${${@'BAR'.lower()}}}")
159 self.assertEqual(str(val), "187")
160
161 def test_runtime(self):
162 val = self.d.expand("${${@'value_of' + '_f'+'o'+'o'+'b'+'a'+'r'}}")
163 self.assertEqual(str(val), "187")
164
165class TestMemoize(unittest.TestCase):
166 def test_memoized(self):
167 d = bb.data.init()
168 d.setVar("FOO", "bar")
169 self.assertTrue(d.getVar("FOO") is d.getVar("FOO"))
170
171 def test_not_memoized(self):
172 d1 = bb.data.init()
173 d2 = bb.data.init()
174 d1.setVar("FOO", "bar")
175 d2.setVar("FOO", "bar2")
176 self.assertTrue(d1.getVar("FOO") is not d2.getVar("FOO"))
177
178 def test_changed_after_memoized(self):
179 d = bb.data.init()
180 d.setVar("foo", "value of foo")
181 self.assertEqual(str(d.getVar("foo")), "value of foo")
182 d.setVar("foo", "second value of foo")
183 self.assertEqual(str(d.getVar("foo")), "second value of foo")
184
185 def test_same_value(self):
186 d = bb.data.init()
187 d.setVar("foo", "value of")
188 d.setVar("bar", "value of")
189 self.assertEqual(d.getVar("foo"),
190 d.getVar("bar"))
191
192class TestConcat(unittest.TestCase):
193 def setUp(self):
194 self.d = bb.data.init()
195 self.d.setVar("FOO", "foo")
196 self.d.setVar("VAL", "val")
197 self.d.setVar("BAR", "bar")
198
199 def test_prepend(self):
200 self.d.setVar("TEST", "${VAL}")
201 self.d.prependVar("TEST", "${FOO}:")
202 self.assertEqual(self.d.getVar("TEST", True), "foo:val")
203
204 def test_append(self):
205 self.d.setVar("TEST", "${VAL}")
206 self.d.appendVar("TEST", ":${BAR}")
207 self.assertEqual(self.d.getVar("TEST", True), "val:bar")
208
209 def test_multiple_append(self):
210 self.d.setVar("TEST", "${VAL}")
211 self.d.prependVar("TEST", "${FOO}:")
212 self.d.appendVar("TEST", ":val2")
213 self.d.appendVar("TEST", ":${BAR}")
214 self.assertEqual(self.d.getVar("TEST", True), "foo:val:val2:bar")
215
216class TestConcatOverride(unittest.TestCase):
217 def setUp(self):
218 self.d = bb.data.init()
219 self.d.setVar("FOO", "foo")
220 self.d.setVar("VAL", "val")
221 self.d.setVar("BAR", "bar")
222
223 def test_prepend(self):
224 self.d.setVar("TEST", "${VAL}")
225 self.d.setVar("TEST_prepend", "${FOO}:")
226 bb.data.update_data(self.d)
227 self.assertEqual(self.d.getVar("TEST", True), "foo:val")
228
229 def test_append(self):
230 self.d.setVar("TEST", "${VAL}")
231 self.d.setVar("TEST_append", ":${BAR}")
232 bb.data.update_data(self.d)
233 self.assertEqual(self.d.getVar("TEST", True), "val:bar")
234
235 def test_multiple_append(self):
236 self.d.setVar("TEST", "${VAL}")
237 self.d.setVar("TEST_prepend", "${FOO}:")
238 self.d.setVar("TEST_append", ":val2")
239 self.d.setVar("TEST_append", ":${BAR}")
240 bb.data.update_data(self.d)
241 self.assertEqual(self.d.getVar("TEST", True), "foo:val:val2:bar")
242
243 def test_remove(self):
244 self.d.setVar("TEST", "${VAL} ${BAR}")
245 self.d.setVar("TEST_remove", "val")
246 bb.data.update_data(self.d)
247 self.assertEqual(self.d.getVar("TEST", True), "bar")
248
249 def test_doubleref_remove(self):
250 self.d.setVar("TEST", "${VAL} ${BAR}")
251 self.d.setVar("TEST_remove", "val")
252 self.d.setVar("TEST_TEST", "${TEST} ${TEST}")
253 bb.data.update_data(self.d)
254 self.assertEqual(self.d.getVar("TEST_TEST", True), "bar bar")
255
256
257class TestOverrides(unittest.TestCase):
258 def setUp(self):
259 self.d = bb.data.init()
260 self.d.setVar("OVERRIDES", "foo:bar:local")
261 self.d.setVar("TEST", "testvalue")
262
263 def test_no_override(self):
264 bb.data.update_data(self.d)
265 self.assertEqual(self.d.getVar("TEST", True), "testvalue")
266
267 def test_one_override(self):
268 self.d.setVar("TEST_bar", "testvalue2")
269 bb.data.update_data(self.d)
270 self.assertEqual(self.d.getVar("TEST", True), "testvalue2")
271
272 def test_multiple_override(self):
273 self.d.setVar("TEST_bar", "testvalue2")
274 self.d.setVar("TEST_local", "testvalue3")
275 self.d.setVar("TEST_foo", "testvalue4")
276 bb.data.update_data(self.d)
277 self.assertEqual(self.d.getVar("TEST", True), "testvalue3")
278
279
280class TestFlags(unittest.TestCase):
281 def setUp(self):
282 self.d = bb.data.init()
283 self.d.setVar("foo", "value of foo")
284 self.d.setVarFlag("foo", "flag1", "value of flag1")
285 self.d.setVarFlag("foo", "flag2", "value of flag2")
286
287 def test_setflag(self):
288 self.assertEqual(self.d.getVarFlag("foo", "flag1"), "value of flag1")
289 self.assertEqual(self.d.getVarFlag("foo", "flag2"), "value of flag2")
290
291 def test_delflag(self):
292 self.d.delVarFlag("foo", "flag2")
293 self.assertEqual(self.d.getVarFlag("foo", "flag1"), "value of flag1")
294 self.assertEqual(self.d.getVarFlag("foo", "flag2"), None)
295
296
diff --git a/bitbake/lib/bb/tests/fetch.py b/bitbake/lib/bb/tests/fetch.py
new file mode 100644
index 0000000000..7df7a0ef51
--- /dev/null
+++ b/bitbake/lib/bb/tests/fetch.py
@@ -0,0 +1,562 @@
1# 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 Fetcher (fetch2/)
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 tempfile
24import subprocess
25import os
26from bb.fetch2 import URI
27import bb
28
29class URITest(unittest.TestCase):
30 test_uris = {
31 "http://www.google.com/index.html" : {
32 'uri': 'http://www.google.com/index.html',
33 'scheme': 'http',
34 'hostname': 'www.google.com',
35 'port': None,
36 'hostport': 'www.google.com',
37 'path': '/index.html',
38 'userinfo': '',
39 'username': '',
40 'password': '',
41 'params': {},
42 'query': {},
43 'relative': False
44 },
45 "http://www.google.com/index.html;param1=value1" : {
46 'uri': 'http://www.google.com/index.html;param1=value1',
47 'scheme': 'http',
48 'hostname': 'www.google.com',
49 'port': None,
50 'hostport': 'www.google.com',
51 'path': '/index.html',
52 'userinfo': '',
53 'username': '',
54 'password': '',
55 'params': {
56 'param1': 'value1'
57 },
58 'query': {},
59 'relative': False
60 },
61 "http://www.example.org/index.html?param1=value1" : {
62 'uri': 'http://www.example.org/index.html?param1=value1',
63 'scheme': 'http',
64 'hostname': 'www.example.org',
65 'port': None,
66 'hostport': 'www.example.org',
67 'path': '/index.html',
68 'userinfo': '',
69 'username': '',
70 'password': '',
71 'params': {},
72 'query': {
73 'param1': 'value1'
74 },
75 'relative': False
76 },
77 "http://www.example.org/index.html?qparam1=qvalue1;param2=value2" : {
78 'uri': 'http://www.example.org/index.html?qparam1=qvalue1;param2=value2',
79 'scheme': 'http',
80 'hostname': 'www.example.org',
81 'port': None,
82 'hostport': 'www.example.org',
83 'path': '/index.html',
84 'userinfo': '',
85 'username': '',
86 'password': '',
87 'params': {
88 'param2': 'value2'
89 },
90 'query': {
91 'qparam1': 'qvalue1'
92 },
93 'relative': False
94 },
95 "http://www.example.com:8080/index.html" : {
96 'uri': 'http://www.example.com:8080/index.html',
97 'scheme': 'http',
98 'hostname': 'www.example.com',
99 'port': 8080,
100 'hostport': 'www.example.com:8080',
101 'path': '/index.html',
102 'userinfo': '',
103 'username': '',
104 'password': '',
105 'params': {},
106 'query': {},
107 'relative': False
108 },
109 "cvs://anoncvs@cvs.handhelds.org/cvs;module=familiar/dist/ipkg" : {
110 'uri': 'cvs://anoncvs@cvs.handhelds.org/cvs;module=familiar/dist/ipkg',
111 'scheme': 'cvs',
112 'hostname': 'cvs.handhelds.org',
113 'port': None,
114 'hostport': 'cvs.handhelds.org',
115 'path': '/cvs',
116 'userinfo': 'anoncvs',
117 'username': 'anoncvs',
118 'password': '',
119 'params': {
120 'module': 'familiar/dist/ipkg'
121 },
122 'query': {},
123 'relative': False
124 },
125 "cvs://anoncvs:anonymous@cvs.handhelds.org/cvs;tag=V0-99-81;module=familiar/dist/ipkg": {
126 'uri': 'cvs://anoncvs:anonymous@cvs.handhelds.org/cvs;tag=V0-99-81;module=familiar/dist/ipkg',
127 'scheme': 'cvs',
128 'hostname': 'cvs.handhelds.org',
129 'port': None,
130 'hostport': 'cvs.handhelds.org',
131 'path': '/cvs',
132 'userinfo': 'anoncvs:anonymous',
133 'username': 'anoncvs',
134 'password': 'anonymous',
135 'params': {
136 'tag': 'V0-99-81',
137 'module': 'familiar/dist/ipkg'
138 },
139 'query': {},
140 'relative': False
141 },
142 "file://example.diff": { # NOTE: Not RFC compliant!
143 'uri': 'file:example.diff',
144 'scheme': 'file',
145 'hostname': '',
146 'port': None,
147 'hostport': '',
148 'path': 'example.diff',
149 'userinfo': '',
150 'username': '',
151 'password': '',
152 'params': {},
153 'query': {},
154 'relative': True
155 },
156 "file:example.diff": { # NOTE: RFC compliant version of the former
157 'uri': 'file:example.diff',
158 'scheme': 'file',
159 'hostname': '',
160 'port': None,
161 'hostport': '',
162 'path': 'example.diff',
163 'userinfo': '',
164 'userinfo': '',
165 'username': '',
166 'password': '',
167 'params': {},
168 'query': {},
169 'relative': True
170 },
171 "file:///tmp/example.diff": {
172 'uri': 'file:///tmp/example.diff',
173 'scheme': 'file',
174 'hostname': '',
175 'port': None,
176 'hostport': '',
177 'path': '/tmp/example.diff',
178 'userinfo': '',
179 'userinfo': '',
180 'username': '',
181 'password': '',
182 'params': {},
183 'query': {},
184 'relative': False
185 },
186 "git:///path/example.git": {
187 'uri': 'git:///path/example.git',
188 'scheme': 'git',
189 'hostname': '',
190 'port': None,
191 'hostport': '',
192 'path': '/path/example.git',
193 'userinfo': '',
194 'userinfo': '',
195 'username': '',
196 'password': '',
197 'params': {},
198 'query': {},
199 'relative': False
200 },
201 "git:path/example.git": {
202 'uri': 'git:path/example.git',
203 'scheme': 'git',
204 'hostname': '',
205 'port': None,
206 'hostport': '',
207 'path': 'path/example.git',
208 'userinfo': '',
209 'userinfo': '',
210 'username': '',
211 'password': '',
212 'params': {},
213 'query': {},
214 'relative': True
215 },
216 "git://example.net/path/example.git": {
217 'uri': 'git://example.net/path/example.git',
218 'scheme': 'git',
219 'hostname': 'example.net',
220 'port': None,
221 'hostport': 'example.net',
222 'path': '/path/example.git',
223 'userinfo': '',
224 'userinfo': '',
225 'username': '',
226 'password': '',
227 'params': {},
228 'query': {},
229 'relative': False
230 }
231 }
232
233 def test_uri(self):
234 for test_uri, ref in self.test_uris.items():
235 uri = URI(test_uri)
236
237 self.assertEqual(str(uri), ref['uri'])
238
239 # expected attributes
240 self.assertEqual(uri.scheme, ref['scheme'])
241
242 self.assertEqual(uri.userinfo, ref['userinfo'])
243 self.assertEqual(uri.username, ref['username'])
244 self.assertEqual(uri.password, ref['password'])
245
246 self.assertEqual(uri.hostname, ref['hostname'])
247 self.assertEqual(uri.port, ref['port'])
248 self.assertEqual(uri.hostport, ref['hostport'])
249
250 self.assertEqual(uri.path, ref['path'])
251 self.assertEqual(uri.params, ref['params'])
252
253 self.assertEqual(uri.relative, ref['relative'])
254
255 def test_dict(self):
256 for test in self.test_uris.values():
257 uri = URI()
258
259 self.assertEqual(uri.scheme, '')
260 self.assertEqual(uri.userinfo, '')
261 self.assertEqual(uri.username, '')
262 self.assertEqual(uri.password, '')
263 self.assertEqual(uri.hostname, '')
264 self.assertEqual(uri.port, None)
265 self.assertEqual(uri.path, '')
266 self.assertEqual(uri.params, {})
267
268
269 uri.scheme = test['scheme']
270 self.assertEqual(uri.scheme, test['scheme'])
271
272 uri.userinfo = test['userinfo']
273 self.assertEqual(uri.userinfo, test['userinfo'])
274 self.assertEqual(uri.username, test['username'])
275 self.assertEqual(uri.password, test['password'])
276
277 # make sure changing the values doesn't do anything unexpected
278 uri.username = 'changeme'
279 self.assertEqual(uri.username, 'changeme')
280 self.assertEqual(uri.password, test['password'])
281 uri.password = 'insecure'
282 self.assertEqual(uri.username, 'changeme')
283 self.assertEqual(uri.password, 'insecure')
284
285 # reset back after our trickery
286 uri.userinfo = test['userinfo']
287 self.assertEqual(uri.userinfo, test['userinfo'])
288 self.assertEqual(uri.username, test['username'])
289 self.assertEqual(uri.password, test['password'])
290
291 uri.hostname = test['hostname']
292 self.assertEqual(uri.hostname, test['hostname'])
293 self.assertEqual(uri.hostport, test['hostname'])
294
295 uri.port = test['port']
296 self.assertEqual(uri.port, test['port'])
297 self.assertEqual(uri.hostport, test['hostport'])
298
299 uri.path = test['path']
300 self.assertEqual(uri.path, test['path'])
301
302 uri.params = test['params']
303 self.assertEqual(uri.params, test['params'])
304
305 uri.query = test['query']
306 self.assertEqual(uri.query, test['query'])
307
308 self.assertEqual(str(uri), test['uri'])
309
310 uri.params = {}
311 self.assertEqual(uri.params, {})
312 self.assertEqual(str(uri), (str(uri).split(";"))[0])
313
314class FetcherTest(unittest.TestCase):
315
316 def setUp(self):
317 self.d = bb.data.init()
318 self.tempdir = tempfile.mkdtemp()
319 self.dldir = os.path.join(self.tempdir, "download")
320 os.mkdir(self.dldir)
321 self.d.setVar("DL_DIR", self.dldir)
322 self.unpackdir = os.path.join(self.tempdir, "unpacked")
323 os.mkdir(self.unpackdir)
324 persistdir = os.path.join(self.tempdir, "persistdata")
325 self.d.setVar("PERSISTENT_DIR", persistdir)
326
327 def tearDown(self):
328 bb.utils.prunedir(self.tempdir)
329
330class MirrorUriTest(FetcherTest):
331
332 replaceuris = {
333 ("git://git.invalid.infradead.org/mtd-utils.git;tag=1234567890123456789012345678901234567890", "git://.*/.*", "http://somewhere.org/somedir/")
334 : "http://somewhere.org/somedir/git2_git.invalid.infradead.org.mtd-utils.git.tar.gz",
335 ("git://git.invalid.infradead.org/mtd-utils.git;tag=1234567890123456789012345678901234567890", "git://.*/([^/]+/)*([^/]*)", "git://somewhere.org/somedir/\\2;protocol=http")
336 : "git://somewhere.org/somedir/mtd-utils.git;tag=1234567890123456789012345678901234567890;protocol=http",
337 ("git://git.invalid.infradead.org/foo/mtd-utils.git;tag=1234567890123456789012345678901234567890", "git://.*/([^/]+/)*([^/]*)", "git://somewhere.org/somedir/\\2;protocol=http")
338 : "git://somewhere.org/somedir/mtd-utils.git;tag=1234567890123456789012345678901234567890;protocol=http",
339 ("git://git.invalid.infradead.org/foo/mtd-utils.git;tag=1234567890123456789012345678901234567890", "git://.*/([^/]+/)*([^/]*)", "git://somewhere.org/\\2;protocol=http")
340 : "git://somewhere.org/mtd-utils.git;tag=1234567890123456789012345678901234567890;protocol=http",
341 ("git://someserver.org/bitbake;tag=1234567890123456789012345678901234567890", "git://someserver.org/bitbake", "git://git.openembedded.org/bitbake")
342 : "git://git.openembedded.org/bitbake;tag=1234567890123456789012345678901234567890",
343 ("file://sstate-xyz.tgz", "file://.*", "file:///somewhere/1234/sstate-cache")
344 : "file:///somewhere/1234/sstate-cache/sstate-xyz.tgz",
345 ("file://sstate-xyz.tgz", "file://.*", "file:///somewhere/1234/sstate-cache/")
346 : "file:///somewhere/1234/sstate-cache/sstate-xyz.tgz",
347 ("http://somewhere.org/somedir1/somedir2/somefile_1.2.3.tar.gz", "http://.*/.*", "http://somewhere2.org/somedir3")
348 : "http://somewhere2.org/somedir3/somefile_1.2.3.tar.gz",
349 ("http://somewhere.org/somedir1/somefile_1.2.3.tar.gz", "http://somewhere.org/somedir1/somefile_1.2.3.tar.gz", "http://somewhere2.org/somedir3/somefile_1.2.3.tar.gz")
350 : "http://somewhere2.org/somedir3/somefile_1.2.3.tar.gz",
351 ("http://www.apache.org/dist/subversion/subversion-1.7.1.tar.bz2", "http://www.apache.org/dist", "http://archive.apache.org/dist")
352 : "http://archive.apache.org/dist/subversion/subversion-1.7.1.tar.bz2",
353 ("http://www.apache.org/dist/subversion/subversion-1.7.1.tar.bz2", "http://.*/.*", "file:///somepath/downloads/")
354 : "file:///somepath/downloads/subversion-1.7.1.tar.bz2",
355 ("git://git.invalid.infradead.org/mtd-utils.git;tag=1234567890123456789012345678901234567890", "git://.*/.*", "git://somewhere.org/somedir/BASENAME;protocol=http")
356 : "git://somewhere.org/somedir/mtd-utils.git;tag=1234567890123456789012345678901234567890;protocol=http",
357 ("git://git.invalid.infradead.org/foo/mtd-utils.git;tag=1234567890123456789012345678901234567890", "git://.*/.*", "git://somewhere.org/somedir/BASENAME;protocol=http")
358 : "git://somewhere.org/somedir/mtd-utils.git;tag=1234567890123456789012345678901234567890;protocol=http",
359 ("git://git.invalid.infradead.org/foo/mtd-utils.git;tag=1234567890123456789012345678901234567890", "git://.*/.*", "git://somewhere.org/somedir/MIRRORNAME;protocol=http")
360 : "git://somewhere.org/somedir/git.invalid.infradead.org.foo.mtd-utils.git;tag=1234567890123456789012345678901234567890;protocol=http",
361
362 #Renaming files doesn't work
363 #("http://somewhere.org/somedir1/somefile_1.2.3.tar.gz", "http://somewhere.org/somedir1/somefile_1.2.3.tar.gz", "http://somewhere2.org/somedir3/somefile_2.3.4.tar.gz") : "http://somewhere2.org/somedir3/somefile_2.3.4.tar.gz"
364 #("file://sstate-xyz.tgz", "file://.*/.*", "file:///somewhere/1234/sstate-cache") : "file:///somewhere/1234/sstate-cache/sstate-xyz.tgz",
365 }
366
367 mirrorvar = "http://.*/.* file:///somepath/downloads/ \n" \
368 "git://someserver.org/bitbake git://git.openembedded.org/bitbake \n" \
369 "https://.*/.* file:///someotherpath/downloads/ \n" \
370 "http://.*/.* file:///someotherpath/downloads/ \n"
371
372 def test_urireplace(self):
373 for k, v in self.replaceuris.items():
374 ud = bb.fetch.FetchData(k[0], self.d)
375 ud.setup_localpath(self.d)
376 mirrors = bb.fetch2.mirror_from_string("%s %s" % (k[1], k[2]))
377 newuris, uds = bb.fetch2.build_mirroruris(ud, mirrors, self.d)
378 self.assertEqual([v], newuris)
379
380 def test_urilist1(self):
381 fetcher = bb.fetch.FetchData("http://downloads.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz", self.d)
382 mirrors = bb.fetch2.mirror_from_string(self.mirrorvar)
383 uris, uds = bb.fetch2.build_mirroruris(fetcher, mirrors, self.d)
384 self.assertEqual(uris, ['file:///somepath/downloads/bitbake-1.0.tar.gz', 'file:///someotherpath/downloads/bitbake-1.0.tar.gz'])
385
386 def test_urilist2(self):
387 # Catch https:// -> files:// bug
388 fetcher = bb.fetch.FetchData("https://downloads.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz", self.d)
389 mirrors = bb.fetch2.mirror_from_string(self.mirrorvar)
390 uris, uds = bb.fetch2.build_mirroruris(fetcher, mirrors, self.d)
391 self.assertEqual(uris, ['file:///someotherpath/downloads/bitbake-1.0.tar.gz'])
392
393
394class FetcherLocalTest(FetcherTest):
395 def setUp(self):
396 def touch(fn):
397 with file(fn, 'a'):
398 os.utime(fn, None)
399
400 super(FetcherLocalTest, self).setUp()
401 self.localsrcdir = os.path.join(self.tempdir, 'localsrc')
402 os.makedirs(self.localsrcdir)
403 touch(os.path.join(self.localsrcdir, 'a'))
404 touch(os.path.join(self.localsrcdir, 'b'))
405 os.makedirs(os.path.join(self.localsrcdir, 'dir'))
406 touch(os.path.join(self.localsrcdir, 'dir', 'c'))
407 touch(os.path.join(self.localsrcdir, 'dir', 'd'))
408 os.makedirs(os.path.join(self.localsrcdir, 'dir', 'subdir'))
409 touch(os.path.join(self.localsrcdir, 'dir', 'subdir', 'e'))
410 self.d.setVar("FILESPATH", self.localsrcdir)
411
412 def fetchUnpack(self, uris):
413 fetcher = bb.fetch.Fetch(uris, self.d)
414 fetcher.download()
415 fetcher.unpack(self.unpackdir)
416 flst = []
417 for root, dirs, files in os.walk(self.unpackdir):
418 for f in files:
419 flst.append(os.path.relpath(os.path.join(root, f), self.unpackdir))
420 flst.sort()
421 return flst
422
423 def test_local(self):
424 tree = self.fetchUnpack(['file://a', 'file://dir/c'])
425 self.assertEqual(tree, ['a', 'dir/c'])
426
427 def test_local_wildcard(self):
428 tree = self.fetchUnpack(['file://a', 'file://dir/*'])
429 # FIXME: this is broken - it should return ['a', 'dir/c', 'dir/d', 'dir/subdir/e']
430 # see https://bugzilla.yoctoproject.org/show_bug.cgi?id=6128
431 self.assertEqual(tree, ['a', 'b', 'dir/c', 'dir/d', 'dir/subdir/e'])
432
433 def test_local_dir(self):
434 tree = self.fetchUnpack(['file://a', 'file://dir'])
435 self.assertEqual(tree, ['a', 'dir/c', 'dir/d', 'dir/subdir/e'])
436
437 def test_local_subdir(self):
438 tree = self.fetchUnpack(['file://dir/subdir'])
439 # FIXME: this is broken - it should return ['dir/subdir/e']
440 # see https://bugzilla.yoctoproject.org/show_bug.cgi?id=6129
441 self.assertEqual(tree, ['subdir/e'])
442
443 def test_local_subdir_file(self):
444 tree = self.fetchUnpack(['file://dir/subdir/e'])
445 self.assertEqual(tree, ['dir/subdir/e'])
446
447
448class FetcherNetworkTest(FetcherTest):
449
450 if os.environ.get("BB_SKIP_NETTESTS") == "yes":
451 print("Unset BB_SKIP_NETTESTS to run network tests")
452 else:
453 def test_fetch(self):
454 fetcher = bb.fetch.Fetch(["http://downloads.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz", "http://downloads.yoctoproject.org/releases/bitbake/bitbake-1.1.tar.gz"], self.d)
455 fetcher.download()
456 self.assertEqual(os.path.getsize(self.dldir + "/bitbake-1.0.tar.gz"), 57749)
457 self.assertEqual(os.path.getsize(self.dldir + "/bitbake-1.1.tar.gz"), 57892)
458 self.d.setVar("BB_NO_NETWORK", "1")
459 fetcher = bb.fetch.Fetch(["http://downloads.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz", "http://downloads.yoctoproject.org/releases/bitbake/bitbake-1.1.tar.gz"], self.d)
460 fetcher.download()
461 fetcher.unpack(self.unpackdir)
462 self.assertEqual(len(os.listdir(self.unpackdir + "/bitbake-1.0/")), 9)
463 self.assertEqual(len(os.listdir(self.unpackdir + "/bitbake-1.1/")), 9)
464
465 def test_fetch_mirror(self):
466 self.d.setVar("MIRRORS", "http://.*/.* http://downloads.yoctoproject.org/releases/bitbake")
467 fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz"], self.d)
468 fetcher.download()
469 self.assertEqual(os.path.getsize(self.dldir + "/bitbake-1.0.tar.gz"), 57749)
470
471 def test_fetch_premirror(self):
472 self.d.setVar("PREMIRRORS", "http://.*/.* http://downloads.yoctoproject.org/releases/bitbake")
473 fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz"], self.d)
474 fetcher.download()
475 self.assertEqual(os.path.getsize(self.dldir + "/bitbake-1.0.tar.gz"), 57749)
476
477 def gitfetcher(self, url1, url2):
478 def checkrevision(self, fetcher):
479 fetcher.unpack(self.unpackdir)
480 revision = bb.process.run("git rev-parse HEAD", shell=True, cwd=self.unpackdir + "/git")[0].strip()
481 self.assertEqual(revision, "270a05b0b4ba0959fe0624d2a4885d7b70426da5")
482
483 self.d.setVar("BB_GENERATE_MIRROR_TARBALLS", "1")
484 self.d.setVar("SRCREV", "270a05b0b4ba0959fe0624d2a4885d7b70426da5")
485 fetcher = bb.fetch.Fetch([url1], self.d)
486 fetcher.download()
487 checkrevision(self, fetcher)
488 # Wipe out the dldir clone and the unpacked source, turn off the network and check mirror tarball works
489 bb.utils.prunedir(self.dldir + "/git2/")
490 bb.utils.prunedir(self.unpackdir)
491 self.d.setVar("BB_NO_NETWORK", "1")
492 fetcher = bb.fetch.Fetch([url2], self.d)
493 fetcher.download()
494 checkrevision(self, fetcher)
495
496 def test_gitfetch(self):
497 url1 = url2 = "git://git.openembedded.org/bitbake"
498 self.gitfetcher(url1, url2)
499
500 def test_gitfetch_goodsrcrev(self):
501 # SRCREV is set but matches rev= parameter
502 url1 = url2 = "git://git.openembedded.org/bitbake;rev=270a05b0b4ba0959fe0624d2a4885d7b70426da5"
503 self.gitfetcher(url1, url2)
504
505 def test_gitfetch_badsrcrev(self):
506 # SRCREV is set but does not match rev= parameter
507 url1 = url2 = "git://git.openembedded.org/bitbake;rev=dead05b0b4ba0959fe0624d2a4885d7b70426da5"
508 self.assertRaises(bb.fetch.FetchError, self.gitfetcher, url1, url2)
509
510 def test_gitfetch_tagandrev(self):
511 # SRCREV is set but does not match rev= parameter
512 url1 = url2 = "git://git.openembedded.org/bitbake;rev=270a05b0b4ba0959fe0624d2a4885d7b70426da5;tag=270a05b0b4ba0959fe0624d2a4885d7b70426da5"
513 self.assertRaises(bb.fetch.FetchError, self.gitfetcher, url1, url2)
514
515 def test_gitfetch_premirror(self):
516 url1 = "git://git.openembedded.org/bitbake"
517 url2 = "git://someserver.org/bitbake"
518 self.d.setVar("PREMIRRORS", "git://someserver.org/bitbake git://git.openembedded.org/bitbake \n")
519 self.gitfetcher(url1, url2)
520
521 def test_gitfetch_premirror2(self):
522 url1 = url2 = "git://someserver.org/bitbake"
523 self.d.setVar("PREMIRRORS", "git://someserver.org/bitbake git://git.openembedded.org/bitbake \n")
524 self.gitfetcher(url1, url2)
525
526 def test_gitfetch_premirror3(self):
527 realurl = "git://git.openembedded.org/bitbake"
528 dummyurl = "git://someserver.org/bitbake"
529 self.sourcedir = self.unpackdir.replace("unpacked", "sourcemirror.git")
530 os.chdir(self.tempdir)
531 bb.process.run("git clone %s %s 2> /dev/null" % (realurl, self.sourcedir), shell=True)
532 self.d.setVar("PREMIRRORS", "%s git://%s;protocol=file \n" % (dummyurl, self.sourcedir))
533 self.gitfetcher(dummyurl, dummyurl)
534
535 def test_git_submodule(self):
536 fetcher = bb.fetch.Fetch(["gitsm://git.yoctoproject.org/git-submodule-test;rev=f12e57f2edf0aa534cf1616fa983d165a92b0842"], self.d)
537 fetcher.download()
538 # Previous cwd has been deleted
539 os.chdir(os.path.dirname(self.unpackdir))
540 fetcher.unpack(self.unpackdir)
541
542class URLHandle(unittest.TestCase):
543
544 datatable = {
545 "http://www.google.com/index.html" : ('http', 'www.google.com', '/index.html', '', '', {}),
546 "cvs://anoncvs@cvs.handhelds.org/cvs;module=familiar/dist/ipkg" : ('cvs', 'cvs.handhelds.org', '/cvs', 'anoncvs', '', {'module': 'familiar/dist/ipkg'}),
547 "cvs://anoncvs:anonymous@cvs.handhelds.org/cvs;tag=V0-99-81;module=familiar/dist/ipkg" : ('cvs', 'cvs.handhelds.org', '/cvs', 'anoncvs', 'anonymous', {'tag': 'V0-99-81', 'module': 'familiar/dist/ipkg'}),
548 "git://git.openembedded.org/bitbake;branch=@foo" : ('git', 'git.openembedded.org', '/bitbake', '', '', {'branch': '@foo'})
549 }
550
551 def test_decodeurl(self):
552 for k, v in self.datatable.items():
553 result = bb.fetch.decodeurl(k)
554 self.assertEqual(result, v)
555
556 def test_encodeurl(self):
557 for k, v in self.datatable.items():
558 result = bb.fetch.encodeurl(v)
559 self.assertEqual(result, k)
560
561
562
diff --git a/bitbake/lib/bb/tests/utils.py b/bitbake/lib/bb/tests/utils.py
new file mode 100644
index 0000000000..7c50b1d786
--- /dev/null
+++ b/bitbake/lib/bb/tests/utils.py
@@ -0,0 +1,53 @@
1# 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
24
25class VerCmpString(unittest.TestCase):
26
27 def test_vercmpstring(self):
28 result = bb.utils.vercmp_string('1', '2')
29 self.assertTrue(result < 0)
30 result = bb.utils.vercmp_string('2', '1')
31 self.assertTrue(result > 0)
32 result = bb.utils.vercmp_string('1', '1.0')
33 self.assertTrue(result < 0)
34 result = bb.utils.vercmp_string('1', '1.1')
35 self.assertTrue(result < 0)
36 result = bb.utils.vercmp_string('1.1', '1_p2')
37 self.assertTrue(result < 0)
38
39 def test_explode_dep_versions(self):
40 correctresult = {"foo" : ["= 1.10"]}
41 result = bb.utils.explode_dep_versions2("foo (= 1.10)")
42 self.assertEqual(result, correctresult)
43 result = bb.utils.explode_dep_versions2("foo (=1.10)")
44 self.assertEqual(result, correctresult)
45 result = bb.utils.explode_dep_versions2("foo ( = 1.10)")
46 self.assertEqual(result, correctresult)
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