diff options
Diffstat (limited to 'bitbake/lib/bb/tests')
21 files changed, 5959 insertions, 740 deletions
diff --git a/bitbake/lib/bb/tests/codeparser.py b/bitbake/lib/bb/tests/codeparser.py index 826a2d2f6d..c0d1362a0c 100644 --- a/bitbake/lib/bb/tests/codeparser.py +++ b/bitbake/lib/bb/tests/codeparser.py | |||
@@ -44,6 +44,7 @@ class VariableReferenceTest(ReferenceTest): | |||
44 | def parseExpression(self, exp): | 44 | def parseExpression(self, exp): |
45 | parsedvar = self.d.expandWithRefs(exp, None) | 45 | parsedvar = self.d.expandWithRefs(exp, None) |
46 | self.references = parsedvar.references | 46 | self.references = parsedvar.references |
47 | self.execs = parsedvar.execs | ||
47 | 48 | ||
48 | def test_simple_reference(self): | 49 | def test_simple_reference(self): |
49 | self.setEmptyVars(["FOO"]) | 50 | self.setEmptyVars(["FOO"]) |
@@ -61,6 +62,11 @@ class VariableReferenceTest(ReferenceTest): | |||
61 | self.parseExpression("${@d.getVar('BAR') + 'foo'}") | 62 | self.parseExpression("${@d.getVar('BAR') + 'foo'}") |
62 | self.assertReferences(set(["BAR"])) | 63 | self.assertReferences(set(["BAR"])) |
63 | 64 | ||
65 | def test_python_exec_reference(self): | ||
66 | self.parseExpression("${@eval('3 * 5')}") | ||
67 | self.assertReferences(set()) | ||
68 | self.assertExecs(set(["eval"])) | ||
69 | |||
64 | class ShellReferenceTest(ReferenceTest): | 70 | class ShellReferenceTest(ReferenceTest): |
65 | 71 | ||
66 | def parseExpression(self, exp): | 72 | def parseExpression(self, exp): |
@@ -100,6 +106,46 @@ ${D}${libdir}/pkgconfig/*.pc | |||
100 | self.parseExpression("foo=$(echo bar)") | 106 | self.parseExpression("foo=$(echo bar)") |
101 | self.assertExecs(set(["echo"])) | 107 | self.assertExecs(set(["echo"])) |
102 | 108 | ||
109 | def test_assign_subshell_expansion_quotes(self): | ||
110 | self.parseExpression('foo="$(echo bar)"') | ||
111 | self.assertExecs(set(["echo"])) | ||
112 | |||
113 | def test_assign_subshell_expansion_nested(self): | ||
114 | self.parseExpression('foo="$(func1 "$(func2 bar$(func3))")"') | ||
115 | self.assertExecs(set(["func1", "func2", "func3"])) | ||
116 | |||
117 | def test_assign_subshell_expansion_multiple(self): | ||
118 | self.parseExpression('foo="$(func1 "$(func2)") $(func3)"') | ||
119 | self.assertExecs(set(["func1", "func2", "func3"])) | ||
120 | |||
121 | def test_assign_subshell_expansion_escaped_quotes(self): | ||
122 | self.parseExpression('foo="\\"fo\\"o$(func1)"') | ||
123 | self.assertExecs(set(["func1"])) | ||
124 | |||
125 | def test_assign_subshell_expansion_empty(self): | ||
126 | self.parseExpression('foo="bar$()foo"') | ||
127 | self.assertExecs(set()) | ||
128 | |||
129 | def test_assign_subshell_backticks(self): | ||
130 | self.parseExpression("foo=`echo bar`") | ||
131 | self.assertExecs(set(["echo"])) | ||
132 | |||
133 | def test_assign_subshell_backticks_quotes(self): | ||
134 | self.parseExpression('foo="`echo bar`"') | ||
135 | self.assertExecs(set(["echo"])) | ||
136 | |||
137 | def test_assign_subshell_backticks_multiple(self): | ||
138 | self.parseExpression('foo="`func1 bar` `func2`"') | ||
139 | self.assertExecs(set(["func1", "func2"])) | ||
140 | |||
141 | def test_assign_subshell_backticks_escaped_quotes(self): | ||
142 | self.parseExpression('foo="\\"fo\\"o`func1`"') | ||
143 | self.assertExecs(set(["func1"])) | ||
144 | |||
145 | def test_assign_subshell_backticks_empty(self): | ||
146 | self.parseExpression('foo="bar``foo"') | ||
147 | self.assertExecs(set()) | ||
148 | |||
103 | def test_shell_unexpanded(self): | 149 | def test_shell_unexpanded(self): |
104 | self.setEmptyVars(["QT_BASE_NAME"]) | 150 | self.setEmptyVars(["QT_BASE_NAME"]) |
105 | self.parseExpression('echo "${QT_BASE_NAME}"') | 151 | self.parseExpression('echo "${QT_BASE_NAME}"') |
@@ -111,9 +157,9 @@ ${D}${libdir}/pkgconfig/*.pc | |||
111 | self.assertExecs(set(["sed"])) | 157 | self.assertExecs(set(["sed"])) |
112 | 158 | ||
113 | def test_parameter_expansion_modifiers(self): | 159 | def test_parameter_expansion_modifiers(self): |
114 | # - and + are also valid modifiers for parameter expansion, but are | 160 | # -,+ and : are also valid modifiers for parameter expansion, but are |
115 | # valid characters in bitbake variable names, so are not included here | 161 | # valid characters in bitbake variable names, so are not included here |
116 | for i in ('=', ':-', ':=', '?', ':?', ':+', '#', '%', '##', '%%'): | 162 | for i in ('=', '?', '#', '%', '##', '%%'): |
117 | name = "foo%sbar" % i | 163 | name = "foo%sbar" % i |
118 | self.parseExpression("${%s}" % name) | 164 | self.parseExpression("${%s}" % name) |
119 | self.assertNotIn(name, self.references) | 165 | self.assertNotIn(name, self.references) |
@@ -318,7 +364,7 @@ d.getVar(a(), False) | |||
318 | "filename": "example.bb", | 364 | "filename": "example.bb", |
319 | }) | 365 | }) |
320 | 366 | ||
321 | deps, values = bb.data.build_dependencies("FOO", set(self.d.keys()), set(), set(), self.d) | 367 | deps, values = bb.data.build_dependencies("FOO", set(self.d.keys()), set(), set(), set(), set(), self.d, self.d) |
322 | 368 | ||
323 | self.assertEqual(deps, set(["somevar", "bar", "something", "inexpand", "test", "test2", "a"])) | 369 | self.assertEqual(deps, set(["somevar", "bar", "something", "inexpand", "test", "test2", "a"])) |
324 | 370 | ||
@@ -365,7 +411,7 @@ esac | |||
365 | self.d.setVarFlags("FOO", {"func": True}) | 411 | self.d.setVarFlags("FOO", {"func": True}) |
366 | self.setEmptyVars(execs) | 412 | self.setEmptyVars(execs) |
367 | 413 | ||
368 | deps, values = bb.data.build_dependencies("FOO", set(self.d.keys()), set(), set(), self.d) | 414 | deps, values = bb.data.build_dependencies("FOO", set(self.d.keys()), set(), set(), set(), set(), self.d, self.d) |
369 | 415 | ||
370 | self.assertEqual(deps, set(["somevar", "inverted"] + execs)) | 416 | self.assertEqual(deps, set(["somevar", "inverted"] + execs)) |
371 | 417 | ||
@@ -375,7 +421,7 @@ esac | |||
375 | self.d.setVar("FOO", "foo=oe_libinstall; eval $foo") | 421 | self.d.setVar("FOO", "foo=oe_libinstall; eval $foo") |
376 | self.d.setVarFlag("FOO", "vardeps", "oe_libinstall") | 422 | self.d.setVarFlag("FOO", "vardeps", "oe_libinstall") |
377 | 423 | ||
378 | deps, values = bb.data.build_dependencies("FOO", set(self.d.keys()), set(), set(), self.d) | 424 | deps, values = bb.data.build_dependencies("FOO", set(self.d.keys()), set(), set(), set(), set(), self.d, self.d) |
379 | 425 | ||
380 | self.assertEqual(deps, set(["oe_libinstall"])) | 426 | self.assertEqual(deps, set(["oe_libinstall"])) |
381 | 427 | ||
@@ -384,7 +430,7 @@ esac | |||
384 | self.d.setVar("FOO", "foo=oe_libinstall; eval $foo") | 430 | self.d.setVar("FOO", "foo=oe_libinstall; eval $foo") |
385 | self.d.setVarFlag("FOO", "vardeps", "${@'oe_libinstall'}") | 431 | self.d.setVarFlag("FOO", "vardeps", "${@'oe_libinstall'}") |
386 | 432 | ||
387 | deps, values = bb.data.build_dependencies("FOO", set(self.d.keys()), set(), set(), self.d) | 433 | deps, values = bb.data.build_dependencies("FOO", set(self.d.keys()), set(), set(), set(), set(), self.d, self.d) |
388 | 434 | ||
389 | self.assertEqual(deps, set(["oe_libinstall"])) | 435 | self.assertEqual(deps, set(["oe_libinstall"])) |
390 | 436 | ||
@@ -399,7 +445,7 @@ esac | |||
399 | # Check dependencies | 445 | # Check dependencies |
400 | self.d.setVar('ANOTHERVAR', expr) | 446 | self.d.setVar('ANOTHERVAR', expr) |
401 | self.d.setVar('TESTVAR', 'anothervalue testval testval2') | 447 | self.d.setVar('TESTVAR', 'anothervalue testval testval2') |
402 | deps, values = bb.data.build_dependencies("ANOTHERVAR", set(self.d.keys()), set(), set(), self.d) | 448 | deps, values = bb.data.build_dependencies("ANOTHERVAR", set(self.d.keys()), set(), set(), set(), set(), self.d, self.d) |
403 | self.assertEqual(sorted(values.splitlines()), | 449 | self.assertEqual(sorted(values.splitlines()), |
404 | sorted([expr, | 450 | sorted([expr, |
405 | 'TESTVAR{anothervalue} = Set', | 451 | 'TESTVAR{anothervalue} = Set', |
@@ -412,11 +458,55 @@ esac | |||
412 | # Check final value | 458 | # Check final value |
413 | self.assertEqual(self.d.getVar('ANOTHERVAR').split(), ['anothervalue', 'yetanothervalue', 'lastone']) | 459 | self.assertEqual(self.d.getVar('ANOTHERVAR').split(), ['anothervalue', 'yetanothervalue', 'lastone']) |
414 | 460 | ||
461 | def test_contains_vardeps_excluded(self): | ||
462 | # Check the ignored_vars option to build_dependencies is handled by contains functionality | ||
463 | varval = '${TESTVAR2} ${@bb.utils.filter("TESTVAR", "somevalue anothervalue", d)}' | ||
464 | self.d.setVar('ANOTHERVAR', varval) | ||
465 | self.d.setVar('TESTVAR', 'anothervalue testval testval2') | ||
466 | self.d.setVar('TESTVAR2', 'testval3') | ||
467 | deps, values = bb.data.build_dependencies("ANOTHERVAR", set(self.d.keys()), set(), set(), set(), set(["TESTVAR"]), self.d, self.d) | ||
468 | self.assertEqual(sorted(values.splitlines()), sorted([varval])) | ||
469 | self.assertEqual(deps, set(["TESTVAR2"])) | ||
470 | self.assertEqual(self.d.getVar('ANOTHERVAR').split(), ['testval3', 'anothervalue']) | ||
471 | |||
472 | # Check the vardepsexclude flag is handled by contains functionality | ||
473 | self.d.setVarFlag('ANOTHERVAR', 'vardepsexclude', 'TESTVAR') | ||
474 | deps, values = bb.data.build_dependencies("ANOTHERVAR", set(self.d.keys()), set(), set(), set(), set(), self.d, self.d) | ||
475 | self.assertEqual(sorted(values.splitlines()), sorted([varval])) | ||
476 | self.assertEqual(deps, set(["TESTVAR2"])) | ||
477 | self.assertEqual(self.d.getVar('ANOTHERVAR').split(), ['testval3', 'anothervalue']) | ||
478 | |||
479 | def test_contains_vardeps_override_operators(self): | ||
480 | # Check override operators handle dependencies correctly with the contains functionality | ||
481 | expr_plain = 'testval' | ||
482 | expr_prepend = '${@bb.utils.filter("TESTVAR1", "testval1", d)} ' | ||
483 | expr_append = ' ${@bb.utils.filter("TESTVAR2", "testval2", d)}' | ||
484 | expr_remove = '${@bb.utils.contains("TESTVAR3", "no-testval", "testval", "", d)}' | ||
485 | # Check dependencies | ||
486 | self.d.setVar('ANOTHERVAR', expr_plain) | ||
487 | self.d.prependVar('ANOTHERVAR', expr_prepend) | ||
488 | self.d.appendVar('ANOTHERVAR', expr_append) | ||
489 | self.d.setVar('ANOTHERVAR:remove', expr_remove) | ||
490 | self.d.setVar('TESTVAR1', 'blah') | ||
491 | self.d.setVar('TESTVAR2', 'testval2') | ||
492 | self.d.setVar('TESTVAR3', 'no-testval') | ||
493 | deps, values = bb.data.build_dependencies("ANOTHERVAR", set(self.d.keys()), set(), set(), set(), set(), self.d, self.d) | ||
494 | self.assertEqual(sorted(values.splitlines()), | ||
495 | sorted([ | ||
496 | expr_prepend + expr_plain + expr_append, | ||
497 | '_remove of ' + expr_remove, | ||
498 | 'TESTVAR1{testval1} = Unset', | ||
499 | 'TESTVAR2{testval2} = Set', | ||
500 | 'TESTVAR3{no-testval} = Set', | ||
501 | ])) | ||
502 | # Check final value | ||
503 | self.assertEqual(self.d.getVar('ANOTHERVAR').split(), ['testval2']) | ||
504 | |||
415 | #Currently no wildcard support | 505 | #Currently no wildcard support |
416 | #def test_vardeps_wildcards(self): | 506 | #def test_vardeps_wildcards(self): |
417 | # self.d.setVar("oe_libinstall", "echo test") | 507 | # self.d.setVar("oe_libinstall", "echo test") |
418 | # self.d.setVar("FOO", "foo=oe_libinstall; eval $foo") | 508 | # self.d.setVar("FOO", "foo=oe_libinstall; eval $foo") |
419 | # self.d.setVarFlag("FOO", "vardeps", "oe_*") | 509 | # self.d.setVarFlag("FOO", "vardeps", "oe_*") |
420 | # self.assertEquals(deps, set(["oe_libinstall"])) | 510 | # self.assertEqual(deps, set(["oe_libinstall"])) |
421 | 511 | ||
422 | 512 | ||
diff --git a/bitbake/lib/bb/tests/color.py b/bitbake/lib/bb/tests/color.py index bf03750c69..bb70cb393d 100644 --- a/bitbake/lib/bb/tests/color.py +++ b/bitbake/lib/bb/tests/color.py | |||
@@ -20,7 +20,7 @@ class ProgressWatcher: | |||
20 | def __init__(self): | 20 | def __init__(self): |
21 | self._reports = [] | 21 | self._reports = [] |
22 | 22 | ||
23 | def handle_event(self, event): | 23 | def handle_event(self, event, d): |
24 | self._reports.append((event.progress, event.rate)) | 24 | self._reports.append((event.progress, event.rate)) |
25 | 25 | ||
26 | def reports(self): | 26 | def reports(self): |
@@ -31,7 +31,7 @@ class ColorCodeTests(unittest.TestCase): | |||
31 | def setUp(self): | 31 | def setUp(self): |
32 | self.d = bb.data.init() | 32 | self.d = bb.data.init() |
33 | self._progress_watcher = ProgressWatcher() | 33 | self._progress_watcher = ProgressWatcher() |
34 | bb.event.register("bb.build.TaskProgress", self._progress_watcher.handle_event) | 34 | bb.event.register("bb.build.TaskProgress", self._progress_watcher.handle_event, data=self.d) |
35 | 35 | ||
36 | def tearDown(self): | 36 | def tearDown(self): |
37 | bb.event.remove("bb.build.TaskProgress", None) | 37 | bb.event.remove("bb.build.TaskProgress", None) |
diff --git a/bitbake/lib/bb/tests/compression.py b/bitbake/lib/bb/tests/compression.py new file mode 100644 index 0000000000..16c297b315 --- /dev/null +++ b/bitbake/lib/bb/tests/compression.py | |||
@@ -0,0 +1,100 @@ | |||
1 | # | ||
2 | # Copyright BitBake Contributors | ||
3 | # | ||
4 | # SPDX-License-Identifier: GPL-2.0-only | ||
5 | # | ||
6 | |||
7 | from pathlib import Path | ||
8 | import bb.compress.lz4 | ||
9 | import bb.compress.zstd | ||
10 | import contextlib | ||
11 | import os | ||
12 | import shutil | ||
13 | import tempfile | ||
14 | import unittest | ||
15 | import subprocess | ||
16 | |||
17 | |||
18 | class CompressionTests(object): | ||
19 | def setUp(self): | ||
20 | self._t = tempfile.TemporaryDirectory() | ||
21 | self.tmpdir = Path(self._t.name) | ||
22 | self.addCleanup(self._t.cleanup) | ||
23 | |||
24 | def _file_helper(self, mode_suffix, data): | ||
25 | tmp_file = self.tmpdir / "compressed" | ||
26 | |||
27 | with self.do_open(tmp_file, mode="w" + mode_suffix) as f: | ||
28 | f.write(data) | ||
29 | |||
30 | with self.do_open(tmp_file, mode="r" + mode_suffix) as f: | ||
31 | read_data = f.read() | ||
32 | |||
33 | self.assertEqual(read_data, data) | ||
34 | |||
35 | def test_text_file(self): | ||
36 | self._file_helper("t", "Hello") | ||
37 | |||
38 | def test_binary_file(self): | ||
39 | self._file_helper("b", "Hello".encode("utf-8")) | ||
40 | |||
41 | def _pipe_helper(self, mode_suffix, data): | ||
42 | rfd, wfd = os.pipe() | ||
43 | with open(rfd, "rb") as r, open(wfd, "wb") as w: | ||
44 | with self.do_open(r, mode="r" + mode_suffix) as decompress: | ||
45 | with self.do_open(w, mode="w" + mode_suffix) as compress: | ||
46 | compress.write(data) | ||
47 | read_data = decompress.read() | ||
48 | |||
49 | self.assertEqual(read_data, data) | ||
50 | |||
51 | def test_text_pipe(self): | ||
52 | self._pipe_helper("t", "Hello") | ||
53 | |||
54 | def test_binary_pipe(self): | ||
55 | self._pipe_helper("b", "Hello".encode("utf-8")) | ||
56 | |||
57 | def test_bad_decompress(self): | ||
58 | tmp_file = self.tmpdir / "compressed" | ||
59 | with tmp_file.open("wb") as f: | ||
60 | f.write(b"\x00") | ||
61 | |||
62 | with self.assertRaises(OSError): | ||
63 | with self.do_open(tmp_file, mode="rb", stderr=subprocess.DEVNULL) as f: | ||
64 | data = f.read() | ||
65 | |||
66 | |||
67 | class LZ4Tests(CompressionTests, unittest.TestCase): | ||
68 | def setUp(self): | ||
69 | if shutil.which("lz4") is None: | ||
70 | self.skipTest("'lz4' not found") | ||
71 | super().setUp() | ||
72 | |||
73 | @contextlib.contextmanager | ||
74 | def do_open(self, *args, **kwargs): | ||
75 | with bb.compress.lz4.open(*args, **kwargs) as f: | ||
76 | yield f | ||
77 | |||
78 | |||
79 | class ZStdTests(CompressionTests, unittest.TestCase): | ||
80 | def setUp(self): | ||
81 | if shutil.which("zstd") is None: | ||
82 | self.skipTest("'zstd' not found") | ||
83 | super().setUp() | ||
84 | |||
85 | @contextlib.contextmanager | ||
86 | def do_open(self, *args, **kwargs): | ||
87 | with bb.compress.zstd.open(*args, **kwargs) as f: | ||
88 | yield f | ||
89 | |||
90 | |||
91 | class PZStdTests(CompressionTests, unittest.TestCase): | ||
92 | def setUp(self): | ||
93 | if shutil.which("pzstd") is None: | ||
94 | self.skipTest("'pzstd' not found") | ||
95 | super().setUp() | ||
96 | |||
97 | @contextlib.contextmanager | ||
98 | def do_open(self, *args, **kwargs): | ||
99 | with bb.compress.zstd.open(*args, num_threads=2, **kwargs) as f: | ||
100 | yield f | ||
diff --git a/bitbake/lib/bb/tests/cooker.py b/bitbake/lib/bb/tests/cooker.py index c82d4b7b81..9e524ae345 100644 --- a/bitbake/lib/bb/tests/cooker.py +++ b/bitbake/lib/bb/tests/cooker.py | |||
@@ -1,6 +1,8 @@ | |||
1 | # | 1 | # |
2 | # BitBake Tests for cooker.py | 2 | # BitBake Tests for cooker.py |
3 | # | 3 | # |
4 | # Copyright BitBake Contributors | ||
5 | # | ||
4 | # SPDX-License-Identifier: GPL-2.0-only | 6 | # SPDX-License-Identifier: GPL-2.0-only |
5 | # | 7 | # |
6 | 8 | ||
diff --git a/bitbake/lib/bb/tests/data.py b/bitbake/lib/bb/tests/data.py index 1d4a64b109..a895f6a58e 100644 --- a/bitbake/lib/bb/tests/data.py +++ b/bitbake/lib/bb/tests/data.py | |||
@@ -60,6 +60,15 @@ class DataExpansions(unittest.TestCase): | |||
60 | val = self.d.expand("${@5*12}") | 60 | val = self.d.expand("${@5*12}") |
61 | self.assertEqual(str(val), "60") | 61 | self.assertEqual(str(val), "60") |
62 | 62 | ||
63 | def test_python_snippet_w_dict(self): | ||
64 | val = self.d.expand("${@{ 'green': 1, 'blue': 2 }['green']}") | ||
65 | self.assertEqual(str(val), "1") | ||
66 | |||
67 | def test_python_unexpanded_multi(self): | ||
68 | self.d.setVar("bar", "${unsetvar}") | ||
69 | val = self.d.expand("${@2*2},${foo},${@d.getVar('foo') + ' ${bar}'},${foo}") | ||
70 | self.assertEqual(str(val), "4,value_of_foo,${@d.getVar('foo') + ' ${unsetvar}'},value_of_foo") | ||
71 | |||
63 | def test_expand_in_python_snippet(self): | 72 | def test_expand_in_python_snippet(self): |
64 | val = self.d.expand("${@'boo ' + '${foo}'}") | 73 | val = self.d.expand("${@'boo ' + '${foo}'}") |
65 | self.assertEqual(str(val), "boo value_of_foo") | 74 | self.assertEqual(str(val), "boo value_of_foo") |
@@ -68,6 +77,18 @@ class DataExpansions(unittest.TestCase): | |||
68 | val = self.d.expand("${@d.getVar('foo') + ' ${bar}'}") | 77 | val = self.d.expand("${@d.getVar('foo') + ' ${bar}'}") |
69 | self.assertEqual(str(val), "value_of_foo value_of_bar") | 78 | self.assertEqual(str(val), "value_of_foo value_of_bar") |
70 | 79 | ||
80 | def test_python_snippet_function_reference(self): | ||
81 | self.d.setVar("TESTVAL", "testvalue") | ||
82 | self.d.setVar("testfunc", 'd.getVar("TESTVAL")') | ||
83 | context = bb.utils.get_context() | ||
84 | context["testfunc"] = lambda d: d.getVar("TESTVAL") | ||
85 | val = self.d.expand("${@testfunc(d)}") | ||
86 | self.assertEqual(str(val), "testvalue") | ||
87 | |||
88 | def test_python_snippet_builtin_metadata(self): | ||
89 | self.d.setVar("eval", "INVALID") | ||
90 | self.d.expand("${@eval('3')}") | ||
91 | |||
71 | def test_python_unexpanded(self): | 92 | def test_python_unexpanded(self): |
72 | self.d.setVar("bar", "${unsetvar}") | 93 | self.d.setVar("bar", "${unsetvar}") |
73 | val = self.d.expand("${@d.getVar('foo') + ' ${bar}'}") | 94 | val = self.d.expand("${@d.getVar('foo') + ' ${bar}'}") |
@@ -245,35 +266,35 @@ class TestConcatOverride(unittest.TestCase): | |||
245 | 266 | ||
246 | def test_prepend(self): | 267 | def test_prepend(self): |
247 | self.d.setVar("TEST", "${VAL}") | 268 | self.d.setVar("TEST", "${VAL}") |
248 | self.d.setVar("TEST_prepend", "${FOO}:") | 269 | self.d.setVar("TEST:prepend", "${FOO}:") |
249 | self.assertEqual(self.d.getVar("TEST"), "foo:val") | 270 | self.assertEqual(self.d.getVar("TEST"), "foo:val") |
250 | 271 | ||
251 | def test_append(self): | 272 | def test_append(self): |
252 | self.d.setVar("TEST", "${VAL}") | 273 | self.d.setVar("TEST", "${VAL}") |
253 | self.d.setVar("TEST_append", ":${BAR}") | 274 | self.d.setVar("TEST:append", ":${BAR}") |
254 | self.assertEqual(self.d.getVar("TEST"), "val:bar") | 275 | self.assertEqual(self.d.getVar("TEST"), "val:bar") |
255 | 276 | ||
256 | def test_multiple_append(self): | 277 | def test_multiple_append(self): |
257 | self.d.setVar("TEST", "${VAL}") | 278 | self.d.setVar("TEST", "${VAL}") |
258 | self.d.setVar("TEST_prepend", "${FOO}:") | 279 | self.d.setVar("TEST:prepend", "${FOO}:") |
259 | self.d.setVar("TEST_append", ":val2") | 280 | self.d.setVar("TEST:append", ":val2") |
260 | self.d.setVar("TEST_append", ":${BAR}") | 281 | self.d.setVar("TEST:append", ":${BAR}") |
261 | self.assertEqual(self.d.getVar("TEST"), "foo:val:val2:bar") | 282 | self.assertEqual(self.d.getVar("TEST"), "foo:val:val2:bar") |
262 | 283 | ||
263 | def test_append_unset(self): | 284 | def test_append_unset(self): |
264 | self.d.setVar("TEST_prepend", "${FOO}:") | 285 | self.d.setVar("TEST:prepend", "${FOO}:") |
265 | self.d.setVar("TEST_append", ":val2") | 286 | self.d.setVar("TEST:append", ":val2") |
266 | self.d.setVar("TEST_append", ":${BAR}") | 287 | self.d.setVar("TEST:append", ":${BAR}") |
267 | self.assertEqual(self.d.getVar("TEST"), "foo::val2:bar") | 288 | self.assertEqual(self.d.getVar("TEST"), "foo::val2:bar") |
268 | 289 | ||
269 | def test_remove(self): | 290 | def test_remove(self): |
270 | self.d.setVar("TEST", "${VAL} ${BAR}") | 291 | self.d.setVar("TEST", "${VAL} ${BAR}") |
271 | self.d.setVar("TEST_remove", "val") | 292 | self.d.setVar("TEST:remove", "val") |
272 | self.assertEqual(self.d.getVar("TEST"), " bar") | 293 | self.assertEqual(self.d.getVar("TEST"), " bar") |
273 | 294 | ||
274 | def test_remove_cleared(self): | 295 | def test_remove_cleared(self): |
275 | self.d.setVar("TEST", "${VAL} ${BAR}") | 296 | self.d.setVar("TEST", "${VAL} ${BAR}") |
276 | self.d.setVar("TEST_remove", "val") | 297 | self.d.setVar("TEST:remove", "val") |
277 | self.d.setVar("TEST", "${VAL} ${BAR}") | 298 | self.d.setVar("TEST", "${VAL} ${BAR}") |
278 | self.assertEqual(self.d.getVar("TEST"), "val bar") | 299 | self.assertEqual(self.d.getVar("TEST"), "val bar") |
279 | 300 | ||
@@ -281,42 +302,42 @@ class TestConcatOverride(unittest.TestCase): | |||
281 | # (including that whitespace is preserved) | 302 | # (including that whitespace is preserved) |
282 | def test_remove_inactive_override(self): | 303 | def test_remove_inactive_override(self): |
283 | self.d.setVar("TEST", "${VAL} ${BAR} 123") | 304 | self.d.setVar("TEST", "${VAL} ${BAR} 123") |
284 | self.d.setVar("TEST_remove_inactiveoverride", "val") | 305 | self.d.setVar("TEST:remove:inactiveoverride", "val") |
285 | self.assertEqual(self.d.getVar("TEST"), "val bar 123") | 306 | self.assertEqual(self.d.getVar("TEST"), "val bar 123") |
286 | 307 | ||
287 | def test_doubleref_remove(self): | 308 | def test_doubleref_remove(self): |
288 | self.d.setVar("TEST", "${VAL} ${BAR}") | 309 | self.d.setVar("TEST", "${VAL} ${BAR}") |
289 | self.d.setVar("TEST_remove", "val") | 310 | self.d.setVar("TEST:remove", "val") |
290 | self.d.setVar("TEST_TEST", "${TEST} ${TEST}") | 311 | self.d.setVar("TEST_TEST", "${TEST} ${TEST}") |
291 | self.assertEqual(self.d.getVar("TEST_TEST"), " bar bar") | 312 | self.assertEqual(self.d.getVar("TEST_TEST"), " bar bar") |
292 | 313 | ||
293 | def test_empty_remove(self): | 314 | def test_empty_remove(self): |
294 | self.d.setVar("TEST", "") | 315 | self.d.setVar("TEST", "") |
295 | self.d.setVar("TEST_remove", "val") | 316 | self.d.setVar("TEST:remove", "val") |
296 | self.assertEqual(self.d.getVar("TEST"), "") | 317 | self.assertEqual(self.d.getVar("TEST"), "") |
297 | 318 | ||
298 | def test_remove_expansion(self): | 319 | def test_remove_expansion(self): |
299 | self.d.setVar("BAR", "Z") | 320 | self.d.setVar("BAR", "Z") |
300 | self.d.setVar("TEST", "${BAR}/X Y") | 321 | self.d.setVar("TEST", "${BAR}/X Y") |
301 | self.d.setVar("TEST_remove", "${BAR}/X") | 322 | self.d.setVar("TEST:remove", "${BAR}/X") |
302 | self.assertEqual(self.d.getVar("TEST"), " Y") | 323 | self.assertEqual(self.d.getVar("TEST"), " Y") |
303 | 324 | ||
304 | def test_remove_expansion_items(self): | 325 | def test_remove_expansion_items(self): |
305 | self.d.setVar("TEST", "A B C D") | 326 | self.d.setVar("TEST", "A B C D") |
306 | self.d.setVar("BAR", "B D") | 327 | self.d.setVar("BAR", "B D") |
307 | self.d.setVar("TEST_remove", "${BAR}") | 328 | self.d.setVar("TEST:remove", "${BAR}") |
308 | self.assertEqual(self.d.getVar("TEST"), "A C ") | 329 | self.assertEqual(self.d.getVar("TEST"), "A C ") |
309 | 330 | ||
310 | def test_remove_preserve_whitespace(self): | 331 | def test_remove_preserve_whitespace(self): |
311 | # When the removal isn't active, the original value should be preserved | 332 | # When the removal isn't active, the original value should be preserved |
312 | self.d.setVar("TEST", " A B") | 333 | self.d.setVar("TEST", " A B") |
313 | self.d.setVar("TEST_remove", "C") | 334 | self.d.setVar("TEST:remove", "C") |
314 | self.assertEqual(self.d.getVar("TEST"), " A B") | 335 | self.assertEqual(self.d.getVar("TEST"), " A B") |
315 | 336 | ||
316 | def test_remove_preserve_whitespace2(self): | 337 | def test_remove_preserve_whitespace2(self): |
317 | # When the removal is active preserve the whitespace | 338 | # When the removal is active preserve the whitespace |
318 | self.d.setVar("TEST", " A B") | 339 | self.d.setVar("TEST", " A B") |
319 | self.d.setVar("TEST_remove", "B") | 340 | self.d.setVar("TEST:remove", "B") |
320 | self.assertEqual(self.d.getVar("TEST"), " A ") | 341 | self.assertEqual(self.d.getVar("TEST"), " A ") |
321 | 342 | ||
322 | class TestOverrides(unittest.TestCase): | 343 | class TestOverrides(unittest.TestCase): |
@@ -329,81 +350,86 @@ class TestOverrides(unittest.TestCase): | |||
329 | self.assertEqual(self.d.getVar("TEST"), "testvalue") | 350 | self.assertEqual(self.d.getVar("TEST"), "testvalue") |
330 | 351 | ||
331 | def test_one_override(self): | 352 | def test_one_override(self): |
332 | self.d.setVar("TEST_bar", "testvalue2") | 353 | self.d.setVar("TEST:bar", "testvalue2") |
333 | self.assertEqual(self.d.getVar("TEST"), "testvalue2") | 354 | self.assertEqual(self.d.getVar("TEST"), "testvalue2") |
334 | 355 | ||
335 | def test_one_override_unset(self): | 356 | def test_one_override_unset(self): |
336 | self.d.setVar("TEST2_bar", "testvalue2") | 357 | self.d.setVar("TEST2:bar", "testvalue2") |
337 | 358 | ||
338 | self.assertEqual(self.d.getVar("TEST2"), "testvalue2") | 359 | self.assertEqual(self.d.getVar("TEST2"), "testvalue2") |
339 | self.assertCountEqual(list(self.d.keys()), ['TEST', 'TEST2', 'OVERRIDES', 'TEST2_bar']) | 360 | self.assertCountEqual(list(self.d.keys()), ['TEST', 'TEST2', 'OVERRIDES', 'TEST2:bar']) |
340 | 361 | ||
341 | def test_multiple_override(self): | 362 | def test_multiple_override(self): |
342 | self.d.setVar("TEST_bar", "testvalue2") | 363 | self.d.setVar("TEST:bar", "testvalue2") |
343 | self.d.setVar("TEST_local", "testvalue3") | 364 | self.d.setVar("TEST:local", "testvalue3") |
344 | self.d.setVar("TEST_foo", "testvalue4") | 365 | self.d.setVar("TEST:foo", "testvalue4") |
345 | self.assertEqual(self.d.getVar("TEST"), "testvalue3") | 366 | self.assertEqual(self.d.getVar("TEST"), "testvalue3") |
346 | self.assertCountEqual(list(self.d.keys()), ['TEST', 'TEST_foo', 'OVERRIDES', 'TEST_bar', 'TEST_local']) | 367 | self.assertCountEqual(list(self.d.keys()), ['TEST', 'TEST:foo', 'OVERRIDES', 'TEST:bar', 'TEST:local']) |
347 | 368 | ||
348 | def test_multiple_combined_overrides(self): | 369 | def test_multiple_combined_overrides(self): |
349 | self.d.setVar("TEST_local_foo_bar", "testvalue3") | 370 | self.d.setVar("TEST:local:foo:bar", "testvalue3") |
350 | self.assertEqual(self.d.getVar("TEST"), "testvalue3") | 371 | self.assertEqual(self.d.getVar("TEST"), "testvalue3") |
351 | 372 | ||
352 | def test_multiple_overrides_unset(self): | 373 | def test_multiple_overrides_unset(self): |
353 | self.d.setVar("TEST2_local_foo_bar", "testvalue3") | 374 | self.d.setVar("TEST2:local:foo:bar", "testvalue3") |
354 | self.assertEqual(self.d.getVar("TEST2"), "testvalue3") | 375 | self.assertEqual(self.d.getVar("TEST2"), "testvalue3") |
355 | 376 | ||
356 | def test_keyexpansion_override(self): | 377 | def test_keyexpansion_override(self): |
357 | self.d.setVar("LOCAL", "local") | 378 | self.d.setVar("LOCAL", "local") |
358 | self.d.setVar("TEST_bar", "testvalue2") | 379 | self.d.setVar("TEST:bar", "testvalue2") |
359 | self.d.setVar("TEST_${LOCAL}", "testvalue3") | 380 | self.d.setVar("TEST:${LOCAL}", "testvalue3") |
360 | self.d.setVar("TEST_foo", "testvalue4") | 381 | self.d.setVar("TEST:foo", "testvalue4") |
361 | bb.data.expandKeys(self.d) | 382 | bb.data.expandKeys(self.d) |
362 | self.assertEqual(self.d.getVar("TEST"), "testvalue3") | 383 | self.assertEqual(self.d.getVar("TEST"), "testvalue3") |
363 | 384 | ||
364 | def test_rename_override(self): | 385 | def test_rename_override(self): |
365 | self.d.setVar("ALTERNATIVE_ncurses-tools_class-target", "a") | 386 | self.d.setVar("ALTERNATIVE:ncurses-tools:class-target", "a") |
366 | self.d.setVar("OVERRIDES", "class-target") | 387 | self.d.setVar("OVERRIDES", "class-target") |
367 | self.d.renameVar("ALTERNATIVE_ncurses-tools", "ALTERNATIVE_lib32-ncurses-tools") | 388 | self.d.renameVar("ALTERNATIVE:ncurses-tools", "ALTERNATIVE:lib32-ncurses-tools") |
368 | self.assertEqual(self.d.getVar("ALTERNATIVE_lib32-ncurses-tools"), "a") | 389 | self.assertEqual(self.d.getVar("ALTERNATIVE:lib32-ncurses-tools"), "a") |
369 | 390 | ||
370 | def test_underscore_override(self): | 391 | def test_underscore_override(self): |
371 | self.d.setVar("TEST_bar", "testvalue2") | 392 | self.d.setVar("TEST:bar", "testvalue2") |
372 | self.d.setVar("TEST_some_val", "testvalue3") | 393 | self.d.setVar("TEST:some_val", "testvalue3") |
373 | self.d.setVar("TEST_foo", "testvalue4") | 394 | self.d.setVar("TEST:foo", "testvalue4") |
374 | self.d.setVar("OVERRIDES", "foo:bar:some_val") | 395 | self.d.setVar("OVERRIDES", "foo:bar:some_val") |
375 | self.assertEqual(self.d.getVar("TEST"), "testvalue3") | 396 | self.assertEqual(self.d.getVar("TEST"), "testvalue3") |
376 | 397 | ||
398 | # Test an override with _<numeric> in it based on a real world OE issue | ||
399 | def test_underscore_override_2(self): | ||
400 | self.d.setVar("TARGET_ARCH", "x86_64") | ||
401 | self.d.setVar("PN", "test-${TARGET_ARCH}") | ||
402 | self.d.setVar("VERSION", "1") | ||
403 | self.d.setVar("VERSION:pn-test-${TARGET_ARCH}", "2") | ||
404 | self.d.setVar("OVERRIDES", "pn-${PN}") | ||
405 | bb.data.expandKeys(self.d) | ||
406 | self.assertEqual(self.d.getVar("VERSION"), "2") | ||
407 | |||
377 | def test_remove_with_override(self): | 408 | def test_remove_with_override(self): |
378 | self.d.setVar("TEST_bar", "testvalue2") | 409 | self.d.setVar("TEST:bar", "testvalue2") |
379 | self.d.setVar("TEST_some_val", "testvalue3 testvalue5") | 410 | self.d.setVar("TEST:some_val", "testvalue3 testvalue5") |
380 | self.d.setVar("TEST_some_val_remove", "testvalue3") | 411 | self.d.setVar("TEST:some_val:remove", "testvalue3") |
381 | self.d.setVar("TEST_foo", "testvalue4") | 412 | self.d.setVar("TEST:foo", "testvalue4") |
382 | self.d.setVar("OVERRIDES", "foo:bar:some_val") | 413 | self.d.setVar("OVERRIDES", "foo:bar:some_val") |
383 | self.assertEqual(self.d.getVar("TEST"), " testvalue5") | 414 | self.assertEqual(self.d.getVar("TEST"), " testvalue5") |
384 | 415 | ||
385 | def test_append_and_override_1(self): | 416 | def test_append_and_override_1(self): |
386 | self.d.setVar("TEST_append", "testvalue2") | 417 | self.d.setVar("TEST:append", "testvalue2") |
387 | self.d.setVar("TEST_bar", "testvalue3") | 418 | self.d.setVar("TEST:bar", "testvalue3") |
388 | self.assertEqual(self.d.getVar("TEST"), "testvalue3testvalue2") | 419 | self.assertEqual(self.d.getVar("TEST"), "testvalue3testvalue2") |
389 | 420 | ||
390 | def test_append_and_override_2(self): | 421 | def test_append_and_override_2(self): |
391 | self.d.setVar("TEST_append_bar", "testvalue2") | 422 | self.d.setVar("TEST:append:bar", "testvalue2") |
392 | self.assertEqual(self.d.getVar("TEST"), "testvaluetestvalue2") | 423 | self.assertEqual(self.d.getVar("TEST"), "testvaluetestvalue2") |
393 | 424 | ||
394 | def test_append_and_override_3(self): | 425 | def test_append_and_override_3(self): |
395 | self.d.setVar("TEST_bar_append", "testvalue2") | 426 | self.d.setVar("TEST:bar:append", "testvalue2") |
396 | self.assertEqual(self.d.getVar("TEST"), "testvalue2") | 427 | self.assertEqual(self.d.getVar("TEST"), "testvalue2") |
397 | 428 | ||
398 | # Test an override with _<numeric> in it based on a real world OE issue | 429 | def test_append_and_unused_override(self): |
399 | def test_underscore_override(self): | 430 | # Had a bug where an unused override append could return "" instead of None |
400 | self.d.setVar("TARGET_ARCH", "x86_64") | 431 | self.d.setVar("BAR:append:unusedoverride", "testvalue2") |
401 | self.d.setVar("PN", "test-${TARGET_ARCH}") | 432 | self.assertEqual(self.d.getVar("BAR"), None) |
402 | self.d.setVar("VERSION", "1") | ||
403 | self.d.setVar("VERSION_pn-test-${TARGET_ARCH}", "2") | ||
404 | self.d.setVar("OVERRIDES", "pn-${PN}") | ||
405 | bb.data.expandKeys(self.d) | ||
406 | self.assertEqual(self.d.getVar("VERSION"), "2") | ||
407 | 433 | ||
408 | class TestKeyExpansion(unittest.TestCase): | 434 | class TestKeyExpansion(unittest.TestCase): |
409 | def setUp(self): | 435 | def setUp(self): |
@@ -424,17 +450,64 @@ class TestFlags(unittest.TestCase): | |||
424 | self.d = bb.data.init() | 450 | self.d = bb.data.init() |
425 | self.d.setVar("foo", "value of foo") | 451 | self.d.setVar("foo", "value of foo") |
426 | self.d.setVarFlag("foo", "flag1", "value of flag1") | 452 | self.d.setVarFlag("foo", "flag1", "value of flag1") |
453 | self.d.setVarFlag("foo", "_defaultval_flag_flag1", "default of flag1") | ||
427 | self.d.setVarFlag("foo", "flag2", "value of flag2") | 454 | self.d.setVarFlag("foo", "flag2", "value of flag2") |
455 | self.d.setVarFlag("foo", "_defaultval_flag_flag2", "default of flag2") | ||
456 | self.d.setVarFlag("foo", "flag3", "value of flag3") | ||
457 | self.d.setVarFlag("foo", "_defaultval_flag_flagnovalue", "default of flagnovalue") | ||
428 | 458 | ||
429 | def test_setflag(self): | 459 | def test_setflag(self): |
430 | self.assertEqual(self.d.getVarFlag("foo", "flag1", False), "value of flag1") | 460 | self.assertEqual(self.d.getVarFlag("foo", "flag1", False), "value of flag1") |
431 | self.assertEqual(self.d.getVarFlag("foo", "flag2", False), "value of flag2") | 461 | self.assertEqual(self.d.getVarFlag("foo", "flag2", False), "value of flag2") |
462 | self.assertDictEqual( | ||
463 | self.d.getVarFlags("foo"), | ||
464 | { | ||
465 | "flag1": "value of flag1", | ||
466 | "flag2": "value of flag2", | ||
467 | "flag3": "value of flag3", | ||
468 | "flagnovalue": "default of flagnovalue", | ||
469 | } | ||
470 | ) | ||
471 | self.assertDictEqual( | ||
472 | self.d.getVarFlags("foo", internalflags=True), | ||
473 | { | ||
474 | "_content": "value of foo", | ||
475 | "flag1": "value of flag1", | ||
476 | "flag2": "value of flag2", | ||
477 | "flag3": "value of flag3", | ||
478 | "_defaultval_flag_flag1": "default of flag1", | ||
479 | "_defaultval_flag_flag2": "default of flag2", | ||
480 | "_defaultval_flag_flagnovalue": "default of flagnovalue", | ||
481 | } | ||
482 | ) | ||
432 | 483 | ||
433 | def test_delflag(self): | 484 | def test_delflag(self): |
434 | self.d.delVarFlag("foo", "flag2") | 485 | self.d.delVarFlag("foo", "flag2") |
486 | self.d.delVarFlag("foo", "flag3") | ||
435 | self.assertEqual(self.d.getVarFlag("foo", "flag1", False), "value of flag1") | 487 | self.assertEqual(self.d.getVarFlag("foo", "flag1", False), "value of flag1") |
436 | self.assertEqual(self.d.getVarFlag("foo", "flag2", False), None) | 488 | self.assertEqual(self.d.getVarFlag("foo", "flag2", False), None) |
437 | 489 | self.assertDictEqual( | |
490 | self.d.getVarFlags("foo"), | ||
491 | { | ||
492 | "flag1": "value of flag1", | ||
493 | "flagnovalue": "default of flagnovalue", | ||
494 | } | ||
495 | ) | ||
496 | self.assertDictEqual( | ||
497 | self.d.getVarFlags("foo", internalflags=True), | ||
498 | { | ||
499 | "_content": "value of foo", | ||
500 | "flag1": "value of flag1", | ||
501 | "_defaultval_flag_flag1": "default of flag1", | ||
502 | "_defaultval_flag_flagnovalue": "default of flagnovalue", | ||
503 | } | ||
504 | ) | ||
505 | |||
506 | def test_delvar(self): | ||
507 | self.d.delVar("foo") | ||
508 | self.assertEqual(self.d.getVarFlag("foo", "flag1", False), None) | ||
509 | self.assertEqual(self.d.getVarFlag("foo", "flag2", False), None) | ||
510 | self.assertEqual(self.d.getVarFlags("foo", internalflags=True), None) | ||
438 | 511 | ||
439 | class Contains(unittest.TestCase): | 512 | class Contains(unittest.TestCase): |
440 | def setUp(self): | 513 | def setUp(self): |
@@ -498,7 +571,7 @@ class TaskHash(unittest.TestCase): | |||
498 | d.setVar("VAR", "val") | 571 | d.setVar("VAR", "val") |
499 | # Adding an inactive removal shouldn't change the hash | 572 | # Adding an inactive removal shouldn't change the hash |
500 | d.setVar("BAR", "notbar") | 573 | d.setVar("BAR", "notbar") |
501 | d.setVar("MYCOMMAND_remove", "${BAR}") | 574 | d.setVar("MYCOMMAND:remove", "${BAR}") |
502 | nexthash = gettask_bashhash("mytask", d) | 575 | nexthash = gettask_bashhash("mytask", d) |
503 | self.assertEqual(orighash, nexthash) | 576 | self.assertEqual(orighash, nexthash) |
504 | 577 | ||
diff --git a/bitbake/lib/bb/tests/event.py b/bitbake/lib/bb/tests/event.py index 9ca7e9bc8e..ef61891d30 100644 --- a/bitbake/lib/bb/tests/event.py +++ b/bitbake/lib/bb/tests/event.py | |||
@@ -13,6 +13,7 @@ import pickle | |||
13 | import threading | 13 | import threading |
14 | import time | 14 | import time |
15 | import unittest | 15 | import unittest |
16 | import tempfile | ||
16 | from unittest.mock import Mock | 17 | from unittest.mock import Mock |
17 | from unittest.mock import call | 18 | from unittest.mock import call |
18 | 19 | ||
@@ -157,7 +158,7 @@ class EventHandlingTest(unittest.TestCase): | |||
157 | self._test_process.event_handler, | 158 | self._test_process.event_handler, |
158 | event, | 159 | event, |
159 | None) | 160 | None) |
160 | self._test_process.event_handler.assert_called_once_with(event) | 161 | self._test_process.event_handler.assert_called_once_with(event, None) |
161 | 162 | ||
162 | def test_fire_class_handlers(self): | 163 | def test_fire_class_handlers(self): |
163 | """ Test fire_class_handlers method """ | 164 | """ Test fire_class_handlers method """ |
@@ -175,10 +176,10 @@ class EventHandlingTest(unittest.TestCase): | |||
175 | bb.event.fire_class_handlers(event1, None) | 176 | bb.event.fire_class_handlers(event1, None) |
176 | bb.event.fire_class_handlers(event2, None) | 177 | bb.event.fire_class_handlers(event2, None) |
177 | bb.event.fire_class_handlers(event2, None) | 178 | bb.event.fire_class_handlers(event2, None) |
178 | expected_event_handler1 = [call(event1)] | 179 | expected_event_handler1 = [call(event1, None)] |
179 | expected_event_handler2 = [call(event1), | 180 | expected_event_handler2 = [call(event1, None), |
180 | call(event2), | 181 | call(event2, None), |
181 | call(event2)] | 182 | call(event2, None)] |
182 | self.assertEqual(self._test_process.event_handler1.call_args_list, | 183 | self.assertEqual(self._test_process.event_handler1.call_args_list, |
183 | expected_event_handler1) | 184 | expected_event_handler1) |
184 | self.assertEqual(self._test_process.event_handler2.call_args_list, | 185 | self.assertEqual(self._test_process.event_handler2.call_args_list, |
@@ -205,7 +206,7 @@ class EventHandlingTest(unittest.TestCase): | |||
205 | bb.event.fire_class_handlers(event2, None) | 206 | bb.event.fire_class_handlers(event2, None) |
206 | bb.event.fire_class_handlers(event2, None) | 207 | bb.event.fire_class_handlers(event2, None) |
207 | expected_event_handler1 = [] | 208 | expected_event_handler1 = [] |
208 | expected_event_handler2 = [call(event1)] | 209 | expected_event_handler2 = [call(event1, None)] |
209 | self.assertEqual(self._test_process.event_handler1.call_args_list, | 210 | self.assertEqual(self._test_process.event_handler1.call_args_list, |
210 | expected_event_handler1) | 211 | expected_event_handler1) |
211 | self.assertEqual(self._test_process.event_handler2.call_args_list, | 212 | self.assertEqual(self._test_process.event_handler2.call_args_list, |
@@ -223,7 +224,7 @@ class EventHandlingTest(unittest.TestCase): | |||
223 | self.assertEqual(result, bb.event.Registered) | 224 | self.assertEqual(result, bb.event.Registered) |
224 | bb.event.fire_class_handlers(event1, None) | 225 | bb.event.fire_class_handlers(event1, None) |
225 | bb.event.fire_class_handlers(event2, None) | 226 | bb.event.fire_class_handlers(event2, None) |
226 | expected = [call(event1), call(event2)] | 227 | expected = [call(event1, None), call(event2, None)] |
227 | self.assertEqual(self._test_process.event_handler1.call_args_list, | 228 | self.assertEqual(self._test_process.event_handler1.call_args_list, |
228 | expected) | 229 | expected) |
229 | 230 | ||
@@ -237,7 +238,7 @@ class EventHandlingTest(unittest.TestCase): | |||
237 | self.assertEqual(result, bb.event.Registered) | 238 | self.assertEqual(result, bb.event.Registered) |
238 | bb.event.fire_class_handlers(event1, None) | 239 | bb.event.fire_class_handlers(event1, None) |
239 | bb.event.fire_class_handlers(event2, None) | 240 | bb.event.fire_class_handlers(event2, None) |
240 | expected = [call(event1), call(event2), call(event1)] | 241 | expected = [call(event1, None), call(event2, None), call(event1, None)] |
241 | self.assertEqual(self._test_process.event_handler1.call_args_list, | 242 | self.assertEqual(self._test_process.event_handler1.call_args_list, |
242 | expected) | 243 | expected) |
243 | 244 | ||
@@ -251,7 +252,7 @@ class EventHandlingTest(unittest.TestCase): | |||
251 | self.assertEqual(result, bb.event.Registered) | 252 | self.assertEqual(result, bb.event.Registered) |
252 | bb.event.fire_class_handlers(event1, None) | 253 | bb.event.fire_class_handlers(event1, None) |
253 | bb.event.fire_class_handlers(event2, None) | 254 | bb.event.fire_class_handlers(event2, None) |
254 | expected = [call(event1), call(event2), call(event1), call(event2)] | 255 | expected = [call(event1,None), call(event2, None), call(event1, None), call(event2, None)] |
255 | self.assertEqual(self._test_process.event_handler1.call_args_list, | 256 | self.assertEqual(self._test_process.event_handler1.call_args_list, |
256 | expected) | 257 | expected) |
257 | 258 | ||
@@ -359,9 +360,10 @@ class EventHandlingTest(unittest.TestCase): | |||
359 | 360 | ||
360 | event1 = bb.event.ConfigParsed() | 361 | event1 = bb.event.ConfigParsed() |
361 | bb.event.fire(event1, None) | 362 | bb.event.fire(event1, None) |
362 | expected = [call(event1)] | 363 | expected = [call(event1, None)] |
363 | self.assertEqual(self._test_process.event_handler1.call_args_list, | 364 | self.assertEqual(self._test_process.event_handler1.call_args_list, |
364 | expected) | 365 | expected) |
366 | expected = [call(event1)] | ||
365 | self.assertEqual(self._test_ui1.event.send.call_args_list, | 367 | self.assertEqual(self._test_ui1.event.send.call_args_list, |
366 | expected) | 368 | expected) |
367 | 369 | ||
@@ -450,10 +452,9 @@ class EventHandlingTest(unittest.TestCase): | |||
450 | and disable threadlocks tests """ | 452 | and disable threadlocks tests """ |
451 | bb.event.fire(bb.event.OperationStarted(), None) | 453 | bb.event.fire(bb.event.OperationStarted(), None) |
452 | 454 | ||
453 | def test_enable_threadlock(self): | 455 | def test_event_threadlock(self): |
454 | """ Test enable_threadlock method """ | 456 | """ Test enable_threadlock method """ |
455 | self._set_threadlock_test_mockups() | 457 | self._set_threadlock_test_mockups() |
456 | bb.event.enable_threadlock() | ||
457 | self._set_and_run_threadlock_test_workers() | 458 | self._set_and_run_threadlock_test_workers() |
458 | # Calls to UI handlers should be in order as all the registered | 459 | # Calls to UI handlers should be in order as all the registered |
459 | # handlers for the event coming from the first worker should be | 460 | # handlers for the event coming from the first worker should be |
@@ -461,20 +462,6 @@ class EventHandlingTest(unittest.TestCase): | |||
461 | self.assertEqual(self._threadlock_test_calls, | 462 | self.assertEqual(self._threadlock_test_calls, |
462 | ["w1_ui1", "w1_ui2", "w2_ui1", "w2_ui2"]) | 463 | ["w1_ui1", "w1_ui2", "w2_ui1", "w2_ui2"]) |
463 | 464 | ||
464 | |||
465 | def test_disable_threadlock(self): | ||
466 | """ Test disable_threadlock method """ | ||
467 | self._set_threadlock_test_mockups() | ||
468 | bb.event.disable_threadlock() | ||
469 | self._set_and_run_threadlock_test_workers() | ||
470 | # Calls to UI handlers should be intertwined together. Thanks to the | ||
471 | # delay in the registered handlers for the event coming from the first | ||
472 | # worker, the event coming from the second worker starts being | ||
473 | # processed before finishing handling the first worker event. | ||
474 | self.assertEqual(self._threadlock_test_calls, | ||
475 | ["w1_ui1", "w2_ui1", "w1_ui2", "w2_ui2"]) | ||
476 | |||
477 | |||
478 | class EventClassesTest(unittest.TestCase): | 465 | class EventClassesTest(unittest.TestCase): |
479 | """ Event classes test class """ | 466 | """ Event classes test class """ |
480 | 467 | ||
@@ -482,6 +469,8 @@ class EventClassesTest(unittest.TestCase): | |||
482 | 469 | ||
483 | def setUp(self): | 470 | def setUp(self): |
484 | bb.event.worker_pid = EventClassesTest._worker_pid | 471 | bb.event.worker_pid = EventClassesTest._worker_pid |
472 | self.d = bb.data.init() | ||
473 | bb.parse.siggen = bb.siggen.init(self.d) | ||
485 | 474 | ||
486 | def test_Event(self): | 475 | def test_Event(self): |
487 | """ Test the Event base class """ | 476 | """ Test the Event base class """ |
@@ -964,3 +953,24 @@ class EventClassesTest(unittest.TestCase): | |||
964 | event = bb.event.FindSigInfoResult(result) | 953 | event = bb.event.FindSigInfoResult(result) |
965 | self.assertEqual(event.result, result) | 954 | self.assertEqual(event.result, result) |
966 | self.assertEqual(event.pid, EventClassesTest._worker_pid) | 955 | self.assertEqual(event.pid, EventClassesTest._worker_pid) |
956 | |||
957 | def test_lineno_in_eventhandler(self): | ||
958 | # The error lineno is 5, not 4 since the first line is '\n' | ||
959 | error_line = """ | ||
960 | # Comment line1 | ||
961 | # Comment line2 | ||
962 | python test_lineno_in_eventhandler() { | ||
963 | This is an error line | ||
964 | } | ||
965 | addhandler test_lineno_in_eventhandler | ||
966 | test_lineno_in_eventhandler[eventmask] = "bb.event.ConfigParsed" | ||
967 | """ | ||
968 | |||
969 | with self.assertLogs() as logs: | ||
970 | f = tempfile.NamedTemporaryFile(suffix = '.bb') | ||
971 | f.write(bytes(error_line, "utf-8")) | ||
972 | f.flush() | ||
973 | d = bb.parse.handle(f.name, self.d)[''] | ||
974 | |||
975 | output = "".join(logs.output) | ||
976 | self.assertTrue(" line 5\n" in output) | ||
diff --git a/bitbake/lib/bb/tests/fetch-testdata/debian/pool/main/m/minicom/index.html b/bitbake/lib/bb/tests/fetch-testdata/debian/pool/main/m/minicom/index.html new file mode 100644 index 0000000000..4a1eb4de13 --- /dev/null +++ b/bitbake/lib/bb/tests/fetch-testdata/debian/pool/main/m/minicom/index.html | |||
@@ -0,0 +1,59 @@ | |||
1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> | ||
2 | <html> | ||
3 | <head> | ||
4 | <title>Index of /debian/pool/main/m/minicom</title> | ||
5 | </head> | ||
6 | <body> | ||
7 | <h1>Index of /debian/pool/main/m/minicom</h1> | ||
8 | <table> | ||
9 | <tr><th valign="top"><img src="/icons/blank.gif" alt="[ICO]"></th><th><a href="?C=N;O=D">Name</a></th><th><a href="?C=M;O=A">Last modified</a></th><th><a href="?C=S;O=A">Size</a></th></tr> | ||
10 | <tr><th colspan="4"><hr></th></tr> | ||
11 | <tr><td valign="top"><img src="/icons/back.gif" alt="[PARENTDIR]"></td><td><a href="/debian/pool/main/m/">Parent Directory</a></td><td> </td><td align="right"> - </td></tr> | ||
12 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.7-1+deb8u1.debian.tar.xz">minicom_2.7-1+deb8u1.debian.tar.xz</a></td><td align="right">2017-04-24 08:22 </td><td align="right"> 14K</td></tr> | ||
13 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.7-1+deb8u1.dsc">minicom_2.7-1+deb8u1.dsc</a></td><td align="right">2017-04-24 08:22 </td><td align="right">1.9K</td></tr> | ||
14 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.7-1+deb8u1_amd64.deb">minicom_2.7-1+deb8u1_amd64.deb</a></td><td align="right">2017-04-25 21:10 </td><td align="right">257K</td></tr> | ||
15 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.7-1+deb8u1_armel.deb">minicom_2.7-1+deb8u1_armel.deb</a></td><td align="right">2017-04-26 00:58 </td><td align="right">246K</td></tr> | ||
16 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.7-1+deb8u1_armhf.deb">minicom_2.7-1+deb8u1_armhf.deb</a></td><td align="right">2017-04-26 00:58 </td><td align="right">245K</td></tr> | ||
17 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.7-1+deb8u1_i386.deb">minicom_2.7-1+deb8u1_i386.deb</a></td><td align="right">2017-04-25 21:41 </td><td align="right">258K</td></tr> | ||
18 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.7-1.1.debian.tar.xz">minicom_2.7-1.1.debian.tar.xz</a></td><td align="right">2017-04-22 09:34 </td><td align="right"> 14K</td></tr> | ||
19 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.7-1.1.dsc">minicom_2.7-1.1.dsc</a></td><td align="right">2017-04-22 09:34 </td><td align="right">1.9K</td></tr> | ||
20 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.7-1.1_amd64.deb">minicom_2.7-1.1_amd64.deb</a></td><td align="right">2017-04-22 15:29 </td><td align="right">261K</td></tr> | ||
21 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.7-1.1_arm64.deb">minicom_2.7-1.1_arm64.deb</a></td><td align="right">2017-04-22 15:29 </td><td align="right">250K</td></tr> | ||
22 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.7-1.1_armel.deb">minicom_2.7-1.1_armel.deb</a></td><td align="right">2017-04-22 15:29 </td><td align="right">255K</td></tr> | ||
23 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.7-1.1_armhf.deb">minicom_2.7-1.1_armhf.deb</a></td><td align="right">2017-04-22 15:29 </td><td align="right">254K</td></tr> | ||
24 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.7-1.1_i386.deb">minicom_2.7-1.1_i386.deb</a></td><td align="right">2017-04-22 15:29 </td><td align="right">266K</td></tr> | ||
25 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.7-1.1_mips.deb">minicom_2.7-1.1_mips.deb</a></td><td align="right">2017-04-22 15:29 </td><td align="right">258K</td></tr> | ||
26 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.7-1.1_mips64el.deb">minicom_2.7-1.1_mips64el.deb</a></td><td align="right">2017-04-22 15:29 </td><td align="right">259K</td></tr> | ||
27 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.7-1.1_mipsel.deb">minicom_2.7-1.1_mipsel.deb</a></td><td align="right">2017-04-22 15:29 </td><td align="right">259K</td></tr> | ||
28 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.7-1.1_ppc64el.deb">minicom_2.7-1.1_ppc64el.deb</a></td><td align="right">2017-04-22 15:29 </td><td align="right">253K</td></tr> | ||
29 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.7-1.1_s390x.deb">minicom_2.7-1.1_s390x.deb</a></td><td align="right">2017-04-22 15:29 </td><td align="right">261K</td></tr> | ||
30 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.7.1-1+b1_amd64.deb">minicom_2.7.1-1+b1_amd64.deb</a></td><td align="right">2018-05-06 08:14 </td><td align="right">262K</td></tr> | ||
31 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.7.1-1+b1_arm64.deb">minicom_2.7.1-1+b1_arm64.deb</a></td><td align="right">2018-05-06 07:58 </td><td align="right">250K</td></tr> | ||
32 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.7.1-1+b1_armel.deb">minicom_2.7.1-1+b1_armel.deb</a></td><td align="right">2018-05-06 08:45 </td><td align="right">253K</td></tr> | ||
33 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.7.1-1+b1_armhf.deb">minicom_2.7.1-1+b1_armhf.deb</a></td><td align="right">2018-05-06 10:42 </td><td align="right">253K</td></tr> | ||
34 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.7.1-1+b1_i386.deb">minicom_2.7.1-1+b1_i386.deb</a></td><td align="right">2018-05-06 08:55 </td><td align="right">266K</td></tr> | ||
35 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.7.1-1+b1_mips.deb">minicom_2.7.1-1+b1_mips.deb</a></td><td align="right">2018-05-06 08:14 </td><td align="right">258K</td></tr> | ||
36 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.7.1-1+b1_mipsel.deb">minicom_2.7.1-1+b1_mipsel.deb</a></td><td align="right">2018-05-06 12:13 </td><td align="right">259K</td></tr> | ||
37 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.7.1-1+b1_ppc64el.deb">minicom_2.7.1-1+b1_ppc64el.deb</a></td><td align="right">2018-05-06 09:10 </td><td align="right">260K</td></tr> | ||
38 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.7.1-1+b1_s390x.deb">minicom_2.7.1-1+b1_s390x.deb</a></td><td align="right">2018-05-06 08:14 </td><td align="right">257K</td></tr> | ||
39 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.7.1-1+b2_mips64el.deb">minicom_2.7.1-1+b2_mips64el.deb</a></td><td align="right">2018-05-06 09:41 </td><td align="right">260K</td></tr> | ||
40 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.7.1-1.debian.tar.xz">minicom_2.7.1-1.debian.tar.xz</a></td><td align="right">2017-08-13 15:40 </td><td align="right"> 14K</td></tr> | ||
41 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.7.1-1.dsc">minicom_2.7.1-1.dsc</a></td><td align="right">2017-08-13 15:40 </td><td align="right">1.8K</td></tr> | ||
42 | <tr><td valign="top"><img src="/icons/compressed.gif" alt="[ ]"></td><td><a href="minicom_2.7.1.orig.tar.gz">minicom_2.7.1.orig.tar.gz</a></td><td align="right">2017-08-13 15:40 </td><td align="right">855K</td></tr> | ||
43 | <tr><td valign="top"><img src="/icons/compressed.gif" alt="[ ]"></td><td><a href="minicom_2.7.orig.tar.gz">minicom_2.7.orig.tar.gz</a></td><td align="right">2014-01-01 09:36 </td><td align="right">843K</td></tr> | ||
44 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.8-2.debian.tar.xz">minicom_2.8-2.debian.tar.xz</a></td><td align="right">2021-06-15 03:47 </td><td align="right"> 14K</td></tr> | ||
45 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.8-2.dsc">minicom_2.8-2.dsc</a></td><td align="right">2021-06-15 03:47 </td><td align="right">1.8K</td></tr> | ||
46 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.8-2_amd64.deb">minicom_2.8-2_amd64.deb</a></td><td align="right">2021-06-15 03:58 </td><td align="right">280K</td></tr> | ||
47 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.8-2_arm64.deb">minicom_2.8-2_arm64.deb</a></td><td align="right">2021-06-15 04:13 </td><td align="right">275K</td></tr> | ||
48 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.8-2_armel.deb">minicom_2.8-2_armel.deb</a></td><td align="right">2021-06-15 04:13 </td><td align="right">271K</td></tr> | ||
49 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.8-2_armhf.deb">minicom_2.8-2_armhf.deb</a></td><td align="right">2021-06-15 04:13 </td><td align="right">272K</td></tr> | ||
50 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.8-2_i386.deb">minicom_2.8-2_i386.deb</a></td><td align="right">2021-06-15 04:13 </td><td align="right">285K</td></tr> | ||
51 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.8-2_mips64el.deb">minicom_2.8-2_mips64el.deb</a></td><td align="right">2021-06-15 04:13 </td><td align="right">277K</td></tr> | ||
52 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.8-2_mipsel.deb">minicom_2.8-2_mipsel.deb</a></td><td align="right">2021-06-15 04:13 </td><td align="right">278K</td></tr> | ||
53 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.8-2_ppc64el.deb">minicom_2.8-2_ppc64el.deb</a></td><td align="right">2021-06-15 04:13 </td><td align="right">286K</td></tr> | ||
54 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.8-2_s390x.deb">minicom_2.8-2_s390x.deb</a></td><td align="right">2021-06-15 03:58 </td><td align="right">275K</td></tr> | ||
55 | <tr><td valign="top"><img src="/icons/unknown.gif" alt="[ ]"></td><td><a href="minicom_2.8.orig.tar.bz2">minicom_2.8.orig.tar.bz2</a></td><td align="right">2021-01-03 12:44 </td><td align="right">598K</td></tr> | ||
56 | <tr><th colspan="4"><hr></th></tr> | ||
57 | </table> | ||
58 | <address>Apache Server at ftp.debian.org Port 80</address> | ||
59 | </body></html> | ||
diff --git a/bitbake/lib/bb/tests/fetch-testdata/software/libxml2/2.10/index.html b/bitbake/lib/bb/tests/fetch-testdata/software/libxml2/2.10/index.html new file mode 100644 index 0000000000..4e41af6d6a --- /dev/null +++ b/bitbake/lib/bb/tests/fetch-testdata/software/libxml2/2.10/index.html | |||
@@ -0,0 +1,20 @@ | |||
1 | <!DOCTYPE html><html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"><meta name="viewport" content="width=device-width"><style type="text/css">body,html {background:#fff;font-family:"Bitstream Vera Sans","Lucida Grande","Lucida Sans Unicode",Lucidux,Verdana,Lucida,sans-serif;}tr:nth-child(even) {background:#f4f4f4;}th,td {padding:0.1em 0.5em;}th {text-align:left;font-weight:bold;background:#eee;border-bottom:1px solid #aaa;}#list {border:1px solid #aaa;width:100%;}a {color:#a33;}a:hover {color:#e33;}</style> | ||
2 | |||
3 | <title>Index of /sources/libxml2/2.10/</title> | ||
4 | </head><body><h1>Index of /sources/libxml2/2.10/</h1> | ||
5 | <table id="list"><thead><tr><th style="width:55%"><a href="?C=N&O=A">File Name</a> <a href="?C=N&O=D"> ↓ </a></th><th style="width:20%"><a href="?C=S&O=A">File Size</a> <a href="?C=S&O=D"> ↓ </a></th><th style="width:25%"><a href="?C=M&O=A">Date</a> <a href="?C=M&O=D"> ↓ </a></th></tr></thead> | ||
6 | <tbody><tr><td class="link"><a href="../">Parent directory/</a></td><td class="size">-</td><td class="date">-</td></tr> | ||
7 | <tr><td class="link"><a href="LATEST-IS-2.10.3" title="LATEST-IS-2.10.3">LATEST-IS-2.10.3</a></td><td class="size">2.5 MiB</td><td class="date">2022-Oct-14 12:55</td></tr> | ||
8 | <tr><td class="link"><a href="libxml2-2.10.0.news" title="libxml2-2.10.0.news">libxml2-2.10.0.news</a></td><td class="size">7.1 KiB</td><td class="date">2022-Aug-17 11:55</td></tr> | ||
9 | <tr><td class="link"><a href="libxml2-2.10.0.sha256sum" title="libxml2-2.10.0.sha256sum">libxml2-2.10.0.sha256sum</a></td><td class="size">174 B</td><td class="date">2022-Aug-17 11:55</td></tr> | ||
10 | <tr><td class="link"><a href="libxml2-2.10.0.tar.xz" title="libxml2-2.10.0.tar.xz">libxml2-2.10.0.tar.xz</a></td><td class="size">2.6 MiB</td><td class="date">2022-Aug-17 11:55</td></tr> | ||
11 | <tr><td class="link"><a href="libxml2-2.10.1.news" title="libxml2-2.10.1.news">libxml2-2.10.1.news</a></td><td class="size">455 B</td><td class="date">2022-Aug-25 11:33</td></tr> | ||
12 | <tr><td class="link"><a href="libxml2-2.10.1.sha256sum" title="libxml2-2.10.1.sha256sum">libxml2-2.10.1.sha256sum</a></td><td class="size">174 B</td><td class="date">2022-Aug-25 11:33</td></tr> | ||
13 | <tr><td class="link"><a href="libxml2-2.10.1.tar.xz" title="libxml2-2.10.1.tar.xz">libxml2-2.10.1.tar.xz</a></td><td class="size">2.6 MiB</td><td class="date">2022-Aug-25 11:33</td></tr> | ||
14 | <tr><td class="link"><a href="libxml2-2.10.2.news" title="libxml2-2.10.2.news">libxml2-2.10.2.news</a></td><td class="size">309 B</td><td class="date">2022-Aug-29 14:56</td></tr> | ||
15 | <tr><td class="link"><a href="libxml2-2.10.2.sha256sum" title="libxml2-2.10.2.sha256sum">libxml2-2.10.2.sha256sum</a></td><td class="size">174 B</td><td class="date">2022-Aug-29 14:56</td></tr> | ||
16 | <tr><td class="link"><a href="libxml2-2.10.2.tar.xz" title="libxml2-2.10.2.tar.xz">libxml2-2.10.2.tar.xz</a></td><td class="size">2.5 MiB</td><td class="date">2022-Aug-29 14:56</td></tr> | ||
17 | <tr><td class="link"><a href="libxml2-2.10.3.news" title="libxml2-2.10.3.news">libxml2-2.10.3.news</a></td><td class="size">294 B</td><td class="date">2022-Oct-14 12:55</td></tr> | ||
18 | <tr><td class="link"><a href="libxml2-2.10.3.sha256sum" title="libxml2-2.10.3.sha256sum">libxml2-2.10.3.sha256sum</a></td><td class="size">174 B</td><td class="date">2022-Oct-14 12:55</td></tr> | ||
19 | <tr><td class="link"><a href="libxml2-2.10.3.tar.xz" title="libxml2-2.10.3.tar.xz">libxml2-2.10.3.tar.xz</a></td><td class="size">2.5 MiB</td><td class="date">2022-Oct-14 12:55</td></tr> | ||
20 | </tbody></table></body></html> | ||
diff --git a/bitbake/lib/bb/tests/fetch-testdata/software/libxml2/2.9/index.html b/bitbake/lib/bb/tests/fetch-testdata/software/libxml2/2.9/index.html new file mode 100644 index 0000000000..abdfdd0fa2 --- /dev/null +++ b/bitbake/lib/bb/tests/fetch-testdata/software/libxml2/2.9/index.html | |||
@@ -0,0 +1,40 @@ | |||
1 | <!DOCTYPE html><html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"><meta name="viewport" content="width=device-width"><style type="text/css">body,html {background:#fff;font-family:"Bitstream Vera Sans","Lucida Grande","Lucida Sans Unicode",Lucidux,Verdana,Lucida,sans-serif;}tr:nth-child(even) {background:#f4f4f4;}th,td {padding:0.1em 0.5em;}th {text-align:left;font-weight:bold;background:#eee;border-bottom:1px solid #aaa;}#list {border:1px solid #aaa;width:100%;}a {color:#a33;}a:hover {color:#e33;}</style> | ||
2 | |||
3 | <title>Index of /sources/libxml2/2.9/</title> | ||
4 | </head><body><h1>Index of /sources/libxml2/2.9/</h1> | ||
5 | <table id="list"><thead><tr><th style="width:55%"><a href="?C=N&O=A">File Name</a> <a href="?C=N&O=D"> ↓ </a></th><th style="width:20%"><a href="?C=S&O=A">File Size</a> <a href="?C=S&O=D"> ↓ </a></th><th style="width:25%"><a href="?C=M&O=A">Date</a> <a href="?C=M&O=D"> ↓ </a></th></tr></thead> | ||
6 | <tbody><tr><td class="link"><a href="../">Parent directory/</a></td><td class="size">-</td><td class="date">-</td></tr> | ||
7 | <tr><td class="link"><a href="LATEST-IS-2.9.14" title="LATEST-IS-2.9.14">LATEST-IS-2.9.14</a></td><td class="size">3.0 MiB</td><td class="date">2022-May-02 12:03</td></tr> | ||
8 | <tr><td class="link"><a href="libxml2-2.9.0.sha256sum" title="libxml2-2.9.0.sha256sum">libxml2-2.9.0.sha256sum</a></td><td class="size">87 B</td><td class="date">2022-Feb-14 18:27</td></tr> | ||
9 | <tr><td class="link"><a href="libxml2-2.9.0.tar.xz" title="libxml2-2.9.0.tar.xz">libxml2-2.9.0.tar.xz</a></td><td class="size">3.0 MiB</td><td class="date">2022-Feb-14 18:27</td></tr> | ||
10 | <tr><td class="link"><a href="libxml2-2.9.1.sha256sum" title="libxml2-2.9.1.sha256sum">libxml2-2.9.1.sha256sum</a></td><td class="size">87 B</td><td class="date">2022-Feb-14 18:28</td></tr> | ||
11 | <tr><td class="link"><a href="libxml2-2.9.1.tar.xz" title="libxml2-2.9.1.tar.xz">libxml2-2.9.1.tar.xz</a></td><td class="size">3.0 MiB</td><td class="date">2022-Feb-14 18:28</td></tr> | ||
12 | <tr><td class="link"><a href="libxml2-2.9.10.sha256sum" title="libxml2-2.9.10.sha256sum">libxml2-2.9.10.sha256sum</a></td><td class="size">88 B</td><td class="date">2022-Feb-14 18:42</td></tr> | ||
13 | <tr><td class="link"><a href="libxml2-2.9.10.tar.xz" title="libxml2-2.9.10.tar.xz">libxml2-2.9.10.tar.xz</a></td><td class="size">3.2 MiB</td><td class="date">2022-Feb-14 18:42</td></tr> | ||
14 | <tr><td class="link"><a href="libxml2-2.9.11.sha256sum" title="libxml2-2.9.11.sha256sum">libxml2-2.9.11.sha256sum</a></td><td class="size">88 B</td><td class="date">2022-Feb-14 18:43</td></tr> | ||
15 | <tr><td class="link"><a href="libxml2-2.9.11.tar.xz" title="libxml2-2.9.11.tar.xz">libxml2-2.9.11.tar.xz</a></td><td class="size">3.2 MiB</td><td class="date">2022-Feb-14 18:43</td></tr> | ||
16 | <tr><td class="link"><a href="libxml2-2.9.12.sha256sum" title="libxml2-2.9.12.sha256sum">libxml2-2.9.12.sha256sum</a></td><td class="size">88 B</td><td class="date">2022-Feb-14 18:45</td></tr> | ||
17 | <tr><td class="link"><a href="libxml2-2.9.12.tar.xz" title="libxml2-2.9.12.tar.xz">libxml2-2.9.12.tar.xz</a></td><td class="size">3.2 MiB</td><td class="date">2022-Feb-14 18:45</td></tr> | ||
18 | <tr><td class="link"><a href="libxml2-2.9.13.news" title="libxml2-2.9.13.news">libxml2-2.9.13.news</a></td><td class="size">26.6 KiB</td><td class="date">2022-Feb-20 12:42</td></tr> | ||
19 | <tr><td class="link"><a href="libxml2-2.9.13.sha256sum" title="libxml2-2.9.13.sha256sum">libxml2-2.9.13.sha256sum</a></td><td class="size">174 B</td><td class="date">2022-Feb-20 12:42</td></tr> | ||
20 | <tr><td class="link"><a href="libxml2-2.9.13.tar.xz" title="libxml2-2.9.13.tar.xz">libxml2-2.9.13.tar.xz</a></td><td class="size">3.1 MiB</td><td class="date">2022-Feb-20 12:42</td></tr> | ||
21 | <tr><td class="link"><a href="libxml2-2.9.14.news" title="libxml2-2.9.14.news">libxml2-2.9.14.news</a></td><td class="size">1.0 KiB</td><td class="date">2022-May-02 12:03</td></tr> | ||
22 | <tr><td class="link"><a href="libxml2-2.9.14.sha256sum" title="libxml2-2.9.14.sha256sum">libxml2-2.9.14.sha256sum</a></td><td class="size">174 B</td><td class="date">2022-May-02 12:03</td></tr> | ||
23 | <tr><td class="link"><a href="libxml2-2.9.14.tar.xz" title="libxml2-2.9.14.tar.xz">libxml2-2.9.14.tar.xz</a></td><td class="size">3.0 MiB</td><td class="date">2022-May-02 12:03</td></tr> | ||
24 | <tr><td class="link"><a href="libxml2-2.9.2.sha256sum" title="libxml2-2.9.2.sha256sum">libxml2-2.9.2.sha256sum</a></td><td class="size">87 B</td><td class="date">2022-Feb-14 18:30</td></tr> | ||
25 | <tr><td class="link"><a href="libxml2-2.9.2.tar.xz" title="libxml2-2.9.2.tar.xz">libxml2-2.9.2.tar.xz</a></td><td class="size">3.2 MiB</td><td class="date">2022-Feb-14 18:30</td></tr> | ||
26 | <tr><td class="link"><a href="libxml2-2.9.3.sha256sum" title="libxml2-2.9.3.sha256sum">libxml2-2.9.3.sha256sum</a></td><td class="size">87 B</td><td class="date">2022-Feb-14 18:31</td></tr> | ||
27 | <tr><td class="link"><a href="libxml2-2.9.3.tar.xz" title="libxml2-2.9.3.tar.xz">libxml2-2.9.3.tar.xz</a></td><td class="size">3.2 MiB</td><td class="date">2022-Feb-14 18:31</td></tr> | ||
28 | <tr><td class="link"><a href="libxml2-2.9.4.sha256sum" title="libxml2-2.9.4.sha256sum">libxml2-2.9.4.sha256sum</a></td><td class="size">87 B</td><td class="date">2022-Feb-14 18:33</td></tr> | ||
29 | <tr><td class="link"><a href="libxml2-2.9.4.tar.xz" title="libxml2-2.9.4.tar.xz">libxml2-2.9.4.tar.xz</a></td><td class="size">2.9 MiB</td><td class="date">2022-Feb-14 18:33</td></tr> | ||
30 | <tr><td class="link"><a href="libxml2-2.9.5.sha256sum" title="libxml2-2.9.5.sha256sum">libxml2-2.9.5.sha256sum</a></td><td class="size">87 B</td><td class="date">2022-Feb-14 18:35</td></tr> | ||
31 | <tr><td class="link"><a href="libxml2-2.9.5.tar.xz" title="libxml2-2.9.5.tar.xz">libxml2-2.9.5.tar.xz</a></td><td class="size">3.0 MiB</td><td class="date">2022-Feb-14 18:35</td></tr> | ||
32 | <tr><td class="link"><a href="libxml2-2.9.6.sha256sum" title="libxml2-2.9.6.sha256sum">libxml2-2.9.6.sha256sum</a></td><td class="size">87 B</td><td class="date">2022-Feb-14 18:36</td></tr> | ||
33 | <tr><td class="link"><a href="libxml2-2.9.6.tar.xz" title="libxml2-2.9.6.tar.xz">libxml2-2.9.6.tar.xz</a></td><td class="size">3.0 MiB</td><td class="date">2022-Feb-14 18:36</td></tr> | ||
34 | <tr><td class="link"><a href="libxml2-2.9.7.sha256sum" title="libxml2-2.9.7.sha256sum">libxml2-2.9.7.sha256sum</a></td><td class="size">87 B</td><td class="date">2022-Feb-14 18:37</td></tr> | ||
35 | <tr><td class="link"><a href="libxml2-2.9.7.tar.xz" title="libxml2-2.9.7.tar.xz">libxml2-2.9.7.tar.xz</a></td><td class="size">3.0 MiB</td><td class="date">2022-Feb-14 18:37</td></tr> | ||
36 | <tr><td class="link"><a href="libxml2-2.9.8.sha256sum" title="libxml2-2.9.8.sha256sum">libxml2-2.9.8.sha256sum</a></td><td class="size">87 B</td><td class="date">2022-Feb-14 18:39</td></tr> | ||
37 | <tr><td class="link"><a href="libxml2-2.9.8.tar.xz" title="libxml2-2.9.8.tar.xz">libxml2-2.9.8.tar.xz</a></td><td class="size">3.0 MiB</td><td class="date">2022-Feb-14 18:39</td></tr> | ||
38 | <tr><td class="link"><a href="libxml2-2.9.9.sha256sum" title="libxml2-2.9.9.sha256sum">libxml2-2.9.9.sha256sum</a></td><td class="size">87 B</td><td class="date">2022-Feb-14 18:40</td></tr> | ||
39 | <tr><td class="link"><a href="libxml2-2.9.9.tar.xz" title="libxml2-2.9.9.tar.xz">libxml2-2.9.9.tar.xz</a></td><td class="size">3.0 MiB</td><td class="date">2022-Feb-14 18:40</td></tr> | ||
40 | </tbody></table></body></html> | ||
diff --git a/bitbake/lib/bb/tests/fetch-testdata/software/libxml2/index.html b/bitbake/lib/bb/tests/fetch-testdata/software/libxml2/index.html new file mode 100644 index 0000000000..c183e06a55 --- /dev/null +++ b/bitbake/lib/bb/tests/fetch-testdata/software/libxml2/index.html | |||
@@ -0,0 +1,19 @@ | |||
1 | <!DOCTYPE html><html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"><meta name="viewport" content="width=device-width"><style type="text/css">body,html {background:#fff;font-family:"Bitstream Vera Sans","Lucida Grande","Lucida Sans Unicode",Lucidux,Verdana,Lucida,sans-serif;}tr:nth-child(even) {background:#f4f4f4;}th,td {padding:0.1em 0.5em;}th {text-align:left;font-weight:bold;background:#eee;border-bottom:1px solid #aaa;}#list {border:1px solid #aaa;width:100%;}a {color:#a33;}a:hover {color:#e33;}</style> | ||
2 | |||
3 | <title>Index of /sources/libxml2/</title> | ||
4 | </head><body><h1>Index of /sources/libxml2/</h1> | ||
5 | <table id="list"><thead><tr><th style="width:55%"><a href="?C=N&O=A">File Name</a> <a href="?C=N&O=D"> ↓ </a></th><th style="width:20%"><a href="?C=S&O=A">File Size</a> <a href="?C=S&O=D"> ↓ </a></th><th style="width:25%"><a href="?C=M&O=A">Date</a> <a href="?C=M&O=D"> ↓ </a></th></tr></thead> | ||
6 | <tbody><tr><td class="link"><a href="../">Parent directory/</a></td><td class="size">-</td><td class="date">-</td></tr> | ||
7 | <tr><td class="link"><a href="2.0/" title="2.0">2.0/</a></td><td class="size">-</td><td class="date">2009-Jul-14 13:04</td></tr> | ||
8 | <tr><td class="link"><a href="2.1/" title="2.1">2.1/</a></td><td class="size">-</td><td class="date">2009-Jul-14 13:04</td></tr> | ||
9 | <tr><td class="link"><a href="2.10/" title="2.10">2.10/</a></td><td class="size">-</td><td class="date">2022-Oct-14 12:55</td></tr> | ||
10 | <tr><td class="link"><a href="2.2/" title="2.2">2.2/</a></td><td class="size">-</td><td class="date">2009-Jul-14 13:04</td></tr> | ||
11 | <tr><td class="link"><a href="2.3/" title="2.3">2.3/</a></td><td class="size">-</td><td class="date">2009-Jul-14 13:05</td></tr> | ||
12 | <tr><td class="link"><a href="2.4/" title="2.4">2.4/</a></td><td class="size">-</td><td class="date">2009-Jul-14 13:05</td></tr> | ||
13 | <tr><td class="link"><a href="2.5/" title="2.5">2.5/</a></td><td class="size">-</td><td class="date">2009-Jul-14 13:05</td></tr> | ||
14 | <tr><td class="link"><a href="2.6/" title="2.6">2.6/</a></td><td class="size">-</td><td class="date">2009-Jul-14 13:05</td></tr> | ||
15 | <tr><td class="link"><a href="2.7/" title="2.7">2.7/</a></td><td class="size">-</td><td class="date">2022-Feb-14 18:24</td></tr> | ||
16 | <tr><td class="link"><a href="2.8/" title="2.8">2.8/</a></td><td class="size">-</td><td class="date">2022-Feb-14 18:26</td></tr> | ||
17 | <tr><td class="link"><a href="2.9/" title="2.9">2.9/</a></td><td class="size">-</td><td class="date">2022-May-02 12:04</td></tr> | ||
18 | <tr><td class="link"><a href="cache.json" title="cache.json">cache.json</a></td><td class="size">22.8 KiB</td><td class="date">2022-Oct-14 12:55</td></tr> | ||
19 | </tbody></table></body></html> | ||
diff --git a/bitbake/lib/bb/tests/fetch-testdata/software/miniupnp/download.php b/bitbake/lib/bb/tests/fetch-testdata/software/miniupnp/download.php new file mode 100644 index 0000000000..e27ee134f2 --- /dev/null +++ b/bitbake/lib/bb/tests/fetch-testdata/software/miniupnp/download.php | |||
@@ -0,0 +1,3528 @@ | |||
1 | <?xml version="1.0" encoding="UTF-8"?> | ||
2 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | ||
3 | "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | ||
4 | <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> | ||
5 | <head> | ||
6 | <title>MiniUPnP download zone</title> | ||
7 | <link href="../css/miniupnp.css" rel="stylesheet" type="text/css"/> | ||
8 | <meta name="description" content="files download of the miniupnp project"/> | ||
9 | <meta name="keywords" content="upnp,download,openbsd,freebsd,linux,windows"/> | ||
10 | <meta name="viewport" content="width=device-width" /> | ||
11 | <link href="rss.php" title="MiniUPnPd, MiniUPnPc and MiniSSDPd Files" type="application/rss+xml" rel="alternate" /> | ||
12 | <link rel="canonical" href="http://miniupnp.free.fr/files/" /> | ||
13 | <link rel="alternate" hreflang="fr" href="/files/index_fr.php" /> | ||
14 | <script async="async" src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js" type="text/javascript"></script> | ||
15 | <script type="text/javascript"> | ||
16 | (adsbygoogle = window.adsbygoogle || []).push({ | ||
17 | google_ad_client: "ca-pub-6883148866513192", | ||
18 | enable_page_level_ads: true | ||
19 | }); | ||
20 | </script> | ||
21 | </head> | ||
22 | <body> | ||
23 | <h2>MiniUPnP Project</h2> | ||
24 | |||
25 | <p align="center"> | ||
26 | <a href="../">Home</a> | | ||
27 | <b>Downloads</b> | | ||
28 | <a href="../devicelist.php">Compatibility list</a> | | ||
29 | <a href="../libnatpmp.html">libnatpmp</a> | | ||
30 | <a href="../minissdpd.html">MiniSSDPd</a> | | ||
31 | <a href="../xchat-upnp.html">xchat upnp patch</a> | | ||
32 | <a href="../search.html">Search</a> | | ||
33 | <a href="https://miniupnp.tuxfamily.org/forum/">Forum</a> | ||
34 | </p> | ||
35 | <p align="center"> | ||
36 | <b>English</b> | <a href="/files/index_fr.php">Français</a> | ||
37 | </p> | ||
38 | |||
39 | <div align="center"> | ||
40 | <script type="text/javascript"><!-- | ||
41 | google_ad_client = "pub-6883148866513192"; | ||
42 | /* 728x90, created 7/10/08 */ | ||
43 | google_ad_slot = "0774293141"; | ||
44 | google_ad_width = 728; | ||
45 | google_ad_height = 90; | ||
46 | //--> | ||
47 | </script> | ||
48 | <script type="text/javascript" | ||
49 | src="https://pagead2.googlesyndication.com/pagead/show_ads.js"> | ||
50 | </script> | ||
51 | </div> | ||
52 | |||
53 | <h2>MiniUPnP download zone</h2> | ||
54 | <p> | ||
55 | Find on this page the source of miniupnp and | ||
56 | some related files. You will also find precompiled binaries | ||
57 | of the UPnP client sample program for windows compiled using | ||
58 | <a href="https://mingw.osdn.io/">MinGW</a>. There are also Windows | ||
59 | binaries (including python module) automatically built using | ||
60 | <a href="https://ci.appveyor.com/project/miniupnp/miniupnp/build/artifacts">AppVeyor</a>. | ||
61 | </p> | ||
62 | <p>If you just need one of the software installed on your machine, | ||
63 | you probably don't need to download and compile the source files. | ||
64 | It is very likely that a package/port already exists for | ||
65 | your system/distribution. Refer to your system documentation | ||
66 | to find how to search and install a package/port. | ||
67 | Mac OS X does have port systems too : see | ||
68 | <a href="http://www.macports.org/">MacPorts</a> or | ||
69 | <a href="http://mxcl.github.com/homebrew/">Homebrew</a> or | ||
70 | <a href="http://www.finkproject.org/">Fink</a>. | ||
71 | </p> | ||
72 | <p> | ||
73 | The miniupnpc (client) sources have been successfully compiled | ||
74 | under Windows XP/vista/7/10/etc. (using | ||
75 | <a href="https://mingw.osdn.io/">MinGW</a>, | ||
76 | <a href="https://www.mingw-w64.org/">Mingw-w64</a> | ||
77 | or <a href="http://www.cygwin.com/">Cygwin</a>), | ||
78 | Linux, OpenBSD, FreeBSD, NetBSD, DragonFlyBSD, | ||
79 | Solaris, MacOS X and AmigaOS. <br/> | ||
80 | The Makefile of the client is made for GNU make : | ||
81 | check which version your system have | ||
82 | with the command "make --version". On some systems, such as OpenBSD, | ||
83 | you have to use "gmake". Under Windows with MinGW, GNU make is | ||
84 | called "mingw32-make" and a sligthly modified version of the Makefile | ||
85 | should be used : Makefile.mingw. Run "mingw32make.bat" to compile. <br/> | ||
86 | If you have any compatibility problem, please post on the | ||
87 | <a href="https://miniupnp.tuxfamily.org/forum/">forum</a> | ||
88 | or contact me by email. | ||
89 | </p> | ||
90 | <!-- | ||
91 | <p>A devoted user compiled miniupnp<strong>c</strong> for | ||
92 | Openwrt (currently Kamikaze 7.09) | ||
93 | and his work is available here : | ||
94 | <a href="http://replay.waybackmachine.org/20081120030628/http://www.myantihero.net/pub/openwrt/packages/">http://myantihero.net/pub/openwrt/packages/</a>.</p> | ||
95 | --> | ||
96 | <p>Get miniupnpc under AmigaOS 4 on | ||
97 | <a href="http://os4depot.net/index.php?function=showfile&file=network/misc/miniupnpc.lha">OS4Depot</a>. | ||
98 | </p> | ||
99 | <p> | ||
100 | Dario Meloni has made a Ruby Gem embedding miniupnpc : | ||
101 | <a href="https://rubygems.org/gems/mupnp">https://rubygems.org/gems/mupnp</a>. | ||
102 | </p> | ||
103 | <p> | ||
104 | The python module is available on pypi.org : | ||
105 | <a href="https://pypi.org/project/miniupnpc/">pip install miniupnpc</a>. | ||
106 | </p> | ||
107 | <p> | ||
108 | The daemon (starting in November 2006) compiles with BSD make under BSD | ||
109 | and Solaris.<br/> | ||
110 | To compile the daemon under linux, use "make -f Makefile.linux"<br/> | ||
111 | To compile for <a href="http://openwrt.org/">OpenWRT</a> | ||
112 | please read the README.openwrt file, or use the packages | ||
113 | <a href="https://openwrt.org/packages/pkgdata/miniupnpd">miniupnpc</a> and | ||
114 | <a href="https://openwrt.org/packages/pkgdata/miniupnpd">miniupnpd</a>. | ||
115 | <!-- The | ||
116 | <a href="http://www.x-wrt.org/">X-Wrt</a> project is providing | ||
117 | precompiled ipkg packages for OpenWrt for both OpenWrt | ||
118 | <a href="ftp://ftp.berlios.de/pub/xwrt/packages/">White Russian</a> | ||
119 | and OpenWrt | ||
120 | <a href="ftp://ftp.berlios.de/pub/xwrt/kamikaze/packages">kamikaze</a>. | ||
121 | Check | ||
122 | <a href="ftp://ftp.berlios.de/pub/xwrt/">ftp://ftp.berlios.de/pub/xwrt/</a>. | ||
123 | For White Russian, take a look at | ||
124 | <a href="http://jackassofalltrades.com/openwrt/">this</a>. --> | ||
125 | <br/> | ||
126 | <a href="http://pfsense.com">pfSense</a> users are advised to use the | ||
127 | miniupnpd port available for their system. Recent versions of | ||
128 | pfSense include MiniUPnPd in the base system. | ||
129 | <br/> | ||
130 | For <a href="http://en.wikipedia.org/wiki/WRT54G">Linksys WRT54G</a> | ||
131 | and WRT54GL owners, | ||
132 | <a href="http://sourceforge.net/projects/tarifa/">Tarifa firmware</a> | ||
133 | is another alternative to get miniUPnPd running on the router. | ||
134 | </p> | ||
135 | <p> | ||
136 | Please read README and | ||
137 | LICENCE files included with the distribution for further informations. | ||
138 | </p> | ||
139 | <p> | ||
140 | The MiniUPnP daemon (miniupnpd) is working under | ||
141 | <a href="http://www.openbsd.org/">OpenBSD</a>, | ||
142 | <a href="http://www.netbsd.org/">NetBSD</a>, | ||
143 | <a href="http://www.freebsd.org/">FreeBSD</a>, | ||
144 | <a href="http://www.dragonflybsd.org/">DragonFlyBSD</a>, | ||
145 | <a href="http://www.apple.com/macosx/">Mac OS X</a> and | ||
146 | (<a href="https://en.wikipedia.org/wiki/OpenSolaris">Open</a>)<a href="http://www.oracle.com/us/products/servers-storage/solaris/solaris11/overview/index.html">Solaris</a> | ||
147 | with <a href="http://www.openbsd.org/faq/pf/">pf</a>, | ||
148 | with <a href="https://en.wikipedia.org/wiki/IPFilter">IP Filter</a> or | ||
149 | with <a href="http://en.wikipedia.org/wiki/Ipfirewall">ipfw</a>. | ||
150 | The linux version uses either libiptc which permits to access | ||
151 | <a href="http://netfilter.org/">netfilter</a> | ||
152 | rules inside the kernel the same way as | ||
153 | <a href="https://www.netfilter.org/projects/iptables/index.html">iptables</a>, or | ||
154 | <a href="https://www.netfilter.org/projects/libnftnl/index.html">libnftnl</a> | ||
155 | which is the equivalent for | ||
156 | <a href="https://www.netfilter.org/projects/nftables/index.html">nftables</a>. | ||
157 | </p> | ||
158 | |||
159 | <p>Releases are now GPG signed with the key <a href="../A31ACAAF.asc">A31ACAAF</a>. | ||
160 | Previous signing key was <a href="../A5C0863C.asc">A5C0863C</a>. | ||
161 | Get it from your favorite | ||
162 | <a href="https://pgp.mit.edu/pks/lookup?search=0xA31ACAAF&op=index&fingerprint=on">key server</a>.</p> | ||
163 | |||
164 | <h4>REST API</h4> | ||
165 | <p>You can use the REST API to get the latest releases available:</p> | ||
166 | <ul> | ||
167 | <li><a href="rest.php/tags/miniupnpd?count=1">rest.php/tags/miniupnpd?count=1</a>: latest miniupnpd.</li> | ||
168 | <li><a href="rest.php/tags?count=1">rest.php/tags?count=1</a>: miniupnpc, miniupnpd and minissdpd.</li> | ||
169 | </ul> | ||
170 | |||
171 | <h4>You can help !</h4> | ||
172 | <p>If you make a package/port for your favorite OS distribution, | ||
173 | inform me so I can upload the package here or add a link to your | ||
174 | repository. | ||
175 | </p> | ||
176 | |||
177 | <h4>Latest files</h4> | ||
178 | <table> | ||
179 | <tr><th>name</th> | ||
180 | <th>size</th> | ||
181 | <th>date</th> | ||
182 | <th>comment</th> | ||
183 | <th><!-- Changelog --></th> | ||
184 | <th><!-- Signature --></th> | ||
185 | </tr> | ||
186 | <tr> | ||
187 | <td class="filename"><a href='miniupnpc-2.3.2.tar.gz'>miniupnpc-2.3.2.tar.gz</a></td> | ||
188 | <td class="filesize">140137</td> | ||
189 | <td class="filedate">05/03/2025 10:31</td> | ||
190 | <td class="comment">MiniUPnP client release source code</td> | ||
191 | <td><a href="changelog.php?file=miniupnpc-2.3.2.tar.gz">changelog</a></td> | ||
192 | <td><a href="miniupnpc-2.3.2.tar.gz.sig">Signature</a></td> | ||
193 | </tr> | ||
194 | <tr> | ||
195 | <td class="filename"><a href='miniupnpd-2.3.7.tar.gz'>miniupnpd-2.3.7.tar.gz</a></td> | ||
196 | <td class="filesize">265329</td> | ||
197 | <td class="filedate">22/06/2024 22:31</td> | ||
198 | <td class="comment">MiniUPnP daemon release source code</td> | ||
199 | <td><a href="changelog.php?file=miniupnpd-2.3.7.tar.gz">changelog</a></td> | ||
200 | <td><a href="miniupnpd-2.3.7.tar.gz.sig">Signature</a></td> | ||
201 | </tr> | ||
202 | <tr> | ||
203 | <td class="filename"><a href='libnatpmp-20230423.tar.gz'>libnatpmp-20230423.tar.gz</a></td> | ||
204 | <td class="filesize">26506</td> | ||
205 | <td class="filedate">23/04/2023 11:02</td> | ||
206 | <td class="comment">latest libnatpmp source code</td> | ||
207 | <td><a href="changelog.php?file=libnatpmp-20230423.tar.gz">changelog</a></td> | ||
208 | <td><a href="libnatpmp-20230423.tar.gz.sig">Signature</a></td> | ||
209 | </tr> | ||
210 | <tr> | ||
211 | <td class="filename"><a href='minissdpd-1.6.0.tar.gz'>minissdpd-1.6.0.tar.gz</a></td> | ||
212 | <td class="filesize">39077</td> | ||
213 | <td class="filedate">22/10/2022 18:41</td> | ||
214 | <td class="comment">MiniSSDPd release source code</td> | ||
215 | <td><a href="changelog.php?file=minissdpd-1.6.0.tar.gz">changelog</a></td> | ||
216 | <td><a href="minissdpd-1.6.0.tar.gz.sig">Signature</a></td> | ||
217 | </tr> | ||
218 | <tr> | ||
219 | <td class="filename"><a href='upnpc-exe-win32-20220515.zip'>upnpc-exe-win32-20220515.zip</a></td> | ||
220 | <td class="filesize">69503</td> | ||
221 | <td class="filedate">15/05/2022 14:31</td> | ||
222 | <td class="comment">Windows executable</td> | ||
223 | <td><a href="changelog.php?file=upnpc-exe-win32-20220515.zip">changelog</a></td> | ||
224 | <td></td> | ||
225 | </tr> | ||
226 | <tr> | ||
227 | <td class="filename"><a href='minissdpd-1.5.20211105.tar.gz'>minissdpd-1.5.20211105.tar.gz</a></td> | ||
228 | <td class="filesize">38870</td> | ||
229 | <td class="filedate">04/11/2021 23:34</td> | ||
230 | <td class="comment">latest MiniSSDPd source code</td> | ||
231 | <td><a href="changelog.php?file=minissdpd-1.5.20211105.tar.gz">changelog</a></td> | ||
232 | <td><a href="minissdpd-1.5.20211105.tar.gz.sig">Signature</a></td> | ||
233 | </tr> | ||
234 | <tr> | ||
235 | <td class="filename"><a href='miniupnpc-2.1.20201016.tar.gz'>miniupnpc-2.1.20201016.tar.gz</a></td> | ||
236 | <td class="filesize">97682</td> | ||
237 | <td class="filedate">15/10/2020 22:31</td> | ||
238 | <td class="comment">latest MiniUPnP client source code</td> | ||
239 | <td><a href="changelog.php?file=miniupnpc-2.1.20201016.tar.gz">changelog</a></td> | ||
240 | <td><a href="miniupnpc-2.1.20201016.tar.gz.sig">Signature</a></td> | ||
241 | </tr> | ||
242 | <tr> | ||
243 | <td class="filename"><a href='miniupnpd-2.1.20200510.tar.gz'>miniupnpd-2.1.20200510.tar.gz</a></td> | ||
244 | <td class="filesize">245426</td> | ||
245 | <td class="filedate">10/05/2020 18:23</td> | ||
246 | <td class="comment">latest MiniUPnP daemon source code</td> | ||
247 | <td><a href="changelog.php?file=miniupnpd-2.1.20200510.tar.gz">changelog</a></td> | ||
248 | <td><a href="miniupnpd-2.1.20200510.tar.gz.sig">Signature</a></td> | ||
249 | </tr> | ||
250 | <tr> | ||
251 | <td class="filename"><a href='xchat-upnp20110811.patch'>xchat-upnp20110811.patch</a></td> | ||
252 | <td class="filesize">10329</td> | ||
253 | <td class="filedate">11/08/2011 15:18</td> | ||
254 | <td class="comment">Patch to add UPnP capabilities to xchat</td> | ||
255 | <td><a href="changelog.php?file=xchat-upnp20110811.patch">changelog</a></td> | ||
256 | <td></td> | ||
257 | </tr> | ||
258 | <tr> | ||
259 | <td class="filename"><a href='minidlna_1.0.21.minissdp1.patch'>minidlna_1.0.21.minissdp1.patch</a></td> | ||
260 | <td class="filesize">7598</td> | ||
261 | <td class="filedate">25/07/2011 14:57</td> | ||
262 | <td class="comment">Patch for MiniDLNA to use miniSSDPD</td> | ||
263 | <td><a href="changelog.php?file=minidlna_1.0.21.minissdp1.patch">changelog</a></td> | ||
264 | <td></td> | ||
265 | </tr> | ||
266 | <tr> | ||
267 | <td class="filename"><a href='miniupnpc-new20060630.tar.gz'>miniupnpc-new20060630.tar.gz</a></td> | ||
268 | <td class="filesize">14840</td> | ||
269 | <td class="filedate">04/11/2006 18:16</td> | ||
270 | <td class="comment">João Paulo Barraca version of the upnp client</td> | ||
271 | <td><a href="changelog.php?file=miniupnpc-new20060630.tar.gz">changelog</a></td> | ||
272 | <td></td> | ||
273 | </tr> | ||
274 | </table> | ||
275 | |||
276 | <h4>All files</h4> | ||
277 | <table> | ||
278 | <tr><th>name</th> | ||
279 | <th>size</th> | ||
280 | <th>date</th> | ||
281 | <th>comment</th> | ||
282 | <th><!-- signature --></th> | ||
283 | </tr> | ||
284 | <tr> | ||
285 | <td class="filename"><a href='download.php?file=miniupnpc-2.3.2.tar.gz'>miniupnpc-2.3.2.tar.gz</a></td> | ||
286 | <td class="filesize">140137</td> | ||
287 | <td class="filedate">05/03/2025 10:31:36 +0000</td> | ||
288 | <td class="comment">MiniUPnP client release source code</td> | ||
289 | <td><a href="miniupnpc-2.3.2.tar.gz.sig">Signature</a></td> | ||
290 | </tr> | ||
291 | <tr> | ||
292 | <td class="filename"><a href='download.php?file=miniupnpc-2.3.1.tar.gz'>miniupnpc-2.3.1.tar.gz</a></td> | ||
293 | <td class="filesize">139499</td> | ||
294 | <td class="filedate">23/02/2025 16:44:16 +0000</td> | ||
295 | <td class="comment">MiniUPnP client release source code</td> | ||
296 | <td><a href="miniupnpc-2.3.1.tar.gz.sig">Signature</a></td> | ||
297 | </tr> | ||
298 | <tr> | ||
299 | <td class="filename"><a href='download.php?file=miniupnpc-2.3.0.tar.gz'>miniupnpc-2.3.0.tar.gz</a></td> | ||
300 | <td class="filesize">105071</td> | ||
301 | <td class="filedate">10/01/2025 23:16:45 +0000</td> | ||
302 | <td class="comment">MiniUPnP client release source code</td> | ||
303 | <td><a href="miniupnpc-2.3.0.tar.gz.sig">Signature</a></td> | ||
304 | </tr> | ||
305 | <tr> | ||
306 | <td class="filename"><a href='download.php?file=miniupnpd-2.3.7.tar.gz'>miniupnpd-2.3.7.tar.gz</a></td> | ||
307 | <td class="filesize">265329</td> | ||
308 | <td class="filedate">22/06/2024 22:31:38 +0000</td> | ||
309 | <td class="comment">MiniUPnP daemon release source code</td> | ||
310 | <td><a href="miniupnpd-2.3.7.tar.gz.sig">Signature</a></td> | ||
311 | </tr> | ||
312 | <tr> | ||
313 | <td class="filename"><a href='download.php?file=miniupnpc-2.2.8.tar.gz'>miniupnpc-2.2.8.tar.gz</a></td> | ||
314 | <td class="filesize">104603</td> | ||
315 | <td class="filedate">08/06/2024 22:13:39 +0000</td> | ||
316 | <td class="comment">MiniUPnP client release source code</td> | ||
317 | <td><a href="miniupnpc-2.2.8.tar.gz.sig">Signature</a></td> | ||
318 | </tr> | ||
319 | <tr> | ||
320 | <td class="filename"><a href='download.php?file=miniupnpd-2.3.6.tar.gz'>miniupnpd-2.3.6.tar.gz</a></td> | ||
321 | <td class="filesize">263018</td> | ||
322 | <td class="filedate">19/03/2024 23:39:51 +0000</td> | ||
323 | <td class="comment">MiniUPnP daemon release source code</td> | ||
324 | <td><a href="miniupnpd-2.3.6.tar.gz.sig">Signature</a></td> | ||
325 | </tr> | ||
326 | <tr> | ||
327 | <td class="filename"><a href='download.php?file=miniupnpc-2.2.7.tar.gz'>miniupnpc-2.2.7.tar.gz</a></td> | ||
328 | <td class="filesize">104258</td> | ||
329 | <td class="filedate">19/03/2024 23:25:18 +0000</td> | ||
330 | <td class="comment">MiniUPnP client release source code</td> | ||
331 | <td><a href="miniupnpc-2.2.7.tar.gz.sig">Signature</a></td> | ||
332 | </tr> | ||
333 | <tr> | ||
334 | <td class="filename"><a href='download.php?file=miniupnpd-2.3.5.tar.gz'>miniupnpd-2.3.5.tar.gz</a></td> | ||
335 | <td class="filesize">261952</td> | ||
336 | <td class="filedate">02/03/2024 11:04:07 +0000</td> | ||
337 | <td class="comment">MiniUPnP daemon release source code</td> | ||
338 | <td><a href="miniupnpd-2.3.5.tar.gz.sig">Signature</a></td> | ||
339 | </tr> | ||
340 | <tr> | ||
341 | <td class="filename"><a href='download.php?file=miniupnpd-2.3.4.tar.gz'>miniupnpd-2.3.4.tar.gz</a></td> | ||
342 | <td class="filesize">260810</td> | ||
343 | <td class="filedate">04/01/2024 00:53:17 +0000</td> | ||
344 | <td class="comment">MiniUPnP daemon release source code</td> | ||
345 | <td><a href="miniupnpd-2.3.4.tar.gz.sig">Signature</a></td> | ||
346 | </tr> | ||
347 | <tr> | ||
348 | <td class="filename"><a href='download.php?file=miniupnpc-2.2.6.tar.gz'>miniupnpc-2.2.6.tar.gz</a></td> | ||
349 | <td class="filesize">103949</td> | ||
350 | <td class="filedate">04/01/2024 00:27:14 +0000</td> | ||
351 | <td class="comment">MiniUPnP client release source code</td> | ||
352 | <td><a href="miniupnpc-2.2.6.tar.gz.sig">Signature</a></td> | ||
353 | </tr> | ||
354 | <tr> | ||
355 | <td class="filename"><a href='download.php?file=miniupnpc-2.2.5.tar.gz'>miniupnpc-2.2.5.tar.gz</a></td> | ||
356 | <td class="filesize">103654</td> | ||
357 | <td class="filedate">11/06/2023 23:14:56 +0000</td> | ||
358 | <td class="comment">MiniUPnP client release source code</td> | ||
359 | <td><a href="miniupnpc-2.2.5.tar.gz.sig">Signature</a></td> | ||
360 | </tr> | ||
361 | <tr> | ||
362 | <td class="filename"><a href='download.php?file=libnatpmp-20230423.tar.gz'>libnatpmp-20230423.tar.gz</a></td> | ||
363 | <td class="filesize">26506</td> | ||
364 | <td class="filedate">23/04/2023 11:02:09 +0000</td> | ||
365 | <td class="comment">libnatpmp source code</td> | ||
366 | <td><a href="libnatpmp-20230423.tar.gz.sig">Signature</a></td> | ||
367 | </tr> | ||
368 | <tr> | ||
369 | <td class="filename"><a href='download.php?file=miniupnpd-2.3.3.tar.gz'>miniupnpd-2.3.3.tar.gz</a></td> | ||
370 | <td class="filesize">260079</td> | ||
371 | <td class="filedate">17/02/2023 03:07:46 +0000</td> | ||
372 | <td class="comment">MiniUPnP daemon release source code</td> | ||
373 | <td><a href="miniupnpd-2.3.3.tar.gz.sig">Signature</a></td> | ||
374 | </tr> | ||
375 | <tr> | ||
376 | <td class="filename"><a href='download.php?file=miniupnpd-2.3.2.tar.gz'>miniupnpd-2.3.2.tar.gz</a></td> | ||
377 | <td class="filesize">259686</td> | ||
378 | <td class="filedate">19/01/2023 23:18:08 +0000</td> | ||
379 | <td class="comment">MiniUPnP daemon release source code</td> | ||
380 | <td><a href="miniupnpd-2.3.2.tar.gz.sig">Signature</a></td> | ||
381 | </tr> | ||
382 | <tr> | ||
383 | <td class="filename"><a href='download.php?file=minissdpd-1.6.0.tar.gz'>minissdpd-1.6.0.tar.gz</a></td> | ||
384 | <td class="filesize">39077</td> | ||
385 | <td class="filedate">22/10/2022 18:41:54 +0000</td> | ||
386 | <td class="comment">MiniSSDPd release source code</td> | ||
387 | <td><a href="minissdpd-1.6.0.tar.gz.sig">Signature</a></td> | ||
388 | </tr> | ||
389 | <tr> | ||
390 | <td class="filename"><a href='download.php?file=miniupnpc-2.2.4.tar.gz'>miniupnpc-2.2.4.tar.gz</a></td> | ||
391 | <td class="filesize">102932</td> | ||
392 | <td class="filedate">21/10/2022 21:01:01 +0000</td> | ||
393 | <td class="comment">MiniUPnP client release source code</td> | ||
394 | <td><a href="miniupnpc-2.2.4.tar.gz.sig">Signature</a></td> | ||
395 | </tr> | ||
396 | <tr> | ||
397 | <td class="filename"><a href='download.php?file=miniupnpd-2.3.1.tar.gz'>miniupnpd-2.3.1.tar.gz</a></td> | ||
398 | <td class="filesize">258050</td> | ||
399 | <td class="filedate">16/10/2022 05:58:44 +0000</td> | ||
400 | <td class="comment">MiniUPnP daemon release source code</td> | ||
401 | <td><a href="miniupnpd-2.3.1.tar.gz.sig">Signature</a></td> | ||
402 | </tr> | ||
403 | <tr> | ||
404 | <td class="filename"><a href='download.php?file=upnpc-exe-win32-20220515.zip'>upnpc-exe-win32-20220515.zip</a></td> | ||
405 | <td class="filesize">69503</td> | ||
406 | <td class="filedate">15/05/2022 14:31:25 +0000</td> | ||
407 | <td class="comment">Windows executable</td> | ||
408 | <td></td> | ||
409 | </tr> | ||
410 | <tr> | ||
411 | <td class="filename"><a href='download.php?file=hexchat-2.16.patch'>hexchat-2.16.patch</a></td> | ||
412 | <td class="filesize">8147</td> | ||
413 | <td class="filedate">19/03/2022 16:52:05 +0000</td> | ||
414 | <td class="comment"></td> | ||
415 | <td></td> | ||
416 | </tr> | ||
417 | <tr> | ||
418 | <td class="filename"><a href='download.php?file=miniupnpd-2.3.0.tar.gz'>miniupnpd-2.3.0.tar.gz</a></td> | ||
419 | <td class="filesize">256069</td> | ||
420 | <td class="filedate">23/01/2022 00:23:32 +0000</td> | ||
421 | <td class="comment">MiniUPnP daemon release source code</td> | ||
422 | <td><a href="miniupnpd-2.3.0.tar.gz.sig">Signature</a></td> | ||
423 | </tr> | ||
424 | <tr> | ||
425 | <td class="filename"><a href='download.php?file=minissdpd-1.5.20211105.tar.gz'>minissdpd-1.5.20211105.tar.gz</a></td> | ||
426 | <td class="filesize">38870</td> | ||
427 | <td class="filedate">04/11/2021 23:34:49 +0000</td> | ||
428 | <td class="comment">MiniSSDPd source code</td> | ||
429 | <td><a href="minissdpd-1.5.20211105.tar.gz.sig">Signature</a></td> | ||
430 | </tr> | ||
431 | <tr> | ||
432 | <td class="filename"><a href='download.php?file=miniupnpc-2.2.3.tar.gz'>miniupnpc-2.2.3.tar.gz</a></td> | ||
433 | <td class="filesize">101360</td> | ||
434 | <td class="filedate">28/09/2021 21:43:32 +0000</td> | ||
435 | <td class="comment">MiniUPnP client release source code</td> | ||
436 | <td><a href="miniupnpc-2.2.3.tar.gz.sig">Signature</a></td> | ||
437 | </tr> | ||
438 | <tr> | ||
439 | <td class="filename"><a href='download.php?file=miniupnpd-2.2.3.tar.gz'>miniupnpd-2.2.3.tar.gz</a></td> | ||
440 | <td class="filesize">254752</td> | ||
441 | <td class="filedate">21/08/2021 08:35:13 +0000</td> | ||
442 | <td class="comment">MiniUPnP daemon release source code</td> | ||
443 | <td><a href="miniupnpd-2.2.3.tar.gz.sig">Signature</a></td> | ||
444 | </tr> | ||
445 | <tr> | ||
446 | <td class="filename"><a href='download.php?file=miniupnpd-2.2.2.tar.gz'>miniupnpd-2.2.2.tar.gz</a></td> | ||
447 | <td class="filesize">250649</td> | ||
448 | <td class="filedate">13/05/2021 11:30:11 +0000</td> | ||
449 | <td class="comment">MiniUPnP daemon release source code</td> | ||
450 | <td><a href="miniupnpd-2.2.2.tar.gz.sig">Signature</a></td> | ||
451 | </tr> | ||
452 | <tr> | ||
453 | <td class="filename"><a href='download.php?file=miniupnpc-2.2.2.tar.gz'>miniupnpc-2.2.2.tar.gz</a></td> | ||
454 | <td class="filesize">100008</td> | ||
455 | <td class="filedate">02/03/2021 23:44:52 +0000</td> | ||
456 | <td class="comment">MiniUPnP client release source code</td> | ||
457 | <td><a href="miniupnpc-2.2.2.tar.gz.sig">Signature</a></td> | ||
458 | </tr> | ||
459 | <tr> | ||
460 | <td class="filename"><a href='download.php?file=miniupnpd-2.2.1.tar.gz'>miniupnpd-2.2.1.tar.gz</a></td> | ||
461 | <td class="filesize">250023</td> | ||
462 | <td class="filedate">20/12/2020 18:08:08 +0000</td> | ||
463 | <td class="comment">MiniUPnP daemon release source code</td> | ||
464 | <td><a href="miniupnpd-2.2.1.tar.gz.sig">Signature</a></td> | ||
465 | </tr> | ||
466 | <tr> | ||
467 | <td class="filename"><a href='download.php?file=miniupnpc-2.2.1.tar.gz'>miniupnpc-2.2.1.tar.gz</a></td> | ||
468 | <td class="filesize">99595</td> | ||
469 | <td class="filedate">20/12/2020 18:08:02 +0000</td> | ||
470 | <td class="comment">MiniUPnP client release source code</td> | ||
471 | <td><a href="miniupnpc-2.2.1.tar.gz.sig">Signature</a></td> | ||
472 | </tr> | ||
473 | <tr> | ||
474 | <td class="filename"><a href='download.php?file=miniupnpc-2.2.0.tar.gz'>miniupnpc-2.2.0.tar.gz</a></td> | ||
475 | <td class="filesize">98348</td> | ||
476 | <td class="filedate">09/11/2020 19:51:24 +0000</td> | ||
477 | <td class="comment">MiniUPnP client release source code</td> | ||
478 | <td><a href="miniupnpc-2.2.0.tar.gz.sig">Signature</a></td> | ||
479 | </tr> | ||
480 | <tr> | ||
481 | <td class="filename"><a href='download.php?file=miniupnpd-2.2.0.tar.gz'>miniupnpd-2.2.0.tar.gz</a></td> | ||
482 | <td class="filesize">249858</td> | ||
483 | <td class="filedate">31/10/2020 09:20:59 +0000</td> | ||
484 | <td class="comment">MiniUPnP daemon release source code</td> | ||
485 | <td><a href="miniupnpd-2.2.0.tar.gz.sig">Signature</a></td> | ||
486 | </tr> | ||
487 | <tr> | ||
488 | <td class="filename"><a href='download.php?file=miniupnpd-2.2.0-RC3.tar.gz'>miniupnpd-2.2.0-RC3.tar.gz</a></td> | ||
489 | <td class="filesize">249879</td> | ||
490 | <td class="filedate">30/10/2020 21:49:49 +0000</td> | ||
491 | <td class="comment">MiniUPnP daemon release source code</td> | ||
492 | <td><a href="miniupnpd-2.2.0-RC3.tar.gz.sig">Signature</a></td> | ||
493 | </tr> | ||
494 | <tr> | ||
495 | <td class="filename"><a href='download.php?file=miniupnpc-2.1.20201016.tar.gz'>miniupnpc-2.1.20201016.tar.gz</a></td> | ||
496 | <td class="filesize">97682</td> | ||
497 | <td class="filedate">15/10/2020 22:31:09 +0000</td> | ||
498 | <td class="comment">MiniUPnP client source code</td> | ||
499 | <td><a href="miniupnpc-2.1.20201016.tar.gz.sig">Signature</a></td> | ||
500 | </tr> | ||
501 | <tr> | ||
502 | <td class="filename"><a href='download.php?file=miniupnpd-2.2.0-RC2.tar.gz'>miniupnpd-2.2.0-RC2.tar.gz</a></td> | ||
503 | <td class="filesize">248756</td> | ||
504 | <td class="filedate">28/09/2020 21:57:22 +0000</td> | ||
505 | <td class="comment">MiniUPnP daemon release source code</td> | ||
506 | <td><a href="miniupnpd-2.2.0-RC2.tar.gz.sig">Signature</a></td> | ||
507 | </tr> | ||
508 | <tr> | ||
509 | <td class="filename"><a href='download.php?file=miniupnpc-2.1.20200928.tar.gz'>miniupnpc-2.1.20200928.tar.gz</a></td> | ||
510 | <td class="filesize">96508</td> | ||
511 | <td class="filedate">28/09/2020 21:56:09 +0000</td> | ||
512 | <td class="comment">MiniUPnP client source code</td> | ||
513 | <td><a href="miniupnpc-2.1.20200928.tar.gz.sig">Signature</a></td> | ||
514 | </tr> | ||
515 | <tr> | ||
516 | <td class="filename"><a href='download.php?file=minissdpd-1.5.20200928.tar.gz'>minissdpd-1.5.20200928.tar.gz</a></td> | ||
517 | <td class="filesize">37860</td> | ||
518 | <td class="filedate">28/09/2020 21:55:40 +0000</td> | ||
519 | <td class="comment">MiniSSDPd source code</td> | ||
520 | <td><a href="minissdpd-1.5.20200928.tar.gz.sig">Signature</a></td> | ||
521 | </tr> | ||
522 | <tr> | ||
523 | <td class="filename"><a href='download.php?file=miniupnpd-2.2.0-RC1.tar.gz'>miniupnpd-2.2.0-RC1.tar.gz</a></td> | ||
524 | <td class="filesize">247772</td> | ||
525 | <td class="filedate">06/06/2020 18:34:50 +0000</td> | ||
526 | <td class="comment">MiniUPnP daemon release source code</td> | ||
527 | <td><a href="miniupnpd-2.2.0-RC1.tar.gz.sig">Signature</a></td> | ||
528 | </tr> | ||
529 | <tr> | ||
530 | <td class="filename"><a href='download.php?file=miniupnpd-2.2.0-RC0.tar.gz'>miniupnpd-2.2.0-RC0.tar.gz</a></td> | ||
531 | <td class="filesize">245507</td> | ||
532 | <td class="filedate">16/05/2020 18:03:17 +0000</td> | ||
533 | <td class="comment">MiniUPnP daemon release source code</td> | ||
534 | <td><a href="miniupnpd-2.2.0-RC0.tar.gz.sig">Signature</a></td> | ||
535 | </tr> | ||
536 | <tr> | ||
537 | <td class="filename"><a href='download.php?file=miniupnpd-2.1.20200510.tar.gz'>miniupnpd-2.1.20200510.tar.gz</a></td> | ||
538 | <td class="filesize">245426</td> | ||
539 | <td class="filedate">10/05/2020 18:23:13 +0000</td> | ||
540 | <td class="comment">MiniUPnP daemon source code</td> | ||
541 | <td><a href="miniupnpd-2.1.20200510.tar.gz.sig">Signature</a></td> | ||
542 | </tr> | ||
543 | <tr> | ||
544 | <td class="filename"><a href='download.php?file=miniupnpd-2.1.20200329.tar.gz'>miniupnpd-2.1.20200329.tar.gz</a></td> | ||
545 | <td class="filesize">243725</td> | ||
546 | <td class="filedate">29/03/2020 09:11:02 +0000</td> | ||
547 | <td class="comment">MiniUPnP daemon source code</td> | ||
548 | <td><a href="miniupnpd-2.1.20200329.tar.gz.sig">Signature</a></td> | ||
549 | </tr> | ||
550 | <tr> | ||
551 | <td class="filename"><a href='download.php?file=miniupnpc-2.1.20191224.tar.gz'>miniupnpc-2.1.20191224.tar.gz</a></td> | ||
552 | <td class="filesize">94740</td> | ||
553 | <td class="filedate">23/12/2019 23:37:32 +0000</td> | ||
554 | <td class="comment">MiniUPnP client source code</td> | ||
555 | <td><a href="miniupnpc-2.1.20191224.tar.gz.sig">Signature</a></td> | ||
556 | </tr> | ||
557 | <tr> | ||
558 | <td class="filename"><a href='download.php?file=miniupnpd-2.1.20191006.tar.gz'>miniupnpd-2.1.20191006.tar.gz</a></td> | ||
559 | <td class="filesize">243255</td> | ||
560 | <td class="filedate">06/10/2019 21:02:31 +0000</td> | ||
561 | <td class="comment">MiniUPnP daemon source code</td> | ||
562 | <td><a href="miniupnpd-2.1.20191006.tar.gz.sig">Signature</a></td> | ||
563 | </tr> | ||
564 | <tr> | ||
565 | <td class="filename"><a href='download.php?file=miniupnpd-2.1.20191005.tar.gz'>miniupnpd-2.1.20191005.tar.gz</a></td> | ||
566 | <td class="filesize">244100</td> | ||
567 | <td class="filedate">05/10/2019 21:33:08 +0000</td> | ||
568 | <td class="comment">MiniUPnP daemon source code</td> | ||
569 | <td><a href="miniupnpd-2.1.20191005.tar.gz.sig">Signature</a></td> | ||
570 | </tr> | ||
571 | <tr> | ||
572 | <td class="filename"><a href='download.php?file=miniupnpd-2.1.20191003.tar.gz'>miniupnpd-2.1.20191003.tar.gz</a></td> | ||
573 | <td class="filesize">243287</td> | ||
574 | <td class="filedate">02/10/2019 22:23:51 +0000</td> | ||
575 | <td class="comment">MiniUPnP daemon source code</td> | ||
576 | <td><a href="miniupnpd-2.1.20191003.tar.gz.sig">Signature</a></td> | ||
577 | </tr> | ||
578 | <tr> | ||
579 | <td class="filename"><a href='download.php?file=miniupnpd-2.1.20190924.tar.gz'>miniupnpd-2.1.20190924.tar.gz</a></td> | ||
580 | <td class="filesize">241008</td> | ||
581 | <td class="filedate">24/09/2019 11:58:15 +0000</td> | ||
582 | <td class="comment">MiniUPnP daemon source code</td> | ||
583 | <td><a href="miniupnpd-2.1.20190924.tar.gz.sig">Signature</a></td> | ||
584 | </tr> | ||
585 | <tr> | ||
586 | <td class="filename"><a href='download.php?file=miniupnpd-2.1.20190902.tar.gz'>miniupnpd-2.1.20190902.tar.gz</a></td> | ||
587 | <td class="filesize">240742</td> | ||
588 | <td class="filedate">01/09/2019 23:03:03 +0000</td> | ||
589 | <td class="comment">MiniUPnP daemon source code</td> | ||
590 | <td><a href="miniupnpd-2.1.20190902.tar.gz.sig">Signature</a></td> | ||
591 | </tr> | ||
592 | <tr> | ||
593 | <td class="filename"><a href='download.php?file=miniupnpd-2.1.20190824.tar.gz'>miniupnpd-2.1.20190824.tar.gz</a></td> | ||
594 | <td class="filesize">240490</td> | ||
595 | <td class="filedate">24/08/2019 09:21:52 +0000</td> | ||
596 | <td class="comment">MiniUPnP daemon source code</td> | ||
597 | <td><a href="miniupnpd-2.1.20190824.tar.gz.sig">Signature</a></td> | ||
598 | </tr> | ||
599 | <tr> | ||
600 | <td class="filename"><a href='download.php?file=minissdpd-1.5.20190824.tar.gz'>minissdpd-1.5.20190824.tar.gz</a></td> | ||
601 | <td class="filesize">37300</td> | ||
602 | <td class="filedate">24/08/2019 09:17:32 +0000</td> | ||
603 | <td class="comment">MiniSSDPd source code</td> | ||
604 | <td><a href="minissdpd-1.5.20190824.tar.gz.sig">Signature</a></td> | ||
605 | </tr> | ||
606 | <tr> | ||
607 | <td class="filename"><a href='download.php?file=miniupnpc-2.1.20190824.tar.gz'>miniupnpc-2.1.20190824.tar.gz</a></td> | ||
608 | <td class="filesize">94564</td> | ||
609 | <td class="filedate">24/08/2019 09:12:50 +0000</td> | ||
610 | <td class="comment">MiniUPnP client source code</td> | ||
611 | <td><a href="miniupnpc-2.1.20190824.tar.gz.sig">Signature</a></td> | ||
612 | </tr> | ||
613 | <tr> | ||
614 | <td class="filename"><a href='download.php?file=miniupnpd-2.1.20190630.tar.gz'>miniupnpd-2.1.20190630.tar.gz</a></td> | ||
615 | <td class="filesize">240466</td> | ||
616 | <td class="filedate">30/06/2019 20:27:38 +0000</td> | ||
617 | <td class="comment">MiniUPnP daemon source code</td> | ||
618 | <td><a href="miniupnpd-2.1.20190630.tar.gz.sig">Signature</a></td> | ||
619 | </tr> | ||
620 | <tr> | ||
621 | <td class="filename"><a href='download.php?file=miniupnpd-2.1.20190625.tar.gz'>miniupnpd-2.1.20190625.tar.gz</a></td> | ||
622 | <td class="filesize">240120</td> | ||
623 | <td class="filedate">25/06/2019 21:33:49 +0000</td> | ||
624 | <td class="comment">MiniUPnP daemon source code</td> | ||
625 | <td><a href="miniupnpd-2.1.20190625.tar.gz.sig">Signature</a></td> | ||
626 | </tr> | ||
627 | <tr> | ||
628 | <td class="filename"><a href='download.php?file=miniupnpc-2.1.20190625.tar.gz'>miniupnpc-2.1.20190625.tar.gz</a></td> | ||
629 | <td class="filesize">94461</td> | ||
630 | <td class="filedate">25/06/2019 21:33:26 +0000</td> | ||
631 | <td class="comment">MiniUPnP client source code</td> | ||
632 | <td><a href="miniupnpc-2.1.20190625.tar.gz.sig">Signature</a></td> | ||
633 | </tr> | ||
634 | <tr> | ||
635 | <td class="filename"><a href='download.php?file=miniupnpd-2.1.20190502.tar.gz'>miniupnpd-2.1.20190502.tar.gz</a></td> | ||
636 | <td class="filesize">236052</td> | ||
637 | <td class="filedate">02/05/2019 17:22:23 +0000</td> | ||
638 | <td class="comment">MiniUPnP daemon source code</td> | ||
639 | <td><a href="miniupnpd-2.1.20190502.tar.gz.sig">Signature</a></td> | ||
640 | </tr> | ||
641 | <tr> | ||
642 | <td class="filename"><a href='download.php?file=miniupnpc-2.1.20190408.tar.gz'>miniupnpc-2.1.20190408.tar.gz</a></td> | ||
643 | <td class="filesize">94216</td> | ||
644 | <td class="filedate">08/04/2019 12:50:21 +0000</td> | ||
645 | <td class="comment">MiniUPnP client source code</td> | ||
646 | <td><a href="miniupnpc-2.1.20190408.tar.gz.sig">Signature</a></td> | ||
647 | </tr> | ||
648 | <tr> | ||
649 | <td class="filename"><a href='download.php?file=miniupnpd-2.1.20190408.tar.gz'>miniupnpd-2.1.20190408.tar.gz</a></td> | ||
650 | <td class="filesize">235989</td> | ||
651 | <td class="filedate">08/04/2019 12:50:01 +0000</td> | ||
652 | <td class="comment">MiniUPnP daemon source code</td> | ||
653 | <td><a href="miniupnpd-2.1.20190408.tar.gz.sig">Signature</a></td> | ||
654 | </tr> | ||
655 | <tr> | ||
656 | <td class="filename"><a href='download.php?file=miniupnpc-2.1.20190403.tar.gz'>miniupnpc-2.1.20190403.tar.gz</a></td> | ||
657 | <td class="filesize">94204</td> | ||
658 | <td class="filedate">03/04/2019 15:41:36 +0000</td> | ||
659 | <td class="comment">MiniUPnP client source code</td> | ||
660 | <td><a href="miniupnpc-2.1.20190403.tar.gz.sig">Signature</a></td> | ||
661 | </tr> | ||
662 | <tr> | ||
663 | <td class="filename"><a href='download.php?file=miniupnpd-2.1.20190403.tar.gz'>miniupnpd-2.1.20190403.tar.gz</a></td> | ||
664 | <td class="filesize">235909</td> | ||
665 | <td class="filedate">03/04/2019 15:41:17 +0000</td> | ||
666 | <td class="comment">MiniUPnP daemon source code</td> | ||
667 | <td><a href="miniupnpd-2.1.20190403.tar.gz.sig">Signature</a></td> | ||
668 | </tr> | ||
669 | <tr> | ||
670 | <td class="filename"><a href='download.php?file=minissdpd-1.5.20190210.tar.gz'>minissdpd-1.5.20190210.tar.gz</a></td> | ||
671 | <td class="filesize">37227</td> | ||
672 | <td class="filedate">10/02/2019 15:21:49 +0000</td> | ||
673 | <td class="comment">MiniSSDPd source code</td> | ||
674 | <td><a href="minissdpd-1.5.20190210.tar.gz.sig">Signature</a></td> | ||
675 | </tr> | ||
676 | <tr> | ||
677 | <td class="filename"><a href='download.php?file=miniupnpc-2.1.20190210.tar.gz'>miniupnpc-2.1.20190210.tar.gz</a></td> | ||
678 | <td class="filesize">94125</td> | ||
679 | <td class="filedate">10/02/2019 12:46:09 +0000</td> | ||
680 | <td class="comment">MiniUPnP client source code</td> | ||
681 | <td><a href="miniupnpc-2.1.20190210.tar.gz.sig">Signature</a></td> | ||
682 | </tr> | ||
683 | <tr> | ||
684 | <td class="filename"><a href='download.php?file=miniupnpd-2.1.20190210.tar.gz'>miniupnpd-2.1.20190210.tar.gz</a></td> | ||
685 | <td class="filesize">235093</td> | ||
686 | <td class="filedate">10/02/2019 11:20:11 +0000</td> | ||
687 | <td class="comment">MiniUPnP daemon source code</td> | ||
688 | <td><a href="miniupnpd-2.1.20190210.tar.gz.sig">Signature</a></td> | ||
689 | </tr> | ||
690 | <tr> | ||
691 | <td class="filename"><a href='download.php?file=miniupnpd-2.1.20180706.tar.gz'>miniupnpd-2.1.20180706.tar.gz</a></td> | ||
692 | <td class="filesize">233675</td> | ||
693 | <td class="filedate">06/07/2018 12:44:24 +0000</td> | ||
694 | <td class="comment">MiniUPnP daemon source code</td> | ||
695 | <td><a href="miniupnpd-2.1.20180706.tar.gz.sig">Signature</a></td> | ||
696 | </tr> | ||
697 | <tr> | ||
698 | <td class="filename"><a href='download.php?file=miniupnpd-2.1.tar.gz'>miniupnpd-2.1.tar.gz</a></td> | ||
699 | <td class="filesize">225458</td> | ||
700 | <td class="filedate">08/05/2018 21:50:32 +0000</td> | ||
701 | <td class="comment">MiniUPnP daemon release source code</td> | ||
702 | <td><a href="miniupnpd-2.1.tar.gz.sig">Signature</a></td> | ||
703 | </tr> | ||
704 | <tr> | ||
705 | <td class="filename"><a href='download.php?file=miniupnpc-2.1.tar.gz'>miniupnpc-2.1.tar.gz</a></td> | ||
706 | <td class="filesize">91914</td> | ||
707 | <td class="filedate">07/05/2018 11:10:59 +0000</td> | ||
708 | <td class="comment">MiniUPnP client release source code</td> | ||
709 | <td><a href="miniupnpc-2.1.tar.gz.sig">Signature</a></td> | ||
710 | </tr> | ||
711 | <tr> | ||
712 | <td class="filename"><a href='download.php?file=miniupnpd-2.0.20180503.tar.gz'>miniupnpd-2.0.20180503.tar.gz</a></td> | ||
713 | <td class="filesize">225454</td> | ||
714 | <td class="filedate">03/05/2018 08:33:10 +0000</td> | ||
715 | <td class="comment">MiniUPnP daemon source code</td> | ||
716 | <td></td> | ||
717 | </tr> | ||
718 | <tr> | ||
719 | <td class="filename"><a href='download.php?file=miniupnpc-2.0.20180503.tar.gz'>miniupnpc-2.0.20180503.tar.gz</a></td> | ||
720 | <td class="filesize">88207</td> | ||
721 | <td class="filedate">03/05/2018 08:31:22 +0000</td> | ||
722 | <td class="comment">MiniUPnP client source code</td> | ||
723 | <td></td> | ||
724 | </tr> | ||
725 | <tr> | ||
726 | <td class="filename"><a href='download.php?file=miniupnpd-2.0.20180422.tar.gz'>miniupnpd-2.0.20180422.tar.gz</a></td> | ||
727 | <td class="filesize">224942</td> | ||
728 | <td class="filedate">22/04/2018 19:48:54 +0000</td> | ||
729 | <td class="comment">MiniUPnP daemon source code</td> | ||
730 | <td></td> | ||
731 | </tr> | ||
732 | <tr> | ||
733 | <td class="filename"><a href='download.php?file=miniupnpd-2.0.20180412.tar.gz'>miniupnpd-2.0.20180412.tar.gz</a></td> | ||
734 | <td class="filesize">224831</td> | ||
735 | <td class="filedate">12/04/2018 08:16:25 +0000</td> | ||
736 | <td class="comment">MiniUPnP daemon source code</td> | ||
737 | <td></td> | ||
738 | </tr> | ||
739 | <tr> | ||
740 | <td class="filename"><a href='download.php?file=miniupnpd-2.0.20180410.tar.gz'>miniupnpd-2.0.20180410.tar.gz</a></td> | ||
741 | <td class="filesize">224736</td> | ||
742 | <td class="filedate">10/04/2018 07:58:28 +0000</td> | ||
743 | <td class="comment">MiniUPnP daemon source code</td> | ||
744 | <td></td> | ||
745 | </tr> | ||
746 | <tr> | ||
747 | <td class="filename"><a href='download.php?file=miniupnpc-2.0.20180410.tar.gz'>miniupnpc-2.0.20180410.tar.gz</a></td> | ||
748 | <td class="filesize">87363</td> | ||
749 | <td class="filedate">10/04/2018 07:52:55 +0000</td> | ||
750 | <td class="comment">MiniUPnP client source code</td> | ||
751 | <td></td> | ||
752 | </tr> | ||
753 | <tr> | ||
754 | <td class="filename"><a href='download.php?file=miniupnpc-2.0.20180406.tar.gz'>miniupnpc-2.0.20180406.tar.gz</a></td> | ||
755 | <td class="filesize">87374</td> | ||
756 | <td class="filedate">06/04/2018 10:55:21 +0000</td> | ||
757 | <td class="comment">MiniUPnP client source code</td> | ||
758 | <td></td> | ||
759 | </tr> | ||
760 | <tr> | ||
761 | <td class="filename"><a href='download.php?file=minissdpd-1.5.20180223.tar.gz'>minissdpd-1.5.20180223.tar.gz</a></td> | ||
762 | <td class="filesize">36179</td> | ||
763 | <td class="filedate">23/02/2018 14:24:07 +0000</td> | ||
764 | <td class="comment">MiniSSDPd source code</td> | ||
765 | <td></td> | ||
766 | </tr> | ||
767 | <tr> | ||
768 | <td class="filename"><a href='download.php?file=miniupnpc-2.0.20180222.tar.gz'>miniupnpc-2.0.20180222.tar.gz</a></td> | ||
769 | <td class="filesize">87018</td> | ||
770 | <td class="filedate">22/02/2018 15:09:24 +0000</td> | ||
771 | <td class="comment">MiniUPnP client source code</td> | ||
772 | <td></td> | ||
773 | </tr> | ||
774 | <tr> | ||
775 | <td class="filename"><a href='download.php?file=miniupnpd-2.0.20180222.tar.gz'>miniupnpd-2.0.20180222.tar.gz</a></td> | ||
776 | <td class="filesize">223697</td> | ||
777 | <td class="filedate">22/02/2018 15:09:14 +0000</td> | ||
778 | <td class="comment">MiniUPnP daemon source code</td> | ||
779 | <td></td> | ||
780 | </tr> | ||
781 | <tr> | ||
782 | <td class="filename"><a href='download.php?file=miniupnpd-2.0.20180203.tar.gz'>miniupnpd-2.0.20180203.tar.gz</a></td> | ||
783 | <td class="filesize">223084</td> | ||
784 | <td class="filedate">03/02/2018 22:34:46 +0000</td> | ||
785 | <td class="comment">MiniUPnP daemon source code</td> | ||
786 | <td></td> | ||
787 | </tr> | ||
788 | <tr> | ||
789 | <td class="filename"><a href='download.php?file=miniupnpc-2.0.20180203.tar.gz'>miniupnpc-2.0.20180203.tar.gz</a></td> | ||
790 | <td class="filesize">86772</td> | ||
791 | <td class="filedate">03/02/2018 22:34:32 +0000</td> | ||
792 | <td class="comment">MiniUPnP client source code</td> | ||
793 | <td></td> | ||
794 | </tr> | ||
795 | <tr> | ||
796 | <td class="filename"><a href='download.php?file=minissdpd-1.5.20180203.tar.gz'>minissdpd-1.5.20180203.tar.gz</a></td> | ||
797 | <td class="filesize">35848</td> | ||
798 | <td class="filedate">03/02/2018 22:33:08 +0000</td> | ||
799 | <td class="comment">MiniSSDPd source code</td> | ||
800 | <td></td> | ||
801 | </tr> | ||
802 | <tr> | ||
803 | <td class="filename"><a href='download.php?file=miniupnpc-2.0.20171212.tar.gz'>miniupnpc-2.0.20171212.tar.gz</a></td> | ||
804 | <td class="filesize">86607</td> | ||
805 | <td class="filedate">12/12/2017 12:03:38 +0000</td> | ||
806 | <td class="comment">MiniUPnP client source code</td> | ||
807 | <td></td> | ||
808 | </tr> | ||
809 | <tr> | ||
810 | <td class="filename"><a href='download.php?file=miniupnpd-2.0.20171212.tar.gz'>miniupnpd-2.0.20171212.tar.gz</a></td> | ||
811 | <td class="filesize">222617</td> | ||
812 | <td class="filedate">12/12/2017 12:03:32 +0000</td> | ||
813 | <td class="comment">MiniUPnP daemon source code</td> | ||
814 | <td></td> | ||
815 | </tr> | ||
816 | <tr> | ||
817 | <td class="filename"><a href='download.php?file=miniupnpc-2.0.20171102.tar.gz'>miniupnpc-2.0.20171102.tar.gz</a></td> | ||
818 | <td class="filesize">86363</td> | ||
819 | <td class="filedate">02/11/2017 17:58:34 +0000</td> | ||
820 | <td class="comment">MiniUPnP client source code</td> | ||
821 | <td></td> | ||
822 | </tr> | ||
823 | <tr> | ||
824 | <td class="filename"><a href='download.php?file=miniupnpc-2.0.20170509.tar.gz'>miniupnpc-2.0.20170509.tar.gz</a></td> | ||
825 | <td class="filesize">86055</td> | ||
826 | <td class="filedate">09/05/2017 10:14:56 +0000</td> | ||
827 | <td class="comment">MiniUPnP client source code</td> | ||
828 | <td></td> | ||
829 | </tr> | ||
830 | <tr> | ||
831 | <td class="filename"><a href='download.php?file=miniupnpc-2.0.20170421.tar.gz'>miniupnpc-2.0.20170421.tar.gz</a></td> | ||
832 | <td class="filesize">85984</td> | ||
833 | <td class="filedate">21/04/2017 12:02:26 +0000</td> | ||
834 | <td class="comment">MiniUPnP client source code</td> | ||
835 | <td></td> | ||
836 | </tr> | ||
837 | <tr> | ||
838 | <td class="filename"><a href='download.php?file=miniupnpd-2.0.20170421.tar.gz'>miniupnpd-2.0.20170421.tar.gz</a></td> | ||
839 | <td class="filesize">219191</td> | ||
840 | <td class="filedate">21/04/2017 12:02:06 +0000</td> | ||
841 | <td class="comment">MiniUPnP daemon source code</td> | ||
842 | <td></td> | ||
843 | </tr> | ||
844 | <tr> | ||
845 | <td class="filename"><a href='download.php?file=miniupnpd-2.0.20161216.tar.gz'>miniupnpd-2.0.20161216.tar.gz</a></td> | ||
846 | <td class="filesize">218119</td> | ||
847 | <td class="filedate">16/12/2016 09:34:08 +0000</td> | ||
848 | <td class="comment">MiniUPnP daemon source code</td> | ||
849 | <td></td> | ||
850 | </tr> | ||
851 | <tr> | ||
852 | <td class="filename"><a href='download.php?file=miniupnpc-2.0.20161216.tar.gz'>miniupnpc-2.0.20161216.tar.gz</a></td> | ||
853 | <td class="filesize">85780</td> | ||
854 | <td class="filedate">16/12/2016 09:34:03 +0000</td> | ||
855 | <td class="comment">MiniUPnP client source code</td> | ||
856 | <td></td> | ||
857 | </tr> | ||
858 | <tr> | ||
859 | <td class="filename"><a href='download.php?file=minissdpd-1.5.20161216.tar.gz'>minissdpd-1.5.20161216.tar.gz</a></td> | ||
860 | <td class="filesize">35078</td> | ||
861 | <td class="filedate">16/12/2016 09:33:59 +0000</td> | ||
862 | <td class="comment">MiniSSDPd source code</td> | ||
863 | <td></td> | ||
864 | </tr> | ||
865 | <tr> | ||
866 | <td class="filename"><a href='download.php?file=miniupnpd-2.0.tar.gz'>miniupnpd-2.0.tar.gz</a></td> | ||
867 | <td class="filesize">217802</td> | ||
868 | <td class="filedate">19/04/2016 21:12:01 +0000</td> | ||
869 | <td class="comment">MiniUPnP daemon release source code</td> | ||
870 | <td><a href="miniupnpd-2.0.tar.gz.sig">Signature</a></td> | ||
871 | </tr> | ||
872 | <tr> | ||
873 | <td class="filename"><a href='download.php?file=miniupnpc-2.0.tar.gz'>miniupnpc-2.0.tar.gz</a></td> | ||
874 | <td class="filesize">85287</td> | ||
875 | <td class="filedate">19/04/2016 21:07:52 +0000</td> | ||
876 | <td class="comment">MiniUPnP client release source code</td> | ||
877 | <td></td> | ||
878 | </tr> | ||
879 | <tr> | ||
880 | <td class="filename"><a href='download.php?file=minissdpd-1.5.20160301.tar.gz'>minissdpd-1.5.20160301.tar.gz</a></td> | ||
881 | <td class="filesize">34827</td> | ||
882 | <td class="filedate">01/03/2016 18:08:23 +0000</td> | ||
883 | <td class="comment">MiniSSDPd source code</td> | ||
884 | <td></td> | ||
885 | </tr> | ||
886 | <tr> | ||
887 | <td class="filename"><a href='download.php?file=miniupnpd-1.9.20160222.tar.gz'>miniupnpd-1.9.20160222.tar.gz</a></td> | ||
888 | <td class="filesize">217541</td> | ||
889 | <td class="filedate">22/02/2016 10:21:40 +0000</td> | ||
890 | <td class="comment">MiniUPnP daemon source code</td> | ||
891 | <td></td> | ||
892 | </tr> | ||
893 | <tr> | ||
894 | <td class="filename"><a href='download.php?file=miniupnpd-1.9.20160216.tar.gz'>miniupnpd-1.9.20160216.tar.gz</a></td> | ||
895 | <td class="filesize">217007</td> | ||
896 | <td class="filedate">16/02/2016 12:41:44 +0000</td> | ||
897 | <td class="comment">MiniUPnP daemon source code</td> | ||
898 | <td></td> | ||
899 | </tr> | ||
900 | <tr> | ||
901 | <td class="filename"><a href='download.php?file=miniupnpd-1.9.20160212.tar.gz'>miniupnpd-1.9.20160212.tar.gz</a></td> | ||
902 | <td class="filesize">215866</td> | ||
903 | <td class="filedate">12/02/2016 15:22:04 +0000</td> | ||
904 | <td class="comment">MiniUPnP daemon source code</td> | ||
905 | <td></td> | ||
906 | </tr> | ||
907 | <tr> | ||
908 | <td class="filename"><a href='download.php?file=miniupnpd-1.9.20160209.tar.gz'>miniupnpd-1.9.20160209.tar.gz</a></td> | ||
909 | <td class="filesize">213416</td> | ||
910 | <td class="filedate">09/02/2016 09:47:03 +0000</td> | ||
911 | <td class="comment">MiniUPnP daemon source code</td> | ||
912 | <td></td> | ||
913 | </tr> | ||
914 | <tr> | ||
915 | <td class="filename"><a href='download.php?file=miniupnpc-1.9.20160209.tar.gz'>miniupnpc-1.9.20160209.tar.gz</a></td> | ||
916 | <td class="filesize">85268</td> | ||
917 | <td class="filedate">09/02/2016 09:44:50 +0000</td> | ||
918 | <td class="comment">MiniUPnP client source code</td> | ||
919 | <td></td> | ||
920 | </tr> | ||
921 | <tr> | ||
922 | <td class="filename"><a href='download.php?file=minissdpd-1.5.20160119.tar.gz'>minissdpd-1.5.20160119.tar.gz</a></td> | ||
923 | <td class="filesize">34711</td> | ||
924 | <td class="filedate">19/01/2016 13:39:51 +0000</td> | ||
925 | <td class="comment">MiniSSDPd source code</td> | ||
926 | <td></td> | ||
927 | </tr> | ||
928 | <tr> | ||
929 | <td class="filename"><a href='download.php?file=miniupnpd-1.9.20160113.tar.gz'>miniupnpd-1.9.20160113.tar.gz</a></td> | ||
930 | <td class="filesize">211437</td> | ||
931 | <td class="filedate">13/01/2016 16:03:14 +0000</td> | ||
932 | <td class="comment">MiniUPnP daemon source code</td> | ||
933 | <td></td> | ||
934 | </tr> | ||
935 | <tr> | ||
936 | <td class="filename"><a href='download.php?file=minissdpd-1.5.tar.gz'>minissdpd-1.5.tar.gz</a></td> | ||
937 | <td class="filesize">34404</td> | ||
938 | <td class="filedate">13/01/2016 15:26:53 +0000</td> | ||
939 | <td class="comment">MiniSSDPd release source code</td> | ||
940 | <td></td> | ||
941 | </tr> | ||
942 | <tr> | ||
943 | <td class="filename"><a href='download.php?file=miniupnpd-1.9.20151212.tar.gz'>miniupnpd-1.9.20151212.tar.gz</a></td> | ||
944 | <td class="filesize">210912</td> | ||
945 | <td class="filedate">12/12/2015 10:06:07 +0000</td> | ||
946 | <td class="comment">MiniUPnP daemon source code</td> | ||
947 | <td></td> | ||
948 | </tr> | ||
949 | <tr> | ||
950 | <td class="filename"><a href='download.php?file=miniupnpd-1.9.20151118.tar.gz'>miniupnpd-1.9.20151118.tar.gz</a></td> | ||
951 | <td class="filesize">210322</td> | ||
952 | <td class="filedate">18/11/2015 08:59:46 +0000</td> | ||
953 | <td class="comment">MiniUPnP daemon source code</td> | ||
954 | <td></td> | ||
955 | </tr> | ||
956 | <tr> | ||
957 | <td class="filename"><a href='download.php?file=miniupnpc-1.9.20151026.tar.gz'>miniupnpc-1.9.20151026.tar.gz</a></td> | ||
958 | <td class="filesize">84208</td> | ||
959 | <td class="filedate">26/10/2015 17:07:34 +0000</td> | ||
960 | <td class="comment">MiniUPnP client source code</td> | ||
961 | <td></td> | ||
962 | </tr> | ||
963 | <tr> | ||
964 | <td class="filename"><a href='download.php?file=miniupnpc-1.9.20151008.tar.gz'>miniupnpc-1.9.20151008.tar.gz</a></td> | ||
965 | <td class="filesize">83538</td> | ||
966 | <td class="filedate">08/10/2015 16:22:28 +0000</td> | ||
967 | <td class="comment">MiniUPnP client source code</td> | ||
968 | <td></td> | ||
969 | </tr> | ||
970 | <tr> | ||
971 | <td class="filename"><a href='download.php?file=miniupnpd-1.9.20150922.tar.gz'>miniupnpd-1.9.20150922.tar.gz</a></td> | ||
972 | <td class="filesize">208700</td> | ||
973 | <td class="filedate">22/09/2015 10:21:50 +0000</td> | ||
974 | <td class="comment">MiniUPnP daemon source code</td> | ||
975 | <td></td> | ||
976 | </tr> | ||
977 | <tr> | ||
978 | <td class="filename"><a href='download.php?file=upnpc-exe-win32-20150918.zip'>upnpc-exe-win32-20150918.zip</a></td> | ||
979 | <td class="filesize">100004</td> | ||
980 | <td class="filedate">18/09/2015 12:50:51 +0000</td> | ||
981 | <td class="comment">Windows executable</td> | ||
982 | <td></td> | ||
983 | </tr> | ||
984 | <tr> | ||
985 | <td class="filename"><a href='download.php?file=miniupnpc-1.9.20150917.tar.gz'>miniupnpc-1.9.20150917.tar.gz</a></td> | ||
986 | <td class="filesize">82609</td> | ||
987 | <td class="filedate">17/09/2015 14:09:14 +0000</td> | ||
988 | <td class="comment">MiniUPnP client source code</td> | ||
989 | <td></td> | ||
990 | </tr> | ||
991 | <tr> | ||
992 | <td class="filename"><a href='download.php?file=upnpc-exe-win32-20150824.zip'>upnpc-exe-win32-20150824.zip</a></td> | ||
993 | <td class="filesize">99520</td> | ||
994 | <td class="filedate">24/08/2015 15:25:18 +0000</td> | ||
995 | <td class="comment">Windows executable</td> | ||
996 | <td></td> | ||
997 | </tr> | ||
998 | <tr> | ||
999 | <td class="filename"><a href='download.php?file=minissdpd-1.4.tar.gz'>minissdpd-1.4.tar.gz</a></td> | ||
1000 | <td class="filesize">32017</td> | ||
1001 | <td class="filedate">06/08/2015 13:38:37 +0000</td> | ||
1002 | <td class="comment">MiniSSDPd release source code</td> | ||
1003 | <td></td> | ||
1004 | </tr> | ||
1005 | <tr> | ||
1006 | <td class="filename"><a href='download.php?file=miniupnpc-1.9.20150730.tar.gz'>miniupnpc-1.9.20150730.tar.gz</a></td> | ||
1007 | <td class="filesize">81431</td> | ||
1008 | <td class="filedate">29/07/2015 22:10:00 +0000</td> | ||
1009 | <td class="comment">MiniUPnP client source code</td> | ||
1010 | <td></td> | ||
1011 | </tr> | ||
1012 | <tr> | ||
1013 | <td class="filename"><a href='download.php?file=miniupnpd-1.9.20150721.tar.gz'>miniupnpd-1.9.20150721.tar.gz</a></td> | ||
1014 | <td class="filesize">207562</td> | ||
1015 | <td class="filedate">21/07/2015 13:35:51 +0000</td> | ||
1016 | <td class="comment">MiniUPnP daemon source code</td> | ||
1017 | <td></td> | ||
1018 | </tr> | ||
1019 | <tr> | ||
1020 | <td class="filename"><a href='download.php?file=miniupnpc-1.9.20150721.tar.gz'>miniupnpc-1.9.20150721.tar.gz</a></td> | ||
1021 | <td class="filesize">80521</td> | ||
1022 | <td class="filedate">21/07/2015 13:27:00 +0000</td> | ||
1023 | <td class="comment">MiniUPnP client source code</td> | ||
1024 | <td></td> | ||
1025 | </tr> | ||
1026 | <tr> | ||
1027 | <td class="filename"><a href='download.php?file=libnatpmp-20150609.tar.gz'>libnatpmp-20150609.tar.gz</a></td> | ||
1028 | <td class="filesize">24392</td> | ||
1029 | <td class="filedate">09/06/2015 15:40:28 +0000</td> | ||
1030 | <td class="comment">libnatpmp source code</td> | ||
1031 | <td></td> | ||
1032 | </tr> | ||
1033 | <tr> | ||
1034 | <td class="filename"><a href='download.php?file=miniupnpc-1.9.20150609.tar.gz'>miniupnpc-1.9.20150609.tar.gz</a></td> | ||
1035 | <td class="filesize">79311</td> | ||
1036 | <td class="filedate">09/06/2015 15:39:48 +0000</td> | ||
1037 | <td class="comment">MiniUPnP client source code</td> | ||
1038 | <td></td> | ||
1039 | </tr> | ||
1040 | <tr> | ||
1041 | <td class="filename"><a href='download.php?file=miniupnpd-1.9.20150609.tar.gz'>miniupnpd-1.9.20150609.tar.gz</a></td> | ||
1042 | <td class="filesize">207088</td> | ||
1043 | <td class="filedate">09/06/2015 15:39:36 +0000</td> | ||
1044 | <td class="comment">MiniUPnP daemon source code</td> | ||
1045 | <td></td> | ||
1046 | </tr> | ||
1047 | <tr> | ||
1048 | <td class="filename"><a href='download.php?file=minissdpd-1.3.20150527.tar.gz'>minissdpd-1.3.20150527.tar.gz</a></td> | ||
1049 | <td class="filesize">31025</td> | ||
1050 | <td class="filedate">27/05/2015 09:17:15 +0000</td> | ||
1051 | <td class="comment">MiniSSDPd source code</td> | ||
1052 | <td></td> | ||
1053 | </tr> | ||
1054 | <tr> | ||
1055 | <td class="filename"><a href='download.php?file=miniupnpc-1.9.20150522.tar.gz'>miniupnpc-1.9.20150522.tar.gz</a></td> | ||
1056 | <td class="filesize">79080</td> | ||
1057 | <td class="filedate">22/05/2015 11:02:27 +0000</td> | ||
1058 | <td class="comment">MiniUPnP client source code</td> | ||
1059 | <td></td> | ||
1060 | </tr> | ||
1061 | <tr> | ||
1062 | <td class="filename"><a href='download.php?file=minissdpd-1.3.20150522.tar.gz'>minissdpd-1.3.20150522.tar.gz</a></td> | ||
1063 | <td class="filesize">30334</td> | ||
1064 | <td class="filedate">22/05/2015 11:02:04 +0000</td> | ||
1065 | <td class="comment">MiniSSDPd source code</td> | ||
1066 | <td></td> | ||
1067 | </tr> | ||
1068 | <tr> | ||
1069 | <td class="filename"><a href='download.php?file=miniupnpd-1.9.20150430.tar.gz'>miniupnpd-1.9.20150430.tar.gz</a></td> | ||
1070 | <td class="filesize">205930</td> | ||
1071 | <td class="filedate">30/04/2015 09:09:27 +0000</td> | ||
1072 | <td class="comment">MiniUPnP daemon source code</td> | ||
1073 | <td></td> | ||
1074 | </tr> | ||
1075 | <tr> | ||
1076 | <td class="filename"><a href='download.php?file=miniupnpc-1.9.20150430.tar.gz'>miniupnpc-1.9.20150430.tar.gz</a></td> | ||
1077 | <td class="filesize">78459</td> | ||
1078 | <td class="filedate">30/04/2015 08:39:31 +0000</td> | ||
1079 | <td class="comment">MiniUPnP client source code</td> | ||
1080 | <td></td> | ||
1081 | </tr> | ||
1082 | <tr> | ||
1083 | <td class="filename"><a href='download.php?file=miniupnpc-1.9.20150427.tar.gz'>miniupnpc-1.9.20150427.tar.gz</a></td> | ||
1084 | <td class="filesize">78424</td> | ||
1085 | <td class="filedate">27/04/2015 16:08:42 +0000</td> | ||
1086 | <td class="comment">MiniUPnP client source code</td> | ||
1087 | <td></td> | ||
1088 | </tr> | ||
1089 | <tr> | ||
1090 | <td class="filename"><a href='download.php?file=miniupnpd-1.9.20150427.tar.gz'>miniupnpd-1.9.20150427.tar.gz</a></td> | ||
1091 | <td class="filesize">191157</td> | ||
1092 | <td class="filedate">27/04/2015 16:08:27 +0000</td> | ||
1093 | <td class="comment">MiniUPnP daemon source code</td> | ||
1094 | <td></td> | ||
1095 | </tr> | ||
1096 | <tr> | ||
1097 | <td class="filename"><a href='download.php?file=miniupnpd-1.9.20150307.tar.gz'>miniupnpd-1.9.20150307.tar.gz</a></td> | ||
1098 | <td class="filesize">190913</td> | ||
1099 | <td class="filedate">07/03/2015 16:11:51 +0000</td> | ||
1100 | <td class="comment">MiniUPnP daemon source code</td> | ||
1101 | <td></td> | ||
1102 | </tr> | ||
1103 | <tr> | ||
1104 | <td class="filename"><a href='download.php?file=miniupnpc-1.9.20150206.tar.gz'>miniupnpc-1.9.20150206.tar.gz</a></td> | ||
1105 | <td class="filesize">76864</td> | ||
1106 | <td class="filedate">06/02/2015 14:38:00 +0000</td> | ||
1107 | <td class="comment">MiniUPnP client source code</td> | ||
1108 | <td></td> | ||
1109 | </tr> | ||
1110 | <tr> | ||
1111 | <td class="filename"><a href='download.php?file=miniupnpd-1.9.20141209.tar.gz'>miniupnpd-1.9.20141209.tar.gz</a></td> | ||
1112 | <td class="filesize">193183</td> | ||
1113 | <td class="filedate">09/12/2014 09:58:34 +0000</td> | ||
1114 | <td class="comment">MiniUPnP daemon source code</td> | ||
1115 | <td></td> | ||
1116 | </tr> | ||
1117 | <tr> | ||
1118 | <td class="filename"><a href='download.php?file=minissdpd-1.3.tar.gz'>minissdpd-1.3.tar.gz</a></td> | ||
1119 | <td class="filesize">30326</td> | ||
1120 | <td class="filedate">09/12/2014 09:57:30 +0000</td> | ||
1121 | <td class="comment">MiniSSDPd release source code</td> | ||
1122 | <td></td> | ||
1123 | </tr> | ||
1124 | <tr> | ||
1125 | <td class="filename"><a href='download.php?file=minissdpd-1.2.20141204.tar.gz'>minissdpd-1.2.20141204.tar.gz</a></td> | ||
1126 | <td class="filesize">26978</td> | ||
1127 | <td class="filedate">04/12/2014 10:55:26 +0000</td> | ||
1128 | <td class="comment">MiniSSDPd source code</td> | ||
1129 | <td></td> | ||
1130 | </tr> | ||
1131 | <tr> | ||
1132 | <td class="filename"><a href='download.php?file=miniupnpd-1.9.20141204.tar.gz'>miniupnpd-1.9.20141204.tar.gz</a></td> | ||
1133 | <td class="filesize">192597</td> | ||
1134 | <td class="filedate">04/12/2014 10:55:03 +0000</td> | ||
1135 | <td class="comment">MiniUPnP daemon source code</td> | ||
1136 | <td></td> | ||
1137 | </tr> | ||
1138 | <tr> | ||
1139 | <td class="filename"><a href='download.php?file=minissdpd-1.2.20141128.tar.gz'>minissdpd-1.2.20141128.tar.gz</a></td> | ||
1140 | <td class="filesize">26795</td> | ||
1141 | <td class="filedate">28/11/2014 16:33:10 +0000</td> | ||
1142 | <td class="comment">MiniSSDPd source code</td> | ||
1143 | <td></td> | ||
1144 | </tr> | ||
1145 | <tr> | ||
1146 | <td class="filename"><a href='download.php?file=miniupnpd-1.9.20141128.tar.gz'>miniupnpd-1.9.20141128.tar.gz</a></td> | ||
1147 | <td class="filesize">192558</td> | ||
1148 | <td class="filedate">28/11/2014 13:31:36 +0000</td> | ||
1149 | <td class="comment">MiniUPnP daemon source code</td> | ||
1150 | <td></td> | ||
1151 | </tr> | ||
1152 | <tr> | ||
1153 | <td class="filename"><a href='download.php?file=miniupnpc-1.9.20141128.tar.gz'>miniupnpc-1.9.20141128.tar.gz</a></td> | ||
1154 | <td class="filesize">76541</td> | ||
1155 | <td class="filedate">28/11/2014 13:31:15 +0000</td> | ||
1156 | <td class="comment">MiniUPnP client source code</td> | ||
1157 | <td></td> | ||
1158 | </tr> | ||
1159 | <tr> | ||
1160 | <td class="filename"><a href='download.php?file=miniupnpc-1.9.20141117.tar.gz'>miniupnpc-1.9.20141117.tar.gz</a></td> | ||
1161 | <td class="filesize">73865</td> | ||
1162 | <td class="filedate">17/11/2014 09:51:36 +0000</td> | ||
1163 | <td class="comment">MiniUPnP client source code</td> | ||
1164 | <td></td> | ||
1165 | </tr> | ||
1166 | <tr> | ||
1167 | <td class="filename"><a href='download.php?file=miniupnpc-1.9.20141113.tar.gz'>miniupnpc-1.9.20141113.tar.gz</a></td> | ||
1168 | <td class="filesize">72857</td> | ||
1169 | <td class="filedate">13/11/2014 10:36:44 +0000</td> | ||
1170 | <td class="comment">MiniUPnP client source code</td> | ||
1171 | <td></td> | ||
1172 | </tr> | ||
1173 | <tr> | ||
1174 | <td class="filename"><a href='download.php?file=minissdpd-1.2.20141108.tar.gz'>minissdpd-1.2.20141108.tar.gz</a></td> | ||
1175 | <td class="filesize">22001</td> | ||
1176 | <td class="filedate">08/11/2014 13:55:41 +0000</td> | ||
1177 | <td class="comment">MiniSSDPd source code</td> | ||
1178 | <td></td> | ||
1179 | </tr> | ||
1180 | <tr> | ||
1181 | <td class="filename"><a href='download.php?file=miniupnpc-1.9.20141108.tar.gz'>miniupnpc-1.9.20141108.tar.gz</a></td> | ||
1182 | <td class="filesize">72781</td> | ||
1183 | <td class="filedate">08/11/2014 13:53:48 +0000</td> | ||
1184 | <td class="comment">MiniUPnP client source code</td> | ||
1185 | <td></td> | ||
1186 | </tr> | ||
1187 | <tr> | ||
1188 | <td class="filename"><a href='download.php?file=miniupnpd-1.9.20141108.tar.gz'>miniupnpd-1.9.20141108.tar.gz</a></td> | ||
1189 | <td class="filesize">192413</td> | ||
1190 | <td class="filedate">08/11/2014 13:53:38 +0000</td> | ||
1191 | <td class="comment">MiniUPnP daemon source code</td> | ||
1192 | <td></td> | ||
1193 | </tr> | ||
1194 | <tr> | ||
1195 | <td class="filename"><a href='download.php?file=miniupnpd-1.9.tar.gz'>miniupnpd-1.9.tar.gz</a></td> | ||
1196 | <td class="filesize">192183</td> | ||
1197 | <td class="filedate">27/10/2014 16:45:34 +0000</td> | ||
1198 | <td class="comment">MiniUPnP daemon release source code</td> | ||
1199 | <td></td> | ||
1200 | </tr> | ||
1201 | <tr> | ||
1202 | <td class="filename"><a href='download.php?file=miniupnpc-1.9.20141027.tar.gz'>miniupnpc-1.9.20141027.tar.gz</a></td> | ||
1203 | <td class="filesize">76763</td> | ||
1204 | <td class="filedate">27/10/2014 16:45:25 +0000</td> | ||
1205 | <td class="comment">MiniUPnP client source code</td> | ||
1206 | <td></td> | ||
1207 | </tr> | ||
1208 | <tr> | ||
1209 | <td class="filename"><a href='download.php?file=miniupnpd-1.8.20141022.tar.gz'>miniupnpd-1.8.20141022.tar.gz</a></td> | ||
1210 | <td class="filesize">191630</td> | ||
1211 | <td class="filedate">22/10/2014 09:17:41 +0000</td> | ||
1212 | <td class="comment">MiniUPnP daemon source code</td> | ||
1213 | <td></td> | ||
1214 | </tr> | ||
1215 | <tr> | ||
1216 | <td class="filename"><a href='download.php?file=miniupnpd-1.8.20141021.tar.gz'>miniupnpd-1.8.20141021.tar.gz</a></td> | ||
1217 | <td class="filesize">191270</td> | ||
1218 | <td class="filedate">21/10/2014 14:18:58 +0000</td> | ||
1219 | <td class="comment">MiniUPnP daemon source code</td> | ||
1220 | <td></td> | ||
1221 | </tr> | ||
1222 | <tr> | ||
1223 | <td class="filename"><a href='download.php?file=miniupnpc-1.9.20140911.tar.gz'>miniupnpc-1.9.20140911.tar.gz</a></td> | ||
1224 | <td class="filesize">76855</td> | ||
1225 | <td class="filedate">11/09/2014 14:15:23 +0000</td> | ||
1226 | <td class="comment">MiniUPnP client source code</td> | ||
1227 | <td></td> | ||
1228 | </tr> | ||
1229 | <tr> | ||
1230 | <td class="filename"><a href='download.php?file=minissdpd-1.2.20140906.tar.gz'>minissdpd-1.2.20140906.tar.gz</a></td> | ||
1231 | <td class="filesize">21956</td> | ||
1232 | <td class="filedate">06/09/2014 08:34:10 +0000</td> | ||
1233 | <td class="comment">MiniSSDPd source code</td> | ||
1234 | <td></td> | ||
1235 | </tr> | ||
1236 | <tr> | ||
1237 | <td class="filename"><a href='download.php?file=miniupnpd-1.8.20140906.tar.gz'>miniupnpd-1.8.20140906.tar.gz</a></td> | ||
1238 | <td class="filesize">191183</td> | ||
1239 | <td class="filedate">06/09/2014 08:34:02 +0000</td> | ||
1240 | <td class="comment">MiniUPnP daemon source code</td> | ||
1241 | <td></td> | ||
1242 | </tr> | ||
1243 | <tr> | ||
1244 | <td class="filename"><a href='download.php?file=miniupnpc-1.9.20140906.tar.gz'>miniupnpc-1.9.20140906.tar.gz</a></td> | ||
1245 | <td class="filesize">76791</td> | ||
1246 | <td class="filedate">06/09/2014 08:33:45 +0000</td> | ||
1247 | <td class="comment">MiniUPnP client source code</td> | ||
1248 | <td></td> | ||
1249 | </tr> | ||
1250 | <tr> | ||
1251 | <td class="filename"><a href='download.php?file=miniupnpc-1.9.20140701.tar.gz'>miniupnpc-1.9.20140701.tar.gz</a></td> | ||
1252 | <td class="filesize">76735</td> | ||
1253 | <td class="filedate">01/07/2014 13:06:51 +0000</td> | ||
1254 | <td class="comment">MiniUPnP client source code</td> | ||
1255 | <td></td> | ||
1256 | </tr> | ||
1257 | <tr> | ||
1258 | <td class="filename"><a href='download.php?file=miniupnpc-1.9.20140610.tar.gz'>miniupnpc-1.9.20140610.tar.gz</a></td> | ||
1259 | <td class="filesize">76674</td> | ||
1260 | <td class="filedate">10/06/2014 10:28:27 +0000</td> | ||
1261 | <td class="comment">MiniUPnP client source code</td> | ||
1262 | <td></td> | ||
1263 | </tr> | ||
1264 | <tr> | ||
1265 | <td class="filename"><a href='download.php?file=minissdpd-1.2.20140610.tar.gz'>minissdpd-1.2.20140610.tar.gz</a></td> | ||
1266 | <td class="filesize">21909</td> | ||
1267 | <td class="filedate">10/06/2014 10:03:29 +0000</td> | ||
1268 | <td class="comment">MiniSSDPd source code</td> | ||
1269 | <td></td> | ||
1270 | </tr> | ||
1271 | <tr> | ||
1272 | <td class="filename"><a href='download.php?file=miniupnpd-1.8.20140523.tar.gz'>miniupnpd-1.8.20140523.tar.gz</a></td> | ||
1273 | <td class="filesize">190936</td> | ||
1274 | <td class="filedate">23/05/2014 15:48:03 +0000</td> | ||
1275 | <td class="comment">MiniUPnP daemon source code</td> | ||
1276 | <td></td> | ||
1277 | </tr> | ||
1278 | <tr> | ||
1279 | <td class="filename"><a href='download.php?file=upnpc-exe-win32-20140422.zip'>upnpc-exe-win32-20140422.zip</a></td> | ||
1280 | <td class="filesize">97505</td> | ||
1281 | <td class="filedate">22/04/2014 10:10:07 +0000</td> | ||
1282 | <td class="comment">Windows executable</td> | ||
1283 | <td></td> | ||
1284 | </tr> | ||
1285 | <tr> | ||
1286 | <td class="filename"><a href='download.php?file=miniupnpd-1.8.20140422.tar.gz'>miniupnpd-1.8.20140422.tar.gz</a></td> | ||
1287 | <td class="filesize">187225</td> | ||
1288 | <td class="filedate">22/04/2014 08:58:56 +0000</td> | ||
1289 | <td class="comment">MiniUPnP daemon source code</td> | ||
1290 | <td></td> | ||
1291 | </tr> | ||
1292 | <tr> | ||
1293 | <td class="filename"><a href='download.php?file=miniupnpd-1.8.20140401.tar.gz'>miniupnpd-1.8.20140401.tar.gz</a></td> | ||
1294 | <td class="filesize">183131</td> | ||
1295 | <td class="filedate">01/04/2014 10:07:20 +0000</td> | ||
1296 | <td class="comment">MiniUPnP daemon source code</td> | ||
1297 | <td></td> | ||
1298 | </tr> | ||
1299 | <tr> | ||
1300 | <td class="filename"><a href='download.php?file=miniupnpc-1.9.20140401.tar.gz'>miniupnpc-1.9.20140401.tar.gz</a></td> | ||
1301 | <td class="filesize">74703</td> | ||
1302 | <td class="filedate">01/04/2014 09:49:46 +0000</td> | ||
1303 | <td class="comment">MiniUPnP client source code</td> | ||
1304 | <td></td> | ||
1305 | </tr> | ||
1306 | <tr> | ||
1307 | <td class="filename"><a href='download.php?file=libnatpmp-20140401.tar.gz'>libnatpmp-20140401.tar.gz</a></td> | ||
1308 | <td class="filesize">23302</td> | ||
1309 | <td class="filedate">01/04/2014 09:49:44 +0000</td> | ||
1310 | <td class="comment">libnatpmp source code</td> | ||
1311 | <td></td> | ||
1312 | </tr> | ||
1313 | <tr> | ||
1314 | <td class="filename"><a href='download.php?file=miniupnpd-1.8.20140313.tar.gz'>miniupnpd-1.8.20140313.tar.gz</a></td> | ||
1315 | <td class="filesize">177120</td> | ||
1316 | <td class="filedate">13/03/2014 10:39:11 +0000</td> | ||
1317 | <td class="comment">MiniUPnP daemon source code</td> | ||
1318 | <td></td> | ||
1319 | </tr> | ||
1320 | <tr> | ||
1321 | <td class="filename"><a href='download.php?file=miniupnpd-1.8.20140310.tar.gz'>miniupnpd-1.8.20140310.tar.gz</a></td> | ||
1322 | <td class="filesize">176585</td> | ||
1323 | <td class="filedate">09/03/2014 23:16:49 +0000</td> | ||
1324 | <td class="comment">MiniUPnP daemon source code</td> | ||
1325 | <td></td> | ||
1326 | </tr> | ||
1327 | <tr> | ||
1328 | <td class="filename"><a href='download.php?file=miniupnpd-1.8.20140225.tar.gz'>miniupnpd-1.8.20140225.tar.gz</a></td> | ||
1329 | <td class="filesize">175183</td> | ||
1330 | <td class="filedate">25/02/2014 11:01:29 +0000</td> | ||
1331 | <td class="comment">MiniUPnP daemon source code</td> | ||
1332 | <td></td> | ||
1333 | </tr> | ||
1334 | <tr> | ||
1335 | <td class="filename"><a href='download.php?file=miniupnpd-1.8.20140203.tar.gz'>miniupnpd-1.8.20140203.tar.gz</a></td> | ||
1336 | <td class="filesize">170112</td> | ||
1337 | <td class="filedate">03/02/2014 09:56:05 +0000</td> | ||
1338 | <td class="comment">MiniUPnP daemon source code</td> | ||
1339 | <td></td> | ||
1340 | </tr> | ||
1341 | <tr> | ||
1342 | <td class="filename"><a href='download.php?file=miniupnpc-1.9.tar.gz'>miniupnpc-1.9.tar.gz</a></td> | ||
1343 | <td class="filesize">74230</td> | ||
1344 | <td class="filedate">31/01/2014 13:57:40 +0000</td> | ||
1345 | <td class="comment">MiniUPnP client release source code</td> | ||
1346 | <td></td> | ||
1347 | </tr> | ||
1348 | <tr> | ||
1349 | <td class="filename"><a href='download.php?file=miniupnpd-1.8.20140127.tar.gz'>miniupnpd-1.8.20140127.tar.gz</a></td> | ||
1350 | <td class="filesize">170467</td> | ||
1351 | <td class="filedate">27/01/2014 11:25:34 +0000</td> | ||
1352 | <td class="comment">MiniUPnP daemon source code</td> | ||
1353 | <td></td> | ||
1354 | </tr> | ||
1355 | <tr> | ||
1356 | <td class="filename"><a href='download.php?file=upnpc-exe-win32-20140117.zip'>upnpc-exe-win32-20140117.zip</a></td> | ||
1357 | <td class="filesize">97270</td> | ||
1358 | <td class="filedate">17/01/2014 11:37:53 +0000</td> | ||
1359 | <td class="comment">Windows executable</td> | ||
1360 | <td></td> | ||
1361 | </tr> | ||
1362 | <tr> | ||
1363 | <td class="filename"><a href='download.php?file=miniupnpd-1.8.20131216.tar.gz'>miniupnpd-1.8.20131216.tar.gz</a></td> | ||
1364 | <td class="filesize">170277</td> | ||
1365 | <td class="filedate">16/12/2013 16:15:40 +0000</td> | ||
1366 | <td class="comment">MiniUPnP daemon source code</td> | ||
1367 | <td></td> | ||
1368 | </tr> | ||
1369 | <tr> | ||
1370 | <td class="filename"><a href='download.php?file=miniupnpd-1.8.20131213.tar.gz'>miniupnpd-1.8.20131213.tar.gz</a></td> | ||
1371 | <td class="filesize">169753</td> | ||
1372 | <td class="filedate">13/12/2013 16:18:10 +0000</td> | ||
1373 | <td class="comment">MiniUPnP daemon source code</td> | ||
1374 | <td></td> | ||
1375 | </tr> | ||
1376 | <tr> | ||
1377 | <td class="filename"><a href='download.php?file=miniupnpc-1.8.20131209.tar.gz'>miniupnpc-1.8.20131209.tar.gz</a></td> | ||
1378 | <td class="filesize">73900</td> | ||
1379 | <td class="filedate">09/12/2013 20:52:54 +0000</td> | ||
1380 | <td class="comment">MiniUPnP client source code</td> | ||
1381 | <td></td> | ||
1382 | </tr> | ||
1383 | <tr> | ||
1384 | <td class="filename"><a href='download.php?file=libnatpmp-20131126.tar.gz'>libnatpmp-20131126.tar.gz</a></td> | ||
1385 | <td class="filesize">22972</td> | ||
1386 | <td class="filedate">26/11/2013 08:51:36 +0000</td> | ||
1387 | <td class="comment">libnatpmp source code</td> | ||
1388 | <td></td> | ||
1389 | </tr> | ||
1390 | <tr> | ||
1391 | <td class="filename"><a href='download.php?file=miniupnpc-1.8.20131007.tar.gz'>miniupnpc-1.8.20131007.tar.gz</a></td> | ||
1392 | <td class="filesize">73750</td> | ||
1393 | <td class="filedate">07/10/2013 10:10:25 +0000</td> | ||
1394 | <td class="comment">MiniUPnP client source code</td> | ||
1395 | <td></td> | ||
1396 | </tr> | ||
1397 | <tr> | ||
1398 | <td class="filename"><a href='download.php?file=libnatpmp-20130911.tar.gz'>libnatpmp-20130911.tar.gz</a></td> | ||
1399 | <td class="filesize">18744</td> | ||
1400 | <td class="filedate">11/09/2013 07:35:51 +0000</td> | ||
1401 | <td class="comment">libnatpmp source code</td> | ||
1402 | <td></td> | ||
1403 | </tr> | ||
1404 | <tr> | ||
1405 | <td class="filename"><a href='download.php?file=libnatpmp-20130910.tar.gz'>libnatpmp-20130910.tar.gz</a></td> | ||
1406 | <td class="filesize">18734</td> | ||
1407 | <td class="filedate">10/09/2013 20:15:34 +0000</td> | ||
1408 | <td class="comment">libnatpmp source code</td> | ||
1409 | <td></td> | ||
1410 | </tr> | ||
1411 | <tr> | ||
1412 | <td class="filename"><a href='download.php?file=minissdpd-1.2.20130907.tar.gz'>minissdpd-1.2.20130907.tar.gz</a></td> | ||
1413 | <td class="filesize">20237</td> | ||
1414 | <td class="filedate">07/09/2013 06:46:31 +0000</td> | ||
1415 | <td class="comment">MiniSSDPd source code</td> | ||
1416 | <td></td> | ||
1417 | </tr> | ||
1418 | <tr> | ||
1419 | <td class="filename"><a href='download.php?file=minissdpd-1.2.20130819.tar.gz'>minissdpd-1.2.20130819.tar.gz</a></td> | ||
1420 | <td class="filesize">20772</td> | ||
1421 | <td class="filedate">19/08/2013 16:50:29 +0000</td> | ||
1422 | <td class="comment">MiniSSDPd source code</td> | ||
1423 | <td></td> | ||
1424 | </tr> | ||
1425 | <tr> | ||
1426 | <td class="filename"><a href='download.php?file=miniupnpc-1.8.20130801.tar.gz'>miniupnpc-1.8.20130801.tar.gz</a></td> | ||
1427 | <td class="filesize">73426</td> | ||
1428 | <td class="filedate">01/08/2013 21:38:05 +0000</td> | ||
1429 | <td class="comment">MiniUPnP client source code</td> | ||
1430 | <td></td> | ||
1431 | </tr> | ||
1432 | <tr> | ||
1433 | <td class="filename"><a href='download.php?file=miniupnpd-1.8.20130730.tar.gz'>miniupnpd-1.8.20130730.tar.gz</a></td> | ||
1434 | <td class="filesize">149904</td> | ||
1435 | <td class="filedate">30/07/2013 11:37:48 +0000</td> | ||
1436 | <td class="comment">MiniUPnP daemon source code</td> | ||
1437 | <td></td> | ||
1438 | </tr> | ||
1439 | <tr> | ||
1440 | <td class="filename"><a href='download.php?file=miniupnpd-1.8.20130607.tar.gz'>miniupnpd-1.8.20130607.tar.gz</a></td> | ||
1441 | <td class="filesize">149521</td> | ||
1442 | <td class="filedate">07/06/2013 08:46:17 +0000</td> | ||
1443 | <td class="comment">MiniUPnP daemon source code</td> | ||
1444 | <td></td> | ||
1445 | </tr> | ||
1446 | <tr> | ||
1447 | <td class="filename"><a href='download.php?file=miniupnpd-1.8.20130521.tar.gz'>miniupnpd-1.8.20130521.tar.gz</a></td> | ||
1448 | <td class="filesize">149276</td> | ||
1449 | <td class="filedate">21/05/2013 09:01:33 +0000</td> | ||
1450 | <td class="comment">MiniUPnP daemon source code</td> | ||
1451 | <td></td> | ||
1452 | </tr> | ||
1453 | <tr> | ||
1454 | <td class="filename"><a href='download.php?file=miniupnpd-1.8.20130503.tar.gz'>miniupnpd-1.8.20130503.tar.gz</a></td> | ||
1455 | <td class="filesize">148420</td> | ||
1456 | <td class="filedate">03/05/2013 19:27:16 +0000</td> | ||
1457 | <td class="comment">MiniUPnP daemon source code</td> | ||
1458 | <td></td> | ||
1459 | </tr> | ||
1460 | <tr> | ||
1461 | <td class="filename"><a href='download.php?file=miniupnpc-1.8.20130503.tar.gz'>miniupnpc-1.8.20130503.tar.gz</a></td> | ||
1462 | <td class="filesize">71858</td> | ||
1463 | <td class="filedate">03/05/2013 19:27:07 +0000</td> | ||
1464 | <td class="comment">MiniUPnP client source code</td> | ||
1465 | <td></td> | ||
1466 | </tr> | ||
1467 | <tr> | ||
1468 | <td class="filename"><a href='download.php?file=miniupnpd-1.8.20130426.tar.gz'>miniupnpd-1.8.20130426.tar.gz</a></td> | ||
1469 | <td class="filesize">147890</td> | ||
1470 | <td class="filedate">26/04/2013 16:57:20 +0000</td> | ||
1471 | <td class="comment">MiniUPnP daemon source code</td> | ||
1472 | <td></td> | ||
1473 | </tr> | ||
1474 | <tr> | ||
1475 | <td class="filename"><a href='download.php?file=miniupnpc-1.8.20130211.tar.gz'>miniupnpc-1.8.20130211.tar.gz</a></td> | ||
1476 | <td class="filesize">70723</td> | ||
1477 | <td class="filedate">11/02/2013 10:32:44 +0000</td> | ||
1478 | <td class="comment">MiniUPnP client source code</td> | ||
1479 | <td></td> | ||
1480 | </tr> | ||
1481 | <tr> | ||
1482 | <td class="filename"><a href='download.php?file=miniupnpd-1.8.20130207.tar.gz'>miniupnpd-1.8.20130207.tar.gz</a></td> | ||
1483 | <td class="filesize">147325</td> | ||
1484 | <td class="filedate">07/02/2013 12:29:32 +0000</td> | ||
1485 | <td class="comment">MiniUPnP daemon source code</td> | ||
1486 | <td></td> | ||
1487 | </tr> | ||
1488 | <tr> | ||
1489 | <td class="filename"><a href='download.php?file=miniupnpc-1.8.tar.gz'>miniupnpc-1.8.tar.gz</a></td> | ||
1490 | <td class="filesize">70624</td> | ||
1491 | <td class="filedate">06/02/2013 14:31:06 +0000</td> | ||
1492 | <td class="comment">MiniUPnP client release source code</td> | ||
1493 | <td></td> | ||
1494 | </tr> | ||
1495 | <tr> | ||
1496 | <td class="filename"><a href='download.php?file=miniupnpd-1.8.tar.gz'>miniupnpd-1.8.tar.gz</a></td> | ||
1497 | <td class="filesize">146679</td> | ||
1498 | <td class="filedate">06/02/2013 14:30:59 +0000</td> | ||
1499 | <td class="comment">MiniUPnP daemon release source code</td> | ||
1500 | <td></td> | ||
1501 | </tr> | ||
1502 | <tr> | ||
1503 | <td class="filename"><a href='download.php?file=upnpc-exe-win32-20121009.zip'>upnpc-exe-win32-20121009.zip</a></td> | ||
1504 | <td class="filesize">96513</td> | ||
1505 | <td class="filedate">09/10/2012 17:54:12 +0000</td> | ||
1506 | <td class="comment">Windows executable</td> | ||
1507 | <td></td> | ||
1508 | </tr> | ||
1509 | <tr> | ||
1510 | <td class="filename"><a href='download.php?file=miniupnpd-1.7.20121005.tar.gz'>miniupnpd-1.7.20121005.tar.gz</a></td> | ||
1511 | <td class="filesize">144393</td> | ||
1512 | <td class="filedate">04/10/2012 22:39:05 +0000</td> | ||
1513 | <td class="comment">MiniUPnP daemon source code</td> | ||
1514 | <td></td> | ||
1515 | </tr> | ||
1516 | <tr> | ||
1517 | <td class="filename"><a href='download.php?file=miniupnpc-1.7.20120830.tar.gz'>miniupnpc-1.7.20120830.tar.gz</a></td> | ||
1518 | <td class="filesize">70074</td> | ||
1519 | <td class="filedate">30/08/2012 08:41:51 +0000</td> | ||
1520 | <td class="comment">MiniUPnP client source code</td> | ||
1521 | <td></td> | ||
1522 | </tr> | ||
1523 | <tr> | ||
1524 | <td class="filename"><a href='download.php?file=miniupnpd-1.7.20120824.tar.gz'>miniupnpd-1.7.20120824.tar.gz</a></td> | ||
1525 | <td class="filesize">141960</td> | ||
1526 | <td class="filedate">24/08/2012 18:15:01 +0000</td> | ||
1527 | <td class="comment">MiniUPnP daemon source code</td> | ||
1528 | <td></td> | ||
1529 | </tr> | ||
1530 | <tr> | ||
1531 | <td class="filename"><a href='download.php?file=libnatpmp-20120821.tar.gz'>libnatpmp-20120821.tar.gz</a></td> | ||
1532 | <td class="filesize">17832</td> | ||
1533 | <td class="filedate">21/08/2012 17:24:46 +0000</td> | ||
1534 | <td class="comment">libnatpmp source code</td> | ||
1535 | <td></td> | ||
1536 | </tr> | ||
1537 | <tr> | ||
1538 | <td class="filename"><a href='download.php?file=miniupnpc-1.7.20120714.tar.gz'>miniupnpc-1.7.20120714.tar.gz</a></td> | ||
1539 | <td class="filesize">69570</td> | ||
1540 | <td class="filedate">14/07/2012 14:40:47 +0000</td> | ||
1541 | <td class="comment">MiniUPnP client source code</td> | ||
1542 | <td></td> | ||
1543 | </tr> | ||
1544 | <tr> | ||
1545 | <td class="filename"><a href='download.php?file=miniupnpc-1.7.20120711.tar.gz'>miniupnpc-1.7.20120711.tar.gz</a></td> | ||
1546 | <td class="filesize">69580</td> | ||
1547 | <td class="filedate">10/07/2012 22:27:05 +0000</td> | ||
1548 | <td class="comment">MiniUPnP client source code</td> | ||
1549 | <td></td> | ||
1550 | </tr> | ||
1551 | <tr> | ||
1552 | <td class="filename"><a href='download.php?file=miniupnpd-1.7.20120711.tar.gz'>miniupnpd-1.7.20120711.tar.gz</a></td> | ||
1553 | <td class="filesize">141380</td> | ||
1554 | <td class="filedate">10/07/2012 22:26:58 +0000</td> | ||
1555 | <td class="comment">MiniUPnP daemon source code</td> | ||
1556 | <td></td> | ||
1557 | </tr> | ||
1558 | <tr> | ||
1559 | <td class="filename"><a href='download.php?file=miniupnpd-1.7.tar.gz'>miniupnpd-1.7.tar.gz</a></td> | ||
1560 | <td class="filesize">138047</td> | ||
1561 | <td class="filedate">27/05/2012 23:13:30 +0000</td> | ||
1562 | <td class="comment">MiniUPnP daemon release source code</td> | ||
1563 | <td></td> | ||
1564 | </tr> | ||
1565 | <tr> | ||
1566 | <td class="filename"><a href='download.php?file=miniupnpc-1.7.tar.gz'>miniupnpc-1.7.tar.gz</a></td> | ||
1567 | <td class="filesize">68327</td> | ||
1568 | <td class="filedate">24/05/2012 18:17:48 +0000</td> | ||
1569 | <td class="comment">MiniUPnP client release source code</td> | ||
1570 | <td></td> | ||
1571 | </tr> | ||
1572 | <tr> | ||
1573 | <td class="filename"><a href='download.php?file=minissdpd-1.2.tar.gz'>minissdpd-1.2.tar.gz</a></td> | ||
1574 | <td class="filesize">19874</td> | ||
1575 | <td class="filedate">24/05/2012 18:06:24 +0000</td> | ||
1576 | <td class="comment">MiniSSDPd release source code</td> | ||
1577 | <td></td> | ||
1578 | </tr> | ||
1579 | <tr> | ||
1580 | <td class="filename"><a href='download.php?file=miniupnpd-1.6.20120509.tar.gz'>miniupnpd-1.6.20120509.tar.gz</a></td> | ||
1581 | <td class="filesize">137147</td> | ||
1582 | <td class="filedate">09/05/2012 10:45:44 +0000</td> | ||
1583 | <td class="comment">MiniUPnP daemon source code</td> | ||
1584 | <td></td> | ||
1585 | </tr> | ||
1586 | <tr> | ||
1587 | <td class="filename"><a href='download.php?file=miniupnpc-1.6.20120509.tar.gz'>miniupnpc-1.6.20120509.tar.gz</a></td> | ||
1588 | <td class="filesize">68205</td> | ||
1589 | <td class="filedate">09/05/2012 10:45:41 +0000</td> | ||
1590 | <td class="comment">MiniUPnP client source code</td> | ||
1591 | <td></td> | ||
1592 | </tr> | ||
1593 | <tr> | ||
1594 | <td class="filename"><a href='download.php?file=minissdpd-1.1.20120509.tar.gz'>minissdpd-1.1.20120509.tar.gz</a></td> | ||
1595 | <td class="filesize">18123</td> | ||
1596 | <td class="filedate">09/05/2012 10:45:39 +0000</td> | ||
1597 | <td class="comment">MiniSSDPd source code</td> | ||
1598 | <td></td> | ||
1599 | </tr> | ||
1600 | <tr> | ||
1601 | <td class="filename"><a href='download.php?file=miniupnpd-1.6.20120502.tar.gz'>miniupnpd-1.6.20120502.tar.gz</a></td> | ||
1602 | <td class="filesize">136688</td> | ||
1603 | <td class="filedate">01/05/2012 22:51:18 +0000</td> | ||
1604 | <td class="comment">MiniUPnP daemon source code</td> | ||
1605 | <td></td> | ||
1606 | </tr> | ||
1607 | <tr> | ||
1608 | <td class="filename"><a href='download.php?file=miniupnpc-1.6.20120502.tar.gz'>miniupnpc-1.6.20120502.tar.gz</a></td> | ||
1609 | <td class="filesize">68170</td> | ||
1610 | <td class="filedate">01/05/2012 22:51:11 +0000</td> | ||
1611 | <td class="comment">MiniUPnP client source code</td> | ||
1612 | <td></td> | ||
1613 | </tr> | ||
1614 | <tr> | ||
1615 | <td class="filename"><a href='download.php?file=miniupnpd-1.6.20120426.tar.gz'>miniupnpd-1.6.20120426.tar.gz</a></td> | ||
1616 | <td class="filesize">134764</td> | ||
1617 | <td class="filedate">26/04/2012 16:24:29 +0000</td> | ||
1618 | <td class="comment">MiniUPnP daemon source code</td> | ||
1619 | <td></td> | ||
1620 | </tr> | ||
1621 | <tr> | ||
1622 | <td class="filename"><a href='download.php?file=miniupnpd-1.6.20120424.tar.gz'>miniupnpd-1.6.20120424.tar.gz</a></td> | ||
1623 | <td class="filesize">132522</td> | ||
1624 | <td class="filedate">23/04/2012 22:43:17 +0000</td> | ||
1625 | <td class="comment">MiniUPnP daemon source code</td> | ||
1626 | <td></td> | ||
1627 | </tr> | ||
1628 | <tr> | ||
1629 | <td class="filename"><a href='download.php?file=miniupnpc-1.6.20120424.tar.gz'>miniupnpc-1.6.20120424.tar.gz</a></td> | ||
1630 | <td class="filesize">68067</td> | ||
1631 | <td class="filedate">23/04/2012 22:43:10 +0000</td> | ||
1632 | <td class="comment">MiniUPnP client source code</td> | ||
1633 | <td></td> | ||
1634 | </tr> | ||
1635 | <tr> | ||
1636 | <td class="filename"><a href='download.php?file=miniupnpd-1.6.20120420.tar.gz'>miniupnpd-1.6.20120420.tar.gz</a></td> | ||
1637 | <td class="filesize">131972</td> | ||
1638 | <td class="filedate">20/04/2012 14:58:57 +0000</td> | ||
1639 | <td class="comment">MiniUPnP daemon source code</td> | ||
1640 | <td></td> | ||
1641 | </tr> | ||
1642 | <tr> | ||
1643 | <td class="filename"><a href='download.php?file=miniupnpc-1.6.20120420.tar.gz'>miniupnpc-1.6.20120420.tar.gz</a></td> | ||
1644 | <td class="filesize">68068</td> | ||
1645 | <td class="filedate">20/04/2012 14:58:39 +0000</td> | ||
1646 | <td class="comment">MiniUPnP client source code</td> | ||
1647 | <td></td> | ||
1648 | </tr> | ||
1649 | <tr> | ||
1650 | <td class="filename"><a href='download.php?file=miniupnpd-1.6.20120419.tar.gz'>miniupnpd-1.6.20120419.tar.gz</a></td> | ||
1651 | <td class="filesize">131088</td> | ||
1652 | <td class="filedate">18/04/2012 23:41:36 +0000</td> | ||
1653 | <td class="comment">MiniUPnP daemon source code</td> | ||
1654 | <td></td> | ||
1655 | </tr> | ||
1656 | <tr> | ||
1657 | <td class="filename"><a href='download.php?file=miniupnpd-1.6.20120418.tar.gz'>miniupnpd-1.6.20120418.tar.gz</a></td> | ||
1658 | <td class="filesize">130879</td> | ||
1659 | <td class="filedate">18/04/2012 21:01:10 +0000</td> | ||
1660 | <td class="comment">MiniUPnP daemon source code</td> | ||
1661 | <td></td> | ||
1662 | </tr> | ||
1663 | <tr> | ||
1664 | <td class="filename"><a href='download.php?file=minissdpd-1.1.20120410.tar.gz'>minissdpd-1.1.20120410.tar.gz</a></td> | ||
1665 | <td class="filesize">18059</td> | ||
1666 | <td class="filedate">09/04/2012 22:45:38 +0000</td> | ||
1667 | <td class="comment">MiniSSDPd source code</td> | ||
1668 | <td></td> | ||
1669 | </tr> | ||
1670 | <tr> | ||
1671 | <td class="filename"><a href='download.php?file=miniupnpc-1.6.20120410.tar.gz'>miniupnpc-1.6.20120410.tar.gz</a></td> | ||
1672 | <td class="filesize">67934</td> | ||
1673 | <td class="filedate">09/04/2012 22:45:10 +0000</td> | ||
1674 | <td class="comment">MiniUPnP client source code</td> | ||
1675 | <td></td> | ||
1676 | </tr> | ||
1677 | <tr> | ||
1678 | <td class="filename"><a href='download.php?file=miniupnpd-1.6.20120406.tar.gz'>miniupnpd-1.6.20120406.tar.gz</a></td> | ||
1679 | <td class="filesize">128992</td> | ||
1680 | <td class="filedate">06/04/2012 17:52:57 +0000</td> | ||
1681 | <td class="comment">MiniUPnP daemon source code</td> | ||
1682 | <td></td> | ||
1683 | </tr> | ||
1684 | <tr> | ||
1685 | <td class="filename"><a href='download.php?file=miniupnpc-1.6.20120320.tar.gz'>miniupnpc-1.6.20120320.tar.gz</a></td> | ||
1686 | <td class="filesize">67374</td> | ||
1687 | <td class="filedate">20/03/2012 16:55:48 +0000</td> | ||
1688 | <td class="comment">MiniUPnP client source code</td> | ||
1689 | <td></td> | ||
1690 | </tr> | ||
1691 | <tr> | ||
1692 | <td class="filename"><a href='download.php?file=miniupnpd-1.6.20120320.tar.gz'>miniupnpd-1.6.20120320.tar.gz</a></td> | ||
1693 | <td class="filesize">127968</td> | ||
1694 | <td class="filedate">20/03/2012 16:46:07 +0000</td> | ||
1695 | <td class="comment">MiniUPnP daemon source code</td> | ||
1696 | <td></td> | ||
1697 | </tr> | ||
1698 | <tr> | ||
1699 | <td class="filename"><a href='download.php?file=miniupnpd-1.6.20120305.tar.gz'>miniupnpd-1.6.20120305.tar.gz</a></td> | ||
1700 | <td class="filesize">126985</td> | ||
1701 | <td class="filedate">05/03/2012 20:42:01 +0000</td> | ||
1702 | <td class="comment">MiniUPnP daemon source code</td> | ||
1703 | <td></td> | ||
1704 | </tr> | ||
1705 | <tr> | ||
1706 | <td class="filename"><a href='download.php?file=miniupnpd-1.6.20120207.tar.gz'>miniupnpd-1.6.20120207.tar.gz</a></td> | ||
1707 | <td class="filesize">127425</td> | ||
1708 | <td class="filedate">07/02/2012 10:21:16 +0000</td> | ||
1709 | <td class="comment">MiniUPnP daemon source code</td> | ||
1710 | <td></td> | ||
1711 | </tr> | ||
1712 | <tr> | ||
1713 | <td class="filename"><a href='download.php?file=miniupnpd-1.6.20120203.tar.gz'>miniupnpd-1.6.20120203.tar.gz</a></td> | ||
1714 | <td class="filesize">126599</td> | ||
1715 | <td class="filedate">03/02/2012 15:14:13 +0000</td> | ||
1716 | <td class="comment">MiniUPnP daemon source code</td> | ||
1717 | <td></td> | ||
1718 | </tr> | ||
1719 | <tr> | ||
1720 | <td class="filename"><a href='download.php?file=miniupnpc-1.6.20120125.tar.gz'>miniupnpc-1.6.20120125.tar.gz</a></td> | ||
1721 | <td class="filesize">67354</td> | ||
1722 | <td class="filedate">25/01/2012 21:12:28 +0000</td> | ||
1723 | <td class="comment">MiniUPnP client source code</td> | ||
1724 | <td></td> | ||
1725 | </tr> | ||
1726 | <tr> | ||
1727 | <td class="filename"><a href='download.php?file=miniupnpc-1.6.20120121.tar.gz'>miniupnpc-1.6.20120121.tar.gz</a></td> | ||
1728 | <td class="filesize">67347</td> | ||
1729 | <td class="filedate">21/01/2012 14:07:41 +0000</td> | ||
1730 | <td class="comment">MiniUPnP client source code</td> | ||
1731 | <td></td> | ||
1732 | </tr> | ||
1733 | <tr> | ||
1734 | <td class="filename"><a href='download.php?file=miniupnpd-1.6.20120121.tar.gz'>miniupnpd-1.6.20120121.tar.gz</a></td> | ||
1735 | <td class="filesize">126021</td> | ||
1736 | <td class="filedate">21/01/2012 14:07:33 +0000</td> | ||
1737 | <td class="comment">MiniUPnP daemon source code</td> | ||
1738 | <td></td> | ||
1739 | </tr> | ||
1740 | <tr> | ||
1741 | <td class="filename"><a href='download.php?file=minissdpd-1.1.20120121.tar.gz'>minissdpd-1.1.20120121.tar.gz</a></td> | ||
1742 | <td class="filesize">17762</td> | ||
1743 | <td class="filedate">21/01/2012 14:07:16 +0000</td> | ||
1744 | <td class="comment">MiniSSDPd source code</td> | ||
1745 | <td></td> | ||
1746 | </tr> | ||
1747 | <tr> | ||
1748 | <td class="filename"><a href='download.php?file=upnpc-exe-win32-20120121.zip'>upnpc-exe-win32-20120121.zip</a></td> | ||
1749 | <td class="filesize">94575</td> | ||
1750 | <td class="filedate">21/01/2012 13:59:11 +0000</td> | ||
1751 | <td class="comment">Windows executable</td> | ||
1752 | <td></td> | ||
1753 | </tr> | ||
1754 | <tr> | ||
1755 | <td class="filename"><a href='download.php?file=upnpc-exe-win32-20111212.zip'>upnpc-exe-win32-20111212.zip</a></td> | ||
1756 | <td class="filesize">94507</td> | ||
1757 | <td class="filedate">12/12/2011 12:33:48 +0000</td> | ||
1758 | <td class="comment">Windows executable</td> | ||
1759 | <td></td> | ||
1760 | </tr> | ||
1761 | <tr> | ||
1762 | <td class="filename"><a href='download.php?file=miniupnpd-1.6.20111118.tar.gz'>miniupnpd-1.6.20111118.tar.gz</a></td> | ||
1763 | <td class="filesize">125683</td> | ||
1764 | <td class="filedate">18/11/2011 11:26:12 +0000</td> | ||
1765 | <td class="comment">MiniUPnP daemon source code</td> | ||
1766 | <td></td> | ||
1767 | </tr> | ||
1768 | <tr> | ||
1769 | <td class="filename"><a href='download.php?file=minissdpd-1.1.20111007.tar.gz'>minissdpd-1.1.20111007.tar.gz</a></td> | ||
1770 | <td class="filesize">17611</td> | ||
1771 | <td class="filedate">07/10/2011 09:47:51 +0000</td> | ||
1772 | <td class="comment">MiniSSDPd source code</td> | ||
1773 | <td></td> | ||
1774 | </tr> | ||
1775 | <tr> | ||
1776 | <td class="filename"><a href='download.php?file=xchat-upnp20110811.patch'>xchat-upnp20110811.patch</a></td> | ||
1777 | <td class="filesize">10329</td> | ||
1778 | <td class="filedate">11/08/2011 15:18:25 +0000</td> | ||
1779 | <td class="comment">Patch to add UPnP capabilities to xchat</td> | ||
1780 | <td></td> | ||
1781 | </tr> | ||
1782 | <tr> | ||
1783 | <td class="filename"><a href='download.php?file=xchat-upnp20110811-2.8.8.patch'>xchat-upnp20110811-2.8.8.patch</a></td> | ||
1784 | <td class="filesize">11529</td> | ||
1785 | <td class="filedate">11/08/2011 15:18:23 +0000</td> | ||
1786 | <td class="comment">Patch to add UPnP capabilities to xchat</td> | ||
1787 | <td></td> | ||
1788 | </tr> | ||
1789 | <tr> | ||
1790 | <td class="filename"><a href='download.php?file=libnatpmp-20110808.tar.gz'>libnatpmp-20110808.tar.gz</a></td> | ||
1791 | <td class="filesize">17762</td> | ||
1792 | <td class="filedate">08/08/2011 21:21:34 +0000</td> | ||
1793 | <td class="comment">libnatpmp source code</td> | ||
1794 | <td></td> | ||
1795 | </tr> | ||
1796 | <tr> | ||
1797 | <td class="filename"><a href='download.php?file=libnatpmp-20110730.tar.gz'>libnatpmp-20110730.tar.gz</a></td> | ||
1798 | <td class="filesize">17687</td> | ||
1799 | <td class="filedate">30/07/2011 13:19:31 +0000</td> | ||
1800 | <td class="comment">libnatpmp source code</td> | ||
1801 | <td></td> | ||
1802 | </tr> | ||
1803 | <tr> | ||
1804 | <td class="filename"><a href='download.php?file=minissdpd-1.1.tar.gz'>minissdpd-1.1.tar.gz</a></td> | ||
1805 | <td class="filesize">17481</td> | ||
1806 | <td class="filedate">30/07/2011 13:17:30 +0000</td> | ||
1807 | <td class="comment">MiniSSDPd release source code</td> | ||
1808 | <td></td> | ||
1809 | </tr> | ||
1810 | <tr> | ||
1811 | <td class="filename"><a href='download.php?file=miniupnpd-1.6.20110730.tar.gz'>miniupnpd-1.6.20110730.tar.gz</a></td> | ||
1812 | <td class="filesize">125583</td> | ||
1813 | <td class="filedate">30/07/2011 13:17:09 +0000</td> | ||
1814 | <td class="comment">MiniUPnP daemon source code</td> | ||
1815 | <td></td> | ||
1816 | </tr> | ||
1817 | <tr> | ||
1818 | <td class="filename"><a href='download.php?file=minissdpd-1.0.20110729.tar.gz'>minissdpd-1.0.20110729.tar.gz</a></td> | ||
1819 | <td class="filesize">15898</td> | ||
1820 | <td class="filedate">29/07/2011 08:47:26 +0000</td> | ||
1821 | <td class="comment">MiniSSDPd source code</td> | ||
1822 | <td></td> | ||
1823 | </tr> | ||
1824 | <tr> | ||
1825 | <td class="filename"><a href='download.php?file=miniupnpc-1.6.tar.gz'>miniupnpc-1.6.tar.gz</a></td> | ||
1826 | <td class="filesize">66454</td> | ||
1827 | <td class="filedate">25/07/2011 18:03:09 +0000</td> | ||
1828 | <td class="comment">MiniUPnP client release source code</td> | ||
1829 | <td></td> | ||
1830 | </tr> | ||
1831 | <tr> | ||
1832 | <td class="filename"><a href='download.php?file=miniupnpd-1.6.tar.gz'>miniupnpd-1.6.tar.gz</a></td> | ||
1833 | <td class="filesize">124917</td> | ||
1834 | <td class="filedate">25/07/2011 16:37:57 +0000</td> | ||
1835 | <td class="comment">MiniUPnP daemon release source code</td> | ||
1836 | <td></td> | ||
1837 | </tr> | ||
1838 | <tr> | ||
1839 | <td class="filename"><a href='download.php?file=minidlna_1.0.21.minissdp1.patch'>minidlna_1.0.21.minissdp1.patch</a></td> | ||
1840 | <td class="filesize">7598</td> | ||
1841 | <td class="filedate">25/07/2011 14:57:50 +0000</td> | ||
1842 | <td class="comment">Patch for MiniDLNA to use miniSSDPD</td> | ||
1843 | <td></td> | ||
1844 | </tr> | ||
1845 | <tr> | ||
1846 | <td class="filename"><a href='download.php?file=libnatpmp-20110715.tar.gz'>libnatpmp-20110715.tar.gz</a></td> | ||
1847 | <td class="filesize">17943</td> | ||
1848 | <td class="filedate">15/07/2011 08:31:40 +0000</td> | ||
1849 | <td class="comment">libnatpmp source code</td> | ||
1850 | <td></td> | ||
1851 | </tr> | ||
1852 | <tr> | ||
1853 | <td class="filename"><a href='download.php?file=miniupnpd-1.5.20110715.tar.gz'>miniupnpd-1.5.20110715.tar.gz</a></td> | ||
1854 | <td class="filesize">124519</td> | ||
1855 | <td class="filedate">15/07/2011 07:55:17 +0000</td> | ||
1856 | <td class="comment">MiniUPnP daemon source code</td> | ||
1857 | <td></td> | ||
1858 | </tr> | ||
1859 | <tr> | ||
1860 | <td class="filename"><a href='download.php?file=upnpc-exe-win32-20110714.zip'>upnpc-exe-win32-20110714.zip</a></td> | ||
1861 | <td class="filesize">94236</td> | ||
1862 | <td class="filedate">13/07/2011 23:16:01 +0000</td> | ||
1863 | <td class="comment">Windows executable</td> | ||
1864 | <td></td> | ||
1865 | </tr> | ||
1866 | <tr> | ||
1867 | <td class="filename"><a href='download.php?file=miniupnpd-1.5.20110623.tar.gz'>miniupnpd-1.5.20110623.tar.gz</a></td> | ||
1868 | <td class="filesize">123529</td> | ||
1869 | <td class="filedate">22/06/2011 22:29:15 +0000</td> | ||
1870 | <td class="comment">MiniUPnP daemon source code</td> | ||
1871 | <td></td> | ||
1872 | </tr> | ||
1873 | <tr> | ||
1874 | <td class="filename"><a href='download.php?file=miniupnpd-1.5.20110620.tar.gz'>miniupnpd-1.5.20110620.tar.gz</a></td> | ||
1875 | <td class="filesize">123221</td> | ||
1876 | <td class="filedate">20/06/2011 14:11:11 +0000</td> | ||
1877 | <td class="comment">MiniUPnP daemon source code</td> | ||
1878 | <td></td> | ||
1879 | </tr> | ||
1880 | <tr> | ||
1881 | <td class="filename"><a href='download.php?file=miniupnpd-1.5.20110618.tar.gz'>miniupnpd-1.5.20110618.tar.gz</a></td> | ||
1882 | <td class="filesize">123176</td> | ||
1883 | <td class="filedate">17/06/2011 23:29:18 +0000</td> | ||
1884 | <td class="comment">MiniUPnP daemon source code</td> | ||
1885 | <td></td> | ||
1886 | </tr> | ||
1887 | <tr> | ||
1888 | <td class="filename"><a href='download.php?file=miniupnpc-1.5.20110618.tar.gz'>miniupnpc-1.5.20110618.tar.gz</a></td> | ||
1889 | <td class="filesize">66401</td> | ||
1890 | <td class="filedate">17/06/2011 23:29:17 +0000</td> | ||
1891 | <td class="comment">MiniUPnP client source code</td> | ||
1892 | <td></td> | ||
1893 | </tr> | ||
1894 | <tr> | ||
1895 | <td class="filename"><a href='download.php?file=libnatpmp-20110618.tar.gz'>libnatpmp-20110618.tar.gz</a></td> | ||
1896 | <td class="filesize">17901</td> | ||
1897 | <td class="filedate">17/06/2011 23:29:16 +0000</td> | ||
1898 | <td class="comment">libnatpmp source code</td> | ||
1899 | <td></td> | ||
1900 | </tr> | ||
1901 | <tr> | ||
1902 | <td class="filename"><a href='download.php?file=minissdpd-1.0.20110618.tar.gz'>minissdpd-1.0.20110618.tar.gz</a></td> | ||
1903 | <td class="filesize">15193</td> | ||
1904 | <td class="filedate">17/06/2011 23:29:16 +0000</td> | ||
1905 | <td class="comment">MiniSSDPd source code</td> | ||
1906 | <td></td> | ||
1907 | </tr> | ||
1908 | <tr> | ||
1909 | <td class="filename" colspan="2"><a href='download.php?file=minidlna_cvs20110529_minissdp1.patch'>minidlna_cvs20110529_minissdp1.patch</a></td> | ||
1910 | <td class="filedate">29/05/2011 21:19:09 +0000</td> | ||
1911 | <td class="comment">Patch for MiniDLNA to use miniSSDPD</td> | ||
1912 | <td></td> | ||
1913 | </tr> | ||
1914 | <tr> | ||
1915 | <td class="filename"><a href='download.php?file=miniupnpd-1.5.20110528.tar.gz'>miniupnpd-1.5.20110528.tar.gz</a></td> | ||
1916 | <td class="filesize">121985</td> | ||
1917 | <td class="filedate">28/05/2011 09:39:04 +0000</td> | ||
1918 | <td class="comment">MiniUPnP daemon source code</td> | ||
1919 | <td></td> | ||
1920 | </tr> | ||
1921 | <tr> | ||
1922 | <td class="filename"><a href='download.php?file=minidlna_1.0.19_minissdp1.patch'>minidlna_1.0.19_minissdp1.patch</a></td> | ||
1923 | <td class="filesize">9080</td> | ||
1924 | <td class="filedate">27/05/2011 09:55:04 +0000</td> | ||
1925 | <td class="comment">Patch for MiniDLNA to use miniSSDPD</td> | ||
1926 | <td></td> | ||
1927 | </tr> | ||
1928 | <tr> | ||
1929 | <td class="filename"><a href='download.php?file=miniupnpd-1.5.20110527.tar.gz'>miniupnpd-1.5.20110527.tar.gz</a></td> | ||
1930 | <td class="filesize">120896</td> | ||
1931 | <td class="filedate">27/05/2011 08:28:35 +0000</td> | ||
1932 | <td class="comment">MiniUPnP daemon source code</td> | ||
1933 | <td></td> | ||
1934 | </tr> | ||
1935 | <tr> | ||
1936 | <td class="filename"><a href='download.php?file=miniupnpc-1.5.20110527.tar.gz'>miniupnpc-1.5.20110527.tar.gz</a></td> | ||
1937 | <td class="filesize">66279</td> | ||
1938 | <td class="filedate">27/05/2011 08:28:34 +0000</td> | ||
1939 | <td class="comment">MiniUPnP client source code</td> | ||
1940 | <td></td> | ||
1941 | </tr> | ||
1942 | <tr> | ||
1943 | <td class="filename"><a href='download.php?file=libnatpmp-20110527.tar.gz'>libnatpmp-20110527.tar.gz</a></td> | ||
1944 | <td class="filesize">17627</td> | ||
1945 | <td class="filedate">27/05/2011 08:28:33 +0000</td> | ||
1946 | <td class="comment">libnatpmp source code</td> | ||
1947 | <td></td> | ||
1948 | </tr> | ||
1949 | <tr> | ||
1950 | <td class="filename"><a href='download.php?file=minissdpd-1.0.20110523.tar.gz'>minissdpd-1.0.20110523.tar.gz</a></td> | ||
1951 | <td class="filesize">15024</td> | ||
1952 | <td class="filedate">23/05/2011 12:55:31 +0000</td> | ||
1953 | <td class="comment">MiniSSDPd source code</td> | ||
1954 | <td></td> | ||
1955 | </tr> | ||
1956 | <tr> | ||
1957 | <td class="filename"><a href='download.php?file=miniupnpd-1.5.20110520.tar.gz'>miniupnpd-1.5.20110520.tar.gz</a></td> | ||
1958 | <td class="filesize">119227</td> | ||
1959 | <td class="filedate">20/05/2011 18:00:41 +0000</td> | ||
1960 | <td class="comment">MiniUPnP daemon source code</td> | ||
1961 | <td></td> | ||
1962 | </tr> | ||
1963 | <tr> | ||
1964 | <td class="filename"><a href='download.php?file=miniupnpd-1.5.20110519.tar.gz'>miniupnpd-1.5.20110519.tar.gz</a></td> | ||
1965 | <td class="filesize">114735</td> | ||
1966 | <td class="filedate">18/05/2011 22:29:06 +0000</td> | ||
1967 | <td class="comment">MiniUPnP daemon source code</td> | ||
1968 | <td></td> | ||
1969 | </tr> | ||
1970 | <tr> | ||
1971 | <td class="filename"><a href='download.php?file=miniupnpd-1.5.20110516.tar.gz'>miniupnpd-1.5.20110516.tar.gz</a></td> | ||
1972 | <td class="filesize">113348</td> | ||
1973 | <td class="filedate">16/05/2011 09:32:51 +0000</td> | ||
1974 | <td class="comment">MiniUPnP daemon source code</td> | ||
1975 | <td></td> | ||
1976 | </tr> | ||
1977 | <tr> | ||
1978 | <td class="filename"><a href='download.php?file=miniupnpd-1.5.20110515.tar.gz'>miniupnpd-1.5.20110515.tar.gz</a></td> | ||
1979 | <td class="filesize">113135</td> | ||
1980 | <td class="filedate">15/05/2011 21:51:29 +0000</td> | ||
1981 | <td class="comment">MiniUPnP daemon source code</td> | ||
1982 | <td></td> | ||
1983 | </tr> | ||
1984 | <tr> | ||
1985 | <td class="filename"><a href='download.php?file=miniupnpc-1.5.20110515.tar.gz'>miniupnpc-1.5.20110515.tar.gz</a></td> | ||
1986 | <td class="filesize">66112</td> | ||
1987 | <td class="filedate">15/05/2011 21:51:28 +0000</td> | ||
1988 | <td class="comment">MiniUPnP client source code</td> | ||
1989 | <td></td> | ||
1990 | </tr> | ||
1991 | <tr> | ||
1992 | <td class="filename"><a href='download.php?file=miniupnpd-1.5.20110513.tar.gz'>miniupnpd-1.5.20110513.tar.gz</a></td> | ||
1993 | <td class="filesize">111029</td> | ||
1994 | <td class="filedate">13/05/2011 14:03:12 +0000</td> | ||
1995 | <td class="comment">MiniUPnP daemon source code</td> | ||
1996 | <td></td> | ||
1997 | </tr> | ||
1998 | <tr> | ||
1999 | <td class="filename"><a href='download.php?file=miniupnpc-1.5.20110506.tar.gz'>miniupnpc-1.5.20110506.tar.gz</a></td> | ||
2000 | <td class="filesize">65536</td> | ||
2001 | <td class="filedate">06/05/2011 16:35:38 +0000</td> | ||
2002 | <td class="comment">MiniUPnP client source code</td> | ||
2003 | <td></td> | ||
2004 | </tr> | ||
2005 | <tr> | ||
2006 | <td class="filename"><a href='download.php?file=miniupnpc-1.4-v6.20100505.zip'>miniupnpc-1.4-v6.20100505.zip</a></td> | ||
2007 | <td class="filesize">91833</td> | ||
2008 | <td class="filedate">18/04/2011 20:14:11 +0000</td> | ||
2009 | <td class="comment"></td> | ||
2010 | <td></td> | ||
2011 | </tr> | ||
2012 | <tr> | ||
2013 | <td class="filename"><a href='download.php?file=miniupnpd-1.4-v6.20100823.zip'>miniupnpd-1.4-v6.20100823.zip</a></td> | ||
2014 | <td class="filesize">222235</td> | ||
2015 | <td class="filedate">18/04/2011 20:14:07 +0000</td> | ||
2016 | <td class="comment"></td> | ||
2017 | <td></td> | ||
2018 | </tr> | ||
2019 | <tr> | ||
2020 | <td class="filename"><a href='download.php?file=miniupnpc-1.5.20110418.tar.gz'>miniupnpc-1.5.20110418.tar.gz</a></td> | ||
2021 | <td class="filesize">61820</td> | ||
2022 | <td class="filedate">18/04/2011 20:09:22 +0000</td> | ||
2023 | <td class="comment">MiniUPnP client source code</td> | ||
2024 | <td></td> | ||
2025 | </tr> | ||
2026 | <tr> | ||
2027 | <td class="filename"><a href='download.php?file=upnpc-exe-win32-20110418.zip'>upnpc-exe-win32-20110418.zip</a></td> | ||
2028 | <td class="filesize">94183</td> | ||
2029 | <td class="filedate">18/04/2011 17:53:26 +0000</td> | ||
2030 | <td class="comment">Windows executable</td> | ||
2031 | <td></td> | ||
2032 | </tr> | ||
2033 | <tr> | ||
2034 | <td class="filename"><a href='download.php?file=miniupnpc-1.5.20110314.tar.gz'>miniupnpc-1.5.20110314.tar.gz</a></td> | ||
2035 | <td class="filesize">57210</td> | ||
2036 | <td class="filedate">14/03/2011 14:27:29 +0000</td> | ||
2037 | <td class="comment">MiniUPnP client source code</td> | ||
2038 | <td></td> | ||
2039 | </tr> | ||
2040 | <tr> | ||
2041 | <td class="filename"><a href='download.php?file=miniupnpd-1.5.20110309.tar.gz'>miniupnpd-1.5.20110309.tar.gz</a></td> | ||
2042 | <td class="filesize">100073</td> | ||
2043 | <td class="filedate">09/03/2011 15:36:12 +0000</td> | ||
2044 | <td class="comment">MiniUPnP daemon source code</td> | ||
2045 | <td></td> | ||
2046 | </tr> | ||
2047 | <tr> | ||
2048 | <td class="filename"><a href='download.php?file=miniupnpd-1.5.20110302.tar.gz'>miniupnpd-1.5.20110302.tar.gz</a></td> | ||
2049 | <td class="filesize">100756</td> | ||
2050 | <td class="filedate">02/03/2011 16:17:44 +0000</td> | ||
2051 | <td class="comment">MiniUPnP daemon source code</td> | ||
2052 | <td></td> | ||
2053 | </tr> | ||
2054 | <tr> | ||
2055 | <td class="filename"><a href='download.php?file=miniupnpd-1.5.20110221.tar.gz'>miniupnpd-1.5.20110221.tar.gz</a></td> | ||
2056 | <td class="filesize">100092</td> | ||
2057 | <td class="filedate">20/02/2011 23:48:17 +0000</td> | ||
2058 | <td class="comment">MiniUPnP daemon source code</td> | ||
2059 | <td></td> | ||
2060 | </tr> | ||
2061 | <tr> | ||
2062 | <td class="filename"><a href='download.php?file=upnpc-exe-win32-20110215.zip'>upnpc-exe-win32-20110215.zip</a></td> | ||
2063 | <td class="filesize">55409</td> | ||
2064 | <td class="filedate">15/02/2011 23:05:00 +0000</td> | ||
2065 | <td class="comment">Windows executable</td> | ||
2066 | <td></td> | ||
2067 | </tr> | ||
2068 | <tr> | ||
2069 | <td class="filename"><a href='download.php?file=miniupnpc-1.5.20110215.tar.gz'>miniupnpc-1.5.20110215.tar.gz</a></td> | ||
2070 | <td class="filesize">54880</td> | ||
2071 | <td class="filedate">15/02/2011 11:16:04 +0000</td> | ||
2072 | <td class="comment">MiniUPnP client source code</td> | ||
2073 | <td></td> | ||
2074 | </tr> | ||
2075 | <tr> | ||
2076 | <td class="filename"><a href='download.php?file=miniupnpd-1.5.20110214.tar.gz'>miniupnpd-1.5.20110214.tar.gz</a></td> | ||
2077 | <td class="filesize">99629</td> | ||
2078 | <td class="filedate">14/02/2011 18:00:43 +0000</td> | ||
2079 | <td class="comment">MiniUPnP daemon source code</td> | ||
2080 | <td></td> | ||
2081 | </tr> | ||
2082 | <tr> | ||
2083 | <td class="filename"><a href='download.php?file=minidlna_1.0.18_minissdp1.patch'>minidlna_1.0.18_minissdp1.patch</a></td> | ||
2084 | <td class="filesize">9747</td> | ||
2085 | <td class="filedate">02/02/2011 15:12:19 +0000</td> | ||
2086 | <td class="comment">Patch for MiniDLNA to use miniSSDPD</td> | ||
2087 | <td></td> | ||
2088 | </tr> | ||
2089 | <tr> | ||
2090 | <td class="filename"><a href='download.php?file=miniupnpd-1.5.20110127.tar.gz'>miniupnpd-1.5.20110127.tar.gz</a></td> | ||
2091 | <td class="filesize">97421</td> | ||
2092 | <td class="filedate">27/01/2011 17:51:25 +0000</td> | ||
2093 | <td class="comment">MiniUPnP daemon source code</td> | ||
2094 | <td></td> | ||
2095 | </tr> | ||
2096 | <tr> | ||
2097 | <td class="filename"><a href='download.php?file=miniupnpd-1.5.tar.gz'>miniupnpd-1.5.tar.gz</a></td> | ||
2098 | <td class="filesize">98993</td> | ||
2099 | <td class="filedate">04/01/2011 09:45:10 +0000</td> | ||
2100 | <td class="comment">MiniUPnP daemon release source code</td> | ||
2101 | <td></td> | ||
2102 | </tr> | ||
2103 | <tr> | ||
2104 | <td class="filename"><a href='download.php?file=miniupnpc-1.5.tar.gz'>miniupnpc-1.5.tar.gz</a></td> | ||
2105 | <td class="filesize">53309</td> | ||
2106 | <td class="filedate">04/01/2011 09:45:06 +0000</td> | ||
2107 | <td class="comment">MiniUPnP client release source code</td> | ||
2108 | <td></td> | ||
2109 | </tr> | ||
2110 | <tr> | ||
2111 | <td class="filename"><a href='download.php?file=libnatpmp-20110103.tar.gz'>libnatpmp-20110103.tar.gz</a></td> | ||
2112 | <td class="filesize">17529</td> | ||
2113 | <td class="filedate">03/01/2011 17:33:16 +0000</td> | ||
2114 | <td class="comment">libnatpmp source code</td> | ||
2115 | <td></td> | ||
2116 | </tr> | ||
2117 | <tr> | ||
2118 | <td class="filename"><a href='download.php?file=miniupnpc-1.4.20101221.tar.gz'>miniupnpc-1.4.20101221.tar.gz</a></td> | ||
2119 | <td class="filesize">52342</td> | ||
2120 | <td class="filedate">21/12/2010 16:15:38 +0000</td> | ||
2121 | <td class="comment">MiniUPnP client source code</td> | ||
2122 | <td></td> | ||
2123 | </tr> | ||
2124 | <tr> | ||
2125 | <td class="filename"><a href='download.php?file=upnpc-exe-win32-20101213.zip'>upnpc-exe-win32-20101213.zip</a></td> | ||
2126 | <td class="filesize">52359</td> | ||
2127 | <td class="filedate">12/12/2010 23:44:01 +0000</td> | ||
2128 | <td class="comment">Windows executable</td> | ||
2129 | <td></td> | ||
2130 | </tr> | ||
2131 | <tr> | ||
2132 | <td class="filename"><a href='download.php?file=libnatpmp-20101211.tar.gz'>libnatpmp-20101211.tar.gz</a></td> | ||
2133 | <td class="filesize">17324</td> | ||
2134 | <td class="filedate">11/12/2010 17:20:36 +0000</td> | ||
2135 | <td class="comment">libnatpmp source code</td> | ||
2136 | <td></td> | ||
2137 | </tr> | ||
2138 | <tr> | ||
2139 | <td class="filename"><a href='download.php?file=miniupnpc-1.4.20101209.tar.gz'>miniupnpc-1.4.20101209.tar.gz</a></td> | ||
2140 | <td class="filesize">51900</td> | ||
2141 | <td class="filedate">09/12/2010 16:17:30 +0000</td> | ||
2142 | <td class="comment">MiniUPnP client source code</td> | ||
2143 | <td></td> | ||
2144 | </tr> | ||
2145 | <tr> | ||
2146 | <td class="filename"><a href='download.php?file=miniupnpd-1.4.20100921.tar.gz'>miniupnpd-1.4.20100921.tar.gz</a></td> | ||
2147 | <td class="filesize">95483</td> | ||
2148 | <td class="filedate">21/09/2010 15:50:00 +0000</td> | ||
2149 | <td class="comment">MiniUPnP daemon source code</td> | ||
2150 | <td></td> | ||
2151 | </tr> | ||
2152 | <tr> | ||
2153 | <td class="filename"><a href='download.php?file=upnpc-exe-win32-20100825.zip'>upnpc-exe-win32-20100825.zip</a></td> | ||
2154 | <td class="filesize">50636</td> | ||
2155 | <td class="filedate">25/08/2010 08:42:59 +0000</td> | ||
2156 | <td class="comment">Windows executable</td> | ||
2157 | <td></td> | ||
2158 | </tr> | ||
2159 | <tr> | ||
2160 | <td class="filename"><a href='download.php?file=miniupnpc-1.4.20100609.tar.gz'>miniupnpc-1.4.20100609.tar.gz</a></td> | ||
2161 | <td class="filesize">50390</td> | ||
2162 | <td class="filedate">09/06/2010 11:03:11 +0000</td> | ||
2163 | <td class="comment">MiniUPnP client source code</td> | ||
2164 | <td></td> | ||
2165 | </tr> | ||
2166 | <tr> | ||
2167 | <td class="filename"><a href='download.php?file=upnpc-exe-win32-20100513.zip'>upnpc-exe-win32-20100513.zip</a></td> | ||
2168 | <td class="filesize">50950</td> | ||
2169 | <td class="filedate">13/05/2010 16:54:33 +0000</td> | ||
2170 | <td class="comment">Windows executable</td> | ||
2171 | <td></td> | ||
2172 | </tr> | ||
2173 | <tr> | ||
2174 | <td class="filename"><a href='download.php?file=miniupnpd-1.4.20100511.tar.gz'>miniupnpd-1.4.20100511.tar.gz</a></td> | ||
2175 | <td class="filesize">93281</td> | ||
2176 | <td class="filedate">11/05/2010 16:22:33 +0000</td> | ||
2177 | <td class="comment">MiniUPnP daemon source code</td> | ||
2178 | <td></td> | ||
2179 | </tr> | ||
2180 | <tr> | ||
2181 | <td class="filename"><a href='download.php?file=upnpc-exe-win32-20100418.zip'>upnpc-exe-win32-20100418.zip</a></td> | ||
2182 | <td class="filesize">40758</td> | ||
2183 | <td class="filedate">17/04/2010 23:00:37 +0000</td> | ||
2184 | <td class="comment">Windows executable</td> | ||
2185 | <td></td> | ||
2186 | </tr> | ||
2187 | <tr> | ||
2188 | <td class="filename"><a href='download.php?file=miniupnpc-1.4.20100418.tar.gz'>miniupnpc-1.4.20100418.tar.gz</a></td> | ||
2189 | <td class="filesize">50245</td> | ||
2190 | <td class="filedate">17/04/2010 22:18:31 +0000</td> | ||
2191 | <td class="comment">MiniUPnP client source code</td> | ||
2192 | <td></td> | ||
2193 | </tr> | ||
2194 | <tr> | ||
2195 | <td class="filename"><a href='download.php?file=miniupnpc-1.4.20100412.tar.gz'>miniupnpc-1.4.20100412.tar.gz</a></td> | ||
2196 | <td class="filesize">50145</td> | ||
2197 | <td class="filedate">12/04/2010 20:42:53 +0000</td> | ||
2198 | <td class="comment">MiniUPnP client source code</td> | ||
2199 | <td></td> | ||
2200 | </tr> | ||
2201 | <tr> | ||
2202 | <td class="filename"><a href='download.php?file=miniupnpc-1.4.20100407.tar.gz'>miniupnpc-1.4.20100407.tar.gz</a></td> | ||
2203 | <td class="filesize">49756</td> | ||
2204 | <td class="filedate">07/04/2010 10:05:08 +0000</td> | ||
2205 | <td class="comment">MiniUPnP client source code</td> | ||
2206 | <td></td> | ||
2207 | </tr> | ||
2208 | <tr> | ||
2209 | <td class="filename"><a href='download.php?file=miniupnpc-1.4.20100405.tar.gz'>miniupnpc-1.4.20100405.tar.gz</a></td> | ||
2210 | <td class="filesize">49549</td> | ||
2211 | <td class="filedate">05/04/2010 14:34:38 +0000</td> | ||
2212 | <td class="comment">MiniUPnP client source code</td> | ||
2213 | <td></td> | ||
2214 | </tr> | ||
2215 | <tr> | ||
2216 | <td class="filename"><a href='download.php?file=miniupnpd-1.4.20100308.tar.gz'>miniupnpd-1.4.20100308.tar.gz</a></td> | ||
2217 | <td class="filesize">92889</td> | ||
2218 | <td class="filedate">08/03/2010 17:18:00 +0000</td> | ||
2219 | <td class="comment">MiniUPnP daemon source code</td> | ||
2220 | <td></td> | ||
2221 | </tr> | ||
2222 | <tr> | ||
2223 | <td class="filename"><a href='download.php?file=libnatpmp-20100202.tar.gz'>libnatpmp-20100202.tar.gz</a></td> | ||
2224 | <td class="filesize">17231</td> | ||
2225 | <td class="filedate">02/02/2010 18:41:13 +0000</td> | ||
2226 | <td class="comment">libnatpmp source code</td> | ||
2227 | <td></td> | ||
2228 | </tr> | ||
2229 | <tr> | ||
2230 | <td class="filename"><a href='download.php?file=miniupnpc-1.4.20100202.tar.gz'>miniupnpc-1.4.20100202.tar.gz</a></td> | ||
2231 | <td class="filesize">46710</td> | ||
2232 | <td class="filedate">02/02/2010 18:41:13 +0000</td> | ||
2233 | <td class="comment">MiniUPnP client source code</td> | ||
2234 | <td></td> | ||
2235 | </tr> | ||
2236 | <tr> | ||
2237 | <td class="filename"><a href='download.php?file=miniupnpc-1.4.20100106.tar.gz'>miniupnpc-1.4.20100106.tar.gz</a></td> | ||
2238 | <td class="filesize">46659</td> | ||
2239 | <td class="filedate">06/01/2010 10:08:21 +0000</td> | ||
2240 | <td class="comment">MiniUPnP client source code</td> | ||
2241 | <td></td> | ||
2242 | </tr> | ||
2243 | <tr> | ||
2244 | <td class="filename"><a href='download.php?file=miniupnpd-1.4.20091222.tar.gz'>miniupnpd-1.4.20091222.tar.gz</a></td> | ||
2245 | <td class="filesize">90993</td> | ||
2246 | <td class="filedate">22/12/2009 17:23:48 +0000</td> | ||
2247 | <td class="comment">MiniUPnP daemon source code</td> | ||
2248 | <td></td> | ||
2249 | </tr> | ||
2250 | <tr> | ||
2251 | <td class="filename"><a href='download.php?file=libnatpmp-20091219.tar.gz'>libnatpmp-20091219.tar.gz</a></td> | ||
2252 | <td class="filesize">16839</td> | ||
2253 | <td class="filedate">19/12/2009 14:35:22 +0000</td> | ||
2254 | <td class="comment">libnatpmp source code</td> | ||
2255 | <td></td> | ||
2256 | </tr> | ||
2257 | <tr> | ||
2258 | <td class="filename"><a href='download.php?file=miniupnpc-1.4.20091213.tar.gz'>miniupnpc-1.4.20091213.tar.gz</a></td> | ||
2259 | <td class="filesize">46510</td> | ||
2260 | <td class="filedate">12/12/2009 23:05:40 +0000</td> | ||
2261 | <td class="comment">MiniUPnP client source code</td> | ||
2262 | <td></td> | ||
2263 | </tr> | ||
2264 | <tr> | ||
2265 | <td class="filename"><a href='download.php?file=miniupnpc-1.4.20091211.tar.gz'>miniupnpc-1.4.20091211.tar.gz</a></td> | ||
2266 | <td class="filesize">45852</td> | ||
2267 | <td class="filedate">11/12/2009 16:43:01 +0000</td> | ||
2268 | <td class="comment">MiniUPnP client source code</td> | ||
2269 | <td></td> | ||
2270 | </tr> | ||
2271 | <tr> | ||
2272 | <td class="filename"><a href='download.php?file=upnpc-exe-win32-20091210.zip'>upnpc-exe-win32-20091210.zip</a></td> | ||
2273 | <td class="filesize">38666</td> | ||
2274 | <td class="filedate">10/12/2009 18:50:27 +0000</td> | ||
2275 | <td class="comment">Windows executable</td> | ||
2276 | <td></td> | ||
2277 | </tr> | ||
2278 | <tr> | ||
2279 | <td class="filename"><a href='download.php?file=miniupnpc-1.4.20091208.tar.gz'>miniupnpc-1.4.20091208.tar.gz</a></td> | ||
2280 | <td class="filesize">43392</td> | ||
2281 | <td class="filedate">08/12/2009 10:58:26 +0000</td> | ||
2282 | <td class="comment">MiniUPnP client source code</td> | ||
2283 | <td></td> | ||
2284 | </tr> | ||
2285 | <tr> | ||
2286 | <td class="filename"><a href='download.php?file=miniupnpc-1.4.20091203.tar.gz'>miniupnpc-1.4.20091203.tar.gz</a></td> | ||
2287 | <td class="filesize">42040</td> | ||
2288 | <td class="filedate">03/12/2009 13:56:28 +0000</td> | ||
2289 | <td class="comment">MiniUPnP client source code</td> | ||
2290 | <td></td> | ||
2291 | </tr> | ||
2292 | <tr> | ||
2293 | <td class="filename"><a href='download.php?file=miniupnpd-1.4.20091106.tar.gz'>miniupnpd-1.4.20091106.tar.gz</a></td> | ||
2294 | <td class="filesize">90787</td> | ||
2295 | <td class="filedate">06/11/2009 21:18:50 +0000</td> | ||
2296 | <td class="comment">MiniUPnP daemon source code</td> | ||
2297 | <td></td> | ||
2298 | </tr> | ||
2299 | <tr> | ||
2300 | <td class="filename"><a href='download.php?file=miniupnpd-1.4.tar.gz'>miniupnpd-1.4.tar.gz</a></td> | ||
2301 | <td class="filesize">90071</td> | ||
2302 | <td class="filedate">30/10/2009 09:20:05 +0000</td> | ||
2303 | <td class="comment">MiniUPnP daemon release source code</td> | ||
2304 | <td></td> | ||
2305 | </tr> | ||
2306 | <tr> | ||
2307 | <td class="filename"><a href='download.php?file=miniupnpc-1.4.tar.gz'>miniupnpc-1.4.tar.gz</a></td> | ||
2308 | <td class="filesize">41790</td> | ||
2309 | <td class="filedate">30/10/2009 09:20:04 +0000</td> | ||
2310 | <td class="comment">MiniUPnP client release source code</td> | ||
2311 | <td></td> | ||
2312 | </tr> | ||
2313 | <tr> | ||
2314 | <td class="filename"><a href='download.php?file=miniupnpc-20091016.tar.gz'>miniupnpc-20091016.tar.gz</a></td> | ||
2315 | <td class="filesize">41792</td> | ||
2316 | <td class="filedate">16/10/2009 09:04:35 +0000</td> | ||
2317 | <td class="comment">MiniUPnP client source code</td> | ||
2318 | <td></td> | ||
2319 | </tr> | ||
2320 | <tr> | ||
2321 | <td class="filename"><a href='download.php?file=miniupnpd-20091010.tar.gz'>miniupnpd-20091010.tar.gz</a></td> | ||
2322 | <td class="filesize">90043</td> | ||
2323 | <td class="filedate">10/10/2009 19:21:30 +0000</td> | ||
2324 | <td class="comment">MiniUPnP daemon source code</td> | ||
2325 | <td></td> | ||
2326 | </tr> | ||
2327 | <tr> | ||
2328 | <td class="filename"><a href='download.php?file=miniupnpc-20091010.tar.gz'>miniupnpc-20091010.tar.gz</a></td> | ||
2329 | <td class="filesize">41671</td> | ||
2330 | <td class="filedate">10/10/2009 19:21:28 +0000</td> | ||
2331 | <td class="comment">MiniUPnP client source code</td> | ||
2332 | <td></td> | ||
2333 | </tr> | ||
2334 | <tr> | ||
2335 | <td class="filename"><a href='download.php?file=miniupnpd-20090921.tar.gz'>miniupnpd-20090921.tar.gz</a></td> | ||
2336 | <td class="filesize">89476</td> | ||
2337 | <td class="filedate">21/09/2009 13:00:04 +0000</td> | ||
2338 | <td class="comment">MiniUPnP daemon source code</td> | ||
2339 | <td></td> | ||
2340 | </tr> | ||
2341 | <tr> | ||
2342 | <td class="filename"><a href='download.php?file=miniupnpc-20090921.tar.gz'>miniupnpc-20090921.tar.gz</a></td> | ||
2343 | <td class="filesize">41630</td> | ||
2344 | <td class="filedate">21/09/2009 13:00:03 +0000</td> | ||
2345 | <td class="comment">MiniUPnP client source code</td> | ||
2346 | <td></td> | ||
2347 | </tr> | ||
2348 | <tr> | ||
2349 | <td class="filename"><a href='download.php?file=miniupnpd-20090904.tar.gz'>miniupnpd-20090904.tar.gz</a></td> | ||
2350 | <td class="filesize">89344</td> | ||
2351 | <td class="filedate">04/09/2009 16:24:26 +0000</td> | ||
2352 | <td class="comment">MiniUPnP daemon source code</td> | ||
2353 | <td></td> | ||
2354 | </tr> | ||
2355 | <tr> | ||
2356 | <td class="filename"><a href='download.php?file=miniupnpd-20090820.tar.gz'>miniupnpd-20090820.tar.gz</a></td> | ||
2357 | <td class="filesize">89149</td> | ||
2358 | <td class="filedate">20/08/2009 09:35:58 +0000</td> | ||
2359 | <td class="comment">MiniUPnP daemon source code</td> | ||
2360 | <td></td> | ||
2361 | </tr> | ||
2362 | <tr> | ||
2363 | <td class="filename"><a href='download.php?file=miniupnpc-20090807.tar.gz'>miniupnpc-20090807.tar.gz</a></td> | ||
2364 | <td class="filesize">41288</td> | ||
2365 | <td class="filedate">07/08/2009 14:46:11 +0000</td> | ||
2366 | <td class="comment">MiniUPnP client source code</td> | ||
2367 | <td></td> | ||
2368 | </tr> | ||
2369 | <tr> | ||
2370 | <td class="filename"><a href='download.php?file=miniupnpc-20090729.tar.gz'>miniupnpc-20090729.tar.gz</a></td> | ||
2371 | <td class="filesize">40588</td> | ||
2372 | <td class="filedate">29/07/2009 08:47:43 +0000</td> | ||
2373 | <td class="comment">MiniUPnP client source code</td> | ||
2374 | <td></td> | ||
2375 | </tr> | ||
2376 | <tr> | ||
2377 | <td class="filename"><a href='download.php?file=xchat-upnp20061022.patch'>xchat-upnp20061022.patch</a></td> | ||
2378 | <td class="filesize">10258</td> | ||
2379 | <td class="filedate">17/07/2009 15:49:46 +0000</td> | ||
2380 | <td class="comment">Patch to add UPnP capabilities to xchat</td> | ||
2381 | <td></td> | ||
2382 | </tr> | ||
2383 | <tr> | ||
2384 | <td class="filename"><a href='download.php?file=miniupnpc-20090713.tar.gz'>miniupnpc-20090713.tar.gz</a></td> | ||
2385 | <td class="filesize">40206</td> | ||
2386 | <td class="filedate">13/07/2009 08:53:49 +0000</td> | ||
2387 | <td class="comment">MiniUPnP client source code</td> | ||
2388 | <td></td> | ||
2389 | </tr> | ||
2390 | <tr> | ||
2391 | <td class="filename"><a href='download.php?file=libnatpmp-20090713.tar.gz'>libnatpmp-20090713.tar.gz</a></td> | ||
2392 | <td class="filesize">14262</td> | ||
2393 | <td class="filedate">13/07/2009 08:53:49 +0000</td> | ||
2394 | <td class="comment">libnatpmp source code</td> | ||
2395 | <td></td> | ||
2396 | </tr> | ||
2397 | <tr> | ||
2398 | <td class="filename"><a href='download.php?file=miniupnpd-20090605.tar.gz'>miniupnpd-20090605.tar.gz</a></td> | ||
2399 | <td class="filesize">83774</td> | ||
2400 | <td class="filedate">04/06/2009 23:32:20 +0000</td> | ||
2401 | <td class="comment">MiniUPnP daemon source code</td> | ||
2402 | <td></td> | ||
2403 | </tr> | ||
2404 | <tr> | ||
2405 | <td class="filename"><a href='download.php?file=miniupnpc-20090605.tar.gz'>miniupnpc-20090605.tar.gz</a></td> | ||
2406 | <td class="filesize">40077</td> | ||
2407 | <td class="filedate">04/06/2009 23:32:16 +0000</td> | ||
2408 | <td class="comment">MiniUPnP client source code</td> | ||
2409 | <td></td> | ||
2410 | </tr> | ||
2411 | <tr> | ||
2412 | <td class="filename"><a href='download.php?file=libnatpmp-20090605.tar.gz'>libnatpmp-20090605.tar.gz</a></td> | ||
2413 | <td class="filesize">13817</td> | ||
2414 | <td class="filedate">04/06/2009 23:32:15 +0000</td> | ||
2415 | <td class="comment">libnatpmp source code</td> | ||
2416 | <td></td> | ||
2417 | </tr> | ||
2418 | <tr> | ||
2419 | <td class="filename"><a href='download.php?file=miniupnpd-20090516.tar.gz'>miniupnpd-20090516.tar.gz</a></td> | ||
2420 | <td class="filesize">83689</td> | ||
2421 | <td class="filedate">16/05/2009 08:47:31 +0000</td> | ||
2422 | <td class="comment">MiniUPnP daemon source code</td> | ||
2423 | <td></td> | ||
2424 | </tr> | ||
2425 | <tr> | ||
2426 | <td class="filename"><a href='download.php?file=miniupnpc-1.3.tar.gz'>miniupnpc-1.3.tar.gz</a></td> | ||
2427 | <td class="filesize">40058</td> | ||
2428 | <td class="filedate">17/04/2009 21:27:55 +0000</td> | ||
2429 | <td class="comment">MiniUPnP client release source code</td> | ||
2430 | <td></td> | ||
2431 | </tr> | ||
2432 | <tr> | ||
2433 | <td class="filename"><a href='download.php?file=miniupnpd-1.3.tar.gz'>miniupnpd-1.3.tar.gz</a></td> | ||
2434 | <td class="filesize">83464</td> | ||
2435 | <td class="filedate">17/04/2009 20:11:21 +0000</td> | ||
2436 | <td class="comment">MiniUPnP daemon release source code</td> | ||
2437 | <td></td> | ||
2438 | </tr> | ||
2439 | <tr> | ||
2440 | <td class="filename"><a href='download.php?file=libnatpmp-20090310.tar.gz'>libnatpmp-20090310.tar.gz</a></td> | ||
2441 | <td class="filesize">11847</td> | ||
2442 | <td class="filedate">10/03/2009 10:19:45 +0000</td> | ||
2443 | <td class="comment">libnatpmp source code</td> | ||
2444 | <td></td> | ||
2445 | </tr> | ||
2446 | <tr> | ||
2447 | <td class="filename"><a href='download.php?file=miniupnpd-20090214.tar.gz'>miniupnpd-20090214.tar.gz</a></td> | ||
2448 | <td class="filesize">82921</td> | ||
2449 | <td class="filedate">14/02/2009 11:27:03 +0000</td> | ||
2450 | <td class="comment">MiniUPnP daemon source code</td> | ||
2451 | <td></td> | ||
2452 | </tr> | ||
2453 | <tr> | ||
2454 | <td class="filename"><a href='download.php?file=miniupnpd-20090213.tar.gz'>miniupnpd-20090213.tar.gz</a></td> | ||
2455 | <td class="filesize">82594</td> | ||
2456 | <td class="filedate">13/02/2009 19:48:01 +0000</td> | ||
2457 | <td class="comment">MiniUPnP daemon source code</td> | ||
2458 | <td></td> | ||
2459 | </tr> | ||
2460 | <tr> | ||
2461 | <td class="filename"><a href='download.php?file=libnatpmp-20090129.tar.gz'>libnatpmp-20090129.tar.gz</a></td> | ||
2462 | <td class="filesize">11748</td> | ||
2463 | <td class="filedate">29/01/2009 21:50:31 +0000</td> | ||
2464 | <td class="comment">libnatpmp source code</td> | ||
2465 | <td></td> | ||
2466 | </tr> | ||
2467 | <tr> | ||
2468 | <td class="filename"><a href='download.php?file=miniupnpc-20090129.tar.gz'>miniupnpc-20090129.tar.gz</a></td> | ||
2469 | <td class="filesize">39976</td> | ||
2470 | <td class="filedate">29/01/2009 21:50:30 +0000</td> | ||
2471 | <td class="comment">MiniUPnP client source code</td> | ||
2472 | <td></td> | ||
2473 | </tr> | ||
2474 | <tr> | ||
2475 | <td class="filename"><a href='download.php?file=miniupnpd-20090129.tar.gz'>miniupnpd-20090129.tar.gz</a></td> | ||
2476 | <td class="filesize">82487</td> | ||
2477 | <td class="filedate">29/01/2009 21:50:27 +0000</td> | ||
2478 | <td class="comment">MiniUPnP daemon source code</td> | ||
2479 | <td></td> | ||
2480 | </tr> | ||
2481 | <tr> | ||
2482 | <td class="filename"><a href='download.php?file=miniupnpd-20081009.tar.gz'>miniupnpd-20081009.tar.gz</a></td> | ||
2483 | <td class="filesize">81732</td> | ||
2484 | <td class="filedate">09/10/2008 12:53:02 +0000</td> | ||
2485 | <td class="comment">MiniUPnP daemon source code</td> | ||
2486 | <td></td> | ||
2487 | </tr> | ||
2488 | <tr> | ||
2489 | <td class="filename"><a href='download.php?file=minissdpd-1.0.tar.gz'>minissdpd-1.0.tar.gz</a></td> | ||
2490 | <td class="filesize">12996</td> | ||
2491 | <td class="filedate">07/10/2008 14:03:49 +0000</td> | ||
2492 | <td class="comment">MiniSSDPd release source code</td> | ||
2493 | <td></td> | ||
2494 | </tr> | ||
2495 | <tr> | ||
2496 | <td class="filename"><a href='download.php?file=miniupnpc-1.2.tar.gz'>miniupnpc-1.2.tar.gz</a></td> | ||
2497 | <td class="filesize">38787</td> | ||
2498 | <td class="filedate">07/10/2008 14:03:47 +0000</td> | ||
2499 | <td class="comment">MiniUPnP client release source code</td> | ||
2500 | <td></td> | ||
2501 | </tr> | ||
2502 | <tr> | ||
2503 | <td class="filename"><a href='download.php?file=miniupnpd-1.2.tar.gz'>miniupnpd-1.2.tar.gz</a></td> | ||
2504 | <td class="filesize">81025</td> | ||
2505 | <td class="filedate">07/10/2008 14:03:45 +0000</td> | ||
2506 | <td class="comment">MiniUPnP daemon release source code</td> | ||
2507 | <td></td> | ||
2508 | </tr> | ||
2509 | <tr> | ||
2510 | <td class="filename"><a href='download.php?file=miniupnpd-20081006.tar.gz'>miniupnpd-20081006.tar.gz</a></td> | ||
2511 | <td class="filesize">80510</td> | ||
2512 | <td class="filedate">06/10/2008 15:50:34 +0000</td> | ||
2513 | <td class="comment">MiniUPnP daemon source code</td> | ||
2514 | <td></td> | ||
2515 | </tr> | ||
2516 | <tr> | ||
2517 | <td class="filename"><a href='download.php?file=minissdpd-20081006.tar.gz'>minissdpd-20081006.tar.gz</a></td> | ||
2518 | <td class="filesize">12230</td> | ||
2519 | <td class="filedate">06/10/2008 15:50:33 +0000</td> | ||
2520 | <td class="comment">MiniSSDPd source code</td> | ||
2521 | <td></td> | ||
2522 | </tr> | ||
2523 | <tr> | ||
2524 | <td class="filename"><a href='download.php?file=libnatpmp-20081006.tar.gz'>libnatpmp-20081006.tar.gz</a></td> | ||
2525 | <td class="filesize">11710</td> | ||
2526 | <td class="filedate">06/10/2008 15:50:31 +0000</td> | ||
2527 | <td class="comment">libnatpmp source code</td> | ||
2528 | <td></td> | ||
2529 | </tr> | ||
2530 | <tr> | ||
2531 | <td class="filename" colspan="2"><a href='download.php?file=mediatomb_minissdp-20081006.patch'>mediatomb_minissdp-20081006.patch</a></td> | ||
2532 | <td class="filedate">06/10/2008 15:48:18 +0000</td> | ||
2533 | <td class="comment"></td> | ||
2534 | <td></td> | ||
2535 | </tr> | ||
2536 | <tr> | ||
2537 | <td class="filename"><a href='download.php?file=miniupnpc-20081002.tar.gz'>miniupnpc-20081002.tar.gz</a></td> | ||
2538 | <td class="filesize">38291</td> | ||
2539 | <td class="filedate">02/10/2008 09:20:18 +0000</td> | ||
2540 | <td class="comment">MiniUPnP client source code</td> | ||
2541 | <td></td> | ||
2542 | </tr> | ||
2543 | <tr> | ||
2544 | <td class="filename"><a href='download.php?file=miniupnpd-20081001.tar.gz'>miniupnpd-20081001.tar.gz</a></td> | ||
2545 | <td class="filesize">79696</td> | ||
2546 | <td class="filedate">01/10/2008 13:11:20 +0000</td> | ||
2547 | <td class="comment">MiniUPnP daemon source code</td> | ||
2548 | <td></td> | ||
2549 | </tr> | ||
2550 | <tr> | ||
2551 | <td class="filename"><a href='download.php?file=upnpc-exe-win32-20080925.zip'>upnpc-exe-win32-20080925.zip</a></td> | ||
2552 | <td class="filesize">36602</td> | ||
2553 | <td class="filedate">25/09/2008 06:59:33 +0000</td> | ||
2554 | <td class="comment">Windows executable</td> | ||
2555 | <td></td> | ||
2556 | </tr> | ||
2557 | <tr> | ||
2558 | <td class="filename"><a href='download.php?file=miniupnpd-20080710.tar.gz'>miniupnpd-20080710.tar.gz</a></td> | ||
2559 | <td class="filesize">78898</td> | ||
2560 | <td class="filedate">10/07/2008 09:38:41 +0000</td> | ||
2561 | <td class="comment">MiniUPnP daemon source code</td> | ||
2562 | <td></td> | ||
2563 | </tr> | ||
2564 | <tr> | ||
2565 | <td class="filename"><a href='download.php?file=libnatpmp-20080707.tar.gz'>libnatpmp-20080707.tar.gz</a></td> | ||
2566 | <td class="filesize">11679</td> | ||
2567 | <td class="filedate">06/07/2008 22:05:23 +0000</td> | ||
2568 | <td class="comment">libnatpmp source code</td> | ||
2569 | <td></td> | ||
2570 | </tr> | ||
2571 | <tr> | ||
2572 | <td class="filename"><a href='download.php?file=miniupnpc-1.1.tar.gz'>miniupnpc-1.1.tar.gz</a></td> | ||
2573 | <td class="filesize">38235</td> | ||
2574 | <td class="filedate">04/07/2008 16:45:24 +0000</td> | ||
2575 | <td class="comment">MiniUPnP client release source code</td> | ||
2576 | <td></td> | ||
2577 | </tr> | ||
2578 | <tr> | ||
2579 | <td class="filename"><a href='download.php?file=miniupnpc-20080703.tar.gz'>miniupnpc-20080703.tar.gz</a></td> | ||
2580 | <td class="filesize">38204</td> | ||
2581 | <td class="filedate">03/07/2008 15:47:37 +0000</td> | ||
2582 | <td class="comment">MiniUPnP client source code</td> | ||
2583 | <td></td> | ||
2584 | </tr> | ||
2585 | <tr> | ||
2586 | <td class="filename"><a href='download.php?file=libnatpmp-20080703.tar.gz'>libnatpmp-20080703.tar.gz</a></td> | ||
2587 | <td class="filesize">11570</td> | ||
2588 | <td class="filedate">03/07/2008 15:47:25 +0000</td> | ||
2589 | <td class="comment">libnatpmp source code</td> | ||
2590 | <td></td> | ||
2591 | </tr> | ||
2592 | <tr> | ||
2593 | <td class="filename"><a href='download.php?file=upnpc-exe-win32-20080703.zip'>upnpc-exe-win32-20080703.zip</a></td> | ||
2594 | <td class="filesize">36137</td> | ||
2595 | <td class="filedate">02/07/2008 23:35:14 +0000</td> | ||
2596 | <td class="comment">Windows executable</td> | ||
2597 | <td></td> | ||
2598 | </tr> | ||
2599 | <tr> | ||
2600 | <td class="filename"><a href='download.php?file=libnatpmp-20080702.tar.gz'>libnatpmp-20080702.tar.gz</a></td> | ||
2601 | <td class="filesize">8873</td> | ||
2602 | <td class="filedate">02/07/2008 17:32:35 +0000</td> | ||
2603 | <td class="comment">libnatpmp source code</td> | ||
2604 | <td></td> | ||
2605 | </tr> | ||
2606 | <tr> | ||
2607 | <td class="filename"><a href='download.php?file=libnatpmp-20080630.tar.gz'>libnatpmp-20080630.tar.gz</a></td> | ||
2608 | <td class="filesize">8864</td> | ||
2609 | <td class="filedate">30/06/2008 14:20:16 +0000</td> | ||
2610 | <td class="comment">libnatpmp source code</td> | ||
2611 | <td></td> | ||
2612 | </tr> | ||
2613 | <tr> | ||
2614 | <td class="filename"><a href='download.php?file=libnatpmp-20080529.tar.gz'>libnatpmp-20080529.tar.gz</a></td> | ||
2615 | <td class="filesize">7397</td> | ||
2616 | <td class="filedate">29/05/2008 09:06:25 +0000</td> | ||
2617 | <td class="comment">libnatpmp source code</td> | ||
2618 | <td></td> | ||
2619 | </tr> | ||
2620 | <tr> | ||
2621 | <td class="filename"><a href='download.php?file=upnpc-exe-win32-20080514.zip'>upnpc-exe-win32-20080514.zip</a></td> | ||
2622 | <td class="filesize">14227</td> | ||
2623 | <td class="filedate">14/05/2008 20:23:19 +0000</td> | ||
2624 | <td class="comment">Windows executable</td> | ||
2625 | <td></td> | ||
2626 | </tr> | ||
2627 | <tr> | ||
2628 | <td class="filename"><a href='download.php?file=libnatpmp-20080428.tar.gz'>libnatpmp-20080428.tar.gz</a></td> | ||
2629 | <td class="filesize">7295</td> | ||
2630 | <td class="filedate">28/04/2008 03:09:14 +0000</td> | ||
2631 | <td class="comment">libnatpmp source code</td> | ||
2632 | <td></td> | ||
2633 | </tr> | ||
2634 | <tr> | ||
2635 | <td class="filename"><a href='download.php?file=miniupnpd-20080427.tar.gz'>miniupnpd-20080427.tar.gz</a></td> | ||
2636 | <td class="filesize">78765</td> | ||
2637 | <td class="filedate">27/04/2008 18:16:36 +0000</td> | ||
2638 | <td class="comment">MiniUPnP daemon source code</td> | ||
2639 | <td></td> | ||
2640 | </tr> | ||
2641 | <tr> | ||
2642 | <td class="filename"><a href='download.php?file=miniupnpc-20080427.tar.gz'>miniupnpc-20080427.tar.gz</a></td> | ||
2643 | <td class="filesize">37610</td> | ||
2644 | <td class="filedate">27/04/2008 18:16:35 +0000</td> | ||
2645 | <td class="comment">MiniUPnP client source code</td> | ||
2646 | <td></td> | ||
2647 | </tr> | ||
2648 | <tr> | ||
2649 | <td class="filename"><a href='download.php?file=miniupnpd-1.1.tar.gz'>miniupnpd-1.1.tar.gz</a></td> | ||
2650 | <td class="filesize">78594</td> | ||
2651 | <td class="filedate">25/04/2008 17:38:05 +0000</td> | ||
2652 | <td class="comment">MiniUPnP daemon release source code</td> | ||
2653 | <td></td> | ||
2654 | </tr> | ||
2655 | <tr> | ||
2656 | <td class="filename"><a href='download.php?file=miniupnpc-20080423.tar.gz'>miniupnpc-20080423.tar.gz</a></td> | ||
2657 | <td class="filesize">36818</td> | ||
2658 | <td class="filedate">23/04/2008 11:57:36 +0000</td> | ||
2659 | <td class="comment">MiniUPnP client source code</td> | ||
2660 | <td></td> | ||
2661 | </tr> | ||
2662 | <tr> | ||
2663 | <td class="filename"><a href='download.php?file=miniupnpd-20080308.tar.gz'>miniupnpd-20080308.tar.gz</a></td> | ||
2664 | <td class="filesize">75679</td> | ||
2665 | <td class="filedate">08/03/2008 11:13:29 +0000</td> | ||
2666 | <td class="comment">MiniUPnP daemon source code</td> | ||
2667 | <td></td> | ||
2668 | </tr> | ||
2669 | <tr> | ||
2670 | <td class="filename"><a href='download.php?file=miniupnpd-20080303.tar.gz'>miniupnpd-20080303.tar.gz</a></td> | ||
2671 | <td class="filesize">74202</td> | ||
2672 | <td class="filedate">03/03/2008 01:43:16 +0000</td> | ||
2673 | <td class="comment">MiniUPnP daemon source code</td> | ||
2674 | <td></td> | ||
2675 | </tr> | ||
2676 | <tr> | ||
2677 | <td class="filename"><a href='download.php?file=miniupnpd-20080224.tar.gz'>miniupnpd-20080224.tar.gz</a></td> | ||
2678 | <td class="filesize">72773</td> | ||
2679 | <td class="filedate">24/02/2008 11:23:17 +0000</td> | ||
2680 | <td class="comment">MiniUPnP daemon source code</td> | ||
2681 | <td></td> | ||
2682 | </tr> | ||
2683 | <tr> | ||
2684 | <td class="filename"><a href='download.php?file=miniupnpc-1.0.tar.gz'>miniupnpc-1.0.tar.gz</a></td> | ||
2685 | <td class="filesize">36223</td> | ||
2686 | <td class="filedate">21/02/2008 13:26:46 +0000</td> | ||
2687 | <td class="comment">MiniUPnP client release source code</td> | ||
2688 | <td></td> | ||
2689 | </tr> | ||
2690 | <tr> | ||
2691 | <td class="filename"><a href='download.php?file=miniupnpd-20080221.tar.gz'>miniupnpd-20080221.tar.gz</a></td> | ||
2692 | <td class="filesize">70823</td> | ||
2693 | <td class="filedate">21/02/2008 10:23:46 +0000</td> | ||
2694 | <td class="comment">MiniUPnP daemon source code</td> | ||
2695 | <td></td> | ||
2696 | </tr> | ||
2697 | <tr> | ||
2698 | <td class="filename"><a href='download.php?file=miniupnpc-20080217.tar.gz'>miniupnpc-20080217.tar.gz</a></td> | ||
2699 | <td class="filesize">35243</td> | ||
2700 | <td class="filedate">16/02/2008 23:47:59 +0000</td> | ||
2701 | <td class="comment">MiniUPnP client source code</td> | ||
2702 | <td></td> | ||
2703 | </tr> | ||
2704 | <tr> | ||
2705 | <td class="filename"><a href='download.php?file=miniupnpd-20080207.tar.gz'>miniupnpd-20080207.tar.gz</a></td> | ||
2706 | <td class="filesize">70647</td> | ||
2707 | <td class="filedate">07/02/2008 21:21:00 +0000</td> | ||
2708 | <td class="comment">MiniUPnP daemon source code</td> | ||
2709 | <td></td> | ||
2710 | </tr> | ||
2711 | <tr> | ||
2712 | <td class="filename"><a href='download.php?file=miniupnpc-20080203.tar.gz'>miniupnpc-20080203.tar.gz</a></td> | ||
2713 | <td class="filesize">34921</td> | ||
2714 | <td class="filedate">03/02/2008 22:28:11 +0000</td> | ||
2715 | <td class="comment">MiniUPnP client source code</td> | ||
2716 | <td></td> | ||
2717 | </tr> | ||
2718 | <tr> | ||
2719 | <td class="filename"><a href='download.php?file=miniupnpd-1.0.tar.gz'>miniupnpd-1.0.tar.gz</a></td> | ||
2720 | <td class="filesize">69427</td> | ||
2721 | <td class="filedate">27/01/2008 22:41:25 +0000</td> | ||
2722 | <td class="comment">MiniUPnP daemon release source code</td> | ||
2723 | <td></td> | ||
2724 | </tr> | ||
2725 | <tr> | ||
2726 | <td class="filename"><a href='download.php?file=upnpc-exe-win32-20080118.zip'>upnpc-exe-win32-20080118.zip</a></td> | ||
2727 | <td class="filesize">13582</td> | ||
2728 | <td class="filedate">18/01/2008 11:42:16 +0000</td> | ||
2729 | <td class="comment">Windows executable</td> | ||
2730 | <td></td> | ||
2731 | </tr> | ||
2732 | <tr> | ||
2733 | <td class="filename"><a href='download.php?file=miniupnpd-1.0-RC13.tar.gz'>miniupnpd-1.0-RC13.tar.gz</a></td> | ||
2734 | <td class="filesize">67892</td> | ||
2735 | <td class="filedate">03/01/2008 16:50:21 +0000</td> | ||
2736 | <td class="comment">MiniUPnP daemon release source code</td> | ||
2737 | <td></td> | ||
2738 | </tr> | ||
2739 | <tr> | ||
2740 | <td class="filename"><a href='download.php?file=miniupnpc-1.0-RC13.tar.gz'>miniupnpc-1.0-RC13.tar.gz</a></td> | ||
2741 | <td class="filesize">34820</td> | ||
2742 | <td class="filedate">03/01/2008 16:50:20 +0000</td> | ||
2743 | <td class="comment">MiniUPnP client release source code</td> | ||
2744 | <td></td> | ||
2745 | </tr> | ||
2746 | <tr> | ||
2747 | <td class="filename"><a href='download.php?file=miniupnpd-20071220.tar.gz'>miniupnpd-20071220.tar.gz</a></td> | ||
2748 | <td class="filesize">67211</td> | ||
2749 | <td class="filedate">20/12/2007 12:08:34 +0000</td> | ||
2750 | <td class="comment">MiniUPnP daemon source code</td> | ||
2751 | <td></td> | ||
2752 | </tr> | ||
2753 | <tr> | ||
2754 | <td class="filename"><a href='download.php?file=miniupnpc-20071219.tar.gz'>miniupnpc-20071219.tar.gz</a></td> | ||
2755 | <td class="filesize">34290</td> | ||
2756 | <td class="filedate">19/12/2007 18:31:47 +0000</td> | ||
2757 | <td class="comment">MiniUPnP client source code</td> | ||
2758 | <td></td> | ||
2759 | </tr> | ||
2760 | <tr> | ||
2761 | <td class="filename"><a href='download.php?file=minissdpd-1.0-RC12.tar.gz'>minissdpd-1.0-RC12.tar.gz</a></td> | ||
2762 | <td class="filesize">9956</td> | ||
2763 | <td class="filedate">19/12/2007 18:30:12 +0000</td> | ||
2764 | <td class="comment">MiniSSDPd release source code</td> | ||
2765 | <td></td> | ||
2766 | </tr> | ||
2767 | <tr> | ||
2768 | <td class="filename"><a href='download.php?file=miniupnpd-1.0-RC12.tar.gz'>miniupnpd-1.0-RC12.tar.gz</a></td> | ||
2769 | <td class="filesize">66911</td> | ||
2770 | <td class="filedate">14/12/2007 17:39:20 +0000</td> | ||
2771 | <td class="comment">MiniUPnP daemon release source code</td> | ||
2772 | <td></td> | ||
2773 | </tr> | ||
2774 | <tr> | ||
2775 | <td class="filename"><a href='download.php?file=miniupnpc-1.0-RC12.tar.gz'>miniupnpc-1.0-RC12.tar.gz</a></td> | ||
2776 | <td class="filesize">32543</td> | ||
2777 | <td class="filedate">14/12/2007 17:39:19 +0000</td> | ||
2778 | <td class="comment">MiniUPnP client release source code</td> | ||
2779 | <td></td> | ||
2780 | </tr> | ||
2781 | <tr> | ||
2782 | <td class="filename"><a href='download.php?file=miniupnpc-20071213.tar.gz'>miniupnpc-20071213.tar.gz</a></td> | ||
2783 | <td class="filesize">32541</td> | ||
2784 | <td class="filedate">13/12/2007 17:09:51 +0000</td> | ||
2785 | <td class="comment">MiniUPnP client source code</td> | ||
2786 | <td></td> | ||
2787 | </tr> | ||
2788 | <tr> | ||
2789 | <td class="filename"><a href='download.php?file=miniupnpd-20071213.tar.gz'>miniupnpd-20071213.tar.gz</a></td> | ||
2790 | <td class="filesize">66826</td> | ||
2791 | <td class="filedate">13/12/2007 16:42:50 +0000</td> | ||
2792 | <td class="comment">MiniUPnP daemon source code</td> | ||
2793 | <td></td> | ||
2794 | </tr> | ||
2795 | <tr> | ||
2796 | <td class="filename"><a href='download.php?file=libnatpmp-20071213.tar.gz'>libnatpmp-20071213.tar.gz</a></td> | ||
2797 | <td class="filesize">5997</td> | ||
2798 | <td class="filedate">13/12/2007 14:56:30 +0000</td> | ||
2799 | <td class="comment">libnatpmp source code</td> | ||
2800 | <td></td> | ||
2801 | </tr> | ||
2802 | <tr> | ||
2803 | <td class="filename"><a href='download.php?file=libnatpmp-20071202.tar.gz'>libnatpmp-20071202.tar.gz</a></td> | ||
2804 | <td class="filesize">5664</td> | ||
2805 | <td class="filedate">02/12/2007 00:15:28 +0000</td> | ||
2806 | <td class="comment">libnatpmp source code</td> | ||
2807 | <td></td> | ||
2808 | </tr> | ||
2809 | <tr> | ||
2810 | <td class="filename"><a href='download.php?file=miniupnpd-20071103.tar.gz'>miniupnpd-20071103.tar.gz</a></td> | ||
2811 | <td class="filesize">65740</td> | ||
2812 | <td class="filedate">02/11/2007 23:58:38 +0000</td> | ||
2813 | <td class="comment">MiniUPnP daemon source code</td> | ||
2814 | <td></td> | ||
2815 | </tr> | ||
2816 | <tr> | ||
2817 | <td class="filename"><a href='download.php?file=miniupnpd-20071102.tar.gz'>miniupnpd-20071102.tar.gz</a></td> | ||
2818 | <td class="filesize">65733</td> | ||
2819 | <td class="filedate">02/11/2007 23:05:44 +0000</td> | ||
2820 | <td class="comment">MiniUPnP daemon source code</td> | ||
2821 | <td></td> | ||
2822 | </tr> | ||
2823 | <tr> | ||
2824 | <td class="filename"><a href='download.php?file=miniupnpc-20071103.tar.gz'>miniupnpc-20071103.tar.gz</a></td> | ||
2825 | <td class="filesize">32239</td> | ||
2826 | <td class="filedate">02/11/2007 23:05:34 +0000</td> | ||
2827 | <td class="comment">MiniUPnP client source code</td> | ||
2828 | <td></td> | ||
2829 | </tr> | ||
2830 | <tr> | ||
2831 | <td class="filename"><a href='download.php?file=miniupnpd-1.0-RC11.tar.gz'>miniupnpd-1.0-RC11.tar.gz</a></td> | ||
2832 | <td class="filesize">64828</td> | ||
2833 | <td class="filedate">25/10/2007 13:27:18 +0000</td> | ||
2834 | <td class="comment">MiniUPnP daemon release source code</td> | ||
2835 | <td></td> | ||
2836 | </tr> | ||
2837 | <tr> | ||
2838 | <td class="filename"><a href='download.php?file=miniupnpc-1.0-RC11.tar.gz'>miniupnpc-1.0-RC11.tar.gz</a></td> | ||
2839 | <td class="filesize">32161</td> | ||
2840 | <td class="filedate">25/10/2007 13:27:17 +0000</td> | ||
2841 | <td class="comment">MiniUPnP client release source code</td> | ||
2842 | <td></td> | ||
2843 | </tr> | ||
2844 | <tr> | ||
2845 | <td class="filename"><a href='download.php?file=upnpc-exe-win32-20071025.zip'>upnpc-exe-win32-20071025.zip</a></td> | ||
2846 | <td class="filesize">12809</td> | ||
2847 | <td class="filedate">24/10/2007 23:15:55 +0000</td> | ||
2848 | <td class="comment">Windows executable</td> | ||
2849 | <td></td> | ||
2850 | </tr> | ||
2851 | <tr> | ||
2852 | <td class="filename"><a href='download.php?file=miniupnpd-1.0-RC10.tar.gz'>miniupnpd-1.0-RC10.tar.gz</a></td> | ||
2853 | <td class="filesize">62674</td> | ||
2854 | <td class="filedate">12/10/2007 08:38:33 +0000</td> | ||
2855 | <td class="comment">MiniUPnP daemon release source code</td> | ||
2856 | <td></td> | ||
2857 | </tr> | ||
2858 | <tr> | ||
2859 | <td class="filename"><a href='download.php?file=miniupnpc-1.0-RC10.tar.gz'>miniupnpc-1.0-RC10.tar.gz</a></td> | ||
2860 | <td class="filesize">31962</td> | ||
2861 | <td class="filedate">12/10/2007 08:38:31 +0000</td> | ||
2862 | <td class="comment">MiniUPnP client release source code</td> | ||
2863 | <td></td> | ||
2864 | </tr> | ||
2865 | <tr> | ||
2866 | <td class="filename"><a href='download.php?file=minissdpd-1.0-RC10.tar.gz'>minissdpd-1.0-RC10.tar.gz</a></td> | ||
2867 | <td class="filesize">9517</td> | ||
2868 | <td class="filedate">12/10/2007 08:38:30 +0000</td> | ||
2869 | <td class="comment">MiniSSDPd release source code</td> | ||
2870 | <td></td> | ||
2871 | </tr> | ||
2872 | <tr> | ||
2873 | <td class="filename"><a href='download.php?file=miniupnpc-20071003.tar.gz'>miniupnpc-20071003.tar.gz</a></td> | ||
2874 | <td class="filesize">31199</td> | ||
2875 | <td class="filedate">03/10/2007 15:30:13 +0000</td> | ||
2876 | <td class="comment">MiniUPnP client source code</td> | ||
2877 | <td></td> | ||
2878 | </tr> | ||
2879 | <tr> | ||
2880 | <td class="filename"><a href='download.php?file=upnpc-exe-win32-20071001.zip'>upnpc-exe-win32-20071001.zip</a></td> | ||
2881 | <td class="filesize">12604</td> | ||
2882 | <td class="filedate">01/10/2007 17:09:22 +0000</td> | ||
2883 | <td class="comment">Windows executable</td> | ||
2884 | <td></td> | ||
2885 | </tr> | ||
2886 | <tr> | ||
2887 | <td class="filename"><a href='download.php?file=miniupnpd-1.0-RC9.tar.gz'>miniupnpd-1.0-RC9.tar.gz</a></td> | ||
2888 | <td class="filesize">54778</td> | ||
2889 | <td class="filedate">27/09/2007 19:38:36 +0000</td> | ||
2890 | <td class="comment">MiniUPnP daemon release source code</td> | ||
2891 | <td></td> | ||
2892 | </tr> | ||
2893 | <tr> | ||
2894 | <td class="filename"><a href='download.php?file=minissdpd-1.0-RC9.tar.gz'>minissdpd-1.0-RC9.tar.gz</a></td> | ||
2895 | <td class="filesize">9163</td> | ||
2896 | <td class="filedate">27/09/2007 17:00:03 +0000</td> | ||
2897 | <td class="comment">MiniSSDPd release source code</td> | ||
2898 | <td></td> | ||
2899 | </tr> | ||
2900 | <tr> | ||
2901 | <td class="filename"><a href='download.php?file=miniupnpc-1.0-RC9.tar.gz'>miniupnpc-1.0-RC9.tar.gz</a></td> | ||
2902 | <td class="filesize">30538</td> | ||
2903 | <td class="filedate">27/09/2007 17:00:03 +0000</td> | ||
2904 | <td class="comment">MiniUPnP client release source code</td> | ||
2905 | <td></td> | ||
2906 | </tr> | ||
2907 | <tr> | ||
2908 | <td class="filename"><a href='download.php?file=miniupnpd-20070924.tar.gz'>miniupnpd-20070924.tar.gz</a></td> | ||
2909 | <td class="filesize">52338</td> | ||
2910 | <td class="filedate">24/09/2007 20:26:05 +0000</td> | ||
2911 | <td class="comment">MiniUPnP daemon source code</td> | ||
2912 | <td></td> | ||
2913 | </tr> | ||
2914 | <tr> | ||
2915 | <td class="filename"><a href='download.php?file=miniupnpd-20070923.tar.gz'>miniupnpd-20070923.tar.gz</a></td> | ||
2916 | <td class="filesize">51060</td> | ||
2917 | <td class="filedate">23/09/2007 21:13:34 +0000</td> | ||
2918 | <td class="comment">MiniUPnP daemon source code</td> | ||
2919 | <td></td> | ||
2920 | </tr> | ||
2921 | <tr> | ||
2922 | <td class="filename"><a href='download.php?file=miniupnpc-20070923.tar.gz'>miniupnpc-20070923.tar.gz</a></td> | ||
2923 | <td class="filesize">30246</td> | ||
2924 | <td class="filedate">23/09/2007 21:13:33 +0000</td> | ||
2925 | <td class="comment">MiniUPnP client source code</td> | ||
2926 | <td></td> | ||
2927 | </tr> | ||
2928 | <tr> | ||
2929 | <td class="filename"><a href='download.php?file=minissdpd-20070923.tar.gz'>minissdpd-20070923.tar.gz</a></td> | ||
2930 | <td class="filesize">8978</td> | ||
2931 | <td class="filedate">23/09/2007 21:13:32 +0000</td> | ||
2932 | <td class="comment">MiniSSDPd source code</td> | ||
2933 | <td></td> | ||
2934 | </tr> | ||
2935 | <tr> | ||
2936 | <td class="filename"><a href='download.php?file=miniupnpc-20070902.tar.gz'>miniupnpc-20070902.tar.gz</a></td> | ||
2937 | <td class="filesize">30205</td> | ||
2938 | <td class="filedate">01/09/2007 23:47:23 +0000</td> | ||
2939 | <td class="comment">MiniUPnP client source code</td> | ||
2940 | <td></td> | ||
2941 | </tr> | ||
2942 | <tr> | ||
2943 | <td class="filename"><a href='download.php?file=minissdpd-20070902.tar.gz'>minissdpd-20070902.tar.gz</a></td> | ||
2944 | <td class="filesize">6539</td> | ||
2945 | <td class="filedate">01/09/2007 23:47:20 +0000</td> | ||
2946 | <td class="comment">MiniSSDPd source code</td> | ||
2947 | <td></td> | ||
2948 | </tr> | ||
2949 | <tr> | ||
2950 | <td class="filename"><a href='download.php?file=miniupnpd-1.0-RC8.tar.gz'>miniupnpd-1.0-RC8.tar.gz</a></td> | ||
2951 | <td class="filesize">50952</td> | ||
2952 | <td class="filedate">29/08/2007 10:56:09 +0000</td> | ||
2953 | <td class="comment">MiniUPnP daemon release source code</td> | ||
2954 | <td></td> | ||
2955 | </tr> | ||
2956 | <tr> | ||
2957 | <td class="filename"><a href='download.php?file=miniupnpc-1.0-RC8.tar.gz'>miniupnpc-1.0-RC8.tar.gz</a></td> | ||
2958 | <td class="filesize">29312</td> | ||
2959 | <td class="filedate">29/08/2007 10:56:08 +0000</td> | ||
2960 | <td class="comment">MiniUPnP client release source code</td> | ||
2961 | <td></td> | ||
2962 | </tr> | ||
2963 | <tr> | ||
2964 | <td class="filename"><a href='download.php?file=miniupnpd-1.0-RC7.tar.gz'>miniupnpd-1.0-RC7.tar.gz</a></td> | ||
2965 | <td class="filesize">50613</td> | ||
2966 | <td class="filedate">20/07/2007 00:15:45 +0000</td> | ||
2967 | <td class="comment">MiniUPnP daemon release source code</td> | ||
2968 | <td></td> | ||
2969 | </tr> | ||
2970 | <tr> | ||
2971 | <td class="filename"><a href='download.php?file=miniupnpd-1.0-RC6.tar.gz'>miniupnpd-1.0-RC6.tar.gz</a></td> | ||
2972 | <td class="filesize">49986</td> | ||
2973 | <td class="filedate">12/06/2007 17:12:07 +0000</td> | ||
2974 | <td class="comment">MiniUPnP daemon release source code</td> | ||
2975 | <td></td> | ||
2976 | </tr> | ||
2977 | <tr> | ||
2978 | <td class="filename"><a href='download.php?file=miniupnpc-1.0-RC6.tar.gz'>miniupnpc-1.0-RC6.tar.gz</a></td> | ||
2979 | <td class="filesize">29032</td> | ||
2980 | <td class="filedate">12/06/2007 17:12:06 +0000</td> | ||
2981 | <td class="comment">MiniUPnP client release source code</td> | ||
2982 | <td></td> | ||
2983 | </tr> | ||
2984 | <tr> | ||
2985 | <td class="filename"><a href='download.php?file=miniupnpd-20070607.tar.gz'>miniupnpd-20070607.tar.gz</a></td> | ||
2986 | <td class="filesize">49768</td> | ||
2987 | <td class="filedate">06/06/2007 23:12:00 +0000</td> | ||
2988 | <td class="comment">MiniUPnP daemon source code</td> | ||
2989 | <td></td> | ||
2990 | </tr> | ||
2991 | <tr> | ||
2992 | <td class="filename"><a href='download.php?file=miniupnpd-20070605.tar.gz'>miniupnpd-20070605.tar.gz</a></td> | ||
2993 | <td class="filesize">49710</td> | ||
2994 | <td class="filedate">05/06/2007 21:01:53 +0000</td> | ||
2995 | <td class="comment">MiniUPnP daemon source code</td> | ||
2996 | <td></td> | ||
2997 | </tr> | ||
2998 | <tr> | ||
2999 | <td class="filename"><a href='download.php?file=miniupnpd-20070521.tar.gz'>miniupnpd-20070521.tar.gz</a></td> | ||
3000 | <td class="filesize">48374</td> | ||
3001 | <td class="filedate">21/05/2007 13:07:43 +0000</td> | ||
3002 | <td class="comment">MiniUPnP daemon source code</td> | ||
3003 | <td></td> | ||
3004 | </tr> | ||
3005 | <tr> | ||
3006 | <td class="filename"><a href='download.php?file=upnpc-exe-win32-20070519.zip'>upnpc-exe-win32-20070519.zip</a></td> | ||
3007 | <td class="filesize">10836</td> | ||
3008 | <td class="filedate">19/05/2007 13:14:15 +0000</td> | ||
3009 | <td class="comment">Windows executable</td> | ||
3010 | <td></td> | ||
3011 | </tr> | ||
3012 | <tr> | ||
3013 | <td class="filename"><a href='download.php?file=miniupnpc-20070515.tar.gz'>miniupnpc-20070515.tar.gz</a></td> | ||
3014 | <td class="filesize">25802</td> | ||
3015 | <td class="filedate">15/05/2007 18:15:25 +0000</td> | ||
3016 | <td class="comment">MiniUPnP client source code</td> | ||
3017 | <td></td> | ||
3018 | </tr> | ||
3019 | <tr> | ||
3020 | <td class="filename"><a href='download.php?file=miniupnpd-1.0-RC5.tar.gz'>miniupnpd-1.0-RC5.tar.gz</a></td> | ||
3021 | <td class="filesize">48064</td> | ||
3022 | <td class="filedate">10/05/2007 20:22:48 +0000</td> | ||
3023 | <td class="comment">MiniUPnP daemon release source code</td> | ||
3024 | <td></td> | ||
3025 | </tr> | ||
3026 | <tr> | ||
3027 | <td class="filename"><a href='download.php?file=miniupnpc-1.0-RC5.tar.gz'>miniupnpc-1.0-RC5.tar.gz</a></td> | ||
3028 | <td class="filesize">25242</td> | ||
3029 | <td class="filedate">10/05/2007 20:22:46 +0000</td> | ||
3030 | <td class="comment">MiniUPnP client release source code</td> | ||
3031 | <td></td> | ||
3032 | </tr> | ||
3033 | <tr> | ||
3034 | <td class="filename"><a href='download.php?file=miniupnpd-20070412.tar.gz'>miniupnpd-20070412.tar.gz</a></td> | ||
3035 | <td class="filesize">47807</td> | ||
3036 | <td class="filedate">12/04/2007 20:21:48 +0000</td> | ||
3037 | <td class="comment">MiniUPnP daemon source code</td> | ||
3038 | <td></td> | ||
3039 | </tr> | ||
3040 | <tr> | ||
3041 | <td class="filename"><a href='download.php?file=miniupnpd-1.0-RC4.tar.gz'>miniupnpd-1.0-RC4.tar.gz</a></td> | ||
3042 | <td class="filesize">47687</td> | ||
3043 | <td class="filedate">17/03/2007 11:43:13 +0000</td> | ||
3044 | <td class="comment">MiniUPnP daemon release source code</td> | ||
3045 | <td></td> | ||
3046 | </tr> | ||
3047 | <tr> | ||
3048 | <td class="filename"><a href='download.php?file=miniupnpc-1.0-RC4.tar.gz'>miniupnpc-1.0-RC4.tar.gz</a></td> | ||
3049 | <td class="filesize">25085</td> | ||
3050 | <td class="filedate">17/03/2007 11:43:10 +0000</td> | ||
3051 | <td class="comment">MiniUPnP client release source code</td> | ||
3052 | <td></td> | ||
3053 | </tr> | ||
3054 | <tr> | ||
3055 | <td class="filename"><a href='download.php?file=miniupnpd-20070311.tar.gz'>miniupnpd-20070311.tar.gz</a></td> | ||
3056 | <td class="filesize">47599</td> | ||
3057 | <td class="filedate">11/03/2007 00:25:26 +0000</td> | ||
3058 | <td class="comment">MiniUPnP daemon source code</td> | ||
3059 | <td></td> | ||
3060 | </tr> | ||
3061 | <tr> | ||
3062 | <td class="filename"><a href='download.php?file=miniupnpd-20070208.tar.gz'>miniupnpd-20070208.tar.gz</a></td> | ||
3063 | <td class="filesize">45084</td> | ||
3064 | <td class="filedate">07/02/2007 23:04:06 +0000</td> | ||
3065 | <td class="comment">MiniUPnP daemon source code</td> | ||
3066 | <td></td> | ||
3067 | </tr> | ||
3068 | <tr> | ||
3069 | <td class="filename"><a href='download.php?file=miniupnpd-1.0-RC3.tar.gz'>miniupnpd-1.0-RC3.tar.gz</a></td> | ||
3070 | <td class="filesize">44683</td> | ||
3071 | <td class="filedate">30/01/2007 23:00:44 +0000</td> | ||
3072 | <td class="comment">MiniUPnP daemon release source code</td> | ||
3073 | <td></td> | ||
3074 | </tr> | ||
3075 | <tr> | ||
3076 | <td class="filename"><a href='download.php?file=miniupnpc-1.0-RC3.tar.gz'>miniupnpc-1.0-RC3.tar.gz</a></td> | ||
3077 | <td class="filesize">25055</td> | ||
3078 | <td class="filedate">30/01/2007 23:00:42 +0000</td> | ||
3079 | <td class="comment">MiniUPnP client release source code</td> | ||
3080 | <td></td> | ||
3081 | </tr> | ||
3082 | <tr> | ||
3083 | <td class="filename"><a href='download.php?file=miniupnpd-20070130.tar.gz'>miniupnpd-20070130.tar.gz</a></td> | ||
3084 | <td class="filesize">43735</td> | ||
3085 | <td class="filedate">29/01/2007 23:26:16 +0000</td> | ||
3086 | <td class="comment">MiniUPnP daemon source code</td> | ||
3087 | <td></td> | ||
3088 | </tr> | ||
3089 | <tr> | ||
3090 | <td class="filename"><a href='download.php?file=miniupnpc-20070130.tar.gz'>miniupnpc-20070130.tar.gz</a></td> | ||
3091 | <td class="filesize">24466</td> | ||
3092 | <td class="filedate">29/01/2007 23:26:13 +0000</td> | ||
3093 | <td class="comment">MiniUPnP client source code</td> | ||
3094 | <td></td> | ||
3095 | </tr> | ||
3096 | <tr> | ||
3097 | <td class="filename"><a href='download.php?file=miniupnpd-20070127.tar.gz'>miniupnpd-20070127.tar.gz</a></td> | ||
3098 | <td class="filesize">42643</td> | ||
3099 | <td class="filedate">27/01/2007 16:02:35 +0000</td> | ||
3100 | <td class="comment">MiniUPnP daemon source code</td> | ||
3101 | <td></td> | ||
3102 | </tr> | ||
3103 | <tr> | ||
3104 | <td class="filename"><a href='download.php?file=miniupnpc-20070127.tar.gz'>miniupnpc-20070127.tar.gz</a></td> | ||
3105 | <td class="filesize">24241</td> | ||
3106 | <td class="filedate">27/01/2007 16:02:33 +0000</td> | ||
3107 | <td class="comment">MiniUPnP client source code</td> | ||
3108 | <td></td> | ||
3109 | </tr> | ||
3110 | <tr> | ||
3111 | <td class="filename"><a href='download.php?file=miniupnpd-1.0-RC2.tar.gz'>miniupnpd-1.0-RC2.tar.gz</a></td> | ||
3112 | <td class="filesize">40424</td> | ||
3113 | <td class="filedate">17/01/2007 16:13:05 +0000</td> | ||
3114 | <td class="comment">MiniUPnP daemon release source code</td> | ||
3115 | <td></td> | ||
3116 | </tr> | ||
3117 | <tr> | ||
3118 | <td class="filename"><a href='download.php?file=miniupnpd-20070112.tar.gz'>miniupnpd-20070112.tar.gz</a></td> | ||
3119 | <td class="filesize">40708</td> | ||
3120 | <td class="filedate">12/01/2007 13:40:50 +0000</td> | ||
3121 | <td class="comment">MiniUPnP daemon source code</td> | ||
3122 | <td></td> | ||
3123 | </tr> | ||
3124 | <tr> | ||
3125 | <td class="filename"><a href='download.php?file=miniupnpd-20070111.tar.gz'>miniupnpd-20070111.tar.gz</a></td> | ||
3126 | <td class="filesize">40651</td> | ||
3127 | <td class="filedate">11/01/2007 18:50:21 +0000</td> | ||
3128 | <td class="comment">MiniUPnP daemon source code</td> | ||
3129 | <td></td> | ||
3130 | </tr> | ||
3131 | <tr> | ||
3132 | <td class="filename"><a href='download.php?file=miniupnpd-20070108.tar.gz'>miniupnpd-20070108.tar.gz</a></td> | ||
3133 | <td class="filesize">40025</td> | ||
3134 | <td class="filedate">08/01/2007 10:02:14 +0000</td> | ||
3135 | <td class="comment">MiniUPnP daemon source code</td> | ||
3136 | <td></td> | ||
3137 | </tr> | ||
3138 | <tr> | ||
3139 | <td class="filename"><a href='download.php?file=miniupnpd-20070103.tar.gz'>miniupnpd-20070103.tar.gz</a></td> | ||
3140 | <td class="filesize">40065</td> | ||
3141 | <td class="filedate">03/01/2007 14:39:11 +0000</td> | ||
3142 | <td class="comment">MiniUPnP daemon source code</td> | ||
3143 | <td></td> | ||
3144 | </tr> | ||
3145 | <tr> | ||
3146 | <td class="filename"><a href='download.php?file=miniupnpc-20061214.tar.gz'>miniupnpc-20061214.tar.gz</a></td> | ||
3147 | <td class="filesize">24106</td> | ||
3148 | <td class="filedate">14/12/2006 15:43:54 +0000</td> | ||
3149 | <td class="comment">MiniUPnP client source code</td> | ||
3150 | <td></td> | ||
3151 | </tr> | ||
3152 | <tr> | ||
3153 | <td class="filename"><a href='download.php?file=miniupnpd-20061214.tar.gz'>miniupnpd-20061214.tar.gz</a></td> | ||
3154 | <td class="filesize">39750</td> | ||
3155 | <td class="filedate">14/12/2006 13:44:51 +0000</td> | ||
3156 | <td class="comment">MiniUPnP daemon source code</td> | ||
3157 | <td></td> | ||
3158 | </tr> | ||
3159 | <tr> | ||
3160 | <td class="filename"><a href='download.php?file=miniupnpd-1.0-RC1.tar.gz'>miniupnpd-1.0-RC1.tar.gz</a></td> | ||
3161 | <td class="filesize">39572</td> | ||
3162 | <td class="filedate">07/12/2006 10:55:31 +0000</td> | ||
3163 | <td class="comment">MiniUPnP daemon release source code</td> | ||
3164 | <td></td> | ||
3165 | </tr> | ||
3166 | <tr> | ||
3167 | <td class="filename"><a href='download.php?file=miniupnpc-1.0-RC1.tar.gz'>miniupnpc-1.0-RC1.tar.gz</a></td> | ||
3168 | <td class="filesize">23582</td> | ||
3169 | <td class="filedate">07/12/2006 10:55:30 +0000</td> | ||
3170 | <td class="comment">MiniUPnP client release source code</td> | ||
3171 | <td></td> | ||
3172 | </tr> | ||
3173 | <tr> | ||
3174 | <td class="filename"><a href='download.php?file=upnpc-exe-win32-20061201.zip'>upnpc-exe-win32-20061201.zip</a></td> | ||
3175 | <td class="filesize">10378</td> | ||
3176 | <td class="filedate">01/12/2006 00:33:08 +0000</td> | ||
3177 | <td class="comment">Windows executable</td> | ||
3178 | <td></td> | ||
3179 | </tr> | ||
3180 | <tr> | ||
3181 | <td class="filename"><a href='download.php?file=miniupnpd20061130.tar.gz'>miniupnpd20061130.tar.gz</a></td> | ||
3182 | <td class="filesize">37184</td> | ||
3183 | <td class="filedate">30/11/2006 12:25:25 +0000</td> | ||
3184 | <td class="comment">MiniUPnP daemon source code</td> | ||
3185 | <td></td> | ||
3186 | </tr> | ||
3187 | <tr> | ||
3188 | <td class="filename"><a href='download.php?file=miniupnpd20061129.tar.gz'>miniupnpd20061129.tar.gz</a></td> | ||
3189 | <td class="filesize">36045</td> | ||
3190 | <td class="filedate">29/11/2006 00:10:49 +0000</td> | ||
3191 | <td class="comment">MiniUPnP daemon source code</td> | ||
3192 | <td></td> | ||
3193 | </tr> | ||
3194 | <tr> | ||
3195 | <td class="filename"><a href='download.php?file=miniupnpd20061127.tar.gz'>miniupnpd20061127.tar.gz</a></td> | ||
3196 | <td class="filesize">34155</td> | ||
3197 | <td class="filedate">26/11/2006 23:15:28 +0000</td> | ||
3198 | <td class="comment">MiniUPnP daemon source code</td> | ||
3199 | <td></td> | ||
3200 | </tr> | ||
3201 | <tr> | ||
3202 | <td class="filename"><a href='download.php?file=miniupnpc20061123.tar.gz'>miniupnpc20061123.tar.gz</a></td> | ||
3203 | <td class="filesize">21004</td> | ||
3204 | <td class="filedate">23/11/2006 22:41:46 +0000</td> | ||
3205 | <td class="comment">MiniUPnP client source code</td> | ||
3206 | <td></td> | ||
3207 | </tr> | ||
3208 | <tr> | ||
3209 | <td class="filename" colspan="2"><a href='download.php?file=miniupnpd-bin-openwrt20061123.tar.gz'>miniupnpd-bin-openwrt20061123.tar.gz</a></td> | ||
3210 | <td class="filedate">23/11/2006 22:41:44 +0000</td> | ||
3211 | <td class="comment">Precompiled binaries for openwrt</td> | ||
3212 | <td></td> | ||
3213 | </tr> | ||
3214 | <tr> | ||
3215 | <td class="filename"><a href='download.php?file=miniupnpd20061123.tar.gz'>miniupnpd20061123.tar.gz</a></td> | ||
3216 | <td class="filesize">33809</td> | ||
3217 | <td class="filedate">23/11/2006 22:28:29 +0000</td> | ||
3218 | <td class="comment">MiniUPnP daemon source code</td> | ||
3219 | <td></td> | ||
3220 | </tr> | ||
3221 | <tr> | ||
3222 | <td class="filename"><a href='download.php?file=miniupnpc20061119.tar.gz'>miniupnpc20061119.tar.gz</a></td> | ||
3223 | <td class="filesize">20897</td> | ||
3224 | <td class="filedate">19/11/2006 22:50:37 +0000</td> | ||
3225 | <td class="comment">MiniUPnP client source code</td> | ||
3226 | <td></td> | ||
3227 | </tr> | ||
3228 | <tr> | ||
3229 | <td class="filename"><a href='download.php?file=miniupnpd20061119.tar.gz'>miniupnpd20061119.tar.gz</a></td> | ||
3230 | <td class="filesize">32580</td> | ||
3231 | <td class="filedate">19/11/2006 22:50:36 +0000</td> | ||
3232 | <td class="comment">MiniUPnP daemon source code</td> | ||
3233 | <td></td> | ||
3234 | </tr> | ||
3235 | <tr> | ||
3236 | <td class="filename"><a href='download.php?file=miniupnpd20061117.tar.gz'>miniupnpd20061117.tar.gz</a></td> | ||
3237 | <td class="filesize">32646</td> | ||
3238 | <td class="filedate">17/11/2006 13:29:33 +0000</td> | ||
3239 | <td class="comment">MiniUPnP daemon source code</td> | ||
3240 | <td></td> | ||
3241 | </tr> | ||
3242 | <tr> | ||
3243 | <td class="filename"><a href='download.php?file=upnpc-exe-win32-20061112.zip'>upnpc-exe-win32-20061112.zip</a></td> | ||
3244 | <td class="filesize">10262</td> | ||
3245 | <td class="filedate">12/11/2006 22:41:25 +0000</td> | ||
3246 | <td class="comment">Windows executable</td> | ||
3247 | <td></td> | ||
3248 | </tr> | ||
3249 | <tr> | ||
3250 | <td class="filename"><a href='download.php?file=miniupnpd20061112.tar.gz'>miniupnpd20061112.tar.gz</a></td> | ||
3251 | <td class="filesize">32023</td> | ||
3252 | <td class="filedate">12/11/2006 21:30:32 +0000</td> | ||
3253 | <td class="comment">MiniUPnP daemon source code</td> | ||
3254 | <td></td> | ||
3255 | </tr> | ||
3256 | <tr> | ||
3257 | <td class="filename"><a href='download.php?file=miniupnpc20061112.tar.gz'>miniupnpc20061112.tar.gz</a></td> | ||
3258 | <td class="filesize">21047</td> | ||
3259 | <td class="filedate">12/11/2006 21:30:31 +0000</td> | ||
3260 | <td class="comment">MiniUPnP client source code</td> | ||
3261 | <td></td> | ||
3262 | </tr> | ||
3263 | <tr> | ||
3264 | <td class="filename"><a href='download.php?file=miniupnpd20061110.tar.gz'>miniupnpd20061110.tar.gz</a></td> | ||
3265 | <td class="filesize">27926</td> | ||
3266 | <td class="filedate">09/11/2006 23:35:02 +0000</td> | ||
3267 | <td class="comment">MiniUPnP daemon source code</td> | ||
3268 | <td></td> | ||
3269 | </tr> | ||
3270 | <tr> | ||
3271 | <td class="filename"><a href='download.php?file=miniupnpc20061110.tar.gz'>miniupnpc20061110.tar.gz</a></td> | ||
3272 | <td class="filesize">21009</td> | ||
3273 | <td class="filedate">09/11/2006 23:32:19 +0000</td> | ||
3274 | <td class="comment">MiniUPnP client source code</td> | ||
3275 | <td></td> | ||
3276 | </tr> | ||
3277 | <tr> | ||
3278 | <td class="filename"><a href='download.php?file=upnpc-exe-win32-20061101.zip'>upnpc-exe-win32-20061101.zip</a></td> | ||
3279 | <td class="filesize">10089</td> | ||
3280 | <td class="filedate">08/11/2006 20:35:09 +0000</td> | ||
3281 | <td class="comment">Windows executable</td> | ||
3282 | <td></td> | ||
3283 | </tr> | ||
3284 | <tr> | ||
3285 | <td class="filename"><a href='download.php?file=upnpc-exe-win32-20061020.zip'>upnpc-exe-win32-20061020.zip</a></td> | ||
3286 | <td class="filesize">9183</td> | ||
3287 | <td class="filedate">08/11/2006 20:35:08 +0000</td> | ||
3288 | <td class="comment">Windows executable</td> | ||
3289 | <td></td> | ||
3290 | </tr> | ||
3291 | <tr> | ||
3292 | <td class="filename"><a href='download.php?file=upnpc-exe-win32-20060909.zip'>upnpc-exe-win32-20060909.zip</a></td> | ||
3293 | <td class="filesize">9994</td> | ||
3294 | <td class="filedate">08/11/2006 20:35:07 +0000</td> | ||
3295 | <td class="comment">Windows executable</td> | ||
3296 | <td></td> | ||
3297 | </tr> | ||
3298 | <tr> | ||
3299 | <td class="filename"><a href='download.php?file=upnpc-exe-win32-20060801.zip'>upnpc-exe-win32-20060801.zip</a></td> | ||
3300 | <td class="filesize">10002</td> | ||
3301 | <td class="filedate">08/11/2006 20:35:06 +0000</td> | ||
3302 | <td class="comment">Windows executable</td> | ||
3303 | <td></td> | ||
3304 | </tr> | ||
3305 | <tr> | ||
3306 | <td class="filename"><a href='download.php?file=upnpc-exe-win32-20060711.zip'>upnpc-exe-win32-20060711.zip</a></td> | ||
3307 | <td class="filesize">13733</td> | ||
3308 | <td class="filedate">08/11/2006 20:35:05 +0000</td> | ||
3309 | <td class="comment">Windows executable</td> | ||
3310 | <td></td> | ||
3311 | </tr> | ||
3312 | <tr> | ||
3313 | <td class="filename"><a href='download.php?file=upnpc-exe-win32-20060709.zip'>upnpc-exe-win32-20060709.zip</a></td> | ||
3314 | <td class="filesize">13713</td> | ||
3315 | <td class="filedate">08/11/2006 20:35:04 +0000</td> | ||
3316 | <td class="comment">Windows executable</td> | ||
3317 | <td></td> | ||
3318 | </tr> | ||
3319 | <tr> | ||
3320 | <td class="filename"><a href='download.php?file=upnpc-exe-win32-20060704.zip'>upnpc-exe-win32-20060704.zip</a></td> | ||
3321 | <td class="filesize">13297</td> | ||
3322 | <td class="filedate">08/11/2006 20:35:03 +0000</td> | ||
3323 | <td class="comment">Windows executable</td> | ||
3324 | <td></td> | ||
3325 | </tr> | ||
3326 | <tr> | ||
3327 | <td class="filename"><a href='download.php?file=miniupnpc20061107.tar.gz'>miniupnpc20061107.tar.gz</a></td> | ||
3328 | <td class="filesize">20708</td> | ||
3329 | <td class="filedate">06/11/2006 23:36:57 +0000</td> | ||
3330 | <td class="comment">MiniUPnP client source code</td> | ||
3331 | <td></td> | ||
3332 | </tr> | ||
3333 | <tr> | ||
3334 | <td class="filename"><a href='download.php?file=miniupnpd20061107.tar.gz'>miniupnpd20061107.tar.gz</a></td> | ||
3335 | <td class="filesize">26992</td> | ||
3336 | <td class="filedate">06/11/2006 23:35:06 +0000</td> | ||
3337 | <td class="comment">MiniUPnP daemon source code</td> | ||
3338 | <td></td> | ||
3339 | </tr> | ||
3340 | <tr> | ||
3341 | <td class="filename"><a href='download.php?file=miniupnpc20061106.tar.gz'>miniupnpc20061106.tar.gz</a></td> | ||
3342 | <td class="filesize">20575</td> | ||
3343 | <td class="filedate">06/11/2006 17:02:15 +0000</td> | ||
3344 | <td class="comment">MiniUPnP client source code</td> | ||
3345 | <td></td> | ||
3346 | </tr> | ||
3347 | <tr> | ||
3348 | <td class="filename"><a href='download.php?file=miniupnpd20061106.tar.gz'>miniupnpd20061106.tar.gz</a></td> | ||
3349 | <td class="filesize">26597</td> | ||
3350 | <td class="filedate">06/11/2006 15:39:10 +0000</td> | ||
3351 | <td class="comment">MiniUPnP daemon source code</td> | ||
3352 | <td></td> | ||
3353 | </tr> | ||
3354 | <tr> | ||
3355 | <td class="filename"><a href='download.php?file=miniupnpc20061101.tar.gz'>miniupnpc20061101.tar.gz</a></td> | ||
3356 | <td class="filesize">20395</td> | ||
3357 | <td class="filedate">04/11/2006 18:16:15 +0000</td> | ||
3358 | <td class="comment">MiniUPnP client source code</td> | ||
3359 | <td></td> | ||
3360 | </tr> | ||
3361 | <tr> | ||
3362 | <td class="filename"><a href='download.php?file=miniupnpc20061031.tar.gz'>miniupnpc20061031.tar.gz</a></td> | ||
3363 | <td class="filesize">20396</td> | ||
3364 | <td class="filedate">04/11/2006 18:16:13 +0000</td> | ||
3365 | <td class="comment">MiniUPnP client source code</td> | ||
3366 | <td></td> | ||
3367 | </tr> | ||
3368 | <tr> | ||
3369 | <td class="filename"><a href='download.php?file=miniupnpc20061023.tar.gz'>miniupnpc20061023.tar.gz</a></td> | ||
3370 | <td class="filesize">20109</td> | ||
3371 | <td class="filedate">04/11/2006 18:16:12 +0000</td> | ||
3372 | <td class="comment">MiniUPnP client source code</td> | ||
3373 | <td></td> | ||
3374 | </tr> | ||
3375 | <tr> | ||
3376 | <td class="filename"><a href='download.php?file=miniupnpc20061020.tar.gz'>miniupnpc20061020.tar.gz</a></td> | ||
3377 | <td class="filesize">19739</td> | ||
3378 | <td class="filedate">04/11/2006 18:16:10 +0000</td> | ||
3379 | <td class="comment">MiniUPnP client source code</td> | ||
3380 | <td></td> | ||
3381 | </tr> | ||
3382 | <tr> | ||
3383 | <td class="filename"><a href='download.php?file=miniupnpc20060909.tar.gz'>miniupnpc20060909.tar.gz</a></td> | ||
3384 | <td class="filesize">19285</td> | ||
3385 | <td class="filedate">04/11/2006 18:16:09 +0000</td> | ||
3386 | <td class="comment">MiniUPnP client source code</td> | ||
3387 | <td></td> | ||
3388 | </tr> | ||
3389 | <tr> | ||
3390 | <td class="filename"><a href='download.php?file=miniupnpc20060731.tar.gz'>miniupnpc20060731.tar.gz</a></td> | ||
3391 | <td class="filesize">19032</td> | ||
3392 | <td class="filedate">04/11/2006 18:16:07 +0000</td> | ||
3393 | <td class="comment">MiniUPnP client source code</td> | ||
3394 | <td></td> | ||
3395 | </tr> | ||
3396 | <tr> | ||
3397 | <td class="filename"><a href='download.php?file=miniupnpc20060711.tar.gz'>miniupnpc20060711.tar.gz</a></td> | ||
3398 | <td class="filesize">19151</td> | ||
3399 | <td class="filedate">04/11/2006 18:16:06 +0000</td> | ||
3400 | <td class="comment">MiniUPnP client source code</td> | ||
3401 | <td></td> | ||
3402 | </tr> | ||
3403 | <tr> | ||
3404 | <td class="filename"><a href='download.php?file=miniupnpc20060709.tar.gz'>miniupnpc20060709.tar.gz</a></td> | ||
3405 | <td class="filesize">19080</td> | ||
3406 | <td class="filedate">04/11/2006 18:16:04 +0000</td> | ||
3407 | <td class="comment">MiniUPnP client source code</td> | ||
3408 | <td></td> | ||
3409 | </tr> | ||
3410 | <tr> | ||
3411 | <td class="filename"><a href='download.php?file=miniupnpc20060703.tar.gz'>miniupnpc20060703.tar.gz</a></td> | ||
3412 | <td class="filesize">17906</td> | ||
3413 | <td class="filedate">04/11/2006 18:16:03 +0000</td> | ||
3414 | <td class="comment">MiniUPnP client source code</td> | ||
3415 | <td></td> | ||
3416 | </tr> | ||
3417 | <tr> | ||
3418 | <td class="filename"><a href='download.php?file=miniupnpc-new20060630.tar.gz'>miniupnpc-new20060630.tar.gz</a></td> | ||
3419 | <td class="filesize">14840</td> | ||
3420 | <td class="filedate">04/11/2006 18:16:01 +0000</td> | ||
3421 | <td class="comment">João Paulo Barraca version of the upnp client</td> | ||
3422 | <td></td> | ||
3423 | </tr> | ||
3424 | <tr> | ||
3425 | <td class="filename"><a href='download.php?file=miniupnpd20061029.tar.gz'>miniupnpd20061029.tar.gz</a></td> | ||
3426 | <td class="filesize">24197</td> | ||
3427 | <td class="filedate">03/11/2006 13:40:30 +0000</td> | ||
3428 | <td class="comment">MiniUPnP daemon source code</td> | ||
3429 | <td></td> | ||
3430 | </tr> | ||
3431 | <tr> | ||
3432 | <td class="filename"><a href='download.php?file=miniupnpd20061027.tar.gz'>miniupnpd20061027.tar.gz</a></td> | ||
3433 | <td class="filesize">23904</td> | ||
3434 | <td class="filedate">03/11/2006 13:40:29 +0000</td> | ||
3435 | <td class="comment">MiniUPnP daemon source code</td> | ||
3436 | <td></td> | ||
3437 | </tr> | ||
3438 | <tr> | ||
3439 | <td class="filename"><a href='download.php?file=miniupnpd20061028.tar.gz'>miniupnpd20061028.tar.gz</a></td> | ||
3440 | <td class="filesize">24383</td> | ||
3441 | <td class="filedate">03/11/2006 13:40:29 +0000</td> | ||
3442 | <td class="comment">MiniUPnP daemon source code</td> | ||
3443 | <td></td> | ||
3444 | </tr> | ||
3445 | <tr> | ||
3446 | <td class="filename"><a href='download.php?file=miniupnpd20061018.tar.gz'>miniupnpd20061018.tar.gz</a></td> | ||
3447 | <td class="filesize">23051</td> | ||
3448 | <td class="filedate">03/11/2006 13:40:28 +0000</td> | ||
3449 | <td class="comment">MiniUPnP daemon source code</td> | ||
3450 | <td></td> | ||
3451 | </tr> | ||
3452 | <tr> | ||
3453 | <td class="filename"><a href='download.php?file=miniupnpd20061023.tar.gz'>miniupnpd20061023.tar.gz</a></td> | ||
3454 | <td class="filesize">23478</td> | ||
3455 | <td class="filedate">03/11/2006 13:40:28 +0000</td> | ||
3456 | <td class="comment">MiniUPnP daemon source code</td> | ||
3457 | <td></td> | ||
3458 | </tr> | ||
3459 | <tr> | ||
3460 | <td class="filename"><a href='download.php?file=miniupnpd20060930.tar.gz'>miniupnpd20060930.tar.gz</a></td> | ||
3461 | <td class="filesize">22832</td> | ||
3462 | <td class="filedate">03/11/2006 13:40:28 +0000</td> | ||
3463 | <td class="comment">MiniUPnP daemon source code</td> | ||
3464 | <td></td> | ||
3465 | </tr> | ||
3466 | <tr> | ||
3467 | <td class="filename"><a href='download.php?file=miniupnpd20060924.tar.gz'>miniupnpd20060924.tar.gz</a></td> | ||
3468 | <td class="filesize">22038</td> | ||
3469 | <td class="filedate">03/11/2006 13:40:27 +0000</td> | ||
3470 | <td class="comment">MiniUPnP daemon source code</td> | ||
3471 | <td></td> | ||
3472 | </tr> | ||
3473 | <tr> | ||
3474 | <td class="filename"><a href='download.php?file=miniupnpd20060919.tar.gz'>miniupnpd20060919.tar.gz</a></td> | ||
3475 | <td class="filesize">21566</td> | ||
3476 | <td class="filedate">03/11/2006 13:40:27 +0000</td> | ||
3477 | <td class="comment">MiniUPnP daemon source code</td> | ||
3478 | <td></td> | ||
3479 | </tr> | ||
3480 | <tr> | ||
3481 | <td class="filename"><a href='download.php?file=miniupnpd20060729.tar.gz'>miniupnpd20060729.tar.gz</a></td> | ||
3482 | <td class="filesize">19202</td> | ||
3483 | <td class="filedate">03/11/2006 13:40:26 +0000</td> | ||
3484 | <td class="comment">MiniUPnP daemon source code</td> | ||
3485 | <td></td> | ||
3486 | </tr> | ||
3487 | <tr> | ||
3488 | <td class="filename"><a href='download.php?file=miniupnpd20060909.tar.gz'>miniupnpd20060909.tar.gz</a></td> | ||
3489 | <td class="filesize">19952</td> | ||
3490 | <td class="filedate">03/11/2006 13:40:26 +0000</td> | ||
3491 | <td class="comment">MiniUPnP daemon source code</td> | ||
3492 | <td></td> | ||
3493 | </tr> | ||
3494 | </table> | ||
3495 | |||
3496 | <p><a href="..">Home</a></p> | ||
3497 | <p>Contact: miniupnp _AT_ free _DOT_ fr</p> | ||
3498 | <p align="center"> | ||
3499 | <a href="https://validator.w3.org/check?uri=referer"><img src="https://www.w3.org/Icons/valid-xhtml10" alt="Valid XHTML 1.0 Transitional" height="31" width="88" /></a> | ||
3500 | <a href="https://jigsaw.w3.org/css-validator/check/referer"><img style="border:0;width:88px;height:31px" src="https://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!" /></a> | ||
3501 | <!-- | ||
3502 | <a href="https://freshmeat.net/projects/miniupnp"><img src="https://s3.amazonaws.com/entp-tender-production/assets/bc5be96f147ec8db3c10fc017f1f53889904ef5b/fm_logo_white_150_normal.png" border="0" alt="freshmeat.net" /></a> | ||
3503 | --> | ||
3504 | <!-- https://futuresimple.github.com/images/github_logo.png --> | ||
3505 | <!-- <a href="https://github.com/miniupnp/miniupnp"><img src="https://assets-cdn.github.com/images/modules/logos_page/GitHub-Logo.png" alt="github.com" height="31" /></a> --> | ||
3506 | <a href="https://github.com/miniupnp/miniupnp"><img style="position: absolute; top: 0; left: 0; border: 0;" src="https://github.blog/wp-content/uploads/2008/12/forkme_left_green_007200.png" alt="Fork me on GitHub" /></a> | ||
3507 | </p> | ||
3508 | |||
3509 | <script type="text/javascript"> | ||
3510 | var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www."); | ||
3511 | document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E")); | ||
3512 | </script> | ||
3513 | <script type="text/javascript"> | ||
3514 | try { | ||
3515 | var ua = 'UA-10295521'; | ||
3516 | if(window.location.hostname == 'miniupnp.free.fr') | ||
3517 | ua += '-1'; | ||
3518 | else if(window.location.hostname == 'miniupnp.tuxfamily.org') | ||
3519 | ua += '-2'; | ||
3520 | else ua = ''; | ||
3521 | if(ua != '') { | ||
3522 | var pageTracker = _gat._getTracker(ua); | ||
3523 | pageTracker._trackPageview(); | ||
3524 | } | ||
3525 | } catch(err) {}</script> | ||
3526 | </body> | ||
3527 | </html> | ||
3528 | |||
diff --git a/bitbake/lib/bb/tests/fetch.py b/bitbake/lib/bb/tests/fetch.py index 7b2dac7b86..077472b8b3 100644 --- a/bitbake/lib/bb/tests/fetch.py +++ b/bitbake/lib/bb/tests/fetch.py | |||
@@ -6,21 +6,59 @@ | |||
6 | # SPDX-License-Identifier: GPL-2.0-only | 6 | # SPDX-License-Identifier: GPL-2.0-only |
7 | # | 7 | # |
8 | 8 | ||
9 | import contextlib | ||
10 | import shutil | ||
9 | import unittest | 11 | import unittest |
12 | import unittest.mock | ||
13 | import urllib.parse | ||
10 | import hashlib | 14 | import hashlib |
11 | import tempfile | 15 | import tempfile |
12 | import collections | 16 | import collections |
13 | import os | 17 | import os |
18 | import signal | ||
19 | import tarfile | ||
14 | from bb.fetch2 import URI | 20 | from bb.fetch2 import URI |
15 | from bb.fetch2 import FetchMethod | 21 | from bb.fetch2 import FetchMethod |
16 | import bb | 22 | import bb |
23 | import bb.utils | ||
17 | from bb.tests.support.httpserver import HTTPService | 24 | from bb.tests.support.httpserver import HTTPService |
18 | 25 | ||
19 | def skipIfNoNetwork(): | 26 | def skipIfNoNetwork(): |
20 | if os.environ.get("BB_SKIP_NETTESTS") == "yes": | 27 | if os.environ.get("BB_SKIP_NETTESTS") == "yes": |
21 | return unittest.skip("Network tests being skipped") | 28 | return unittest.skip("network test") |
22 | return lambda f: f | 29 | return lambda f: f |
23 | 30 | ||
31 | |||
32 | @contextlib.contextmanager | ||
33 | def hide_directory(directory): | ||
34 | """Hide the given directory and restore it after the context is left""" | ||
35 | temp_name = directory + ".bak" | ||
36 | os.rename(directory, temp_name) | ||
37 | try: | ||
38 | yield | ||
39 | finally: | ||
40 | os.rename(temp_name, directory) | ||
41 | |||
42 | |||
43 | class TestTimeout(Exception): | ||
44 | # Indicate to pytest that this is not a test suite | ||
45 | __test__ = False | ||
46 | |||
47 | class Timeout(): | ||
48 | |||
49 | def __init__(self, seconds): | ||
50 | self.seconds = seconds | ||
51 | |||
52 | def handle_timeout(self, signum, frame): | ||
53 | raise TestTimeout("Test failed: timeout reached") | ||
54 | |||
55 | def __enter__(self): | ||
56 | signal.signal(signal.SIGALRM, self.handle_timeout) | ||
57 | signal.alarm(self.seconds) | ||
58 | |||
59 | def __exit__(self, exc_type, exc_val, exc_tb): | ||
60 | signal.alarm(0) | ||
61 | |||
24 | class URITest(unittest.TestCase): | 62 | class URITest(unittest.TestCase): |
25 | test_uris = { | 63 | test_uris = { |
26 | "http://www.google.com/index.html" : { | 64 | "http://www.google.com/index.html" : { |
@@ -286,6 +324,36 @@ class URITest(unittest.TestCase): | |||
286 | 'params': {"someparam" : "1"}, | 324 | 'params': {"someparam" : "1"}, |
287 | 'query': {}, | 325 | 'query': {}, |
288 | 'relative': True | 326 | 'relative': True |
327 | }, | ||
328 | "https://www.innodisk.com/Download_file?9BE0BF6657;downloadfilename=EGPL-T101.zip": { | ||
329 | 'uri': 'https://www.innodisk.com/Download_file?9BE0BF6657;downloadfilename=EGPL-T101.zip', | ||
330 | 'scheme': 'https', | ||
331 | 'hostname': 'www.innodisk.com', | ||
332 | 'port': None, | ||
333 | 'hostport': 'www.innodisk.com', | ||
334 | 'path': '/Download_file', | ||
335 | 'userinfo': '', | ||
336 | 'userinfo': '', | ||
337 | 'username': '', | ||
338 | 'password': '', | ||
339 | 'params': {"downloadfilename" : "EGPL-T101.zip"}, | ||
340 | 'query': {"9BE0BF6657": None}, | ||
341 | 'relative': False | ||
342 | }, | ||
343 | "file://example@.service": { | ||
344 | 'uri': 'file:example%40.service', | ||
345 | 'scheme': 'file', | ||
346 | 'hostname': '', | ||
347 | 'port': None, | ||
348 | 'hostport': '', | ||
349 | 'path': 'example@.service', | ||
350 | 'userinfo': '', | ||
351 | 'userinfo': '', | ||
352 | 'username': '', | ||
353 | 'password': '', | ||
354 | 'params': {}, | ||
355 | 'query': {}, | ||
356 | 'relative': True | ||
289 | } | 357 | } |
290 | 358 | ||
291 | } | 359 | } |
@@ -376,7 +444,7 @@ class FetcherTest(unittest.TestCase): | |||
376 | def setUp(self): | 444 | def setUp(self): |
377 | self.origdir = os.getcwd() | 445 | self.origdir = os.getcwd() |
378 | self.d = bb.data.init() | 446 | self.d = bb.data.init() |
379 | self.tempdir = tempfile.mkdtemp() | 447 | self.tempdir = tempfile.mkdtemp(prefix="bitbake-fetch-") |
380 | self.dldir = os.path.join(self.tempdir, "download") | 448 | self.dldir = os.path.join(self.tempdir, "download") |
381 | os.mkdir(self.dldir) | 449 | os.mkdir(self.dldir) |
382 | self.d.setVar("DL_DIR", self.dldir) | 450 | self.d.setVar("DL_DIR", self.dldir) |
@@ -390,63 +458,104 @@ class FetcherTest(unittest.TestCase): | |||
390 | if os.environ.get("BB_TMPDIR_NOCLEAN") == "yes": | 458 | if os.environ.get("BB_TMPDIR_NOCLEAN") == "yes": |
391 | print("Not cleaning up %s. Please remove manually." % self.tempdir) | 459 | print("Not cleaning up %s. Please remove manually." % self.tempdir) |
392 | else: | 460 | else: |
461 | bb.process.run('chmod u+rw -R %s' % self.tempdir) | ||
393 | bb.utils.prunedir(self.tempdir) | 462 | bb.utils.prunedir(self.tempdir) |
394 | 463 | ||
464 | def git(self, cmd, cwd=None): | ||
465 | if isinstance(cmd, str): | ||
466 | cmd = 'git -c safe.bareRepository=all ' + cmd | ||
467 | else: | ||
468 | cmd = ['git', '-c', 'safe.bareRepository=all'] + cmd | ||
469 | if cwd is None: | ||
470 | cwd = self.gitdir | ||
471 | return bb.process.run(cmd, cwd=cwd)[0] | ||
472 | |||
473 | def git_init(self, cwd=None): | ||
474 | self.git('init', cwd=cwd) | ||
475 | # Explicitly set initial branch to master as | ||
476 | # a common setup is to use other default | ||
477 | # branch than master. | ||
478 | self.git(['checkout', '-b', 'master'], cwd=cwd) | ||
479 | |||
480 | try: | ||
481 | self.git(['config', 'user.email'], cwd=cwd) | ||
482 | except bb.process.ExecutionError: | ||
483 | self.git(['config', 'user.email', 'you@example.com'], cwd=cwd) | ||
484 | |||
485 | try: | ||
486 | self.git(['config', 'user.name'], cwd=cwd) | ||
487 | except bb.process.ExecutionError: | ||
488 | self.git(['config', 'user.name', 'Your Name'], cwd=cwd) | ||
489 | |||
395 | class MirrorUriTest(FetcherTest): | 490 | class MirrorUriTest(FetcherTest): |
396 | 491 | ||
397 | replaceuris = { | 492 | replaceuris = { |
398 | ("git://git.invalid.infradead.org/mtd-utils.git;tag=1234567890123456789012345678901234567890", "git://.*/.*", "http://somewhere.org/somedir/") | 493 | ("git://git.invalid.infradead.org/mtd-utils.git;tag=1234567890123456789012345678901234567890;branch=master", "git://.*/.*", "http://somewhere.org/somedir/") |
399 | : "http://somewhere.org/somedir/git2_git.invalid.infradead.org.mtd-utils.git.tar.gz", | 494 | : "http://somewhere.org/somedir/git2_git.invalid.infradead.org.mtd-utils.git.tar.gz", |
400 | ("git://git.invalid.infradead.org/mtd-utils.git;tag=1234567890123456789012345678901234567890", "git://.*/([^/]+/)*([^/]*)", "git://somewhere.org/somedir/\\2;protocol=http") | 495 | ("git://git.invalid.infradead.org/mtd-utils.git;tag=1234567890123456789012345678901234567890;branch=master", "git://.*/([^/]+/)*([^/]*)", "git://somewhere.org/somedir/\\2;protocol=http") |
401 | : "git://somewhere.org/somedir/mtd-utils.git;tag=1234567890123456789012345678901234567890;protocol=http", | 496 | : "git://somewhere.org/somedir/mtd-utils.git;tag=1234567890123456789012345678901234567890;branch=master;protocol=http", |
402 | ("git://git.invalid.infradead.org/foo/mtd-utils.git;tag=1234567890123456789012345678901234567890", "git://.*/([^/]+/)*([^/]*)", "git://somewhere.org/somedir/\\2;protocol=http") | 497 | ("git://git.invalid.infradead.org/foo/mtd-utils.git;tag=1234567890123456789012345678901234567890;branch=master", "git://.*/([^/]+/)*([^/]*)", "git://somewhere.org/somedir/\\2;protocol=http") |
403 | : "git://somewhere.org/somedir/mtd-utils.git;tag=1234567890123456789012345678901234567890;protocol=http", | 498 | : "git://somewhere.org/somedir/mtd-utils.git;tag=1234567890123456789012345678901234567890;branch=master;protocol=http", |
404 | ("git://git.invalid.infradead.org/foo/mtd-utils.git;tag=1234567890123456789012345678901234567890", "git://.*/([^/]+/)*([^/]*)", "git://somewhere.org/\\2;protocol=http") | 499 | ("git://git.invalid.infradead.org/foo/mtd-utils.git;tag=1234567890123456789012345678901234567890;branch=master", "git://.*/([^/]+/)*([^/]*)", "git://somewhere.org/\\2;protocol=http") |
405 | : "git://somewhere.org/mtd-utils.git;tag=1234567890123456789012345678901234567890;protocol=http", | 500 | : "git://somewhere.org/mtd-utils.git;tag=1234567890123456789012345678901234567890;branch=master;protocol=http", |
406 | ("git://someserver.org/bitbake;tag=1234567890123456789012345678901234567890", "git://someserver.org/bitbake", "git://git.openembedded.org/bitbake") | 501 | ("git://someserver.org/bitbake;tag=1234567890123456789012345678901234567890;branch=master", "git://someserver.org/bitbake", "git://git.openembedded.org/bitbake") |
407 | : "git://git.openembedded.org/bitbake;tag=1234567890123456789012345678901234567890", | 502 | : "git://git.openembedded.org/bitbake;tag=1234567890123456789012345678901234567890;branch=master", |
408 | ("file://sstate-xyz.tgz", "file://.*", "file:///somewhere/1234/sstate-cache") | 503 | ("file://sstate-xyz.tgz", "file://.*", "file:///somewhere/1234/sstate-cache") |
409 | : "file:///somewhere/1234/sstate-cache/sstate-xyz.tgz", | 504 | : "file:///somewhere/1234/sstate-cache/sstate-xyz.tgz", |
410 | ("file://sstate-xyz.tgz", "file://.*", "file:///somewhere/1234/sstate-cache/") | 505 | ("file://sstate-xyz.tgz", "file://.*", "file:///somewhere/1234/sstate-cache/") |
411 | : "file:///somewhere/1234/sstate-cache/sstate-xyz.tgz", | 506 | : "file:///somewhere/1234/sstate-cache/sstate-xyz.tgz", |
412 | ("http://somewhere.org/somedir1/somedir2/somefile_1.2.3.tar.gz", "http://.*/.*", "http://somewhere2.org/somedir3") | 507 | ("http://somewhere.org/somedir1/somedir2/somefile_1.2.3.tar.gz", "http://.*/.*", "http://somewhere2.org/somedir3") |
413 | : "http://somewhere2.org/somedir3/somefile_1.2.3.tar.gz", | 508 | : "http://somewhere2.org/somedir3/somefile_1.2.3.tar.gz", |
414 | ("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") | 509 | ("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") |
415 | : "http://somewhere2.org/somedir3/somefile_1.2.3.tar.gz", | 510 | : "http://somewhere2.org/somedir3/somefile_1.2.3.tar.gz", |
416 | ("http://www.apache.org/dist/subversion/subversion-1.7.1.tar.bz2", "http://www.apache.org/dist", "http://archive.apache.org/dist") | 511 | ("http://www.apache.org/dist/subversion/subversion-1.7.1.tar.bz2", "http://www.apache.org/dist", "http://archive.apache.org/dist") |
417 | : "http://archive.apache.org/dist/subversion/subversion-1.7.1.tar.bz2", | 512 | : "http://archive.apache.org/dist/subversion/subversion-1.7.1.tar.bz2", |
418 | ("http://www.apache.org/dist/subversion/subversion-1.7.1.tar.bz2", "http://.*/.*", "file:///somepath/downloads/") | 513 | ("http://www.apache.org/dist/subversion/subversion-1.7.1.tar.bz2", "http://.*/.*", "file:///somepath/downloads/") |
419 | : "file:///somepath/downloads/subversion-1.7.1.tar.bz2", | 514 | : "file:///somepath/downloads/subversion-1.7.1.tar.bz2", |
420 | ("git://git.invalid.infradead.org/mtd-utils.git;tag=1234567890123456789012345678901234567890", "git://.*/.*", "git://somewhere.org/somedir/BASENAME;protocol=http") | 515 | ("git://git.invalid.infradead.org/mtd-utils.git;tag=1234567890123456789012345678901234567890;branch=master", "git://.*/.*", "git://somewhere.org/somedir/BASENAME;protocol=http") |
421 | : "git://somewhere.org/somedir/mtd-utils.git;tag=1234567890123456789012345678901234567890;protocol=http", | 516 | : "git://somewhere.org/somedir/mtd-utils.git;tag=1234567890123456789012345678901234567890;branch=master;protocol=http", |
422 | ("git://git.invalid.infradead.org/foo/mtd-utils.git;tag=1234567890123456789012345678901234567890", "git://.*/.*", "git://somewhere.org/somedir/BASENAME;protocol=http") | 517 | ("git://git.invalid.infradead.org/foo/mtd-utils.git;tag=1234567890123456789012345678901234567890;branch=master", "git://.*/.*", "git://somewhere.org/somedir/BASENAME;protocol=http") |
423 | : "git://somewhere.org/somedir/mtd-utils.git;tag=1234567890123456789012345678901234567890;protocol=http", | 518 | : "git://somewhere.org/somedir/mtd-utils.git;tag=1234567890123456789012345678901234567890;branch=master;protocol=http", |
424 | ("git://git.invalid.infradead.org/foo/mtd-utils.git;tag=1234567890123456789012345678901234567890", "git://.*/.*", "git://somewhere.org/somedir/MIRRORNAME;protocol=http") | 519 | ("git://git.invalid.infradead.org/foo/mtd-utils.git;tag=1234567890123456789012345678901234567890;branch=master", "git://.*/.*", "git://somewhere.org/somedir/MIRRORNAME;protocol=http") |
425 | : "git://somewhere.org/somedir/git.invalid.infradead.org.foo.mtd-utils.git;tag=1234567890123456789012345678901234567890;protocol=http", | 520 | : "git://somewhere.org/somedir/git.invalid.infradead.org.foo.mtd-utils.git;tag=1234567890123456789012345678901234567890;branch=master;protocol=http", |
426 | ("http://somewhere.org/somedir1/somedir2/somefile_1.2.3.tar.gz", "http://.*/.*", "http://somewhere2.org") | 521 | ("http://somewhere.org/somedir1/somedir2/somefile_1.2.3.tar.gz", "http://.*/.*", "http://somewhere2.org") |
427 | : "http://somewhere2.org/somefile_1.2.3.tar.gz", | 522 | : "http://somewhere2.org/somefile_1.2.3.tar.gz", |
428 | ("http://somewhere.org/somedir1/somedir2/somefile_1.2.3.tar.gz", "http://.*/.*", "http://somewhere2.org/") | 523 | ("http://somewhere.org/somedir1/somedir2/somefile_1.2.3.tar.gz", "http://.*/.*", "http://somewhere2.org/") |
429 | : "http://somewhere2.org/somefile_1.2.3.tar.gz", | 524 | : "http://somewhere2.org/somefile_1.2.3.tar.gz", |
430 | ("git://someserver.org/bitbake;tag=1234567890123456789012345678901234567890;branch=master", "git://someserver.org/bitbake;branch=master", "git://git.openembedded.org/bitbake;protocol=http") | 525 | ("git://someserver.org/bitbake;tag=1234567890123456789012345678901234567890;branch=master", "git://someserver.org/bitbake;branch=master", "git://git.openembedded.org/bitbake;protocol=http") |
431 | : "git://git.openembedded.org/bitbake;tag=1234567890123456789012345678901234567890;branch=master;protocol=http", | 526 | : "git://git.openembedded.org/bitbake;tag=1234567890123456789012345678901234567890;branch=master;protocol=http", |
527 | ("git://user1@someserver.org/bitbake;tag=1234567890123456789012345678901234567890;branch=master", "git://someserver.org/bitbake;branch=master", "git://user2@git.openembedded.org/bitbake;protocol=http") | ||
528 | : "git://user2@git.openembedded.org/bitbake;tag=1234567890123456789012345678901234567890;branch=master;protocol=http", | ||
529 | ("git://someserver.org/bitbake;tag=1234567890123456789012345678901234567890;protocol=git;branch=master", "git://someserver.org/bitbake", "git://someotherserver.org/bitbake;protocol=https") | ||
530 | : "git://someotherserver.org/bitbake;tag=1234567890123456789012345678901234567890;protocol=https;branch=master", | ||
531 | ("gitsm://git.qemu.org/git/seabios.git/;protocol=https;name=roms/seabios;subpath=roms/seabios;bareclone=1;nobranch=1;rev=1234567890123456789012345678901234567890", "gitsm://.*/.*", "http://petalinux.xilinx.com/sswreleases/rel-v${XILINX_VER_MAIN}/downloads") : "http://petalinux.xilinx.com/sswreleases/rel-v%24%7BXILINX_VER_MAIN%7D/downloads/git2_git.qemu.org.git.seabios.git..tar.gz", | ||
532 | ("https://somewhere.org/example/1.0.0/example;downloadfilename=some-example-1.0.0.tgz", "https://.*/.*", "file:///mirror/PATH") | ||
533 | : "file:///mirror/example/1.0.0/some-example-1.0.0.tgz;downloadfilename=some-example-1.0.0.tgz", | ||
534 | ("https://somewhere.org/example-1.0.0.tgz;downloadfilename=some-example-1.0.0.tgz", "https://.*/.*", "file:///mirror/some-example-1.0.0.tgz") | ||
535 | : "file:///mirror/some-example-1.0.0.tgz;downloadfilename=some-example-1.0.0.tgz", | ||
536 | ("git://git.invalid.infradead.org/mtd-utils.git;tag=1234567890123456789012345678901234567890;branch=master", r"git://(?!internal\.git\.server).*/.*", "http://somewhere.org/somedir/") | ||
537 | : "http://somewhere.org/somedir/git2_git.invalid.infradead.org.mtd-utils.git.tar.gz", | ||
538 | ("git://internal.git.server.org/mtd-utils.git;tag=1234567890123456789012345678901234567890;branch=master", r"git://(?!internal\.git\.server).*/.*", "http://somewhere.org/somedir/") | ||
539 | : None, | ||
432 | 540 | ||
433 | #Renaming files doesn't work | 541 | #Renaming files doesn't work |
434 | #("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" | 542 | #("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" |
435 | #("file://sstate-xyz.tgz", "file://.*/.*", "file:///somewhere/1234/sstate-cache") : "file:///somewhere/1234/sstate-cache/sstate-xyz.tgz", | 543 | #("file://sstate-xyz.tgz", "file://.*/.*", "file:///somewhere/1234/sstate-cache") : "file:///somewhere/1234/sstate-cache/sstate-xyz.tgz", |
436 | } | 544 | } |
437 | 545 | ||
438 | mirrorvar = "http://.*/.* file:///somepath/downloads/ \n" \ | 546 | mirrorvar = "http://.*/.* file:///somepath/downloads/ " \ |
439 | "git://someserver.org/bitbake git://git.openembedded.org/bitbake \n" \ | 547 | "git://someserver.org/bitbake git://git.openembedded.org/bitbake " \ |
440 | "https://.*/.* file:///someotherpath/downloads/ \n" \ | 548 | "https?://.*/.* file:///someotherpath/downloads/ " \ |
441 | "http://.*/.* file:///someotherpath/downloads/ \n" | 549 | "svn://svn.server1.com/ svn://svn.server2.com/" |
442 | 550 | ||
443 | def test_urireplace(self): | 551 | def test_urireplace(self): |
552 | self.d.setVar("FILESPATH", ".") | ||
444 | for k, v in self.replaceuris.items(): | 553 | for k, v in self.replaceuris.items(): |
445 | ud = bb.fetch.FetchData(k[0], self.d) | 554 | ud = bb.fetch.FetchData(k[0], self.d) |
446 | ud.setup_localpath(self.d) | 555 | ud.setup_localpath(self.d) |
447 | mirrors = bb.fetch2.mirror_from_string("%s %s" % (k[1], k[2])) | 556 | mirrors = bb.fetch2.mirror_from_string("%s %s" % (k[1], k[2])) |
448 | newuris, uds = bb.fetch2.build_mirroruris(ud, mirrors, self.d) | 557 | newuris, uds = bb.fetch2.build_mirroruris(ud, mirrors, self.d) |
449 | self.assertEqual([v], newuris) | 558 | self.assertEqual([v] if v else [], newuris) |
450 | 559 | ||
451 | def test_urilist1(self): | 560 | def test_urilist1(self): |
452 | fetcher = bb.fetch.FetchData("http://downloads.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz", self.d) | 561 | fetcher = bb.fetch.FetchData("http://downloads.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz", self.d) |
@@ -461,10 +570,17 @@ class MirrorUriTest(FetcherTest): | |||
461 | uris, uds = bb.fetch2.build_mirroruris(fetcher, mirrors, self.d) | 570 | uris, uds = bb.fetch2.build_mirroruris(fetcher, mirrors, self.d) |
462 | self.assertEqual(uris, ['file:///someotherpath/downloads/bitbake-1.0.tar.gz']) | 571 | self.assertEqual(uris, ['file:///someotherpath/downloads/bitbake-1.0.tar.gz']) |
463 | 572 | ||
573 | def test_urilistsvn(self): | ||
574 | # Catch svn:// -> svn:// bug | ||
575 | fetcher = bb.fetch.FetchData("svn://svn.server1.com/isource/svnroot/reponame/tags/tagname;module=path_in_tagnamefolder;protocol=https;rev=2", self.d) | ||
576 | mirrors = bb.fetch2.mirror_from_string(self.mirrorvar) | ||
577 | uris, uds = bb.fetch2.build_mirroruris(fetcher, mirrors, self.d) | ||
578 | self.assertEqual(uris, ['svn://svn.server2.com/isource/svnroot/reponame/tags/tagname;module=path_in_tagnamefolder;protocol=https;rev=2']) | ||
579 | |||
464 | def test_mirror_of_mirror(self): | 580 | def test_mirror_of_mirror(self): |
465 | # Test if mirror of a mirror works | 581 | # Test if mirror of a mirror works |
466 | mirrorvar = self.mirrorvar + " http://.*/.* http://otherdownloads.yoctoproject.org/downloads/ \n" | 582 | mirrorvar = self.mirrorvar + " http://.*/.* http://otherdownloads.yoctoproject.org/downloads/" |
467 | mirrorvar = mirrorvar + " http://otherdownloads.yoctoproject.org/.* http://downloads2.yoctoproject.org/downloads/ \n" | 583 | mirrorvar = mirrorvar + " http://otherdownloads.yoctoproject.org/.* http://downloads2.yoctoproject.org/downloads/" |
468 | fetcher = bb.fetch.FetchData("http://downloads.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz", self.d) | 584 | fetcher = bb.fetch.FetchData("http://downloads.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz", self.d) |
469 | mirrors = bb.fetch2.mirror_from_string(mirrorvar) | 585 | mirrors = bb.fetch2.mirror_from_string(mirrorvar) |
470 | uris, uds = bb.fetch2.build_mirroruris(fetcher, mirrors, self.d) | 586 | uris, uds = bb.fetch2.build_mirroruris(fetcher, mirrors, self.d) |
@@ -473,30 +589,30 @@ class MirrorUriTest(FetcherTest): | |||
473 | 'http://otherdownloads.yoctoproject.org/downloads/bitbake-1.0.tar.gz', | 589 | 'http://otherdownloads.yoctoproject.org/downloads/bitbake-1.0.tar.gz', |
474 | 'http://downloads2.yoctoproject.org/downloads/bitbake-1.0.tar.gz']) | 590 | 'http://downloads2.yoctoproject.org/downloads/bitbake-1.0.tar.gz']) |
475 | 591 | ||
476 | recmirrorvar = "https://.*/[^/]* http://AAAA/A/A/A/ \n" \ | 592 | recmirrorvar = "https://.*/[^/]* http://aaaa/A/A/A/ " \ |
477 | "https://.*/[^/]* https://BBBB/B/B/B/ \n" | 593 | "https://.*/[^/]* https://bbbb/B/B/B/" |
478 | 594 | ||
479 | def test_recursive(self): | 595 | def test_recursive(self): |
480 | fetcher = bb.fetch.FetchData("https://downloads.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz", self.d) | 596 | fetcher = bb.fetch.FetchData("https://downloads.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz", self.d) |
481 | mirrors = bb.fetch2.mirror_from_string(self.recmirrorvar) | 597 | mirrors = bb.fetch2.mirror_from_string(self.recmirrorvar) |
482 | uris, uds = bb.fetch2.build_mirroruris(fetcher, mirrors, self.d) | 598 | uris, uds = bb.fetch2.build_mirroruris(fetcher, mirrors, self.d) |
483 | self.assertEqual(uris, ['http://AAAA/A/A/A/bitbake/bitbake-1.0.tar.gz', | 599 | self.assertEqual(uris, ['http://aaaa/A/A/A/bitbake/bitbake-1.0.tar.gz', |
484 | 'https://BBBB/B/B/B/bitbake/bitbake-1.0.tar.gz', | 600 | 'https://bbbb/B/B/B/bitbake/bitbake-1.0.tar.gz', |
485 | 'http://AAAA/A/A/A/B/B/bitbake/bitbake-1.0.tar.gz']) | 601 | 'http://aaaa/A/A/A/B/B/bitbake/bitbake-1.0.tar.gz']) |
486 | 602 | ||
487 | 603 | ||
488 | class GitDownloadDirectoryNamingTest(FetcherTest): | 604 | class GitDownloadDirectoryNamingTest(FetcherTest): |
489 | def setUp(self): | 605 | def setUp(self): |
490 | super(GitDownloadDirectoryNamingTest, self).setUp() | 606 | super(GitDownloadDirectoryNamingTest, self).setUp() |
491 | self.recipe_url = "git://git.openembedded.org/bitbake" | 607 | self.recipe_url = "git://git.openembedded.org/bitbake;branch=master;protocol=https" |
492 | self.recipe_dir = "git.openembedded.org.bitbake" | 608 | self.recipe_dir = "git.openembedded.org.bitbake" |
493 | self.mirror_url = "git://github.com/openembedded/bitbake.git" | 609 | self.mirror_url = "git://github.com/openembedded/bitbake.git;protocol=https;branch=master" |
494 | self.mirror_dir = "github.com.openembedded.bitbake.git" | 610 | self.mirror_dir = "github.com.openembedded.bitbake.git" |
495 | 611 | ||
496 | self.d.setVar('SRCREV', '82ea737a0b42a8b53e11c9cde141e9e9c0bd8c40') | 612 | self.d.setVar('SRCREV', '82ea737a0b42a8b53e11c9cde141e9e9c0bd8c40') |
497 | 613 | ||
498 | def setup_mirror_rewrite(self): | 614 | def setup_mirror_rewrite(self): |
499 | self.d.setVar("PREMIRRORS", self.recipe_url + " " + self.mirror_url + " \n") | 615 | self.d.setVar("PREMIRRORS", self.recipe_url + " " + self.mirror_url) |
500 | 616 | ||
501 | @skipIfNoNetwork() | 617 | @skipIfNoNetwork() |
502 | def test_that_directory_is_named_after_recipe_url_when_no_mirroring_is_used(self): | 618 | def test_that_directory_is_named_after_recipe_url_when_no_mirroring_is_used(self): |
@@ -536,16 +652,16 @@ class GitDownloadDirectoryNamingTest(FetcherTest): | |||
536 | class TarballNamingTest(FetcherTest): | 652 | class TarballNamingTest(FetcherTest): |
537 | def setUp(self): | 653 | def setUp(self): |
538 | super(TarballNamingTest, self).setUp() | 654 | super(TarballNamingTest, self).setUp() |
539 | self.recipe_url = "git://git.openembedded.org/bitbake" | 655 | self.recipe_url = "git://git.openembedded.org/bitbake;branch=master;protocol=https" |
540 | self.recipe_tarball = "git2_git.openembedded.org.bitbake.tar.gz" | 656 | self.recipe_tarball = "git2_git.openembedded.org.bitbake.tar.gz" |
541 | self.mirror_url = "git://github.com/openembedded/bitbake.git" | 657 | self.mirror_url = "git://github.com/openembedded/bitbake.git;protocol=https;branch=master" |
542 | self.mirror_tarball = "git2_github.com.openembedded.bitbake.git.tar.gz" | 658 | self.mirror_tarball = "git2_github.com.openembedded.bitbake.git.tar.gz" |
543 | 659 | ||
544 | self.d.setVar('BB_GENERATE_MIRROR_TARBALLS', '1') | 660 | self.d.setVar('BB_GENERATE_MIRROR_TARBALLS', '1') |
545 | self.d.setVar('SRCREV', '82ea737a0b42a8b53e11c9cde141e9e9c0bd8c40') | 661 | self.d.setVar('SRCREV', '82ea737a0b42a8b53e11c9cde141e9e9c0bd8c40') |
546 | 662 | ||
547 | def setup_mirror_rewrite(self): | 663 | def setup_mirror_rewrite(self): |
548 | self.d.setVar("PREMIRRORS", self.recipe_url + " " + self.mirror_url + " \n") | 664 | self.d.setVar("PREMIRRORS", self.recipe_url + " " + self.mirror_url) |
549 | 665 | ||
550 | @skipIfNoNetwork() | 666 | @skipIfNoNetwork() |
551 | def test_that_the_recipe_tarball_is_created_when_no_mirroring_is_used(self): | 667 | def test_that_the_recipe_tarball_is_created_when_no_mirroring_is_used(self): |
@@ -570,9 +686,9 @@ class TarballNamingTest(FetcherTest): | |||
570 | class GitShallowTarballNamingTest(FetcherTest): | 686 | class GitShallowTarballNamingTest(FetcherTest): |
571 | def setUp(self): | 687 | def setUp(self): |
572 | super(GitShallowTarballNamingTest, self).setUp() | 688 | super(GitShallowTarballNamingTest, self).setUp() |
573 | self.recipe_url = "git://git.openembedded.org/bitbake" | 689 | self.recipe_url = "git://git.openembedded.org/bitbake;branch=master;protocol=https" |
574 | self.recipe_tarball = "gitshallow_git.openembedded.org.bitbake_82ea737-1_master.tar.gz" | 690 | self.recipe_tarball = "gitshallow_git.openembedded.org.bitbake_82ea737-1_master.tar.gz" |
575 | self.mirror_url = "git://github.com/openembedded/bitbake.git" | 691 | self.mirror_url = "git://github.com/openembedded/bitbake.git;protocol=https;branch=master" |
576 | self.mirror_tarball = "gitshallow_github.com.openembedded.bitbake.git_82ea737-1_master.tar.gz" | 692 | self.mirror_tarball = "gitshallow_github.com.openembedded.bitbake.git_82ea737-1_master.tar.gz" |
577 | 693 | ||
578 | self.d.setVar('BB_GIT_SHALLOW', '1') | 694 | self.d.setVar('BB_GIT_SHALLOW', '1') |
@@ -580,7 +696,7 @@ class GitShallowTarballNamingTest(FetcherTest): | |||
580 | self.d.setVar('SRCREV', '82ea737a0b42a8b53e11c9cde141e9e9c0bd8c40') | 696 | self.d.setVar('SRCREV', '82ea737a0b42a8b53e11c9cde141e9e9c0bd8c40') |
581 | 697 | ||
582 | def setup_mirror_rewrite(self): | 698 | def setup_mirror_rewrite(self): |
583 | self.d.setVar("PREMIRRORS", self.recipe_url + " " + self.mirror_url + " \n") | 699 | self.d.setVar("PREMIRRORS", self.recipe_url + " " + self.mirror_url) |
584 | 700 | ||
585 | @skipIfNoNetwork() | 701 | @skipIfNoNetwork() |
586 | def test_that_the_tarball_is_named_after_recipe_url_when_no_mirroring_is_used(self): | 702 | def test_that_the_tarball_is_named_after_recipe_url_when_no_mirroring_is_used(self): |
@@ -602,6 +718,39 @@ class GitShallowTarballNamingTest(FetcherTest): | |||
602 | self.assertIn(self.mirror_tarball, dir) | 718 | self.assertIn(self.mirror_tarball, dir) |
603 | 719 | ||
604 | 720 | ||
721 | class CleanTarballTest(FetcherTest): | ||
722 | def setUp(self): | ||
723 | super(CleanTarballTest, self).setUp() | ||
724 | self.recipe_url = "git://git.openembedded.org/bitbake;protocol=https;branch=master" | ||
725 | self.recipe_tarball = "git2_git.openembedded.org.bitbake.tar.gz" | ||
726 | |||
727 | self.d.setVar('BB_GENERATE_MIRROR_TARBALLS', '1') | ||
728 | self.d.setVar('SRCREV', '82ea737a0b42a8b53e11c9cde141e9e9c0bd8c40') | ||
729 | |||
730 | @skipIfNoNetwork() | ||
731 | def test_that_the_tarball_contents_does_not_leak_info(self): | ||
732 | fetcher = bb.fetch.Fetch([self.recipe_url], self.d) | ||
733 | |||
734 | fetcher.download() | ||
735 | |||
736 | fetcher.unpack(self.unpackdir) | ||
737 | mtime = bb.process.run('git log --all -1 --format=%ct', | ||
738 | cwd=os.path.join(self.unpackdir, 'git')) | ||
739 | self.assertEqual(len(mtime), 2) | ||
740 | mtime = int(mtime[0]) | ||
741 | |||
742 | archive = tarfile.open(os.path.join(self.dldir, self.recipe_tarball)) | ||
743 | self.assertNotEqual(len(archive.members), 0) | ||
744 | for member in archive.members: | ||
745 | if member.name == ".": | ||
746 | continue | ||
747 | self.assertEqual(member.uname, 'oe', "user name for %s differs" % member.name) | ||
748 | self.assertEqual(member.uid, 0, "uid for %s differs" % member.name) | ||
749 | self.assertEqual(member.gname, 'oe', "group name for %s differs" % member.name) | ||
750 | self.assertEqual(member.gid, 0, "gid for %s differs" % member.name) | ||
751 | self.assertEqual(member.mtime, mtime, "mtime for %s differs" % member.name) | ||
752 | |||
753 | |||
605 | class FetcherLocalTest(FetcherTest): | 754 | class FetcherLocalTest(FetcherTest): |
606 | def setUp(self): | 755 | def setUp(self): |
607 | def touch(fn): | 756 | def touch(fn): |
@@ -613,12 +762,16 @@ class FetcherLocalTest(FetcherTest): | |||
613 | os.makedirs(self.localsrcdir) | 762 | os.makedirs(self.localsrcdir) |
614 | touch(os.path.join(self.localsrcdir, 'a')) | 763 | touch(os.path.join(self.localsrcdir, 'a')) |
615 | touch(os.path.join(self.localsrcdir, 'b')) | 764 | touch(os.path.join(self.localsrcdir, 'b')) |
765 | touch(os.path.join(self.localsrcdir, 'c@d')) | ||
616 | os.makedirs(os.path.join(self.localsrcdir, 'dir')) | 766 | os.makedirs(os.path.join(self.localsrcdir, 'dir')) |
617 | touch(os.path.join(self.localsrcdir, 'dir', 'c')) | 767 | touch(os.path.join(self.localsrcdir, 'dir', 'c')) |
618 | touch(os.path.join(self.localsrcdir, 'dir', 'd')) | 768 | touch(os.path.join(self.localsrcdir, 'dir', 'd')) |
619 | os.makedirs(os.path.join(self.localsrcdir, 'dir', 'subdir')) | 769 | os.makedirs(os.path.join(self.localsrcdir, 'dir', 'subdir')) |
620 | touch(os.path.join(self.localsrcdir, 'dir', 'subdir', 'e')) | 770 | touch(os.path.join(self.localsrcdir, 'dir', 'subdir', 'e')) |
621 | touch(os.path.join(self.localsrcdir, r'backslash\x2dsystemd-unit.device')) | 771 | touch(os.path.join(self.localsrcdir, r'backslash\x2dsystemd-unit.device')) |
772 | bb.process.run('tar cf archive.tar -C dir .', cwd=self.localsrcdir) | ||
773 | bb.process.run('tar czf archive.tar.gz -C dir .', cwd=self.localsrcdir) | ||
774 | bb.process.run('tar cjf archive.tar.bz2 -C dir .', cwd=self.localsrcdir) | ||
622 | self.d.setVar("FILESPATH", self.localsrcdir) | 775 | self.d.setVar("FILESPATH", self.localsrcdir) |
623 | 776 | ||
624 | def fetchUnpack(self, uris): | 777 | def fetchUnpack(self, uris): |
@@ -632,10 +785,19 @@ class FetcherLocalTest(FetcherTest): | |||
632 | flst.sort() | 785 | flst.sort() |
633 | return flst | 786 | return flst |
634 | 787 | ||
788 | def test_local_checksum_fails_no_file(self): | ||
789 | self.d.setVar("SRC_URI", "file://404") | ||
790 | with self.assertRaises(bb.BBHandledException): | ||
791 | bb.fetch.get_checksum_file_list(self.d) | ||
792 | |||
635 | def test_local(self): | 793 | def test_local(self): |
636 | tree = self.fetchUnpack(['file://a', 'file://dir/c']) | 794 | tree = self.fetchUnpack(['file://a', 'file://dir/c']) |
637 | self.assertEqual(tree, ['a', 'dir/c']) | 795 | self.assertEqual(tree, ['a', 'dir/c']) |
638 | 796 | ||
797 | def test_local_at(self): | ||
798 | tree = self.fetchUnpack(['file://c@d']) | ||
799 | self.assertEqual(tree, ['c@d']) | ||
800 | |||
639 | def test_local_backslash(self): | 801 | def test_local_backslash(self): |
640 | tree = self.fetchUnpack([r'file://backslash\x2dsystemd-unit.device']) | 802 | tree = self.fetchUnpack([r'file://backslash\x2dsystemd-unit.device']) |
641 | self.assertEqual(tree, [r'backslash\x2dsystemd-unit.device']) | 803 | self.assertEqual(tree, [r'backslash\x2dsystemd-unit.device']) |
@@ -673,57 +835,58 @@ class FetcherLocalTest(FetcherTest): | |||
673 | with self.assertRaises(bb.fetch2.UnpackError): | 835 | with self.assertRaises(bb.fetch2.UnpackError): |
674 | self.fetchUnpack(['file://a;subdir=/bin/sh']) | 836 | self.fetchUnpack(['file://a;subdir=/bin/sh']) |
675 | 837 | ||
676 | def test_local_gitfetch_usehead(self): | 838 | def test_local_striplevel(self): |
839 | tree = self.fetchUnpack(['file://archive.tar;subdir=bar;striplevel=1']) | ||
840 | self.assertEqual(tree, ['bar/c', 'bar/d', 'bar/subdir/e']) | ||
841 | |||
842 | def test_local_striplevel_gzip(self): | ||
843 | tree = self.fetchUnpack(['file://archive.tar.gz;subdir=bar;striplevel=1']) | ||
844 | self.assertEqual(tree, ['bar/c', 'bar/d', 'bar/subdir/e']) | ||
845 | |||
846 | def test_local_striplevel_bzip2(self): | ||
847 | tree = self.fetchUnpack(['file://archive.tar.bz2;subdir=bar;striplevel=1']) | ||
848 | self.assertEqual(tree, ['bar/c', 'bar/d', 'bar/subdir/e']) | ||
849 | |||
850 | def dummyGitTest(self, suffix): | ||
677 | # Create dummy local Git repo | 851 | # Create dummy local Git repo |
678 | src_dir = tempfile.mkdtemp(dir=self.tempdir, | 852 | src_dir = tempfile.mkdtemp(dir=self.tempdir, |
679 | prefix='gitfetch_localusehead_') | 853 | prefix='gitfetch_localusehead_') |
680 | src_dir = os.path.abspath(src_dir) | 854 | self.gitdir = os.path.abspath(src_dir) |
681 | bb.process.run("git init", cwd=src_dir) | 855 | self.git_init() |
682 | bb.process.run("git commit --allow-empty -m'Dummy commit'", | 856 | self.git(['commit', '--allow-empty', '-m', 'Dummy commit']) |
683 | cwd=src_dir) | ||
684 | # Use other branch than master | 857 | # Use other branch than master |
685 | bb.process.run("git checkout -b my-devel", cwd=src_dir) | 858 | self.git(['checkout', '-b', 'my-devel']) |
686 | bb.process.run("git commit --allow-empty -m'Dummy commit 2'", | 859 | self.git(['commit', '--allow-empty', '-m', 'Dummy commit 2']) |
687 | cwd=src_dir) | 860 | orig_rev = self.git(['rev-parse', 'HEAD']).strip() |
688 | stdout = bb.process.run("git rev-parse HEAD", cwd=src_dir) | ||
689 | orig_rev = stdout[0].strip() | ||
690 | 861 | ||
691 | # Fetch and check revision | 862 | # Fetch and check revision |
692 | self.d.setVar("SRCREV", "AUTOINC") | 863 | self.d.setVar("SRCREV", "AUTOINC") |
693 | url = "git://" + src_dir + ";protocol=file;usehead=1" | 864 | self.d.setVar("__BBSRCREV_SEEN", "1") |
865 | url = "git://" + self.gitdir + ";branch=master;protocol=file;" + suffix | ||
694 | fetcher = bb.fetch.Fetch([url], self.d) | 866 | fetcher = bb.fetch.Fetch([url], self.d) |
695 | fetcher.download() | 867 | fetcher.download() |
696 | fetcher.unpack(self.unpackdir) | 868 | fetcher.unpack(self.unpackdir) |
697 | stdout = bb.process.run("git rev-parse HEAD", | 869 | unpack_rev = self.git(['rev-parse', 'HEAD'], |
698 | cwd=os.path.join(self.unpackdir, 'git')) | 870 | cwd=os.path.join(self.unpackdir, 'git')).strip() |
699 | unpack_rev = stdout[0].strip() | ||
700 | self.assertEqual(orig_rev, unpack_rev) | 871 | self.assertEqual(orig_rev, unpack_rev) |
701 | 872 | ||
873 | def test_local_gitfetch_usehead(self): | ||
874 | self.dummyGitTest("usehead=1") | ||
875 | |||
702 | def test_local_gitfetch_usehead_withname(self): | 876 | def test_local_gitfetch_usehead_withname(self): |
703 | # Create dummy local Git repo | 877 | self.dummyGitTest("usehead=1;name=newName") |
704 | src_dir = tempfile.mkdtemp(dir=self.tempdir, | ||
705 | prefix='gitfetch_localusehead_') | ||
706 | src_dir = os.path.abspath(src_dir) | ||
707 | bb.process.run("git init", cwd=src_dir) | ||
708 | bb.process.run("git commit --allow-empty -m'Dummy commit'", | ||
709 | cwd=src_dir) | ||
710 | # Use other branch than master | ||
711 | bb.process.run("git checkout -b my-devel", cwd=src_dir) | ||
712 | bb.process.run("git commit --allow-empty -m'Dummy commit 2'", | ||
713 | cwd=src_dir) | ||
714 | stdout = bb.process.run("git rev-parse HEAD", cwd=src_dir) | ||
715 | orig_rev = stdout[0].strip() | ||
716 | 878 | ||
717 | # Fetch and check revision | 879 | def test_local_gitfetch_shared(self): |
718 | self.d.setVar("SRCREV", "AUTOINC") | 880 | self.dummyGitTest("usehead=1;name=sharedName") |
719 | url = "git://" + src_dir + ";protocol=file;usehead=1;name=newName" | 881 | alt = os.path.join(self.unpackdir, 'git/.git/objects/info/alternates') |
720 | fetcher = bb.fetch.Fetch([url], self.d) | 882 | self.assertTrue(os.path.exists(alt)) |
721 | fetcher.download() | 883 | |
722 | fetcher.unpack(self.unpackdir) | 884 | def test_local_gitfetch_noshared(self): |
723 | stdout = bb.process.run("git rev-parse HEAD", | 885 | self.d.setVar('BB_GIT_NOSHARED', '1') |
724 | cwd=os.path.join(self.unpackdir, 'git')) | 886 | self.unpackdir += '_noshared' |
725 | unpack_rev = stdout[0].strip() | 887 | self.dummyGitTest("usehead=1;name=noSharedName") |
726 | self.assertEqual(orig_rev, unpack_rev) | 888 | alt = os.path.join(self.unpackdir, 'git/.git/objects/info/alternates') |
889 | self.assertFalse(os.path.exists(alt)) | ||
727 | 890 | ||
728 | class FetcherNoNetworkTest(FetcherTest): | 891 | class FetcherNoNetworkTest(FetcherTest): |
729 | def setUp(self): | 892 | def setUp(self): |
@@ -831,12 +994,12 @@ class FetcherNoNetworkTest(FetcherTest): | |||
831 | class FetcherNetworkTest(FetcherTest): | 994 | class FetcherNetworkTest(FetcherTest): |
832 | @skipIfNoNetwork() | 995 | @skipIfNoNetwork() |
833 | def test_fetch(self): | 996 | def test_fetch(self): |
834 | 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) | 997 | fetcher = bb.fetch.Fetch(["https://downloads.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz", "https://downloads.yoctoproject.org/releases/bitbake/bitbake-1.1.tar.gz"], self.d) |
835 | fetcher.download() | 998 | fetcher.download() |
836 | self.assertEqual(os.path.getsize(self.dldir + "/bitbake-1.0.tar.gz"), 57749) | 999 | self.assertEqual(os.path.getsize(self.dldir + "/bitbake-1.0.tar.gz"), 57749) |
837 | self.assertEqual(os.path.getsize(self.dldir + "/bitbake-1.1.tar.gz"), 57892) | 1000 | self.assertEqual(os.path.getsize(self.dldir + "/bitbake-1.1.tar.gz"), 57892) |
838 | self.d.setVar("BB_NO_NETWORK", "1") | 1001 | self.d.setVar("BB_NO_NETWORK", "1") |
839 | 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) | 1002 | fetcher = bb.fetch.Fetch(["https://downloads.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz", "https://downloads.yoctoproject.org/releases/bitbake/bitbake-1.1.tar.gz"], self.d) |
840 | fetcher.download() | 1003 | fetcher.download() |
841 | fetcher.unpack(self.unpackdir) | 1004 | fetcher.unpack(self.unpackdir) |
842 | self.assertEqual(len(os.listdir(self.unpackdir + "/bitbake-1.0/")), 9) | 1005 | self.assertEqual(len(os.listdir(self.unpackdir + "/bitbake-1.0/")), 9) |
@@ -844,21 +1007,22 @@ class FetcherNetworkTest(FetcherTest): | |||
844 | 1007 | ||
845 | @skipIfNoNetwork() | 1008 | @skipIfNoNetwork() |
846 | def test_fetch_mirror(self): | 1009 | def test_fetch_mirror(self): |
847 | self.d.setVar("MIRRORS", "http://.*/.* http://downloads.yoctoproject.org/releases/bitbake") | 1010 | self.d.setVar("MIRRORS", "http://.*/.* https://downloads.yoctoproject.org/releases/bitbake") |
848 | fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz"], self.d) | 1011 | fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz"], self.d) |
849 | fetcher.download() | 1012 | fetcher.download() |
850 | self.assertEqual(os.path.getsize(self.dldir + "/bitbake-1.0.tar.gz"), 57749) | 1013 | self.assertEqual(os.path.getsize(self.dldir + "/bitbake-1.0.tar.gz"), 57749) |
851 | 1014 | ||
852 | @skipIfNoNetwork() | 1015 | @skipIfNoNetwork() |
853 | def test_fetch_mirror_of_mirror(self): | 1016 | def test_fetch_mirror_of_mirror(self): |
854 | self.d.setVar("MIRRORS", "http://.*/.* http://invalid2.yoctoproject.org/ \n http://invalid2.yoctoproject.org/.* http://downloads.yoctoproject.org/releases/bitbake") | 1017 | self.d.setVar("MIRRORS", "http://.*/.* http://invalid2.yoctoproject.org/ http://invalid2.yoctoproject.org/.* https://downloads.yoctoproject.org/releases/bitbake") |
855 | fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz"], self.d) | 1018 | fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz"], self.d) |
856 | fetcher.download() | 1019 | fetcher.download() |
857 | self.assertEqual(os.path.getsize(self.dldir + "/bitbake-1.0.tar.gz"), 57749) | 1020 | self.assertEqual(os.path.getsize(self.dldir + "/bitbake-1.0.tar.gz"), 57749) |
858 | 1021 | ||
859 | @skipIfNoNetwork() | 1022 | @skipIfNoNetwork() |
860 | def test_fetch_file_mirror_of_mirror(self): | 1023 | def test_fetch_file_mirror_of_mirror(self): |
861 | self.d.setVar("MIRRORS", "http://.*/.* file:///some1where/ \n file:///some1where/.* file://some2where/ \n file://some2where/.* http://downloads.yoctoproject.org/releases/bitbake") | 1024 | self.d.setVar("FILESPATH", ".") |
1025 | self.d.setVar("MIRRORS", "http://.*/.* file:///some1where/ file:///some1where/.* file://some2where/ file://some2where/.* https://downloads.yoctoproject.org/releases/bitbake") | ||
862 | fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz"], self.d) | 1026 | fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz"], self.d) |
863 | os.mkdir(self.dldir + "/some2where") | 1027 | os.mkdir(self.dldir + "/some2where") |
864 | fetcher.download() | 1028 | fetcher.download() |
@@ -866,16 +1030,46 @@ class FetcherNetworkTest(FetcherTest): | |||
866 | 1030 | ||
867 | @skipIfNoNetwork() | 1031 | @skipIfNoNetwork() |
868 | def test_fetch_premirror(self): | 1032 | def test_fetch_premirror(self): |
869 | self.d.setVar("PREMIRRORS", "http://.*/.* http://downloads.yoctoproject.org/releases/bitbake") | 1033 | self.d.setVar("PREMIRRORS", "http://.*/.* https://downloads.yoctoproject.org/releases/bitbake") |
870 | fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz"], self.d) | 1034 | fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz"], self.d) |
871 | fetcher.download() | 1035 | fetcher.download() |
872 | self.assertEqual(os.path.getsize(self.dldir + "/bitbake-1.0.tar.gz"), 57749) | 1036 | self.assertEqual(os.path.getsize(self.dldir + "/bitbake-1.0.tar.gz"), 57749) |
873 | 1037 | ||
874 | @skipIfNoNetwork() | 1038 | @skipIfNoNetwork() |
1039 | def test_fetch_specify_downloadfilename(self): | ||
1040 | fetcher = bb.fetch.Fetch(["https://downloads.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz;downloadfilename=bitbake-v1.0.0.tar.gz"], self.d) | ||
1041 | fetcher.download() | ||
1042 | self.assertEqual(os.path.getsize(self.dldir + "/bitbake-v1.0.0.tar.gz"), 57749) | ||
1043 | |||
1044 | @skipIfNoNetwork() | ||
1045 | def test_fetch_premirror_specify_downloadfilename_regex_uri(self): | ||
1046 | self.d.setVar("PREMIRRORS", "http://.*/.* https://downloads.yoctoproject.org/releases/bitbake/") | ||
1047 | fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/releases/bitbake/1.0.tar.gz;downloadfilename=bitbake-1.0.tar.gz"], self.d) | ||
1048 | fetcher.download() | ||
1049 | self.assertEqual(os.path.getsize(self.dldir + "/bitbake-1.0.tar.gz"), 57749) | ||
1050 | |||
1051 | @skipIfNoNetwork() | ||
1052 | # BZ13039 | ||
1053 | def test_fetch_premirror_specify_downloadfilename_specific_uri(self): | ||
1054 | self.d.setVar("PREMIRRORS", "http://invalid.yoctoproject.org/releases/bitbake https://downloads.yoctoproject.org/releases/bitbake") | ||
1055 | fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/releases/bitbake/1.0.tar.gz;downloadfilename=bitbake-1.0.tar.gz"], self.d) | ||
1056 | fetcher.download() | ||
1057 | self.assertEqual(os.path.getsize(self.dldir + "/bitbake-1.0.tar.gz"), 57749) | ||
1058 | |||
1059 | @skipIfNoNetwork() | ||
1060 | def test_fetch_premirror_use_downloadfilename_to_fetch(self): | ||
1061 | # Ensure downloadfilename is used when fetching from premirror. | ||
1062 | self.d.setVar("PREMIRRORS", "http://.*/.* https://downloads.yoctoproject.org/releases/bitbake") | ||
1063 | fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/releases/bitbake/bitbake-1.1.tar.gz;downloadfilename=bitbake-1.0.tar.gz"], self.d) | ||
1064 | fetcher.download() | ||
1065 | self.assertEqual(os.path.getsize(self.dldir + "/bitbake-1.0.tar.gz"), 57749) | ||
1066 | |||
1067 | @skipIfNoNetwork() | ||
875 | def gitfetcher(self, url1, url2): | 1068 | def gitfetcher(self, url1, url2): |
876 | def checkrevision(self, fetcher): | 1069 | def checkrevision(self, fetcher): |
877 | fetcher.unpack(self.unpackdir) | 1070 | fetcher.unpack(self.unpackdir) |
878 | revision = bb.process.run("git rev-parse HEAD", shell=True, cwd=self.unpackdir + "/git")[0].strip() | 1071 | revision = self.git(['rev-parse', 'HEAD'], |
1072 | cwd=os.path.join(self.unpackdir, 'git')).strip() | ||
879 | self.assertEqual(revision, "270a05b0b4ba0959fe0624d2a4885d7b70426da5") | 1073 | self.assertEqual(revision, "270a05b0b4ba0959fe0624d2a4885d7b70426da5") |
880 | 1074 | ||
881 | self.d.setVar("BB_GENERATE_MIRROR_TARBALLS", "1") | 1075 | self.d.setVar("BB_GENERATE_MIRROR_TARBALLS", "1") |
@@ -893,25 +1087,19 @@ class FetcherNetworkTest(FetcherTest): | |||
893 | 1087 | ||
894 | @skipIfNoNetwork() | 1088 | @skipIfNoNetwork() |
895 | def test_gitfetch(self): | 1089 | def test_gitfetch(self): |
896 | url1 = url2 = "git://git.openembedded.org/bitbake" | 1090 | url1 = url2 = "git://git.openembedded.org/bitbake;branch=master;protocol=https" |
897 | self.gitfetcher(url1, url2) | 1091 | self.gitfetcher(url1, url2) |
898 | 1092 | ||
899 | @skipIfNoNetwork() | 1093 | @skipIfNoNetwork() |
900 | def test_gitfetch_goodsrcrev(self): | 1094 | def test_gitfetch_goodsrcrev(self): |
901 | # SRCREV is set but matches rev= parameter | 1095 | # SRCREV is set but matches rev= parameter |
902 | url1 = url2 = "git://git.openembedded.org/bitbake;rev=270a05b0b4ba0959fe0624d2a4885d7b70426da5" | 1096 | url1 = url2 = "git://git.openembedded.org/bitbake;rev=270a05b0b4ba0959fe0624d2a4885d7b70426da5;branch=master;protocol=https" |
903 | self.gitfetcher(url1, url2) | 1097 | self.gitfetcher(url1, url2) |
904 | 1098 | ||
905 | @skipIfNoNetwork() | 1099 | @skipIfNoNetwork() |
906 | def test_gitfetch_badsrcrev(self): | 1100 | def test_gitfetch_badsrcrev(self): |
907 | # SRCREV is set but does not match rev= parameter | 1101 | # SRCREV is set but does not match rev= parameter |
908 | url1 = url2 = "git://git.openembedded.org/bitbake;rev=dead05b0b4ba0959fe0624d2a4885d7b70426da5" | 1102 | url1 = url2 = "git://git.openembedded.org/bitbake;rev=dead05b0b4ba0959fe0624d2a4885d7b70426da5;branch=master;protocol=https" |
909 | self.assertRaises(bb.fetch.FetchError, self.gitfetcher, url1, url2) | ||
910 | |||
911 | @skipIfNoNetwork() | ||
912 | def test_gitfetch_tagandrev(self): | ||
913 | # SRCREV is set but does not match rev= parameter | ||
914 | url1 = url2 = "git://git.openembedded.org/bitbake;rev=270a05b0b4ba0959fe0624d2a4885d7b70426da5;tag=270a05b0b4ba0959fe0624d2a4885d7b70426da5" | ||
915 | self.assertRaises(bb.fetch.FetchError, self.gitfetcher, url1, url2) | 1103 | self.assertRaises(bb.fetch.FetchError, self.gitfetcher, url1, url2) |
916 | 1104 | ||
917 | @skipIfNoNetwork() | 1105 | @skipIfNoNetwork() |
@@ -920,7 +1108,7 @@ class FetcherNetworkTest(FetcherTest): | |||
920 | # `usehead=1' and instead fetch the specified SRCREV. See | 1108 | # `usehead=1' and instead fetch the specified SRCREV. See |
921 | # test_local_gitfetch_usehead() for a positive use of the usehead | 1109 | # test_local_gitfetch_usehead() for a positive use of the usehead |
922 | # feature. | 1110 | # feature. |
923 | url = "git://git.openembedded.org/bitbake;usehead=1" | 1111 | url = "git://git.openembedded.org/bitbake;usehead=1;branch=master;protocol=https" |
924 | self.assertRaises(bb.fetch.ParameterError, self.gitfetcher, url, url) | 1112 | self.assertRaises(bb.fetch.ParameterError, self.gitfetcher, url, url) |
925 | 1113 | ||
926 | @skipIfNoNetwork() | 1114 | @skipIfNoNetwork() |
@@ -929,38 +1117,38 @@ class FetcherNetworkTest(FetcherTest): | |||
929 | # `usehead=1' and instead fetch the specified SRCREV. See | 1117 | # `usehead=1' and instead fetch the specified SRCREV. See |
930 | # test_local_gitfetch_usehead() for a positive use of the usehead | 1118 | # test_local_gitfetch_usehead() for a positive use of the usehead |
931 | # feature. | 1119 | # feature. |
932 | url = "git://git.openembedded.org/bitbake;usehead=1;name=newName" | 1120 | url = "git://git.openembedded.org/bitbake;usehead=1;name=newName;branch=master;protocol=https" |
933 | self.assertRaises(bb.fetch.ParameterError, self.gitfetcher, url, url) | 1121 | self.assertRaises(bb.fetch.ParameterError, self.gitfetcher, url, url) |
934 | 1122 | ||
935 | @skipIfNoNetwork() | 1123 | @skipIfNoNetwork() |
936 | def test_gitfetch_finds_local_tarball_for_mirrored_url_when_previous_downloaded_by_the_recipe_url(self): | 1124 | def test_gitfetch_finds_local_tarball_for_mirrored_url_when_previous_downloaded_by_the_recipe_url(self): |
937 | recipeurl = "git://git.openembedded.org/bitbake" | 1125 | recipeurl = "git://git.openembedded.org/bitbake;branch=master;protocol=https" |
938 | mirrorurl = "git://someserver.org/bitbake" | 1126 | mirrorurl = "git://someserver.org/bitbake;branch=master;protocol=https" |
939 | self.d.setVar("PREMIRRORS", "git://someserver.org/bitbake git://git.openembedded.org/bitbake \n") | 1127 | self.d.setVar("PREMIRRORS", "git://someserver.org/bitbake git://git.openembedded.org/bitbake") |
940 | self.gitfetcher(recipeurl, mirrorurl) | 1128 | self.gitfetcher(recipeurl, mirrorurl) |
941 | 1129 | ||
942 | @skipIfNoNetwork() | 1130 | @skipIfNoNetwork() |
943 | def test_gitfetch_finds_local_tarball_when_previous_downloaded_from_a_premirror(self): | 1131 | def test_gitfetch_finds_local_tarball_when_previous_downloaded_from_a_premirror(self): |
944 | recipeurl = "git://someserver.org/bitbake" | 1132 | recipeurl = "git://someserver.org/bitbake;branch=master;protocol=https" |
945 | self.d.setVar("PREMIRRORS", "git://someserver.org/bitbake git://git.openembedded.org/bitbake \n") | 1133 | self.d.setVar("PREMIRRORS", "git://someserver.org/bitbake git://git.openembedded.org/bitbake") |
946 | self.gitfetcher(recipeurl, recipeurl) | 1134 | self.gitfetcher(recipeurl, recipeurl) |
947 | 1135 | ||
948 | @skipIfNoNetwork() | 1136 | @skipIfNoNetwork() |
949 | def test_gitfetch_finds_local_repository_when_premirror_rewrites_the_recipe_url(self): | 1137 | def test_gitfetch_finds_local_repository_when_premirror_rewrites_the_recipe_url(self): |
950 | realurl = "git://git.openembedded.org/bitbake" | 1138 | realurl = "https://git.openembedded.org/bitbake" |
951 | recipeurl = "git://someserver.org/bitbake" | 1139 | recipeurl = "git://someserver.org/bitbake;protocol=https;branch=master" |
952 | self.sourcedir = self.unpackdir.replace("unpacked", "sourcemirror.git") | 1140 | self.sourcedir = self.unpackdir.replace("unpacked", "sourcemirror.git") |
953 | os.chdir(self.tempdir) | 1141 | os.chdir(self.tempdir) |
954 | bb.process.run("git clone %s %s 2> /dev/null" % (realurl, self.sourcedir), shell=True) | 1142 | self.git(['clone', realurl, self.sourcedir], cwd=self.tempdir) |
955 | self.d.setVar("PREMIRRORS", "%s git://%s;protocol=file \n" % (recipeurl, self.sourcedir)) | 1143 | self.d.setVar("PREMIRRORS", "%s git://%s;protocol=file" % (recipeurl, self.sourcedir)) |
956 | self.gitfetcher(recipeurl, recipeurl) | 1144 | self.gitfetcher(recipeurl, recipeurl) |
957 | 1145 | ||
958 | @skipIfNoNetwork() | 1146 | @skipIfNoNetwork() |
959 | def test_git_submodule(self): | 1147 | def test_git_submodule(self): |
960 | # URL with ssh submodules | 1148 | # URL with ssh submodules |
961 | url = "gitsm://git.yoctoproject.org/git-submodule-test;branch=ssh-gitsm-tests;rev=049da4a6cb198d7c0302e9e8b243a1443cb809a7" | 1149 | url = "gitsm://git.yoctoproject.org/git-submodule-test;branch=ssh-gitsm-tests;rev=049da4a6cb198d7c0302e9e8b243a1443cb809a7;branch=master;protocol=https" |
962 | # Original URL (comment this if you have ssh access to git.yoctoproject.org) | 1150 | # Original URL (comment this if you have ssh access to git.yoctoproject.org) |
963 | url = "gitsm://git.yoctoproject.org/git-submodule-test;branch=master;rev=a2885dd7d25380d23627e7544b7bbb55014b16ee" | 1151 | url = "gitsm://git.yoctoproject.org/git-submodule-test;branch=master;rev=a2885dd7d25380d23627e7544b7bbb55014b16ee;branch=master;protocol=https" |
964 | fetcher = bb.fetch.Fetch([url], self.d) | 1152 | fetcher = bb.fetch.Fetch([url], self.d) |
965 | fetcher.download() | 1153 | fetcher.download() |
966 | # Previous cwd has been deleted | 1154 | # Previous cwd has been deleted |
@@ -977,10 +1165,29 @@ class FetcherNetworkTest(FetcherTest): | |||
977 | self.assertTrue(os.path.exists(os.path.join(repo_path, 'bitbake-gitsm-test1', 'bitbake')), msg='submodule of submodule missing') | 1165 | self.assertTrue(os.path.exists(os.path.join(repo_path, 'bitbake-gitsm-test1', 'bitbake')), msg='submodule of submodule missing') |
978 | 1166 | ||
979 | @skipIfNoNetwork() | 1167 | @skipIfNoNetwork() |
1168 | def test_git_submodule_restricted_network_premirrors(self): | ||
1169 | # this test is to ensure that premirrors will be tried in restricted network | ||
1170 | # that is, BB_ALLOWED_NETWORKS does not contain the domain the url uses | ||
1171 | url = "gitsm://github.com/grpc/grpc.git;protocol=https;name=grpc;branch=v1.60.x;rev=0ef13a7555dbaadd4633399242524129eef5e231" | ||
1172 | # create a download directory to be used as premirror later | ||
1173 | tempdir = tempfile.mkdtemp(prefix="bitbake-fetch-") | ||
1174 | dl_premirror = os.path.join(tempdir, "download-premirror") | ||
1175 | os.mkdir(dl_premirror) | ||
1176 | self.d.setVar("DL_DIR", dl_premirror) | ||
1177 | fetcher = bb.fetch.Fetch([url], self.d) | ||
1178 | fetcher.download() | ||
1179 | # now use the premirror in restricted network | ||
1180 | self.d.setVar("DL_DIR", self.dldir) | ||
1181 | self.d.setVar("PREMIRRORS", "gitsm://.*/.* gitsm://%s/git2/MIRRORNAME;protocol=file" % dl_premirror) | ||
1182 | self.d.setVar("BB_ALLOWED_NETWORKS", "*.some.domain") | ||
1183 | fetcher = bb.fetch.Fetch([url], self.d) | ||
1184 | fetcher.download() | ||
1185 | |||
1186 | @skipIfNoNetwork() | ||
980 | def test_git_submodule_dbus_broker(self): | 1187 | def test_git_submodule_dbus_broker(self): |
981 | # The following external repositories have show failures in fetch and unpack operations | 1188 | # The following external repositories have show failures in fetch and unpack operations |
982 | # We want to avoid regressions! | 1189 | # We want to avoid regressions! |
983 | url = "gitsm://github.com/bus1/dbus-broker;protocol=git;rev=fc874afa0992d0c75ec25acb43d344679f0ee7d2;branch=main" | 1190 | url = "gitsm://github.com/bus1/dbus-broker;protocol=https;rev=fc874afa0992d0c75ec25acb43d344679f0ee7d2;branch=main" |
984 | fetcher = bb.fetch.Fetch([url], self.d) | 1191 | fetcher = bb.fetch.Fetch([url], self.d) |
985 | fetcher.download() | 1192 | fetcher.download() |
986 | # Previous cwd has been deleted | 1193 | # Previous cwd has been deleted |
@@ -996,7 +1203,7 @@ class FetcherNetworkTest(FetcherTest): | |||
996 | 1203 | ||
997 | @skipIfNoNetwork() | 1204 | @skipIfNoNetwork() |
998 | def test_git_submodule_CLI11(self): | 1205 | def test_git_submodule_CLI11(self): |
999 | url = "gitsm://github.com/CLIUtils/CLI11;protocol=git;rev=bd4dc911847d0cde7a6b41dfa626a85aab213baf" | 1206 | url = "gitsm://github.com/CLIUtils/CLI11;protocol=https;rev=bd4dc911847d0cde7a6b41dfa626a85aab213baf;branch=main" |
1000 | fetcher = bb.fetch.Fetch([url], self.d) | 1207 | fetcher = bb.fetch.Fetch([url], self.d) |
1001 | fetcher.download() | 1208 | fetcher.download() |
1002 | # Previous cwd has been deleted | 1209 | # Previous cwd has been deleted |
@@ -1011,12 +1218,12 @@ class FetcherNetworkTest(FetcherTest): | |||
1011 | @skipIfNoNetwork() | 1218 | @skipIfNoNetwork() |
1012 | def test_git_submodule_update_CLI11(self): | 1219 | def test_git_submodule_update_CLI11(self): |
1013 | """ Prevent regression on update detection not finding missing submodule, or modules without needed commits """ | 1220 | """ Prevent regression on update detection not finding missing submodule, or modules without needed commits """ |
1014 | url = "gitsm://github.com/CLIUtils/CLI11;protocol=git;rev=cf6a99fa69aaefe477cc52e3ef4a7d2d7fa40714" | 1221 | url = "gitsm://github.com/CLIUtils/CLI11;protocol=https;rev=cf6a99fa69aaefe477cc52e3ef4a7d2d7fa40714;branch=main" |
1015 | fetcher = bb.fetch.Fetch([url], self.d) | 1222 | fetcher = bb.fetch.Fetch([url], self.d) |
1016 | fetcher.download() | 1223 | fetcher.download() |
1017 | 1224 | ||
1018 | # CLI11 that pulls in a newer nlohmann-json | 1225 | # CLI11 that pulls in a newer nlohmann-json |
1019 | url = "gitsm://github.com/CLIUtils/CLI11;protocol=git;rev=49ac989a9527ee9bb496de9ded7b4872c2e0e5ca" | 1226 | url = "gitsm://github.com/CLIUtils/CLI11;protocol=https;rev=49ac989a9527ee9bb496de9ded7b4872c2e0e5ca;branch=main" |
1020 | fetcher = bb.fetch.Fetch([url], self.d) | 1227 | fetcher = bb.fetch.Fetch([url], self.d) |
1021 | fetcher.download() | 1228 | fetcher.download() |
1022 | # Previous cwd has been deleted | 1229 | # Previous cwd has been deleted |
@@ -1030,7 +1237,7 @@ class FetcherNetworkTest(FetcherTest): | |||
1030 | 1237 | ||
1031 | @skipIfNoNetwork() | 1238 | @skipIfNoNetwork() |
1032 | def test_git_submodule_aktualizr(self): | 1239 | def test_git_submodule_aktualizr(self): |
1033 | url = "gitsm://github.com/advancedtelematic/aktualizr;branch=master;protocol=git;rev=d00d1a04cc2366d1a5f143b84b9f507f8bd32c44" | 1240 | url = "gitsm://github.com/advancedtelematic/aktualizr;branch=master;protocol=https;rev=d00d1a04cc2366d1a5f143b84b9f507f8bd32c44" |
1034 | fetcher = bb.fetch.Fetch([url], self.d) | 1241 | fetcher = bb.fetch.Fetch([url], self.d) |
1035 | fetcher.download() | 1242 | fetcher.download() |
1036 | # Previous cwd has been deleted | 1243 | # Previous cwd has been deleted |
@@ -1050,7 +1257,7 @@ class FetcherNetworkTest(FetcherTest): | |||
1050 | """ Prevent regression on deeply nested submodules not being checked out properly, even though they were fetched. """ | 1257 | """ Prevent regression on deeply nested submodules not being checked out properly, even though they were fetched. """ |
1051 | 1258 | ||
1052 | # This repository also has submodules where the module (name), path and url do not align | 1259 | # This repository also has submodules where the module (name), path and url do not align |
1053 | url = "gitsm://github.com/azure/iotedge.git;protocol=git;rev=d76e0316c6f324345d77c48a83ce836d09392699" | 1260 | url = "gitsm://github.com/azure/iotedge.git;protocol=https;rev=d76e0316c6f324345d77c48a83ce836d09392699;branch=main" |
1054 | fetcher = bb.fetch.Fetch([url], self.d) | 1261 | fetcher = bb.fetch.Fetch([url], self.d) |
1055 | fetcher.download() | 1262 | fetcher.download() |
1056 | # Previous cwd has been deleted | 1263 | # Previous cwd has been deleted |
@@ -1073,9 +1280,17 @@ class FetcherNetworkTest(FetcherTest): | |||
1073 | self.assertTrue(os.path.exists(os.path.join(repo_path, 'edgelet/hsm-sys/azure-iot-hsm-c/deps/utpm/deps/c-utility/testtools/umock-c/deps/ctest/README.md')), msg='Missing submodule checkout') | 1280 | self.assertTrue(os.path.exists(os.path.join(repo_path, 'edgelet/hsm-sys/azure-iot-hsm-c/deps/utpm/deps/c-utility/testtools/umock-c/deps/ctest/README.md')), msg='Missing submodule checkout') |
1074 | self.assertTrue(os.path.exists(os.path.join(repo_path, 'edgelet/hsm-sys/azure-iot-hsm-c/deps/utpm/deps/c-utility/testtools/umock-c/deps/testrunner/readme.md')), msg='Missing submodule checkout') | 1281 | self.assertTrue(os.path.exists(os.path.join(repo_path, 'edgelet/hsm-sys/azure-iot-hsm-c/deps/utpm/deps/c-utility/testtools/umock-c/deps/testrunner/readme.md')), msg='Missing submodule checkout') |
1075 | 1282 | ||
1283 | @skipIfNoNetwork() | ||
1284 | def test_git_submodule_reference_to_parent(self): | ||
1285 | self.recipe_url = "gitsm://github.com/gflags/gflags.git;protocol=https;branch=master" | ||
1286 | self.d.setVar("SRCREV", "14e1138441bbbb584160cb1c0a0426ec1bac35f1") | ||
1287 | with Timeout(60): | ||
1288 | fetcher = bb.fetch.Fetch([self.recipe_url], self.d) | ||
1289 | with self.assertRaises(bb.fetch2.FetchError): | ||
1290 | fetcher.download() | ||
1291 | |||
1076 | class SVNTest(FetcherTest): | 1292 | class SVNTest(FetcherTest): |
1077 | def skipIfNoSvn(): | 1293 | def skipIfNoSvn(): |
1078 | import shutil | ||
1079 | if not shutil.which("svn"): | 1294 | if not shutil.which("svn"): |
1080 | return unittest.skip("svn not installed, tests being skipped") | 1295 | return unittest.skip("svn not installed, tests being skipped") |
1081 | 1296 | ||
@@ -1107,8 +1322,9 @@ class SVNTest(FetcherTest): | |||
1107 | cwd=repo_dir) | 1322 | cwd=repo_dir) |
1108 | 1323 | ||
1109 | bb.process.run("svn co %s svnfetch_co" % self.repo_url, cwd=self.tempdir) | 1324 | bb.process.run("svn co %s svnfetch_co" % self.repo_url, cwd=self.tempdir) |
1110 | # Github will emulate SVN. Use this to check if we're downloding... | 1325 | # Github won't emulate SVN anymore (see https://github.blog/2023-01-20-sunsetting-subversion-support/) |
1111 | bb.process.run("svn propset svn:externals 'bitbake svn://vcs.pcre.org/pcre2/code' .", | 1326 | # Use still accessible svn repo (only trunk to avoid longer downloads) |
1327 | bb.process.run("svn propset svn:externals 'bitbake https://svn.apache.org/repos/asf/serf/trunk' .", | ||
1112 | cwd=os.path.join(self.tempdir, 'svnfetch_co', 'trunk')) | 1328 | cwd=os.path.join(self.tempdir, 'svnfetch_co', 'trunk')) |
1113 | bb.process.run("svn commit --non-interactive -m 'Add external'", | 1329 | bb.process.run("svn commit --non-interactive -m 'Add external'", |
1114 | cwd=os.path.join(self.tempdir, 'svnfetch_co', 'trunk')) | 1330 | cwd=os.path.join(self.tempdir, 'svnfetch_co', 'trunk')) |
@@ -1136,8 +1352,8 @@ class SVNTest(FetcherTest): | |||
1136 | 1352 | ||
1137 | self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'trunk')), msg="Missing trunk") | 1353 | self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'trunk')), msg="Missing trunk") |
1138 | self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'trunk', 'README.md')), msg="Missing contents") | 1354 | self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'trunk', 'README.md')), msg="Missing contents") |
1139 | self.assertFalse(os.path.exists(os.path.join(self.unpackdir, 'trunk/bitbake/trunk')), msg="External dir should NOT exist") | 1355 | self.assertFalse(os.path.exists(os.path.join(self.unpackdir, 'trunk/bitbake/protocols')), msg="External dir should NOT exist") |
1140 | self.assertFalse(os.path.exists(os.path.join(self.unpackdir, 'trunk/bitbake/trunk', 'README')), msg="External README should NOT exit") | 1356 | self.assertFalse(os.path.exists(os.path.join(self.unpackdir, 'trunk/bitbake/protocols', 'fcgi_buckets.h')), msg="External fcgi_buckets.h should NOT exit") |
1141 | 1357 | ||
1142 | @skipIfNoSvn() | 1358 | @skipIfNoSvn() |
1143 | def test_external_svn(self): | 1359 | def test_external_svn(self): |
@@ -1150,66 +1366,71 @@ class SVNTest(FetcherTest): | |||
1150 | 1366 | ||
1151 | self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'trunk')), msg="Missing trunk") | 1367 | self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'trunk')), msg="Missing trunk") |
1152 | self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'trunk', 'README.md')), msg="Missing contents") | 1368 | self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'trunk', 'README.md')), msg="Missing contents") |
1153 | self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'trunk/bitbake/trunk')), msg="External dir should exist") | 1369 | self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'trunk/bitbake/protocols')), msg="External dir should exist") |
1154 | self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'trunk/bitbake/trunk', 'README')), msg="External README should exit") | 1370 | self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'trunk/bitbake/protocols', 'fcgi_buckets.h')), msg="External fcgi_buckets.h should exit") |
1155 | 1371 | ||
1156 | class TrustedNetworksTest(FetcherTest): | 1372 | class TrustedNetworksTest(FetcherTest): |
1157 | def test_trusted_network(self): | 1373 | def test_trusted_network(self): |
1158 | # Ensure trusted_network returns False when the host IS in the list. | 1374 | # Ensure trusted_network returns False when the host IS in the list. |
1159 | url = "git://Someserver.org/foo;rev=1" | 1375 | url = "git://Someserver.org/foo;rev=1;branch=master" |
1160 | self.d.setVar("BB_ALLOWED_NETWORKS", "server1.org someserver.org server2.org server3.org") | 1376 | self.d.setVar("BB_ALLOWED_NETWORKS", "server1.org someserver.org server2.org server3.org") |
1161 | self.assertTrue(bb.fetch.trusted_network(self.d, url)) | 1377 | self.assertTrue(bb.fetch.trusted_network(self.d, url)) |
1162 | 1378 | ||
1163 | def test_wild_trusted_network(self): | 1379 | def test_wild_trusted_network(self): |
1164 | # Ensure trusted_network returns true when the *.host IS in the list. | 1380 | # Ensure trusted_network returns true when the *.host IS in the list. |
1165 | url = "git://Someserver.org/foo;rev=1" | 1381 | url = "git://Someserver.org/foo;rev=1;branch=master" |
1166 | self.d.setVar("BB_ALLOWED_NETWORKS", "server1.org *.someserver.org server2.org server3.org") | 1382 | self.d.setVar("BB_ALLOWED_NETWORKS", "server1.org *.someserver.org server2.org server3.org") |
1167 | self.assertTrue(bb.fetch.trusted_network(self.d, url)) | 1383 | self.assertTrue(bb.fetch.trusted_network(self.d, url)) |
1168 | 1384 | ||
1169 | def test_prefix_wild_trusted_network(self): | 1385 | def test_prefix_wild_trusted_network(self): |
1170 | # Ensure trusted_network returns true when the prefix matches *.host. | 1386 | # Ensure trusted_network returns true when the prefix matches *.host. |
1171 | url = "git://git.Someserver.org/foo;rev=1" | 1387 | url = "git://git.Someserver.org/foo;rev=1;branch=master" |
1172 | self.d.setVar("BB_ALLOWED_NETWORKS", "server1.org *.someserver.org server2.org server3.org") | 1388 | self.d.setVar("BB_ALLOWED_NETWORKS", "server1.org *.someserver.org server2.org server3.org") |
1173 | self.assertTrue(bb.fetch.trusted_network(self.d, url)) | 1389 | self.assertTrue(bb.fetch.trusted_network(self.d, url)) |
1174 | 1390 | ||
1175 | def test_two_prefix_wild_trusted_network(self): | 1391 | def test_two_prefix_wild_trusted_network(self): |
1176 | # Ensure trusted_network returns true when the prefix matches *.host. | 1392 | # Ensure trusted_network returns true when the prefix matches *.host. |
1177 | url = "git://something.git.Someserver.org/foo;rev=1" | 1393 | url = "git://something.git.Someserver.org/foo;rev=1;branch=master" |
1178 | self.d.setVar("BB_ALLOWED_NETWORKS", "server1.org *.someserver.org server2.org server3.org") | 1394 | self.d.setVar("BB_ALLOWED_NETWORKS", "server1.org *.someserver.org server2.org server3.org") |
1179 | self.assertTrue(bb.fetch.trusted_network(self.d, url)) | 1395 | self.assertTrue(bb.fetch.trusted_network(self.d, url)) |
1180 | 1396 | ||
1181 | def test_port_trusted_network(self): | 1397 | def test_port_trusted_network(self): |
1182 | # Ensure trusted_network returns True, even if the url specifies a port. | 1398 | # Ensure trusted_network returns True, even if the url specifies a port. |
1183 | url = "git://someserver.org:8080/foo;rev=1" | 1399 | url = "git://someserver.org:8080/foo;rev=1;branch=master" |
1184 | self.d.setVar("BB_ALLOWED_NETWORKS", "someserver.org") | 1400 | self.d.setVar("BB_ALLOWED_NETWORKS", "someserver.org") |
1185 | self.assertTrue(bb.fetch.trusted_network(self.d, url)) | 1401 | self.assertTrue(bb.fetch.trusted_network(self.d, url)) |
1186 | 1402 | ||
1187 | def test_untrusted_network(self): | 1403 | def test_untrusted_network(self): |
1188 | # Ensure trusted_network returns False when the host is NOT in the list. | 1404 | # Ensure trusted_network returns False when the host is NOT in the list. |
1189 | url = "git://someserver.org/foo;rev=1" | 1405 | url = "git://someserver.org/foo;rev=1;branch=master" |
1190 | self.d.setVar("BB_ALLOWED_NETWORKS", "server1.org server2.org server3.org") | 1406 | self.d.setVar("BB_ALLOWED_NETWORKS", "server1.org server2.org server3.org") |
1191 | self.assertFalse(bb.fetch.trusted_network(self.d, url)) | 1407 | self.assertFalse(bb.fetch.trusted_network(self.d, url)) |
1192 | 1408 | ||
1193 | def test_wild_untrusted_network(self): | 1409 | def test_wild_untrusted_network(self): |
1194 | # Ensure trusted_network returns False when the host is NOT in the list. | 1410 | # Ensure trusted_network returns False when the host is NOT in the list. |
1195 | url = "git://*.someserver.org/foo;rev=1" | 1411 | url = "git://*.someserver.org/foo;rev=1;branch=master" |
1196 | self.d.setVar("BB_ALLOWED_NETWORKS", "server1.org server2.org server3.org") | 1412 | self.d.setVar("BB_ALLOWED_NETWORKS", "server1.org server2.org server3.org") |
1197 | self.assertFalse(bb.fetch.trusted_network(self.d, url)) | 1413 | self.assertFalse(bb.fetch.trusted_network(self.d, url)) |
1198 | 1414 | ||
1199 | class URLHandle(unittest.TestCase): | 1415 | class URLHandle(unittest.TestCase): |
1200 | 1416 | # Quote password as per RFC3986 | |
1417 | password = urllib.parse.quote(r"!#$%^&*()-_={}[]\|:?,.<>~`", r"!$&'/()*+,;=") | ||
1201 | datatable = { | 1418 | datatable = { |
1202 | "http://www.google.com/index.html" : ('http', 'www.google.com', '/index.html', '', '', {}), | 1419 | "http://www.google.com/index.html" : ('http', 'www.google.com', '/index.html', '', '', {}), |
1203 | "cvs://anoncvs@cvs.handhelds.org/cvs;module=familiar/dist/ipkg" : ('cvs', 'cvs.handhelds.org', '/cvs', 'anoncvs', '', {'module': 'familiar/dist/ipkg'}), | 1420 | "cvs://anoncvs@cvs.handhelds.org/cvs;module=familiar/dist/ipkg" : ('cvs', 'cvs.handhelds.org', '/cvs', 'anoncvs', '', {'module': 'familiar/dist/ipkg'}), |
1204 | "cvs://anoncvs:anonymous@cvs.handhelds.org/cvs;tag=V0-99-81;module=familiar/dist/ipkg" : ('cvs', 'cvs.handhelds.org', '/cvs', 'anoncvs', 'anonymous', collections.OrderedDict([('tag', 'V0-99-81'), ('module', 'familiar/dist/ipkg')])), | 1421 | "cvs://anoncvs:anonymous@cvs.handhelds.org/cvs;tag=V0-99-81;module=familiar/dist/ipkg" : ('cvs', 'cvs.handhelds.org', '/cvs', 'anoncvs', 'anonymous', collections.OrderedDict([('tag', 'V0-99-81'), ('module', 'familiar/dist/ipkg')])), |
1205 | "git://git.openembedded.org/bitbake;branch=@foo" : ('git', 'git.openembedded.org', '/bitbake', '', '', {'branch': '@foo'}), | 1422 | "git://git.openembedded.org/bitbake;branch=@foo;protocol=https" : ('git', 'git.openembedded.org', '/bitbake', '', '', {'branch': '@foo', 'protocol' : 'https'}), |
1206 | "file://somelocation;someparam=1": ('file', '', 'somelocation', '', '', {'someparam': '1'}), | 1423 | "file://somelocation;someparam=1": ('file', '', 'somelocation', '', '', {'someparam': '1'}), |
1424 | "file://example@.service": ('file', '', 'example@.service', '', '', {}), | ||
1425 | "https://somesite.com/somerepo.git;user=anyUser:idtoken=1234" : ('https', 'somesite.com', '/somerepo.git', '', '', {'user': 'anyUser:idtoken=1234'}), | ||
1426 | 'git://s.o-me_ONE:%s@git.openembedded.org/bitbake;branch=main;protocol=https' % password: ('git', 'git.openembedded.org', '/bitbake', 's.o-me_ONE', password, {'branch': 'main', 'protocol' : 'https'}), | ||
1207 | } | 1427 | } |
1208 | # we require a pathname to encodeurl but users can still pass such urls to | 1428 | # we require a pathname to encodeurl but users can still pass such urls to |
1209 | # decodeurl and we need to handle them | 1429 | # decodeurl and we need to handle them |
1210 | decodedata = datatable.copy() | 1430 | decodedata = datatable.copy() |
1211 | decodedata.update({ | 1431 | decodedata.update({ |
1212 | "http://somesite.net;someparam=1": ('http', 'somesite.net', '/', '', '', {'someparam': '1'}), | 1432 | "http://somesite.net;someparam=1": ('http', 'somesite.net', '/', '', '', {'someparam': '1'}), |
1433 | "npmsw://some.registry.url;package=@pkg;version=latest": ('npmsw', 'some.registry.url', '/', '', '', {'package': '@pkg', 'version': 'latest'}), | ||
1213 | }) | 1434 | }) |
1214 | 1435 | ||
1215 | def test_decodeurl(self): | 1436 | def test_decodeurl(self): |
@@ -1220,138 +1441,179 @@ class URLHandle(unittest.TestCase): | |||
1220 | def test_encodeurl(self): | 1441 | def test_encodeurl(self): |
1221 | for k, v in self.datatable.items(): | 1442 | for k, v in self.datatable.items(): |
1222 | result = bb.fetch.encodeurl(v) | 1443 | result = bb.fetch.encodeurl(v) |
1444 | if result.startswith("file:"): | ||
1445 | result = urllib.parse.unquote(result) | ||
1223 | self.assertEqual(result, k) | 1446 | self.assertEqual(result, k) |
1224 | 1447 | ||
1225 | class FetchLatestVersionTest(FetcherTest): | 1448 | class FetchLatestVersionTest(FetcherTest): |
1226 | 1449 | ||
1227 | test_git_uris = { | 1450 | test_git_uris = { |
1228 | # version pattern "X.Y.Z" | 1451 | # version pattern "X.Y.Z" |
1229 | ("mx-1.0", "git://github.com/clutter-project/mx.git;branch=mx-1.4", "9b1db6b8060bd00b121a692f942404a24ae2960f", "") | 1452 | ("mx-1.0", "git://github.com/clutter-project/mx.git;branch=mx-1.4;protocol=https", "9b1db6b8060bd00b121a692f942404a24ae2960f", "", "") |
1230 | : "1.99.4", | 1453 | : "1.99.4", |
1231 | # version pattern "vX.Y" | 1454 | # version pattern "vX.Y" |
1232 | # mirror of git.infradead.org since network issues interfered with testing | 1455 | # mirror of git.infradead.org since network issues interfered with testing |
1233 | ("mtd-utils", "git://git.yoctoproject.org/mtd-utils.git", "ca39eb1d98e736109c64ff9c1aa2a6ecca222d8f", "") | 1456 | ("mtd-utils", "git://git.yoctoproject.org/mtd-utils.git;branch=master;protocol=https", "ca39eb1d98e736109c64ff9c1aa2a6ecca222d8f", "", "") |
1234 | : "1.5.0", | 1457 | : "1.5.0", |
1235 | # version pattern "pkg_name-X.Y" | 1458 | # version pattern "pkg_name-X.Y" |
1236 | # mirror of git://anongit.freedesktop.org/git/xorg/proto/presentproto since network issues interfered with testing | 1459 | # mirror of git://anongit.freedesktop.org/git/xorg/proto/presentproto since network issues interfered with testing |
1237 | ("presentproto", "git://git.yoctoproject.org/bbfetchtests-presentproto", "24f3a56e541b0a9e6c6ee76081f441221a120ef9", "") | 1460 | ("presentproto", "git://git.yoctoproject.org/bbfetchtests-presentproto;branch=master;protocol=https", "24f3a56e541b0a9e6c6ee76081f441221a120ef9", "", "") |
1238 | : "1.0", | 1461 | : "1.0", |
1239 | # version pattern "pkg_name-vX.Y.Z" | 1462 | # version pattern "pkg_name-vX.Y.Z" |
1240 | ("dtc", "git://git.qemu.org/dtc.git", "65cc4d2748a2c2e6f27f1cf39e07a5dbabd80ebf", "") | 1463 | ("dtc", "git://git.yoctoproject.org/bbfetchtests-dtc.git;branch=master;protocol=https", "65cc4d2748a2c2e6f27f1cf39e07a5dbabd80ebf", "", "") |
1241 | : "1.4.0", | 1464 | : "1.4.0", |
1242 | # combination version pattern | 1465 | # combination version pattern |
1243 | ("sysprof", "git://gitlab.gnome.org/GNOME/sysprof.git;protocol=https", "cd44ee6644c3641507fb53b8a2a69137f2971219", "") | 1466 | ("sysprof", "git://git.yoctoproject.org/sysprof.git;protocol=https;branch=master", "cd44ee6644c3641507fb53b8a2a69137f2971219", "", "") |
1244 | : "1.2.0", | 1467 | : "1.2.0", |
1245 | ("u-boot-mkimage", "git://git.denx.de/u-boot.git;branch=master;protocol=git", "62c175fbb8a0f9a926c88294ea9f7e88eb898f6c", "") | 1468 | ("u-boot-mkimage", "git://source.denx.de/u-boot/u-boot.git;branch=master;protocol=https", "62c175fbb8a0f9a926c88294ea9f7e88eb898f6c", "", "") |
1246 | : "2014.01", | 1469 | : "2014.01", |
1247 | # version pattern "yyyymmdd" | 1470 | # version pattern "yyyymmdd" |
1248 | ("mobile-broadband-provider-info", "git://gitlab.gnome.org/GNOME/mobile-broadband-provider-info.git;protocol=https", "4ed19e11c2975105b71b956440acdb25d46a347d", "") | 1471 | ("mobile-broadband-provider-info", "git://git.yoctoproject.org/mobile-broadband-provider-info.git;protocol=https;branch=master", "4ed19e11c2975105b71b956440acdb25d46a347d", "", "") |
1249 | : "20120614", | 1472 | : "20120614", |
1250 | # packages with a valid UPSTREAM_CHECK_GITTAGREGEX | 1473 | # packages with a valid UPSTREAM_CHECK_GITTAGREGEX |
1251 | # mirror of git://anongit.freedesktop.org/xorg/driver/xf86-video-omap since network issues interfered with testing | 1474 | # mirror of git://anongit.freedesktop.org/xorg/driver/xf86-video-omap since network issues interfered with testing |
1252 | ("xf86-video-omap", "git://git.yoctoproject.org/bbfetchtests-xf86-video-omap", "ae0394e687f1a77e966cf72f895da91840dffb8f", "(?P<pver>(\d+\.(\d\.?)*))") | 1475 | ("xf86-video-omap", "git://git.yoctoproject.org/bbfetchtests-xf86-video-omap;branch=master;protocol=https", "ae0394e687f1a77e966cf72f895da91840dffb8f", r"(?P<pver>(\d+\.(\d\.?)*))", "") |
1253 | : "0.4.3", | 1476 | : "0.4.3", |
1254 | ("build-appliance-image", "git://git.yoctoproject.org/poky", "b37dd451a52622d5b570183a81583cc34c2ff555", "(?P<pver>(([0-9][\.|_]?)+[0-9]))") | 1477 | ("build-appliance-image", "git://git.yoctoproject.org/poky;branch=master;protocol=https", "b37dd451a52622d5b570183a81583cc34c2ff555", r"(?P<pver>(([0-9][\.|_]?)+[0-9]))", "") |
1255 | : "11.0.0", | 1478 | : "11.0.0", |
1256 | ("chkconfig-alternatives-native", "git://github.com/kergoth/chkconfig;branch=sysroot", "cd437ecbd8986c894442f8fce1e0061e20f04dee", "chkconfig\-(?P<pver>((\d+[\.\-_]*)+))") | 1479 | ("chkconfig-alternatives-native", "git://github.com/kergoth/chkconfig;branch=sysroot;protocol=https", "cd437ecbd8986c894442f8fce1e0061e20f04dee", r"chkconfig\-(?P<pver>((\d+[\.\-_]*)+))", "") |
1257 | : "1.3.59", | 1480 | : "1.3.59", |
1258 | ("remake", "git://github.com/rocky/remake.git", "f05508e521987c8494c92d9c2871aec46307d51d", "(?P<pver>(\d+\.(\d+\.)*\d*(\+dbg\d+(\.\d+)*)*))") | 1481 | ("remake", "git://github.com/rocky/remake.git;protocol=https;branch=master", "f05508e521987c8494c92d9c2871aec46307d51d", r"(?P<pver>(\d+\.(\d+\.)*\d*(\+dbg\d+(\.\d+)*)*))", "") |
1259 | : "3.82+dbg0.9", | 1482 | : "3.82+dbg0.9", |
1483 | ("sysdig", "git://github.com/draios/sysdig.git;branch=dev;protocol=https", "4fb6288275f567f63515df0ff0a6518043ecfa9b", r"^(?P<pver>\d+(\.\d+)+)", "10.0.0") | ||
1484 | : "0.28.0", | ||
1260 | } | 1485 | } |
1261 | 1486 | ||
1487 | WgetTestData = collections.namedtuple("WgetTestData", ["pn", "path", "pv", "check_uri", "check_regex"], defaults=[None, None, None]) | ||
1262 | test_wget_uris = { | 1488 | test_wget_uris = { |
1263 | # | 1489 | # |
1264 | # packages with versions inside directory name | 1490 | # packages with versions inside directory name |
1265 | # | 1491 | # |
1266 | # http://kernel.org/pub/linux/utils/util-linux/v2.23/util-linux-2.24.2.tar.bz2 | 1492 | # http://kernel.org/pub/linux/utils/util-linux/v2.23/util-linux-2.24.2.tar.bz2 |
1267 | ("util-linux", "/pub/linux/utils/util-linux/v2.23/util-linux-2.24.2.tar.bz2", "", "") | 1493 | WgetTestData("util-linux", "/pub/linux/utils/util-linux/v2.23/util-linux-2.24.2.tar.bz2") |
1268 | : "2.24.2", | 1494 | : "2.24.2", |
1269 | # http://www.abisource.com/downloads/enchant/1.6.0/enchant-1.6.0.tar.gz | 1495 | # http://www.abisource.com/downloads/enchant/1.6.0/enchant-1.6.0.tar.gz |
1270 | ("enchant", "/downloads/enchant/1.6.0/enchant-1.6.0.tar.gz", "", "") | 1496 | WgetTestData("enchant", "/downloads/enchant/1.6.0/enchant-1.6.0.tar.gz") |
1271 | : "1.6.0", | 1497 | : "1.6.0", |
1272 | # http://www.cmake.org/files/v2.8/cmake-2.8.12.1.tar.gz | 1498 | # http://www.cmake.org/files/v2.8/cmake-2.8.12.1.tar.gz |
1273 | ("cmake", "/files/v2.8/cmake-2.8.12.1.tar.gz", "", "") | 1499 | WgetTestData("cmake", "/files/v2.8/cmake-2.8.12.1.tar.gz") |
1274 | : "2.8.12.1", | 1500 | : "2.8.12.1", |
1501 | # https://download.gnome.org/sources/libxml2/2.9/libxml2-2.9.14.tar.xz | ||
1502 | WgetTestData("libxml2", "/software/libxml2/2.9/libxml2-2.9.14.tar.xz") | ||
1503 | : "2.10.3", | ||
1275 | # | 1504 | # |
1276 | # packages with versions only in current directory | 1505 | # packages with versions only in current directory |
1277 | # | 1506 | # |
1278 | # http://downloads.yoctoproject.org/releases/eglibc/eglibc-2.18-svnr23787.tar.bz2 | 1507 | # https://downloads.yoctoproject.org/releases/eglibc/eglibc-2.18-svnr23787.tar.bz2 |
1279 | ("eglic", "/releases/eglibc/eglibc-2.18-svnr23787.tar.bz2", "", "") | 1508 | WgetTestData("eglic", "/releases/eglibc/eglibc-2.18-svnr23787.tar.bz2") |
1280 | : "2.19", | 1509 | : "2.19", |
1281 | # http://downloads.yoctoproject.org/releases/gnu-config/gnu-config-20120814.tar.bz2 | 1510 | # https://downloads.yoctoproject.org/releases/gnu-config/gnu-config-20120814.tar.bz2 |
1282 | ("gnu-config", "/releases/gnu-config/gnu-config-20120814.tar.bz2", "", "") | 1511 | WgetTestData("gnu-config", "/releases/gnu-config/gnu-config-20120814.tar.bz2") |
1283 | : "20120814", | 1512 | : "20120814", |
1284 | # | 1513 | # |
1285 | # packages with "99" in the name of possible version | 1514 | # packages with "99" in the name of possible version |
1286 | # | 1515 | # |
1287 | # http://freedesktop.org/software/pulseaudio/releases/pulseaudio-4.0.tar.xz | 1516 | # http://freedesktop.org/software/pulseaudio/releases/pulseaudio-4.0.tar.xz |
1288 | ("pulseaudio", "/software/pulseaudio/releases/pulseaudio-4.0.tar.xz", "", "") | 1517 | WgetTestData("pulseaudio", "/software/pulseaudio/releases/pulseaudio-4.0.tar.xz") |
1289 | : "5.0", | 1518 | : "5.0", |
1290 | # http://xorg.freedesktop.org/releases/individual/xserver/xorg-server-1.15.1.tar.bz2 | 1519 | # http://xorg.freedesktop.org/releases/individual/xserver/xorg-server-1.15.1.tar.bz2 |
1291 | ("xserver-xorg", "/releases/individual/xserver/xorg-server-1.15.1.tar.bz2", "", "") | 1520 | WgetTestData("xserver-xorg", "/releases/individual/xserver/xorg-server-1.15.1.tar.bz2") |
1292 | : "1.15.1", | 1521 | : "1.15.1", |
1293 | # | 1522 | # |
1294 | # packages with valid UPSTREAM_CHECK_URI and UPSTREAM_CHECK_REGEX | 1523 | # packages with valid UPSTREAM_CHECK_URI and UPSTREAM_CHECK_REGEX |
1295 | # | 1524 | # |
1296 | # http://www.cups.org/software/1.7.2/cups-1.7.2-source.tar.bz2 | 1525 | # http://www.cups.org/software/1.7.2/cups-1.7.2-source.tar.bz2 |
1297 | # https://github.com/apple/cups/releases | 1526 | # https://github.com/apple/cups/releases |
1298 | ("cups", "/software/1.7.2/cups-1.7.2-source.tar.bz2", "/apple/cups/releases", "(?P<name>cups\-)(?P<pver>((\d+[\.\-_]*)+))\-source\.tar\.gz") | 1527 | WgetTestData("cups", "/software/1.7.2/cups-1.7.2-source.tar.bz2", check_uri="/apple/cups/releases", check_regex=r"(?P<name>cups\-)(?P<pver>((\d+[\.\-_]*)+))\-source\.tar\.gz") |
1299 | : "2.0.0", | 1528 | : "2.0.0", |
1300 | # http://download.oracle.com/berkeley-db/db-5.3.21.tar.gz | 1529 | # http://download.oracle.com/berkeley-db/db-5.3.21.tar.gz |
1301 | # http://ftp.debian.org/debian/pool/main/d/db5.3/ | 1530 | # http://ftp.debian.org/debian/pool/main/d/db5.3/ |
1302 | ("db", "/berkeley-db/db-5.3.21.tar.gz", "/debian/pool/main/d/db5.3/", "(?P<name>db5\.3_)(?P<pver>\d+(\.\d+)+).+\.orig\.tar\.xz") | 1531 | WgetTestData("db", "/berkeley-db/db-5.3.21.tar.gz", check_uri="/debian/pool/main/d/db5.3/", check_regex=r"(?P<name>db5\.3_)(?P<pver>\d+(\.\d+)+).+\.orig\.tar\.xz") |
1303 | : "5.3.10", | 1532 | : "5.3.10", |
1533 | # | ||
1534 | # packages where the tarball compression changed in the new version | ||
1535 | # | ||
1536 | # http://ftp.debian.org/debian/pool/main/m/minicom/minicom_2.7.1.orig.tar.gz | ||
1537 | WgetTestData("minicom", "/debian/pool/main/m/minicom/minicom_2.7.1.orig.tar.gz") | ||
1538 | : "2.8", | ||
1539 | |||
1540 | # | ||
1541 | # packages where the path doesn't actually contain the filename, so downloadfilename should be respected | ||
1542 | # | ||
1543 | WgetTestData("miniupnpd", "/software/miniupnp/download.php?file=miniupnpd_2.1.20191006.tar.gz;downloadfilename=miniupnpd_2.1.20191006.tar.gz", pv="2.1.20191006", check_uri="/software/miniupnp/download.php", check_regex=r"miniupnpd-(?P<pver>\d+(\.\d+)+)\.tar") | ||
1544 | : "2.3.7", | ||
1304 | } | 1545 | } |
1305 | 1546 | ||
1547 | test_crate_uris = { | ||
1548 | # basic example; version pattern "A.B.C+cargo-D.E.F" | ||
1549 | ("cargo-c", "crate://crates.io/cargo-c/0.9.18+cargo-0.69") | ||
1550 | : "0.9.29" | ||
1551 | } | ||
1552 | |||
1306 | @skipIfNoNetwork() | 1553 | @skipIfNoNetwork() |
1307 | def test_git_latest_versionstring(self): | 1554 | def test_git_latest_versionstring(self): |
1308 | for k, v in self.test_git_uris.items(): | 1555 | for k, v in self.test_git_uris.items(): |
1309 | self.d.setVar("PN", k[0]) | 1556 | with self.subTest(pn=k[0]): |
1310 | self.d.setVar("SRCREV", k[2]) | 1557 | self.d.setVar("PN", k[0]) |
1311 | self.d.setVar("UPSTREAM_CHECK_GITTAGREGEX", k[3]) | 1558 | self.d.setVar("SRCREV", k[2]) |
1312 | ud = bb.fetch2.FetchData(k[1], self.d) | 1559 | self.d.setVar("UPSTREAM_CHECK_GITTAGREGEX", k[3]) |
1313 | pupver= ud.method.latest_versionstring(ud, self.d) | 1560 | ud = bb.fetch2.FetchData(k[1], self.d) |
1314 | verstring = pupver[0] | 1561 | pupver= ud.method.latest_versionstring(ud, self.d) |
1315 | self.assertTrue(verstring, msg="Could not find upstream version for %s" % k[0]) | 1562 | verstring = pupver[0] |
1316 | r = bb.utils.vercmp_string(v, verstring) | 1563 | self.assertTrue(verstring, msg="Could not find upstream version for %s" % k[0]) |
1317 | self.assertTrue(r == -1 or r == 0, msg="Package %s, version: %s <= %s" % (k[0], v, verstring)) | 1564 | r = bb.utils.vercmp_string(v, verstring) |
1565 | self.assertTrue(r == -1 or r == 0, msg="Package %s, version: %s <= %s" % (k[0], v, verstring)) | ||
1566 | if k[4]: | ||
1567 | r = bb.utils.vercmp_string(verstring, k[4]) | ||
1568 | self.assertTrue(r == -1 or r == 0, msg="Package %s, version: %s <= %s" % (k[0], verstring, k[4])) | ||
1318 | 1569 | ||
1319 | def test_wget_latest_versionstring(self): | 1570 | def test_wget_latest_versionstring(self): |
1320 | testdata = os.path.dirname(os.path.abspath(__file__)) + "/fetch-testdata" | 1571 | testdata = os.path.dirname(os.path.abspath(__file__)) + "/fetch-testdata" |
1321 | server = HTTPService(testdata) | 1572 | server = HTTPService(testdata, host="127.0.0.1") |
1322 | server.start() | 1573 | server.start() |
1323 | port = server.port | 1574 | port = server.port |
1324 | try: | 1575 | try: |
1325 | for k, v in self.test_wget_uris.items(): | 1576 | for data, v in self.test_wget_uris.items(): |
1577 | with self.subTest(pn=data.pn): | ||
1578 | self.d.setVar("PN", data.pn) | ||
1579 | self.d.setVar("PV", data.pv) | ||
1580 | if data.check_uri: | ||
1581 | checkuri = "http://127.0.0.1:%s/%s" % (port, data.check_uri) | ||
1582 | self.d.setVar("UPSTREAM_CHECK_URI", checkuri) | ||
1583 | if data.check_regex: | ||
1584 | self.d.setVar("UPSTREAM_CHECK_REGEX", data.check_regex) | ||
1585 | |||
1586 | url = "http://127.0.0.1:%s/%s" % (port, data.path) | ||
1587 | ud = bb.fetch2.FetchData(url, self.d) | ||
1588 | pupver = ud.method.latest_versionstring(ud, self.d) | ||
1589 | verstring = pupver[0] | ||
1590 | self.assertTrue(verstring, msg="Could not find upstream version for %s" % data.pn) | ||
1591 | r = bb.utils.vercmp_string(v, verstring) | ||
1592 | self.assertTrue(r == -1 or r == 0, msg="Package %s, version: %s <= %s" % (data.pn, v, verstring)) | ||
1593 | finally: | ||
1594 | server.stop() | ||
1595 | |||
1596 | @skipIfNoNetwork() | ||
1597 | def test_crate_latest_versionstring(self): | ||
1598 | for k, v in self.test_crate_uris.items(): | ||
1599 | with self.subTest(pn=k[0]): | ||
1326 | self.d.setVar("PN", k[0]) | 1600 | self.d.setVar("PN", k[0]) |
1327 | checkuri = "" | 1601 | ud = bb.fetch2.FetchData(k[1], self.d) |
1328 | if k[2]: | ||
1329 | checkuri = "http://localhost:%s/" % port + k[2] | ||
1330 | self.d.setVar("UPSTREAM_CHECK_URI", checkuri) | ||
1331 | self.d.setVar("UPSTREAM_CHECK_REGEX", k[3]) | ||
1332 | url = "http://localhost:%s/" % port + k[1] | ||
1333 | ud = bb.fetch2.FetchData(url, self.d) | ||
1334 | pupver = ud.method.latest_versionstring(ud, self.d) | 1602 | pupver = ud.method.latest_versionstring(ud, self.d) |
1335 | verstring = pupver[0] | 1603 | verstring = pupver[0] |
1336 | self.assertTrue(verstring, msg="Could not find upstream version for %s" % k[0]) | 1604 | self.assertTrue(verstring, msg="Could not find upstream version for %s" % k[0]) |
1337 | r = bb.utils.vercmp_string(v, verstring) | 1605 | r = bb.utils.vercmp_string(v, verstring) |
1338 | self.assertTrue(r == -1 or r == 0, msg="Package %s, version: %s <= %s" % (k[0], v, verstring)) | 1606 | self.assertTrue(r == -1 or r == 0, msg="Package %s, version: %s <= %s" % (k[0], v, verstring)) |
1339 | finally: | ||
1340 | server.stop() | ||
1341 | |||
1342 | 1607 | ||
1343 | class FetchCheckStatusTest(FetcherTest): | 1608 | class FetchCheckStatusTest(FetcherTest): |
1344 | test_wget_uris = ["http://downloads.yoctoproject.org/releases/sato/sato-engine-0.1.tar.gz", | 1609 | test_wget_uris = ["https://downloads.yoctoproject.org/releases/sato/sato-engine-0.1.tar.gz", |
1345 | "http://downloads.yoctoproject.org/releases/sato/sato-engine-0.2.tar.gz", | 1610 | "https://downloads.yoctoproject.org/releases/sato/sato-engine-0.2.tar.gz", |
1346 | "http://downloads.yoctoproject.org/releases/sato/sato-engine-0.3.tar.gz", | 1611 | "https://downloads.yoctoproject.org/releases/sato/sato-engine-0.3.tar.gz", |
1347 | "https://yoctoproject.org/", | 1612 | "https://yoctoproject.org/", |
1348 | "https://yoctoproject.org/documentation", | 1613 | "https://docs.yoctoproject.org", |
1349 | "http://downloads.yoctoproject.org/releases/opkg/opkg-0.1.7.tar.gz", | 1614 | "https://downloads.yoctoproject.org/releases/opkg/opkg-0.1.7.tar.gz", |
1350 | "http://downloads.yoctoproject.org/releases/opkg/opkg-0.3.0.tar.gz", | 1615 | "https://downloads.yoctoproject.org/releases/opkg/opkg-0.3.0.tar.gz", |
1351 | "ftp://sourceware.org/pub/libffi/libffi-1.20.tar.gz", | 1616 | "ftp://sourceware.org/pub/libffi/libffi-1.20.tar.gz", |
1352 | "http://ftp.gnu.org/gnu/autoconf/autoconf-2.60.tar.gz", | ||
1353 | "https://ftp.gnu.org/gnu/chess/gnuchess-5.08.tar.gz", | ||
1354 | "https://ftp.gnu.org/gnu/gmp/gmp-4.0.tar.gz", | ||
1355 | # GitHub releases are hosted on Amazon S3, which doesn't support HEAD | 1617 | # GitHub releases are hosted on Amazon S3, which doesn't support HEAD |
1356 | "https://github.com/kergoth/tslib/releases/download/1.1/tslib-1.1.tar.xz" | 1618 | "https://github.com/kergoth/tslib/releases/download/1.1/tslib-1.1.tar.xz" |
1357 | ] | 1619 | ] |
@@ -1389,7 +1651,7 @@ class GitMakeShallowTest(FetcherTest): | |||
1389 | FetcherTest.setUp(self) | 1651 | FetcherTest.setUp(self) |
1390 | self.gitdir = os.path.join(self.tempdir, 'gitshallow') | 1652 | self.gitdir = os.path.join(self.tempdir, 'gitshallow') |
1391 | bb.utils.mkdirhier(self.gitdir) | 1653 | bb.utils.mkdirhier(self.gitdir) |
1392 | bb.process.run('git init', cwd=self.gitdir) | 1654 | self.git_init() |
1393 | 1655 | ||
1394 | def assertRefs(self, expected_refs): | 1656 | def assertRefs(self, expected_refs): |
1395 | actual_refs = self.git(['for-each-ref', '--format=%(refname)']).splitlines() | 1657 | actual_refs = self.git(['for-each-ref', '--format=%(refname)']).splitlines() |
@@ -1403,13 +1665,6 @@ class GitMakeShallowTest(FetcherTest): | |||
1403 | actual_count = len(revs.splitlines()) | 1665 | actual_count = len(revs.splitlines()) |
1404 | self.assertEqual(expected_count, actual_count, msg='Object count `%d` is not the expected `%d`' % (actual_count, expected_count)) | 1666 | self.assertEqual(expected_count, actual_count, msg='Object count `%d` is not the expected `%d`' % (actual_count, expected_count)) |
1405 | 1667 | ||
1406 | def git(self, cmd): | ||
1407 | if isinstance(cmd, str): | ||
1408 | cmd = 'git ' + cmd | ||
1409 | else: | ||
1410 | cmd = ['git'] + cmd | ||
1411 | return bb.process.run(cmd, cwd=self.gitdir)[0] | ||
1412 | |||
1413 | def make_shallow(self, args=None): | 1668 | def make_shallow(self, args=None): |
1414 | if args is None: | 1669 | if args is None: |
1415 | args = ['HEAD'] | 1670 | args = ['HEAD'] |
@@ -1512,13 +1767,13 @@ class GitShallowTest(FetcherTest): | |||
1512 | self.srcdir = os.path.join(self.tempdir, 'gitsource') | 1767 | self.srcdir = os.path.join(self.tempdir, 'gitsource') |
1513 | 1768 | ||
1514 | bb.utils.mkdirhier(self.srcdir) | 1769 | bb.utils.mkdirhier(self.srcdir) |
1515 | self.git('init', cwd=self.srcdir) | 1770 | self.git_init(cwd=self.srcdir) |
1516 | self.d.setVar('WORKDIR', self.tempdir) | 1771 | self.d.setVar('WORKDIR', self.tempdir) |
1517 | self.d.setVar('S', self.gitdir) | 1772 | self.d.setVar('S', self.gitdir) |
1518 | self.d.delVar('PREMIRRORS') | 1773 | self.d.delVar('PREMIRRORS') |
1519 | self.d.delVar('MIRRORS') | 1774 | self.d.delVar('MIRRORS') |
1520 | 1775 | ||
1521 | uri = 'git://%s;protocol=file;subdir=${S}' % self.srcdir | 1776 | uri = 'git://%s;protocol=file;subdir=${S};branch=master' % self.srcdir |
1522 | self.d.setVar('SRC_URI', uri) | 1777 | self.d.setVar('SRC_URI', uri) |
1523 | self.d.setVar('SRCREV', '${AUTOREV}') | 1778 | self.d.setVar('SRCREV', '${AUTOREV}') |
1524 | self.d.setVar('AUTOREV', '${@bb.fetch2.get_autorev(d)}') | 1779 | self.d.setVar('AUTOREV', '${@bb.fetch2.get_autorev(d)}') |
@@ -1526,11 +1781,14 @@ class GitShallowTest(FetcherTest): | |||
1526 | self.d.setVar('BB_GIT_SHALLOW', '1') | 1781 | self.d.setVar('BB_GIT_SHALLOW', '1') |
1527 | self.d.setVar('BB_GENERATE_MIRROR_TARBALLS', '0') | 1782 | self.d.setVar('BB_GENERATE_MIRROR_TARBALLS', '0') |
1528 | self.d.setVar('BB_GENERATE_SHALLOW_TARBALLS', '1') | 1783 | self.d.setVar('BB_GENERATE_SHALLOW_TARBALLS', '1') |
1784 | self.d.setVar("__BBSRCREV_SEEN", "1") | ||
1529 | 1785 | ||
1530 | def assertRefs(self, expected_refs, cwd=None): | 1786 | def assertRefs(self, expected_refs, cwd=None): |
1531 | if cwd is None: | 1787 | if cwd is None: |
1532 | cwd = self.gitdir | 1788 | cwd = self.gitdir |
1533 | actual_refs = self.git(['for-each-ref', '--format=%(refname)'], cwd=cwd).splitlines() | 1789 | actual_refs = self.git(['for-each-ref', '--format=%(refname)'], cwd=cwd).splitlines() |
1790 | # Resolve references into the same format as the comparision (needed by git 2.48 onwards) | ||
1791 | actual_refs = self.git(['rev-parse', '--symbolic-full-name'] + actual_refs, cwd=cwd).splitlines() | ||
1534 | full_expected = self.git(['rev-parse', '--symbolic-full-name'] + expected_refs, cwd=cwd).splitlines() | 1792 | full_expected = self.git(['rev-parse', '--symbolic-full-name'] + expected_refs, cwd=cwd).splitlines() |
1535 | self.assertEqual(sorted(set(full_expected)), sorted(set(actual_refs))) | 1793 | self.assertEqual(sorted(set(full_expected)), sorted(set(actual_refs))) |
1536 | 1794 | ||
@@ -1543,15 +1801,6 @@ class GitShallowTest(FetcherTest): | |||
1543 | actual_count = len(revs.splitlines()) | 1801 | actual_count = len(revs.splitlines()) |
1544 | self.assertEqual(expected_count, actual_count, msg='Object count `%d` is not the expected `%d`' % (actual_count, expected_count)) | 1802 | self.assertEqual(expected_count, actual_count, msg='Object count `%d` is not the expected `%d`' % (actual_count, expected_count)) |
1545 | 1803 | ||
1546 | def git(self, cmd, cwd=None): | ||
1547 | if isinstance(cmd, str): | ||
1548 | cmd = 'git ' + cmd | ||
1549 | else: | ||
1550 | cmd = ['git'] + cmd | ||
1551 | if cwd is None: | ||
1552 | cwd = self.gitdir | ||
1553 | return bb.process.run(cmd, cwd=cwd)[0] | ||
1554 | |||
1555 | def add_empty_file(self, path, cwd=None, msg=None): | 1804 | def add_empty_file(self, path, cwd=None, msg=None): |
1556 | if msg is None: | 1805 | if msg is None: |
1557 | msg = path | 1806 | msg = path |
@@ -1586,7 +1835,6 @@ class GitShallowTest(FetcherTest): | |||
1586 | def fetch_shallow(self, uri=None, disabled=False, keepclone=False): | 1835 | def fetch_shallow(self, uri=None, disabled=False, keepclone=False): |
1587 | """Fetch a uri, generating a shallow tarball, then unpack using it""" | 1836 | """Fetch a uri, generating a shallow tarball, then unpack using it""" |
1588 | fetcher, ud = self.fetch_and_unpack(uri) | 1837 | fetcher, ud = self.fetch_and_unpack(uri) |
1589 | assert os.path.exists(ud.clonedir), 'Git clone in DLDIR (%s) does not exist for uri %s' % (ud.clonedir, uri) | ||
1590 | 1838 | ||
1591 | # Confirm that the unpacked repo is unshallow | 1839 | # Confirm that the unpacked repo is unshallow |
1592 | if not disabled: | 1840 | if not disabled: |
@@ -1594,8 +1842,10 @@ class GitShallowTest(FetcherTest): | |||
1594 | 1842 | ||
1595 | # fetch and unpack, from the shallow tarball | 1843 | # fetch and unpack, from the shallow tarball |
1596 | bb.utils.remove(self.gitdir, recurse=True) | 1844 | bb.utils.remove(self.gitdir, recurse=True) |
1597 | bb.utils.remove(ud.clonedir, recurse=True) | 1845 | if os.path.exists(ud.clonedir): |
1598 | bb.utils.remove(ud.clonedir.replace('gitsource', 'gitsubmodule'), recurse=True) | 1846 | bb.process.run('chmod u+w -R "%s"' % ud.clonedir) |
1847 | bb.utils.remove(ud.clonedir, recurse=True) | ||
1848 | bb.utils.remove(ud.clonedir.replace('gitsource', 'gitsubmodule'), recurse=True) | ||
1599 | 1849 | ||
1600 | # confirm that the unpacked repo is used when no git clone or git | 1850 | # confirm that the unpacked repo is used when no git clone or git |
1601 | # mirror tarball is available | 1851 | # mirror tarball is available |
@@ -1678,7 +1928,12 @@ class GitShallowTest(FetcherTest): | |||
1678 | self.add_empty_file('c') | 1928 | self.add_empty_file('c') |
1679 | self.assertRevCount(3, cwd=self.srcdir) | 1929 | self.assertRevCount(3, cwd=self.srcdir) |
1680 | 1930 | ||
1931 | # Clone without tarball | ||
1932 | self.d.setVar('BB_GIT_SHALLOW', '0') | ||
1933 | fetcher, ud = self.fetch() | ||
1934 | |||
1681 | # Clone and generate mirror tarball | 1935 | # Clone and generate mirror tarball |
1936 | self.d.setVar('BB_GIT_SHALLOW', '1') | ||
1682 | fetcher, ud = self.fetch() | 1937 | fetcher, ud = self.fetch() |
1683 | 1938 | ||
1684 | # Ensure we have a current mirror tarball, but an out of date clone | 1939 | # Ensure we have a current mirror tarball, but an out of date clone |
@@ -1690,6 +1945,7 @@ class GitShallowTest(FetcherTest): | |||
1690 | fetcher, ud = self.fetch() | 1945 | fetcher, ud = self.fetch() |
1691 | fetcher.unpack(self.d.getVar('WORKDIR')) | 1946 | fetcher.unpack(self.d.getVar('WORKDIR')) |
1692 | self.assertRevCount(1) | 1947 | self.assertRevCount(1) |
1948 | assert os.path.exists(os.path.join(self.d.getVar('WORKDIR'), 'git', 'c')) | ||
1693 | 1949 | ||
1694 | def test_shallow_single_branch_no_merge(self): | 1950 | def test_shallow_single_branch_no_merge(self): |
1695 | self.add_empty_file('a') | 1951 | self.add_empty_file('a') |
@@ -1745,7 +2001,7 @@ class GitShallowTest(FetcherTest): | |||
1745 | 2001 | ||
1746 | smdir = os.path.join(self.tempdir, 'gitsubmodule') | 2002 | smdir = os.path.join(self.tempdir, 'gitsubmodule') |
1747 | bb.utils.mkdirhier(smdir) | 2003 | bb.utils.mkdirhier(smdir) |
1748 | self.git('init', cwd=smdir) | 2004 | self.git_init(cwd=smdir) |
1749 | # Make this look like it was cloned from a remote... | 2005 | # Make this look like it was cloned from a remote... |
1750 | self.git('config --add remote.origin.url "%s"' % smdir, cwd=smdir) | 2006 | self.git('config --add remote.origin.url "%s"' % smdir, cwd=smdir) |
1751 | self.git('config --add remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"', cwd=smdir) | 2007 | self.git('config --add remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"', cwd=smdir) |
@@ -1753,11 +2009,11 @@ class GitShallowTest(FetcherTest): | |||
1753 | self.add_empty_file('bsub', cwd=smdir) | 2009 | self.add_empty_file('bsub', cwd=smdir) |
1754 | 2010 | ||
1755 | self.git('submodule init', cwd=self.srcdir) | 2011 | self.git('submodule init', cwd=self.srcdir) |
1756 | self.git('submodule add file://%s' % smdir, cwd=self.srcdir) | 2012 | self.git('-c protocol.file.allow=always submodule add file://%s' % smdir, cwd=self.srcdir) |
1757 | self.git('submodule update', cwd=self.srcdir) | 2013 | self.git('submodule update', cwd=self.srcdir) |
1758 | self.git('commit -m submodule -a', cwd=self.srcdir) | 2014 | self.git('commit -m submodule -a', cwd=self.srcdir) |
1759 | 2015 | ||
1760 | uri = 'gitsm://%s;protocol=file;subdir=${S}' % self.srcdir | 2016 | uri = 'gitsm://%s;protocol=file;subdir=${S};branch=master' % self.srcdir |
1761 | fetcher, ud = self.fetch_shallow(uri) | 2017 | fetcher, ud = self.fetch_shallow(uri) |
1762 | 2018 | ||
1763 | # Verify the main repository is shallow | 2019 | # Verify the main repository is shallow |
@@ -1775,7 +2031,7 @@ class GitShallowTest(FetcherTest): | |||
1775 | 2031 | ||
1776 | smdir = os.path.join(self.tempdir, 'gitsubmodule') | 2032 | smdir = os.path.join(self.tempdir, 'gitsubmodule') |
1777 | bb.utils.mkdirhier(smdir) | 2033 | bb.utils.mkdirhier(smdir) |
1778 | self.git('init', cwd=smdir) | 2034 | self.git_init(cwd=smdir) |
1779 | # Make this look like it was cloned from a remote... | 2035 | # Make this look like it was cloned from a remote... |
1780 | self.git('config --add remote.origin.url "%s"' % smdir, cwd=smdir) | 2036 | self.git('config --add remote.origin.url "%s"' % smdir, cwd=smdir) |
1781 | self.git('config --add remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"', cwd=smdir) | 2037 | self.git('config --add remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"', cwd=smdir) |
@@ -1783,19 +2039,19 @@ class GitShallowTest(FetcherTest): | |||
1783 | self.add_empty_file('bsub', cwd=smdir) | 2039 | self.add_empty_file('bsub', cwd=smdir) |
1784 | 2040 | ||
1785 | self.git('submodule init', cwd=self.srcdir) | 2041 | self.git('submodule init', cwd=self.srcdir) |
1786 | self.git('submodule add file://%s' % smdir, cwd=self.srcdir) | 2042 | self.git('-c protocol.file.allow=always submodule add file://%s' % smdir, cwd=self.srcdir) |
1787 | self.git('submodule update', cwd=self.srcdir) | 2043 | self.git('submodule update', cwd=self.srcdir) |
1788 | self.git('commit -m submodule -a', cwd=self.srcdir) | 2044 | self.git('commit -m submodule -a', cwd=self.srcdir) |
1789 | 2045 | ||
1790 | uri = 'gitsm://%s;protocol=file;subdir=${S}' % self.srcdir | 2046 | uri = 'gitsm://%s;protocol=file;subdir=${S};branch=master' % self.srcdir |
1791 | 2047 | ||
1792 | # Fetch once to generate the shallow tarball | 2048 | # Fetch once to generate the shallow tarball |
1793 | fetcher, ud = self.fetch(uri) | 2049 | fetcher, ud = self.fetch(uri) |
1794 | 2050 | ||
1795 | # Set up the mirror | 2051 | # Set up the mirror |
1796 | mirrordir = os.path.join(self.tempdir, 'mirror') | 2052 | mirrordir = os.path.join(self.tempdir, 'mirror') |
1797 | os.rename(self.dldir, mirrordir) | 2053 | bb.utils.rename(self.dldir, mirrordir) |
1798 | self.d.setVar('PREMIRRORS', 'gitsm://.*/.* file://%s/\n' % mirrordir) | 2054 | self.d.setVar('PREMIRRORS', 'gitsm://.*/.* file://%s/' % mirrordir) |
1799 | 2055 | ||
1800 | # Fetch from the mirror | 2056 | # Fetch from the mirror |
1801 | bb.utils.remove(self.dldir, recurse=True) | 2057 | bb.utils.remove(self.dldir, recurse=True) |
@@ -1818,80 +2074,27 @@ class GitShallowTest(FetcherTest): | |||
1818 | self.git('annex init', cwd=self.srcdir) | 2074 | self.git('annex init', cwd=self.srcdir) |
1819 | open(os.path.join(self.srcdir, 'c'), 'w').close() | 2075 | open(os.path.join(self.srcdir, 'c'), 'w').close() |
1820 | self.git('annex add c', cwd=self.srcdir) | 2076 | self.git('annex add c', cwd=self.srcdir) |
1821 | self.git('commit -m annex-c -a', cwd=self.srcdir) | 2077 | self.git('commit --author "Foo Bar <foo@bar>" -m annex-c -a', cwd=self.srcdir) |
1822 | bb.process.run('chmod u+w -R %s' % os.path.join(self.srcdir, '.git', 'annex')) | 2078 | bb.process.run('chmod u+w -R %s' % self.srcdir) |
1823 | 2079 | ||
1824 | uri = 'gitannex://%s;protocol=file;subdir=${S}' % self.srcdir | 2080 | uri = 'gitannex://%s;protocol=file;subdir=${S};branch=master' % self.srcdir |
1825 | fetcher, ud = self.fetch_shallow(uri) | 2081 | fetcher, ud = self.fetch_shallow(uri) |
1826 | 2082 | ||
1827 | self.assertRevCount(1) | 2083 | self.assertRevCount(1) |
1828 | assert './.git/annex/' in bb.process.run('tar -tzf %s' % os.path.join(self.dldir, ud.mirrortarballs[0]))[0] | 2084 | assert './.git/annex/' in bb.process.run('tar -tzf %s' % os.path.join(self.dldir, ud.mirrortarballs[0]))[0] |
1829 | assert os.path.exists(os.path.join(self.gitdir, 'c')) | 2085 | assert os.path.exists(os.path.join(self.gitdir, 'c')) |
1830 | 2086 | ||
1831 | def test_shallow_multi_one_uri(self): | ||
1832 | # Create initial git repo | ||
1833 | self.add_empty_file('a') | ||
1834 | self.add_empty_file('b') | ||
1835 | self.git('checkout -b a_branch', cwd=self.srcdir) | ||
1836 | self.add_empty_file('c') | ||
1837 | self.add_empty_file('d') | ||
1838 | self.git('checkout master', cwd=self.srcdir) | ||
1839 | self.git('tag v0.0 a_branch', cwd=self.srcdir) | ||
1840 | self.add_empty_file('e') | ||
1841 | self.git('merge --no-ff --no-edit a_branch', cwd=self.srcdir) | ||
1842 | self.add_empty_file('f') | ||
1843 | self.assertRevCount(7, cwd=self.srcdir) | ||
1844 | |||
1845 | uri = self.d.getVar('SRC_URI').split()[0] | ||
1846 | uri = '%s;branch=master,a_branch;name=master,a_branch' % uri | ||
1847 | |||
1848 | self.d.setVar('BB_GIT_SHALLOW_DEPTH', '0') | ||
1849 | self.d.setVar('BB_GIT_SHALLOW_REVS', 'v0.0') | ||
1850 | self.d.setVar('SRCREV_master', '${AUTOREV}') | ||
1851 | self.d.setVar('SRCREV_a_branch', '${AUTOREV}') | ||
1852 | |||
1853 | self.fetch_shallow(uri) | ||
1854 | |||
1855 | self.assertRevCount(5) | ||
1856 | self.assertRefs(['master', 'origin/master', 'origin/a_branch']) | ||
1857 | |||
1858 | def test_shallow_multi_one_uri_depths(self): | ||
1859 | # Create initial git repo | ||
1860 | self.add_empty_file('a') | ||
1861 | self.add_empty_file('b') | ||
1862 | self.git('checkout -b a_branch', cwd=self.srcdir) | ||
1863 | self.add_empty_file('c') | ||
1864 | self.add_empty_file('d') | ||
1865 | self.git('checkout master', cwd=self.srcdir) | ||
1866 | self.add_empty_file('e') | ||
1867 | self.git('merge --no-ff --no-edit a_branch', cwd=self.srcdir) | ||
1868 | self.add_empty_file('f') | ||
1869 | self.assertRevCount(7, cwd=self.srcdir) | ||
1870 | |||
1871 | uri = self.d.getVar('SRC_URI').split()[0] | ||
1872 | uri = '%s;branch=master,a_branch;name=master,a_branch' % uri | ||
1873 | |||
1874 | self.d.setVar('BB_GIT_SHALLOW_DEPTH', '0') | ||
1875 | self.d.setVar('BB_GIT_SHALLOW_DEPTH_master', '3') | ||
1876 | self.d.setVar('BB_GIT_SHALLOW_DEPTH_a_branch', '1') | ||
1877 | self.d.setVar('SRCREV_master', '${AUTOREV}') | ||
1878 | self.d.setVar('SRCREV_a_branch', '${AUTOREV}') | ||
1879 | |||
1880 | self.fetch_shallow(uri) | ||
1881 | |||
1882 | self.assertRevCount(4, ['--all']) | ||
1883 | self.assertRefs(['master', 'origin/master', 'origin/a_branch']) | ||
1884 | |||
1885 | def test_shallow_clone_preferred_over_shallow(self): | 2087 | def test_shallow_clone_preferred_over_shallow(self): |
1886 | self.add_empty_file('a') | 2088 | self.add_empty_file('a') |
1887 | self.add_empty_file('b') | 2089 | self.add_empty_file('b') |
1888 | 2090 | ||
1889 | # Fetch once to generate the shallow tarball | 2091 | # Fetch once to generate the shallow tarball |
2092 | self.d.setVar('BB_GIT_SHALLOW', '0') | ||
1890 | fetcher, ud = self.fetch() | 2093 | fetcher, ud = self.fetch() |
1891 | assert os.path.exists(os.path.join(self.dldir, ud.mirrortarballs[0])) | ||
1892 | 2094 | ||
1893 | # Fetch and unpack with both the clonedir and shallow tarball available | 2095 | # Fetch and unpack with both the clonedir and shallow tarball available |
1894 | bb.utils.remove(self.gitdir, recurse=True) | 2096 | bb.utils.remove(self.gitdir, recurse=True) |
2097 | self.d.setVar('BB_GIT_SHALLOW', '1') | ||
1895 | fetcher, ud = self.fetch_and_unpack() | 2098 | fetcher, ud = self.fetch_and_unpack() |
1896 | 2099 | ||
1897 | # The unpacked tree should *not* be shallow | 2100 | # The unpacked tree should *not* be shallow |
@@ -1910,9 +2113,9 @@ class GitShallowTest(FetcherTest): | |||
1910 | # Set up the mirror | 2113 | # Set up the mirror |
1911 | mirrordir = os.path.join(self.tempdir, 'mirror') | 2114 | mirrordir = os.path.join(self.tempdir, 'mirror') |
1912 | bb.utils.mkdirhier(mirrordir) | 2115 | bb.utils.mkdirhier(mirrordir) |
1913 | self.d.setVar('PREMIRRORS', 'git://.*/.* file://%s/\n' % mirrordir) | 2116 | self.d.setVar('PREMIRRORS', 'git://.*/.* file://%s/' % mirrordir) |
1914 | 2117 | ||
1915 | os.rename(os.path.join(self.dldir, mirrortarball), | 2118 | bb.utils.rename(os.path.join(self.dldir, mirrortarball), |
1916 | os.path.join(mirrordir, mirrortarball)) | 2119 | os.path.join(mirrordir, mirrortarball)) |
1917 | 2120 | ||
1918 | # Fetch from the mirror | 2121 | # Fetch from the mirror |
@@ -1999,7 +2202,7 @@ class GitShallowTest(FetcherTest): | |||
1999 | 2202 | ||
2000 | self.fetch_shallow() | 2203 | self.fetch_shallow() |
2001 | 2204 | ||
2002 | self.assertRevCount(5) | 2205 | self.assertRevCount(2) |
2003 | 2206 | ||
2004 | def test_shallow_invalid_revs(self): | 2207 | def test_shallow_invalid_revs(self): |
2005 | self.add_empty_file('a') | 2208 | self.add_empty_file('a') |
@@ -2018,7 +2221,10 @@ class GitShallowTest(FetcherTest): | |||
2018 | self.git('tag v0.0 master', cwd=self.srcdir) | 2221 | self.git('tag v0.0 master', cwd=self.srcdir) |
2019 | self.d.setVar('BB_GIT_SHALLOW_DEPTH', '0') | 2222 | self.d.setVar('BB_GIT_SHALLOW_DEPTH', '0') |
2020 | self.d.setVar('BB_GIT_SHALLOW_REVS', 'v0.0') | 2223 | self.d.setVar('BB_GIT_SHALLOW_REVS', 'v0.0') |
2021 | self.fetch_shallow() | 2224 | |
2225 | with self.assertRaises(bb.fetch2.FetchError), self.assertLogs("BitBake.Fetcher", level="ERROR") as cm: | ||
2226 | self.fetch_shallow() | ||
2227 | self.assertIn("fatal: no commits selected for shallow requests", cm.output[0]) | ||
2022 | 2228 | ||
2023 | def test_shallow_fetch_missing_revs_fails(self): | 2229 | def test_shallow_fetch_missing_revs_fails(self): |
2024 | self.add_empty_file('a') | 2230 | self.add_empty_file('a') |
@@ -2032,8 +2238,35 @@ class GitShallowTest(FetcherTest): | |||
2032 | self.assertIn("Unable to find revision v0.0 even from upstream", cm.output[0]) | 2238 | self.assertIn("Unable to find revision v0.0 even from upstream", cm.output[0]) |
2033 | 2239 | ||
2034 | @skipIfNoNetwork() | 2240 | @skipIfNoNetwork() |
2241 | def test_git_shallow_fetch_premirrors(self): | ||
2242 | url = "git://git.openembedded.org/bitbake;branch=master;protocol=https" | ||
2243 | |||
2244 | # Create a separate premirror directory within tempdir | ||
2245 | premirror = os.path.join(self.tempdir, "premirror") | ||
2246 | os.mkdir(premirror) | ||
2247 | |||
2248 | # Fetch a non-shallow clone into the premirror subdir | ||
2249 | self.d.setVar('BB_GIT_SHALLOW', '0') | ||
2250 | self.d.setVar("DL_DIR", premirror) | ||
2251 | fetcher, ud = self.fetch(url) | ||
2252 | |||
2253 | # Fetch a shallow clone from the premirror subdir with unpacking | ||
2254 | # using the original recipe URL and the premirror mapping | ||
2255 | self.d.setVar('BB_GIT_SHALLOW', '1') | ||
2256 | self.d.setVar("DL_DIR", self.dldir) | ||
2257 | self.d.setVar('BB_FETCH_PREMIRRORONLY', '1') | ||
2258 | self.d.setVar('BB_NO_NETWORK', '1') | ||
2259 | self.d.setVar('BB_GENERATE_MIRROR_TARBALLS', '0') | ||
2260 | self.d.setVar("PREMIRRORS", "git://.*/.* git://{0};protocol=file".format(premirror + "/git2/" + ud.host + ud.path.replace("/", "."))) | ||
2261 | fetcher = self.fetch_and_unpack(url) | ||
2262 | |||
2263 | # Verify that the unpacked sources are shallow clones | ||
2264 | self.assertRevCount(1) | ||
2265 | assert os.path.exists(os.path.join(self.gitdir, '.git', 'shallow')) | ||
2266 | |||
2267 | @skipIfNoNetwork() | ||
2035 | def test_bitbake(self): | 2268 | def test_bitbake(self): |
2036 | self.git('remote add --mirror=fetch origin git://github.com/openembedded/bitbake', cwd=self.srcdir) | 2269 | self.git('remote add --mirror=fetch origin https://github.com/openembedded/bitbake', cwd=self.srcdir) |
2037 | self.git('config core.bare true', cwd=self.srcdir) | 2270 | self.git('config core.bare true', cwd=self.srcdir) |
2038 | self.git('fetch', cwd=self.srcdir) | 2271 | self.git('fetch', cwd=self.srcdir) |
2039 | 2272 | ||
@@ -2049,7 +2282,7 @@ class GitShallowTest(FetcherTest): | |||
2049 | revs = len(self.git('rev-list master').splitlines()) | 2282 | revs = len(self.git('rev-list master').splitlines()) |
2050 | self.assertNotEqual(orig_revs, revs) | 2283 | self.assertNotEqual(orig_revs, revs) |
2051 | self.assertRefs(['master', 'origin/master']) | 2284 | self.assertRefs(['master', 'origin/master']) |
2052 | self.assertRevCount(orig_revs - 1758) | 2285 | self.assertRevCount(orig_revs - 1760) |
2053 | 2286 | ||
2054 | def test_that_unpack_throws_an_error_when_the_git_clone_nor_shallow_tarball_exist(self): | 2287 | def test_that_unpack_throws_an_error_when_the_git_clone_nor_shallow_tarball_exist(self): |
2055 | self.add_empty_file('a') | 2288 | self.add_empty_file('a') |
@@ -2063,27 +2296,43 @@ class GitShallowTest(FetcherTest): | |||
2063 | self.assertIn("No up to date source found", context.exception.msg) | 2296 | self.assertIn("No up to date source found", context.exception.msg) |
2064 | self.assertIn("clone directory not available or not up to date", context.exception.msg) | 2297 | self.assertIn("clone directory not available or not up to date", context.exception.msg) |
2065 | 2298 | ||
2066 | @skipIfNoNetwork() | 2299 | def test_shallow_check_is_shallow(self): |
2067 | def test_that_unpack_does_work_when_using_git_shallow_tarball_but_tarball_is_not_available(self): | 2300 | self.add_empty_file('a') |
2068 | self.d.setVar('SRCREV', 'e5939ff608b95cdd4d0ab0e1935781ab9a276ac0') | 2301 | self.add_empty_file('b') |
2069 | self.d.setVar('BB_GIT_SHALLOW', '1') | ||
2070 | self.d.setVar('BB_GENERATE_SHALLOW_TARBALLS', '1') | ||
2071 | fetcher = bb.fetch.Fetch(["git://git.yoctoproject.org/fstests"], self.d) | ||
2072 | fetcher.download() | ||
2073 | 2302 | ||
2074 | bb.utils.remove(self.dldir + "/*.tar.gz") | 2303 | # Fetch and unpack without the clonedir and *only* shallow tarball available |
2075 | fetcher.unpack(self.unpackdir) | 2304 | bb.utils.remove(self.gitdir, recurse=True) |
2305 | fetcher, ud = self.fetch_and_unpack() | ||
2076 | 2306 | ||
2077 | dir = os.listdir(self.unpackdir + "/git/") | 2307 | # The unpacked tree *should* be shallow |
2078 | self.assertIn("fstests.doap", dir) | 2308 | self.assertRevCount(1) |
2309 | assert os.path.exists(os.path.join(self.gitdir, '.git', 'shallow')) | ||
2310 | |||
2311 | def test_shallow_succeeds_with_tag_containing_slash(self): | ||
2312 | self.add_empty_file('a') | ||
2313 | self.add_empty_file('b') | ||
2314 | self.git('tag t1/t2/t3', cwd=self.srcdir) | ||
2315 | self.assertRevCount(2, cwd=self.srcdir) | ||
2316 | |||
2317 | srcrev = self.git('rev-parse HEAD', cwd=self.srcdir).strip() | ||
2318 | self.d.setVar('SRCREV', srcrev) | ||
2319 | uri = self.d.getVar('SRC_URI').split()[0] | ||
2320 | uri = '%s;tag=t1/t2/t3' % uri | ||
2321 | self.fetch_shallow(uri) | ||
2322 | self.assertRevCount(1) | ||
2079 | 2323 | ||
2080 | class GitLfsTest(FetcherTest): | 2324 | class GitLfsTest(FetcherTest): |
2325 | def skipIfNoGitLFS(): | ||
2326 | if not shutil.which('git-lfs'): | ||
2327 | return unittest.skip('git-lfs not installed') | ||
2328 | return lambda f: f | ||
2329 | |||
2081 | def setUp(self): | 2330 | def setUp(self): |
2082 | FetcherTest.setUp(self) | 2331 | FetcherTest.setUp(self) |
2083 | 2332 | ||
2084 | self.gitdir = os.path.join(self.tempdir, 'git') | 2333 | self.gitdir = os.path.join(self.tempdir, 'git') |
2085 | self.srcdir = os.path.join(self.tempdir, 'gitsource') | 2334 | self.srcdir = os.path.join(self.tempdir, 'gitsource') |
2086 | 2335 | ||
2087 | self.d.setVar('WORKDIR', self.tempdir) | 2336 | self.d.setVar('WORKDIR', self.tempdir) |
2088 | self.d.setVar('S', self.gitdir) | 2337 | self.d.setVar('S', self.gitdir) |
2089 | self.d.delVar('PREMIRRORS') | 2338 | self.d.delVar('PREMIRRORS') |
@@ -2091,22 +2340,24 @@ class GitLfsTest(FetcherTest): | |||
2091 | 2340 | ||
2092 | self.d.setVar('SRCREV', '${AUTOREV}') | 2341 | self.d.setVar('SRCREV', '${AUTOREV}') |
2093 | self.d.setVar('AUTOREV', '${@bb.fetch2.get_autorev(d)}') | 2342 | self.d.setVar('AUTOREV', '${@bb.fetch2.get_autorev(d)}') |
2343 | self.d.setVar("__BBSRCREV_SEEN", "1") | ||
2094 | 2344 | ||
2095 | bb.utils.mkdirhier(self.srcdir) | 2345 | bb.utils.mkdirhier(self.srcdir) |
2096 | self.git('init', cwd=self.srcdir) | 2346 | self.git_init(cwd=self.srcdir) |
2097 | with open(os.path.join(self.srcdir, '.gitattributes'), 'wt') as attrs: | 2347 | self.commit_file('.gitattributes', '*.mp3 filter=lfs -text') |
2098 | attrs.write('*.mp3 filter=lfs -text') | ||
2099 | self.git(['add', '.gitattributes'], cwd=self.srcdir) | ||
2100 | self.git(['commit', '-m', "attributes", '.gitattributes'], cwd=self.srcdir) | ||
2101 | 2348 | ||
2102 | def git(self, cmd, cwd=None): | 2349 | def commit(self, *, cwd=None): |
2103 | if isinstance(cmd, str): | 2350 | cwd = cwd or self.srcdir |
2104 | cmd = 'git ' + cmd | 2351 | self.git(["commit", "-m", "Change"], cwd=cwd) |
2105 | else: | 2352 | return self.git(["rev-parse", "HEAD"], cwd=cwd).strip() |
2106 | cmd = ['git'] + cmd | 2353 | |
2107 | if cwd is None: | 2354 | def commit_file(self, filename, content, *, cwd=None): |
2108 | cwd = self.gitdir | 2355 | cwd = cwd or self.srcdir |
2109 | return bb.process.run(cmd, cwd=cwd)[0] | 2356 | |
2357 | with open(os.path.join(cwd, filename), "w") as f: | ||
2358 | f.write(content) | ||
2359 | self.git(["add", filename], cwd=cwd) | ||
2360 | return self.commit(cwd=cwd) | ||
2110 | 2361 | ||
2111 | def fetch(self, uri=None, download=True): | 2362 | def fetch(self, uri=None, download=True): |
2112 | uris = self.d.getVar('SRC_URI').split() | 2363 | uris = self.d.getVar('SRC_URI').split() |
@@ -2119,65 +2370,259 @@ class GitLfsTest(FetcherTest): | |||
2119 | ud = fetcher.ud[uri] | 2370 | ud = fetcher.ud[uri] |
2120 | return fetcher, ud | 2371 | return fetcher, ud |
2121 | 2372 | ||
2373 | def get_real_git_lfs_file(self): | ||
2374 | self.d.setVar('PATH', os.environ.get('PATH')) | ||
2375 | fetcher, ud = self.fetch() | ||
2376 | fetcher.unpack(self.d.getVar('WORKDIR')) | ||
2377 | unpacked_lfs_file = os.path.join(self.d.getVar('WORKDIR'), 'git', "Cat_poster_1.jpg") | ||
2378 | return unpacked_lfs_file | ||
2379 | |||
2380 | @skipIfNoGitLFS() | ||
2381 | def test_gitsm_lfs(self): | ||
2382 | """Test that the gitsm fetcher caches objects stored via LFS""" | ||
2383 | self.git(["lfs", "install", "--local"], cwd=self.srcdir) | ||
2384 | |||
2385 | def fetch_and_verify(revision, filename, content): | ||
2386 | self.d.setVar('SRCREV', revision) | ||
2387 | fetcher, ud = self.fetch() | ||
2388 | |||
2389 | with hide_directory(submoduledir), hide_directory(self.srcdir): | ||
2390 | workdir = self.d.getVar('WORKDIR') | ||
2391 | fetcher.unpack(workdir) | ||
2392 | |||
2393 | with open(os.path.join(workdir, "git", filename)) as f: | ||
2394 | self.assertEqual(f.read(), content) | ||
2395 | |||
2396 | # Create the git repository that will later be used as a submodule | ||
2397 | submoduledir = self.tempdir + "/submodule" | ||
2398 | bb.utils.mkdirhier(submoduledir) | ||
2399 | self.git_init(submoduledir) | ||
2400 | self.git(["lfs", "install", "--local"], cwd=submoduledir) | ||
2401 | self.commit_file('.gitattributes', '*.mp3 filter=lfs -text', cwd=submoduledir) | ||
2402 | |||
2403 | submodule_commit_1 = self.commit_file("a.mp3", "submodule version 1", cwd=submoduledir) | ||
2404 | _ = self.commit_file("a.mp3", "submodule version 2", cwd=submoduledir) | ||
2405 | |||
2406 | # Add the submodule to the repository at its current HEAD revision | ||
2407 | self.git(["-c", "protocol.file.allow=always", "submodule", "add", submoduledir, "submodule"], | ||
2408 | cwd=self.srcdir) | ||
2409 | base_commit_1 = self.commit() | ||
2410 | |||
2411 | # Let the submodule point at a different revision | ||
2412 | self.git(["checkout", submodule_commit_1], self.srcdir + "/submodule") | ||
2413 | self.git(["add", "submodule"], cwd=self.srcdir) | ||
2414 | base_commit_2 = self.commit() | ||
2415 | |||
2416 | # Add a LFS file to the repository | ||
2417 | base_commit_3 = self.commit_file("a.mp3", "version 1") | ||
2418 | # Update the added LFS file | ||
2419 | base_commit_4 = self.commit_file("a.mp3", "version 2") | ||
2420 | |||
2421 | self.d.setVar('SRC_URI', "gitsm://%s;protocol=file;lfs=1;branch=master" % self.srcdir) | ||
2422 | |||
2423 | # Verify that LFS objects referenced from submodules are fetched and checked out | ||
2424 | fetch_and_verify(base_commit_1, "submodule/a.mp3", "submodule version 2") | ||
2425 | # Verify that the repository inside the download cache of a submodile is extended with any | ||
2426 | # additional LFS objects needed when checking out a different revision. | ||
2427 | fetch_and_verify(base_commit_2, "submodule/a.mp3", "submodule version 1") | ||
2428 | # Verify that LFS objects referenced from the base repository are fetched and checked out | ||
2429 | fetch_and_verify(base_commit_3, "a.mp3", "version 1") | ||
2430 | # Verify that the cached repository is extended with any additional LFS objects required | ||
2431 | # when checking out a different revision. | ||
2432 | fetch_and_verify(base_commit_4, "a.mp3", "version 2") | ||
2433 | |||
2434 | @skipIfNoGitLFS() | ||
2435 | def test_gitsm_lfs_disabled(self): | ||
2436 | """Test that the gitsm fetcher does not use LFS when explicitly disabled""" | ||
2437 | self.git(["lfs", "install", "--local"], cwd=self.srcdir) | ||
2438 | |||
2439 | def fetch_and_verify(revision, filename, content): | ||
2440 | self.d.setVar('SRCREV', revision) | ||
2441 | fetcher, ud = self.fetch() | ||
2442 | |||
2443 | with hide_directory(submoduledir), hide_directory(self.srcdir): | ||
2444 | workdir = self.d.getVar('WORKDIR') | ||
2445 | fetcher.unpack(workdir) | ||
2446 | |||
2447 | with open(os.path.join(workdir, "git", filename)) as f: | ||
2448 | # Assume that LFS did not perform smudging when the expected content is | ||
2449 | # missing. | ||
2450 | self.assertNotEqual(f.read(), content) | ||
2451 | |||
2452 | # Create the git repository that will later be used as a submodule | ||
2453 | submoduledir = self.tempdir + "/submodule" | ||
2454 | bb.utils.mkdirhier(submoduledir) | ||
2455 | self.git_init(submoduledir) | ||
2456 | self.git(["lfs", "install", "--local"], cwd=submoduledir) | ||
2457 | self.commit_file('.gitattributes', '*.mp3 filter=lfs -text', cwd=submoduledir) | ||
2458 | |||
2459 | submodule_commit_1 = self.commit_file("a.mp3", "submodule version 1", cwd=submoduledir) | ||
2460 | |||
2461 | # Add the submodule to the repository at its current HEAD revision | ||
2462 | self.git(["-c", "protocol.file.allow=always", "submodule", "add", submoduledir, "submodule"], | ||
2463 | cwd=self.srcdir) | ||
2464 | base_commit_1 = self.commit() | ||
2465 | |||
2466 | # Add a LFS file to the repository | ||
2467 | base_commit_2 = self.commit_file("a.mp3", "version 1") | ||
2468 | |||
2469 | self.d.setVar('SRC_URI', "gitsm://%s;protocol=file;lfs=1;branch=master;lfs=0" % self.srcdir) | ||
2470 | |||
2471 | # Verify that LFS objects referenced from submodules are not fetched nor checked out | ||
2472 | fetch_and_verify(base_commit_1, "submodule/a.mp3", "submodule version 1") | ||
2473 | # Verify that the LFS objects referenced from the base repository are not fetched nor | ||
2474 | # checked out | ||
2475 | fetch_and_verify(base_commit_2, "a.mp3", "version 1") | ||
2476 | |||
2477 | @skipIfNoGitLFS() | ||
2478 | def test_fetch_lfs_on_srcrev_change(self): | ||
2479 | """Test if fetch downloads missing LFS objects when a different revision within an existing repository is requested""" | ||
2480 | self.git(["lfs", "install", "--local"], cwd=self.srcdir) | ||
2481 | |||
2482 | def fetch_and_verify(revision, filename, content): | ||
2483 | self.d.setVar('SRCREV', revision) | ||
2484 | fetcher, ud = self.fetch() | ||
2485 | |||
2486 | with hide_directory(self.srcdir): | ||
2487 | workdir = self.d.getVar('WORKDIR') | ||
2488 | fetcher.unpack(workdir) | ||
2489 | |||
2490 | with open(os.path.join(workdir, "git", filename)) as f: | ||
2491 | self.assertEqual(f.read(), content) | ||
2492 | |||
2493 | commit_1 = self.commit_file("a.mp3", "version 1") | ||
2494 | commit_2 = self.commit_file("a.mp3", "version 2") | ||
2495 | |||
2496 | self.d.setVar('SRC_URI', "git://%s;protocol=file;lfs=1;branch=master" % self.srcdir) | ||
2497 | |||
2498 | # Seed the local download folder by fetching the latest commit and verifying that the LFS contents are | ||
2499 | # available even when the upstream repository disappears. | ||
2500 | fetch_and_verify(commit_2, "a.mp3", "version 2") | ||
2501 | # Verify that even when an older revision is fetched, the needed LFS objects are fetched into the download | ||
2502 | # folder. | ||
2503 | fetch_and_verify(commit_1, "a.mp3", "version 1") | ||
2504 | |||
2505 | @skipIfNoGitLFS() | ||
2506 | @skipIfNoNetwork() | ||
2507 | def test_real_git_lfs_repo_succeeds_without_lfs_param(self): | ||
2508 | self.d.setVar('SRC_URI', "git://gitlab.com/gitlab-examples/lfs.git;protocol=https;branch=master") | ||
2509 | f = self.get_real_git_lfs_file() | ||
2510 | self.assertTrue(os.path.exists(f)) | ||
2511 | self.assertEqual("c0baab607a97839c9a328b4310713307", bb.utils.md5_file(f)) | ||
2512 | |||
2513 | @skipIfNoGitLFS() | ||
2514 | @skipIfNoNetwork() | ||
2515 | def test_real_git_lfs_repo_succeeds(self): | ||
2516 | self.d.setVar('SRC_URI', "git://gitlab.com/gitlab-examples/lfs.git;protocol=https;branch=master;lfs=1") | ||
2517 | f = self.get_real_git_lfs_file() | ||
2518 | self.assertTrue(os.path.exists(f)) | ||
2519 | self.assertEqual("c0baab607a97839c9a328b4310713307", bb.utils.md5_file(f)) | ||
2520 | |||
2521 | @skipIfNoGitLFS() | ||
2522 | @skipIfNoNetwork() | ||
2523 | def test_real_git_lfs_repo_skips(self): | ||
2524 | self.d.setVar('SRC_URI', "git://gitlab.com/gitlab-examples/lfs.git;protocol=https;branch=master;lfs=0") | ||
2525 | f = self.get_real_git_lfs_file() | ||
2526 | # This is the actual non-smudged placeholder file on the repo if git-lfs does not run | ||
2527 | lfs_file = ( | ||
2528 | 'version https://git-lfs.github.com/spec/v1\n' | ||
2529 | 'oid sha256:34be66b1a39a1955b46a12588df9d5f6fc1da790e05cf01f3c7422f4bbbdc26b\n' | ||
2530 | 'size 11423554\n' | ||
2531 | ) | ||
2532 | |||
2533 | with open(f) as fh: | ||
2534 | self.assertEqual(lfs_file, fh.read()) | ||
2535 | |||
2536 | @skipIfNoGitLFS() | ||
2122 | def test_lfs_enabled(self): | 2537 | def test_lfs_enabled(self): |
2123 | import shutil | 2538 | uri = 'git://%s;protocol=file;lfs=1;branch=master' % self.srcdir |
2539 | self.d.setVar('SRC_URI', uri) | ||
2540 | |||
2541 | # With git-lfs installed, test that we can fetch and unpack | ||
2542 | fetcher, ud = self.fetch() | ||
2543 | shutil.rmtree(self.gitdir, ignore_errors=True) | ||
2544 | fetcher.unpack(self.d.getVar('WORKDIR')) | ||
2124 | 2545 | ||
2125 | uri = 'git://%s;protocol=file;subdir=${S};lfs=1' % self.srcdir | 2546 | @skipIfNoGitLFS() |
2547 | def test_lfs_disabled(self): | ||
2548 | uri = 'git://%s;protocol=file;lfs=0;branch=master' % self.srcdir | ||
2126 | self.d.setVar('SRC_URI', uri) | 2549 | self.d.setVar('SRC_URI', uri) |
2127 | 2550 | ||
2128 | # Careful: suppress initial attempt at downloading until | 2551 | # Verify that the fetcher can survive even if the source |
2129 | # we know whether git-lfs is installed. | 2552 | # repository has Git LFS usage configured. |
2130 | fetcher, ud = self.fetch(uri=None, download=False) | 2553 | fetcher, ud = self.fetch() |
2131 | self.assertIsNotNone(ud.method._find_git_lfs) | 2554 | fetcher.unpack(self.d.getVar('WORKDIR')) |
2132 | 2555 | ||
2133 | # If git-lfs can be found, the unpack should be successful. Only | 2556 | @skipIfNoGitLFS() |
2134 | # attempt this with the real live copy of git-lfs installed. | 2557 | def test_lfs_enabled_not_installed_during_unpack(self): |
2135 | if ud.method._find_git_lfs(self.d): | 2558 | uri = 'git://%s;protocol=file;lfs=1;branch=master' % self.srcdir |
2136 | fetcher.download() | 2559 | self.d.setVar('SRC_URI', uri) |
2137 | shutil.rmtree(self.gitdir, ignore_errors=True) | ||
2138 | fetcher.unpack(self.d.getVar('WORKDIR')) | ||
2139 | 2560 | ||
2561 | # Careful: suppress initial attempt at downloading | ||
2562 | fetcher, ud = self.fetch(uri=None, download=False) | ||
2563 | |||
2564 | fetcher.download() | ||
2140 | # If git-lfs cannot be found, the unpack should throw an error | 2565 | # If git-lfs cannot be found, the unpack should throw an error |
2141 | with self.assertRaises(bb.fetch2.FetchError): | 2566 | with self.assertRaises(bb.fetch2.FetchError): |
2567 | with unittest.mock.patch("shutil.which", return_value=None): | ||
2568 | shutil.rmtree(self.gitdir, ignore_errors=True) | ||
2569 | fetcher.unpack(self.d.getVar('WORKDIR')) | ||
2570 | |||
2571 | def test_lfs_enabled_not_installed(self): | ||
2572 | uri = 'git://%s;protocol=file;lfs=1;branch=master' % self.srcdir | ||
2573 | self.d.setVar('SRC_URI', uri) | ||
2574 | |||
2575 | # Careful: suppress initial attempt at downloading | ||
2576 | fetcher, ud = self.fetch(uri=None, download=False) | ||
2577 | |||
2578 | # If git-lfs cannot be found, the download should throw an error | ||
2579 | with unittest.mock.patch("shutil.which", return_value=None): | ||
2580 | with self.assertRaises(bb.fetch2.FetchError): | ||
2581 | fetcher.download() | ||
2582 | |||
2583 | def test_lfs_disabled_not_installed(self): | ||
2584 | uri = 'git://%s;protocol=file;lfs=0;branch=master' % self.srcdir | ||
2585 | self.d.setVar('SRC_URI', uri) | ||
2586 | |||
2587 | # Careful: suppress initial attempt at downloading | ||
2588 | fetcher, ud = self.fetch(uri=None, download=False) | ||
2589 | |||
2590 | # Even if git-lfs cannot be found, the download / unpack should be successful | ||
2591 | with unittest.mock.patch("shutil.which", return_value=None): | ||
2142 | fetcher.download() | 2592 | fetcher.download() |
2143 | ud.method._find_git_lfs = lambda d: False | ||
2144 | shutil.rmtree(self.gitdir, ignore_errors=True) | 2593 | shutil.rmtree(self.gitdir, ignore_errors=True) |
2145 | fetcher.unpack(self.d.getVar('WORKDIR')) | 2594 | fetcher.unpack(self.d.getVar('WORKDIR')) |
2146 | 2595 | ||
2147 | def test_lfs_disabled(self): | 2596 | def test_lfs_enabled_not_installed_but_not_needed(self): |
2148 | import shutil | 2597 | srcdir = os.path.join(self.tempdir, "emptygit") |
2598 | bb.utils.mkdirhier(srcdir) | ||
2599 | self.git_init(srcdir) | ||
2600 | self.commit_file("test", "test content", cwd=srcdir) | ||
2149 | 2601 | ||
2150 | uri = 'git://%s;protocol=file;subdir=${S};lfs=0' % self.srcdir | 2602 | uri = 'git://%s;protocol=file;lfs=1;branch=master' % srcdir |
2151 | self.d.setVar('SRC_URI', uri) | 2603 | self.d.setVar('SRC_URI', uri) |
2152 | 2604 | ||
2153 | # In contrast to test_lfs_enabled(), allow the implicit download | 2605 | # Careful: suppress initial attempt at downloading |
2154 | # done by self.fetch() to occur here. The point of this test case | 2606 | fetcher, ud = self.fetch(uri=None, download=False) |
2155 | # is to verify that the fetcher can survive even if the source | ||
2156 | # repository has Git LFS usage configured. | ||
2157 | fetcher, ud = self.fetch() | ||
2158 | self.assertIsNotNone(ud.method._find_git_lfs) | ||
2159 | |||
2160 | # If git-lfs can be found, the unpack should be successful. A | ||
2161 | # live copy of git-lfs is not required for this case, so | ||
2162 | # unconditionally forge its presence. | ||
2163 | ud.method._find_git_lfs = lambda d: True | ||
2164 | shutil.rmtree(self.gitdir, ignore_errors=True) | ||
2165 | fetcher.unpack(self.d.getVar('WORKDIR')) | ||
2166 | 2607 | ||
2167 | # If git-lfs cannot be found, the unpack should be successful | 2608 | # It shouldnt't matter that git-lfs cannot be found as the repository configuration does not |
2168 | ud.method._find_git_lfs = lambda d: False | 2609 | # specify any LFS filters. |
2169 | shutil.rmtree(self.gitdir, ignore_errors=True) | 2610 | with unittest.mock.patch("shutil.which", return_value=None): |
2170 | fetcher.unpack(self.d.getVar('WORKDIR')) | 2611 | fetcher.download() |
2612 | shutil.rmtree(self.gitdir, ignore_errors=True) | ||
2613 | fetcher.unpack(self.d.getVar('WORKDIR')) | ||
2171 | 2614 | ||
2172 | class GitURLWithSpacesTest(FetcherTest): | 2615 | class GitURLWithSpacesTest(FetcherTest): |
2173 | test_git_urls = { | 2616 | test_git_urls = { |
2174 | "git://tfs-example.org:22/tfs/example%20path/example.git" : { | 2617 | "git://tfs-example.org:22/tfs/example%20path/example.git;branch=master" : { |
2175 | 'url': 'git://tfs-example.org:22/tfs/example%20path/example.git', | 2618 | 'url': 'git://tfs-example.org:22/tfs/example%20path/example.git;branch=master', |
2619 | 'repo_url': 'git://tfs-example.org:22/tfs/example%20path/example.git', | ||
2176 | 'gitsrcname': 'tfs-example.org.22.tfs.example_path.example.git', | 2620 | 'gitsrcname': 'tfs-example.org.22.tfs.example_path.example.git', |
2177 | 'path': '/tfs/example path/example.git' | 2621 | 'path': '/tfs/example path/example.git' |
2178 | }, | 2622 | }, |
2179 | "git://tfs-example.org:22/tfs/example%20path/example%20repo.git" : { | 2623 | "git://tfs-example.org:22/tfs/example%20path/example%20repo.git;branch=master" : { |
2180 | 'url': 'git://tfs-example.org:22/tfs/example%20path/example%20repo.git', | 2624 | 'url': 'git://tfs-example.org:22/tfs/example%20path/example%20repo.git;branch=master', |
2625 | 'repo_url': 'git://tfs-example.org:22/tfs/example%20path/example%20repo.git', | ||
2181 | 'gitsrcname': 'tfs-example.org.22.tfs.example_path.example_repo.git', | 2626 | 'gitsrcname': 'tfs-example.org.22.tfs.example_path.example_repo.git', |
2182 | 'path': '/tfs/example path/example repo.git' | 2627 | 'path': '/tfs/example path/example repo.git' |
2183 | } | 2628 | } |
@@ -2200,19 +2645,137 @@ class GitURLWithSpacesTest(FetcherTest): | |||
2200 | self.assertEqual(ud.lockfile, os.path.join(self.dldir, "git2", ref['gitsrcname'] + '.lock')) | 2645 | self.assertEqual(ud.lockfile, os.path.join(self.dldir, "git2", ref['gitsrcname'] + '.lock')) |
2201 | self.assertEqual(ud.clonedir, os.path.join(self.dldir, "git2", ref['gitsrcname'])) | 2646 | self.assertEqual(ud.clonedir, os.path.join(self.dldir, "git2", ref['gitsrcname'])) |
2202 | self.assertEqual(ud.fullmirror, os.path.join(self.dldir, "git2_" + ref['gitsrcname'] + '.tar.gz')) | 2647 | self.assertEqual(ud.fullmirror, os.path.join(self.dldir, "git2_" + ref['gitsrcname'] + '.tar.gz')) |
2648 | self.assertEqual(ud.method._get_repo_url(ud), ref['repo_url']) | ||
2649 | |||
2650 | class CrateTest(FetcherTest): | ||
2651 | @skipIfNoNetwork() | ||
2652 | def test_crate_url(self): | ||
2653 | |||
2654 | uri = "crate://crates.io/glob/0.2.11" | ||
2655 | self.d.setVar('SRC_URI', uri) | ||
2656 | |||
2657 | uris = self.d.getVar('SRC_URI').split() | ||
2658 | d = self.d | ||
2659 | |||
2660 | fetcher = bb.fetch2.Fetch(uris, self.d) | ||
2661 | ud = fetcher.ud[fetcher.urls[0]] | ||
2662 | |||
2663 | self.assertIn("name", ud.parm) | ||
2664 | self.assertEqual(ud.parm["name"], "glob-0.2.11") | ||
2665 | self.assertIn("downloadfilename", ud.parm) | ||
2666 | self.assertEqual(ud.parm["downloadfilename"], "glob-0.2.11.crate") | ||
2667 | |||
2668 | fetcher.download() | ||
2669 | fetcher.unpack(self.tempdir) | ||
2670 | self.assertEqual(sorted(os.listdir(self.tempdir)), ['cargo_home', 'download' , 'unpacked']) | ||
2671 | self.assertEqual(sorted(os.listdir(self.tempdir + "/download")), ['glob-0.2.11.crate', 'glob-0.2.11.crate.done']) | ||
2672 | self.assertTrue(os.path.exists(self.tempdir + "/cargo_home/bitbake/glob-0.2.11/.cargo-checksum.json")) | ||
2673 | self.assertTrue(os.path.exists(self.tempdir + "/cargo_home/bitbake/glob-0.2.11/src/lib.rs")) | ||
2674 | |||
2675 | @skipIfNoNetwork() | ||
2676 | def test_crate_url_matching_recipe(self): | ||
2677 | |||
2678 | self.d.setVar('BP', 'glob-0.2.11') | ||
2679 | |||
2680 | uri = "crate://crates.io/glob/0.2.11" | ||
2681 | self.d.setVar('SRC_URI', uri) | ||
2682 | |||
2683 | uris = self.d.getVar('SRC_URI').split() | ||
2684 | d = self.d | ||
2685 | |||
2686 | fetcher = bb.fetch2.Fetch(uris, self.d) | ||
2687 | ud = fetcher.ud[fetcher.urls[0]] | ||
2688 | |||
2689 | self.assertIn("name", ud.parm) | ||
2690 | self.assertEqual(ud.parm["name"], "glob-0.2.11") | ||
2691 | self.assertIn("downloadfilename", ud.parm) | ||
2692 | self.assertEqual(ud.parm["downloadfilename"], "glob-0.2.11.crate") | ||
2693 | |||
2694 | fetcher.download() | ||
2695 | fetcher.unpack(self.tempdir) | ||
2696 | self.assertEqual(sorted(os.listdir(self.tempdir)), ['download', 'glob-0.2.11', 'unpacked']) | ||
2697 | self.assertEqual(sorted(os.listdir(self.tempdir + "/download")), ['glob-0.2.11.crate', 'glob-0.2.11.crate.done']) | ||
2698 | self.assertTrue(os.path.exists(self.tempdir + "/glob-0.2.11/src/lib.rs")) | ||
2699 | |||
2700 | @skipIfNoNetwork() | ||
2701 | def test_crate_url_params(self): | ||
2702 | |||
2703 | uri = "crate://crates.io/aho-corasick/0.7.20;name=aho-corasick-renamed" | ||
2704 | self.d.setVar('SRC_URI', uri) | ||
2705 | |||
2706 | uris = self.d.getVar('SRC_URI').split() | ||
2707 | d = self.d | ||
2708 | |||
2709 | fetcher = bb.fetch2.Fetch(uris, self.d) | ||
2710 | ud = fetcher.ud[fetcher.urls[0]] | ||
2711 | |||
2712 | self.assertIn("name", ud.parm) | ||
2713 | self.assertEqual(ud.parm["name"], "aho-corasick-renamed") | ||
2714 | self.assertIn("downloadfilename", ud.parm) | ||
2715 | self.assertEqual(ud.parm["downloadfilename"], "aho-corasick-0.7.20.crate") | ||
2716 | |||
2717 | fetcher.download() | ||
2718 | fetcher.unpack(self.tempdir) | ||
2719 | self.assertEqual(sorted(os.listdir(self.tempdir)), ['cargo_home', 'download' , 'unpacked']) | ||
2720 | self.assertEqual(sorted(os.listdir(self.tempdir + "/download")), ['aho-corasick-0.7.20.crate', 'aho-corasick-0.7.20.crate.done']) | ||
2721 | self.assertTrue(os.path.exists(self.tempdir + "/cargo_home/bitbake/aho-corasick-0.7.20/.cargo-checksum.json")) | ||
2722 | self.assertTrue(os.path.exists(self.tempdir + "/cargo_home/bitbake/aho-corasick-0.7.20/src/lib.rs")) | ||
2723 | |||
2724 | @skipIfNoNetwork() | ||
2725 | def test_crate_url_multi(self): | ||
2726 | |||
2727 | uri = "crate://crates.io/glob/0.2.11 crate://crates.io/time/0.1.35" | ||
2728 | self.d.setVar('SRC_URI', uri) | ||
2729 | |||
2730 | uris = self.d.getVar('SRC_URI').split() | ||
2731 | d = self.d | ||
2732 | |||
2733 | fetcher = bb.fetch2.Fetch(uris, self.d) | ||
2734 | ud = fetcher.ud[fetcher.urls[0]] | ||
2735 | |||
2736 | self.assertIn("name", ud.parm) | ||
2737 | self.assertEqual(ud.parm["name"], "glob-0.2.11") | ||
2738 | self.assertIn("downloadfilename", ud.parm) | ||
2739 | self.assertEqual(ud.parm["downloadfilename"], "glob-0.2.11.crate") | ||
2740 | |||
2741 | ud = fetcher.ud[fetcher.urls[1]] | ||
2742 | self.assertIn("name", ud.parm) | ||
2743 | self.assertEqual(ud.parm["name"], "time-0.1.35") | ||
2744 | self.assertIn("downloadfilename", ud.parm) | ||
2745 | self.assertEqual(ud.parm["downloadfilename"], "time-0.1.35.crate") | ||
2746 | |||
2747 | fetcher.download() | ||
2748 | fetcher.unpack(self.tempdir) | ||
2749 | self.assertEqual(sorted(os.listdir(self.tempdir)), ['cargo_home', 'download' , 'unpacked']) | ||
2750 | self.assertEqual(sorted(os.listdir(self.tempdir + "/download")), ['glob-0.2.11.crate', 'glob-0.2.11.crate.done', 'time-0.1.35.crate', 'time-0.1.35.crate.done']) | ||
2751 | self.assertTrue(os.path.exists(self.tempdir + "/cargo_home/bitbake/glob-0.2.11/.cargo-checksum.json")) | ||
2752 | self.assertTrue(os.path.exists(self.tempdir + "/cargo_home/bitbake/glob-0.2.11/src/lib.rs")) | ||
2753 | self.assertTrue(os.path.exists(self.tempdir + "/cargo_home/bitbake/time-0.1.35/.cargo-checksum.json")) | ||
2754 | self.assertTrue(os.path.exists(self.tempdir + "/cargo_home/bitbake/time-0.1.35/src/lib.rs")) | ||
2755 | |||
2756 | @skipIfNoNetwork() | ||
2757 | def test_crate_incorrect_cksum(self): | ||
2758 | uri = "crate://crates.io/aho-corasick/0.7.20" | ||
2759 | self.d.setVar('SRC_URI', uri) | ||
2760 | self.d.setVarFlag("SRC_URI", "aho-corasick-0.7.20.sha256sum", hashlib.sha256("Invalid".encode("utf-8")).hexdigest()) | ||
2761 | |||
2762 | uris = self.d.getVar('SRC_URI').split() | ||
2763 | |||
2764 | fetcher = bb.fetch2.Fetch(uris, self.d) | ||
2765 | with self.assertRaisesRegex(bb.fetch2.FetchError, "Fetcher failure for URL"): | ||
2766 | fetcher.download() | ||
2203 | 2767 | ||
2204 | class NPMTest(FetcherTest): | 2768 | class NPMTest(FetcherTest): |
2205 | def skipIfNoNpm(): | 2769 | def skipIfNoNpm(): |
2206 | import shutil | ||
2207 | if not shutil.which('npm'): | 2770 | if not shutil.which('npm'): |
2208 | return unittest.skip('npm not installed, tests being skipped') | 2771 | return unittest.skip('npm not installed') |
2209 | return lambda f: f | 2772 | return lambda f: f |
2210 | 2773 | ||
2211 | @skipIfNoNpm() | 2774 | @skipIfNoNpm() |
2212 | @skipIfNoNetwork() | 2775 | @skipIfNoNetwork() |
2213 | def test_npm(self): | 2776 | def test_npm(self): |
2214 | url = 'npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=1.0.0' | 2777 | urls = ['npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=1.0.0'] |
2215 | fetcher = bb.fetch.Fetch([url], self.d) | 2778 | fetcher = bb.fetch.Fetch(urls, self.d) |
2216 | ud = fetcher.ud[fetcher.urls[0]] | 2779 | ud = fetcher.ud[fetcher.urls[0]] |
2217 | fetcher.download() | 2780 | fetcher.download() |
2218 | self.assertTrue(os.path.exists(ud.localpath)) | 2781 | self.assertTrue(os.path.exists(ud.localpath)) |
@@ -2225,9 +2788,9 @@ class NPMTest(FetcherTest): | |||
2225 | @skipIfNoNpm() | 2788 | @skipIfNoNpm() |
2226 | @skipIfNoNetwork() | 2789 | @skipIfNoNetwork() |
2227 | def test_npm_bad_checksum(self): | 2790 | def test_npm_bad_checksum(self): |
2228 | url = 'npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=1.0.0' | 2791 | urls = ['npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=1.0.0'] |
2229 | # Fetch once to get a tarball | 2792 | # Fetch once to get a tarball |
2230 | fetcher = bb.fetch.Fetch([url], self.d) | 2793 | fetcher = bb.fetch.Fetch(urls, self.d) |
2231 | ud = fetcher.ud[fetcher.urls[0]] | 2794 | ud = fetcher.ud[fetcher.urls[0]] |
2232 | fetcher.download() | 2795 | fetcher.download() |
2233 | self.assertTrue(os.path.exists(ud.localpath)) | 2796 | self.assertTrue(os.path.exists(ud.localpath)) |
@@ -2244,17 +2807,48 @@ class NPMTest(FetcherTest): | |||
2244 | @skipIfNoNpm() | 2807 | @skipIfNoNpm() |
2245 | @skipIfNoNetwork() | 2808 | @skipIfNoNetwork() |
2246 | def test_npm_premirrors(self): | 2809 | def test_npm_premirrors(self): |
2247 | url = 'npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=1.0.0' | 2810 | urls = ['npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=1.0.0'] |
2248 | # Fetch once to get a tarball | 2811 | # Fetch once to get a tarball |
2249 | fetcher = bb.fetch.Fetch([url], self.d) | 2812 | fetcher = bb.fetch.Fetch(urls, self.d) |
2813 | ud = fetcher.ud[fetcher.urls[0]] | ||
2814 | fetcher.download() | ||
2815 | self.assertTrue(os.path.exists(ud.localpath)) | ||
2816 | |||
2817 | # Setup the mirror by renaming the download directory | ||
2818 | mirrordir = os.path.join(self.tempdir, 'mirror') | ||
2819 | bb.utils.rename(self.dldir, mirrordir) | ||
2820 | os.mkdir(self.dldir) | ||
2821 | |||
2822 | # Configure the premirror to be used | ||
2823 | self.d.setVar('PREMIRRORS', 'https?$://.*/.* file://%s/npm2' % mirrordir) | ||
2824 | self.d.setVar('BB_FETCH_PREMIRRORONLY', '1') | ||
2825 | |||
2826 | # Fetch again | ||
2827 | self.assertFalse(os.path.exists(ud.localpath)) | ||
2828 | # The npm fetcher doesn't handle that the .resolved file disappears | ||
2829 | # while the fetcher object exists, which it does when we rename the | ||
2830 | # download directory to "mirror" above. Thus we need a new fetcher to go | ||
2831 | # with the now empty download directory. | ||
2832 | fetcher = bb.fetch.Fetch(urls, self.d) | ||
2833 | ud = fetcher.ud[fetcher.urls[0]] | ||
2834 | fetcher.download() | ||
2835 | self.assertTrue(os.path.exists(ud.localpath)) | ||
2836 | |||
2837 | @skipIfNoNpm() | ||
2838 | @skipIfNoNetwork() | ||
2839 | def test_npm_premirrors_with_specified_filename(self): | ||
2840 | urls = ['npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=1.0.0'] | ||
2841 | # Fetch once to get a tarball | ||
2842 | fetcher = bb.fetch.Fetch(urls, self.d) | ||
2250 | ud = fetcher.ud[fetcher.urls[0]] | 2843 | ud = fetcher.ud[fetcher.urls[0]] |
2251 | fetcher.download() | 2844 | fetcher.download() |
2252 | self.assertTrue(os.path.exists(ud.localpath)) | 2845 | self.assertTrue(os.path.exists(ud.localpath)) |
2253 | # Setup the mirror | 2846 | # Setup the mirror |
2254 | mirrordir = os.path.join(self.tempdir, 'mirror') | 2847 | mirrordir = os.path.join(self.tempdir, 'mirror') |
2255 | bb.utils.mkdirhier(mirrordir) | 2848 | bb.utils.mkdirhier(mirrordir) |
2256 | os.replace(ud.localpath, os.path.join(mirrordir, os.path.basename(ud.localpath))) | 2849 | mirrorfilename = os.path.join(mirrordir, os.path.basename(ud.localpath)) |
2257 | self.d.setVar('PREMIRRORS', 'https?$://.*/.* file://%s/\n' % mirrordir) | 2850 | os.replace(ud.localpath, mirrorfilename) |
2851 | self.d.setVar('PREMIRRORS', 'https?$://.*/.* file://%s' % mirrorfilename) | ||
2258 | self.d.setVar('BB_FETCH_PREMIRRORONLY', '1') | 2852 | self.d.setVar('BB_FETCH_PREMIRRORONLY', '1') |
2259 | # Fetch again | 2853 | # Fetch again |
2260 | self.assertFalse(os.path.exists(ud.localpath)) | 2854 | self.assertFalse(os.path.exists(ud.localpath)) |
@@ -2265,8 +2859,8 @@ class NPMTest(FetcherTest): | |||
2265 | @skipIfNoNetwork() | 2859 | @skipIfNoNetwork() |
2266 | def test_npm_mirrors(self): | 2860 | def test_npm_mirrors(self): |
2267 | # Fetch once to get a tarball | 2861 | # Fetch once to get a tarball |
2268 | url = 'npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=1.0.0' | 2862 | urls = ['npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=1.0.0'] |
2269 | fetcher = bb.fetch.Fetch([url], self.d) | 2863 | fetcher = bb.fetch.Fetch(urls, self.d) |
2270 | ud = fetcher.ud[fetcher.urls[0]] | 2864 | ud = fetcher.ud[fetcher.urls[0]] |
2271 | fetcher.download() | 2865 | fetcher.download() |
2272 | self.assertTrue(os.path.exists(ud.localpath)) | 2866 | self.assertTrue(os.path.exists(ud.localpath)) |
@@ -2274,7 +2868,7 @@ class NPMTest(FetcherTest): | |||
2274 | mirrordir = os.path.join(self.tempdir, 'mirror') | 2868 | mirrordir = os.path.join(self.tempdir, 'mirror') |
2275 | bb.utils.mkdirhier(mirrordir) | 2869 | bb.utils.mkdirhier(mirrordir) |
2276 | os.replace(ud.localpath, os.path.join(mirrordir, os.path.basename(ud.localpath))) | 2870 | os.replace(ud.localpath, os.path.join(mirrordir, os.path.basename(ud.localpath))) |
2277 | self.d.setVar('MIRRORS', 'https?$://.*/.* file://%s/\n' % mirrordir) | 2871 | self.d.setVar('MIRRORS', 'https?$://.*/.* file://%s/' % mirrordir) |
2278 | # Update the resolved url to an invalid url | 2872 | # Update the resolved url to an invalid url |
2279 | with open(ud.resolvefile, 'r') as f: | 2873 | with open(ud.resolvefile, 'r') as f: |
2280 | url = f.read() | 2874 | url = f.read() |
@@ -2290,27 +2884,27 @@ class NPMTest(FetcherTest): | |||
2290 | @skipIfNoNpm() | 2884 | @skipIfNoNpm() |
2291 | @skipIfNoNetwork() | 2885 | @skipIfNoNetwork() |
2292 | def test_npm_destsuffix_downloadfilename(self): | 2886 | def test_npm_destsuffix_downloadfilename(self): |
2293 | url = 'npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=1.0.0;destsuffix=foo/bar;downloadfilename=foo-bar.tgz' | 2887 | urls = ['npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=1.0.0;destsuffix=foo/bar;downloadfilename=foo-bar.tgz'] |
2294 | fetcher = bb.fetch.Fetch([url], self.d) | 2888 | fetcher = bb.fetch.Fetch(urls, self.d) |
2295 | fetcher.download() | 2889 | fetcher.download() |
2296 | self.assertTrue(os.path.exists(os.path.join(self.dldir, 'foo-bar.tgz'))) | 2890 | self.assertTrue(os.path.exists(os.path.join(self.dldir, 'npm2', 'foo-bar.tgz'))) |
2297 | fetcher.unpack(self.unpackdir) | 2891 | fetcher.unpack(self.unpackdir) |
2298 | unpackdir = os.path.join(self.unpackdir, 'foo', 'bar') | 2892 | unpackdir = os.path.join(self.unpackdir, 'foo', 'bar') |
2299 | self.assertTrue(os.path.exists(os.path.join(unpackdir, 'package.json'))) | 2893 | self.assertTrue(os.path.exists(os.path.join(unpackdir, 'package.json'))) |
2300 | 2894 | ||
2301 | def test_npm_no_network_no_tarball(self): | 2895 | def test_npm_no_network_no_tarball(self): |
2302 | url = 'npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=1.0.0' | 2896 | urls = ['npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=1.0.0'] |
2303 | self.d.setVar('BB_NO_NETWORK', '1') | 2897 | self.d.setVar('BB_NO_NETWORK', '1') |
2304 | fetcher = bb.fetch.Fetch([url], self.d) | 2898 | fetcher = bb.fetch.Fetch(urls, self.d) |
2305 | with self.assertRaises(bb.fetch2.NetworkAccess): | 2899 | with self.assertRaises(bb.fetch2.NetworkAccess): |
2306 | fetcher.download() | 2900 | fetcher.download() |
2307 | 2901 | ||
2308 | @skipIfNoNpm() | 2902 | @skipIfNoNpm() |
2309 | @skipIfNoNetwork() | 2903 | @skipIfNoNetwork() |
2310 | def test_npm_no_network_with_tarball(self): | 2904 | def test_npm_no_network_with_tarball(self): |
2311 | url = 'npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=1.0.0' | 2905 | urls = ['npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=1.0.0'] |
2312 | # Fetch once to get a tarball | 2906 | # Fetch once to get a tarball |
2313 | fetcher = bb.fetch.Fetch([url], self.d) | 2907 | fetcher = bb.fetch.Fetch(urls, self.d) |
2314 | fetcher.download() | 2908 | fetcher.download() |
2315 | # Disable network access | 2909 | # Disable network access |
2316 | self.d.setVar('BB_NO_NETWORK', '1') | 2910 | self.d.setVar('BB_NO_NETWORK', '1') |
@@ -2323,8 +2917,8 @@ class NPMTest(FetcherTest): | |||
2323 | @skipIfNoNpm() | 2917 | @skipIfNoNpm() |
2324 | @skipIfNoNetwork() | 2918 | @skipIfNoNetwork() |
2325 | def test_npm_registry_alternate(self): | 2919 | def test_npm_registry_alternate(self): |
2326 | url = 'npm://registry.freajs.org;package=@savoirfairelinux/node-server-example;version=1.0.0' | 2920 | urls = ['npm://skimdb.npmjs.com;package=@savoirfairelinux/node-server-example;version=1.0.0'] |
2327 | fetcher = bb.fetch.Fetch([url], self.d) | 2921 | fetcher = bb.fetch.Fetch(urls, self.d) |
2328 | fetcher.download() | 2922 | fetcher.download() |
2329 | fetcher.unpack(self.unpackdir) | 2923 | fetcher.unpack(self.unpackdir) |
2330 | unpackdir = os.path.join(self.unpackdir, 'npm') | 2924 | unpackdir = os.path.join(self.unpackdir, 'npm') |
@@ -2333,8 +2927,8 @@ class NPMTest(FetcherTest): | |||
2333 | @skipIfNoNpm() | 2927 | @skipIfNoNpm() |
2334 | @skipIfNoNetwork() | 2928 | @skipIfNoNetwork() |
2335 | def test_npm_version_latest(self): | 2929 | def test_npm_version_latest(self): |
2336 | url = 'npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=latest' | 2930 | url = ['npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=latest'] |
2337 | fetcher = bb.fetch.Fetch([url], self.d) | 2931 | fetcher = bb.fetch.Fetch(url, self.d) |
2338 | fetcher.download() | 2932 | fetcher.download() |
2339 | fetcher.unpack(self.unpackdir) | 2933 | fetcher.unpack(self.unpackdir) |
2340 | unpackdir = os.path.join(self.unpackdir, 'npm') | 2934 | unpackdir = os.path.join(self.unpackdir, 'npm') |
@@ -2343,46 +2937,46 @@ class NPMTest(FetcherTest): | |||
2343 | @skipIfNoNpm() | 2937 | @skipIfNoNpm() |
2344 | @skipIfNoNetwork() | 2938 | @skipIfNoNetwork() |
2345 | def test_npm_registry_invalid(self): | 2939 | def test_npm_registry_invalid(self): |
2346 | url = 'npm://registry.invalid.org;package=@savoirfairelinux/node-server-example;version=1.0.0' | 2940 | urls = ['npm://registry.invalid.org;package=@savoirfairelinux/node-server-example;version=1.0.0'] |
2347 | fetcher = bb.fetch.Fetch([url], self.d) | 2941 | fetcher = bb.fetch.Fetch(urls, self.d) |
2348 | with self.assertRaises(bb.fetch2.FetchError): | 2942 | with self.assertRaises(bb.fetch2.FetchError): |
2349 | fetcher.download() | 2943 | fetcher.download() |
2350 | 2944 | ||
2351 | @skipIfNoNpm() | 2945 | @skipIfNoNpm() |
2352 | @skipIfNoNetwork() | 2946 | @skipIfNoNetwork() |
2353 | def test_npm_package_invalid(self): | 2947 | def test_npm_package_invalid(self): |
2354 | url = 'npm://registry.npmjs.org;package=@savoirfairelinux/invalid;version=1.0.0' | 2948 | urls = ['npm://registry.npmjs.org;package=@savoirfairelinux/invalid;version=1.0.0'] |
2355 | fetcher = bb.fetch.Fetch([url], self.d) | 2949 | fetcher = bb.fetch.Fetch(urls, self.d) |
2356 | with self.assertRaises(bb.fetch2.FetchError): | 2950 | with self.assertRaises(bb.fetch2.FetchError): |
2357 | fetcher.download() | 2951 | fetcher.download() |
2358 | 2952 | ||
2359 | @skipIfNoNpm() | 2953 | @skipIfNoNpm() |
2360 | @skipIfNoNetwork() | 2954 | @skipIfNoNetwork() |
2361 | def test_npm_version_invalid(self): | 2955 | def test_npm_version_invalid(self): |
2362 | url = 'npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=invalid' | 2956 | urls = ['npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=invalid'] |
2363 | with self.assertRaises(bb.fetch2.ParameterError): | 2957 | with self.assertRaises(bb.fetch2.ParameterError): |
2364 | fetcher = bb.fetch.Fetch([url], self.d) | 2958 | fetcher = bb.fetch.Fetch(urls, self.d) |
2365 | 2959 | ||
2366 | @skipIfNoNpm() | 2960 | @skipIfNoNpm() |
2367 | @skipIfNoNetwork() | 2961 | @skipIfNoNetwork() |
2368 | def test_npm_registry_none(self): | 2962 | def test_npm_registry_none(self): |
2369 | url = 'npm://;package=@savoirfairelinux/node-server-example;version=1.0.0' | 2963 | urls = ['npm://;package=@savoirfairelinux/node-server-example;version=1.0.0'] |
2370 | with self.assertRaises(bb.fetch2.MalformedUrl): | 2964 | with self.assertRaises(bb.fetch2.MalformedUrl): |
2371 | fetcher = bb.fetch.Fetch([url], self.d) | 2965 | fetcher = bb.fetch.Fetch(urls, self.d) |
2372 | 2966 | ||
2373 | @skipIfNoNpm() | 2967 | @skipIfNoNpm() |
2374 | @skipIfNoNetwork() | 2968 | @skipIfNoNetwork() |
2375 | def test_npm_package_none(self): | 2969 | def test_npm_package_none(self): |
2376 | url = 'npm://registry.npmjs.org;version=1.0.0' | 2970 | urls = ['npm://registry.npmjs.org;version=1.0.0'] |
2377 | with self.assertRaises(bb.fetch2.MissingParameterError): | 2971 | with self.assertRaises(bb.fetch2.MissingParameterError): |
2378 | fetcher = bb.fetch.Fetch([url], self.d) | 2972 | fetcher = bb.fetch.Fetch(urls, self.d) |
2379 | 2973 | ||
2380 | @skipIfNoNpm() | 2974 | @skipIfNoNpm() |
2381 | @skipIfNoNetwork() | 2975 | @skipIfNoNetwork() |
2382 | def test_npm_version_none(self): | 2976 | def test_npm_version_none(self): |
2383 | url = 'npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example' | 2977 | urls = ['npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example'] |
2384 | with self.assertRaises(bb.fetch2.MissingParameterError): | 2978 | with self.assertRaises(bb.fetch2.MissingParameterError): |
2385 | fetcher = bb.fetch.Fetch([url], self.d) | 2979 | fetcher = bb.fetch.Fetch(urls, self.d) |
2386 | 2980 | ||
2387 | def create_shrinkwrap_file(self, data): | 2981 | def create_shrinkwrap_file(self, data): |
2388 | import json | 2982 | import json |
@@ -2391,32 +2985,30 @@ class NPMTest(FetcherTest): | |||
2391 | bb.utils.mkdirhier(datadir) | 2985 | bb.utils.mkdirhier(datadir) |
2392 | with open(swfile, 'w') as f: | 2986 | with open(swfile, 'w') as f: |
2393 | json.dump(data, f) | 2987 | json.dump(data, f) |
2394 | # Also configure the S directory | ||
2395 | self.sdir = os.path.join(self.unpackdir, 'S') | ||
2396 | self.d.setVar('S', self.sdir) | ||
2397 | return swfile | 2988 | return swfile |
2398 | 2989 | ||
2399 | @skipIfNoNpm() | ||
2400 | @skipIfNoNetwork() | 2990 | @skipIfNoNetwork() |
2401 | def test_npmsw(self): | 2991 | def test_npmsw(self): |
2402 | swfile = self.create_shrinkwrap_file({ | 2992 | swfile = self.create_shrinkwrap_file({ |
2403 | 'dependencies': { | 2993 | 'packages': { |
2404 | 'array-flatten': { | 2994 | 'node_modules/array-flatten': { |
2405 | 'version': '1.1.1', | 2995 | 'version': '1.1.1', |
2406 | 'resolved': 'https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz', | 2996 | 'resolved': 'https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz', |
2407 | 'integrity': 'sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=', | 2997 | 'integrity': 'sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=', |
2408 | 'dependencies': { | 2998 | 'dependencies': { |
2409 | 'content-type': { | 2999 | 'content-type': "1.0.4" |
2410 | 'version': 'https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz', | ||
2411 | 'integrity': 'sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==', | ||
2412 | 'dependencies': { | ||
2413 | 'cookie': { | ||
2414 | 'version': 'git+https://github.com/jshttp/cookie.git#aec1177c7da67e3b3273df96cf476824dbc9ae09', | ||
2415 | 'from': 'git+https://github.com/jshttp/cookie.git' | ||
2416 | } | ||
2417 | } | ||
2418 | } | ||
2419 | } | 3000 | } |
3001 | }, | ||
3002 | 'node_modules/array-flatten/node_modules/content-type': { | ||
3003 | 'version': '1.0.4', | ||
3004 | 'resolved': 'https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz', | ||
3005 | 'integrity': 'sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==', | ||
3006 | 'dependencies': { | ||
3007 | 'cookie': 'git+https://github.com/jshttp/cookie.git#aec1177c7da67e3b3273df96cf476824dbc9ae09' | ||
3008 | } | ||
3009 | }, | ||
3010 | 'node_modules/array-flatten/node_modules/content-type/node_modules/cookie': { | ||
3011 | 'resolved': 'git+https://github.com/jshttp/cookie.git#aec1177c7da67e3b3273df96cf476824dbc9ae09' | ||
2420 | } | 3012 | } |
2421 | } | 3013 | } |
2422 | }) | 3014 | }) |
@@ -2426,22 +3018,34 @@ class NPMTest(FetcherTest): | |||
2426 | self.assertTrue(os.path.exists(os.path.join(self.dldir, 'npm2', 'content-type-1.0.4.tgz'))) | 3018 | self.assertTrue(os.path.exists(os.path.join(self.dldir, 'npm2', 'content-type-1.0.4.tgz'))) |
2427 | self.assertTrue(os.path.exists(os.path.join(self.dldir, 'git2', 'github.com.jshttp.cookie.git'))) | 3019 | self.assertTrue(os.path.exists(os.path.join(self.dldir, 'git2', 'github.com.jshttp.cookie.git'))) |
2428 | fetcher.unpack(self.unpackdir) | 3020 | fetcher.unpack(self.unpackdir) |
2429 | self.assertTrue(os.path.exists(os.path.join(self.sdir, 'npm-shrinkwrap.json'))) | 3021 | self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'npm-shrinkwrap.json'))) |
2430 | self.assertTrue(os.path.exists(os.path.join(self.sdir, 'node_modules', 'array-flatten', 'package.json'))) | 3022 | self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'node_modules', 'array-flatten', 'package.json'))) |
2431 | self.assertTrue(os.path.exists(os.path.join(self.sdir, 'node_modules', 'array-flatten', 'node_modules', 'content-type', 'package.json'))) | 3023 | self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'node_modules', 'array-flatten', 'node_modules', 'content-type', 'package.json'))) |
2432 | self.assertTrue(os.path.exists(os.path.join(self.sdir, 'node_modules', 'array-flatten', 'node_modules', 'content-type', 'node_modules', 'cookie', 'package.json'))) | 3024 | self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'node_modules', 'array-flatten', 'node_modules', 'content-type', 'node_modules', 'cookie', 'package.json'))) |
3025 | |||
3026 | @skipIfNoNetwork() | ||
3027 | def test_npmsw_git(self): | ||
3028 | swfile = self.create_shrinkwrap_file({ | ||
3029 | 'packages': { | ||
3030 | 'node_modules/cookie': { | ||
3031 | 'resolved': 'git+https://github.com/jshttp/cookie.git#aec1177c7da67e3b3273df96cf476824dbc9ae09' | ||
3032 | } | ||
3033 | } | ||
3034 | }) | ||
3035 | fetcher = bb.fetch.Fetch(['npmsw://' + swfile], self.d) | ||
3036 | fetcher.download() | ||
3037 | self.assertTrue(os.path.exists(os.path.join(self.dldir, 'git2', 'github.com.jshttp.cookie.git'))) | ||
2433 | 3038 | ||
2434 | @skipIfNoNpm() | ||
2435 | @skipIfNoNetwork() | 3039 | @skipIfNoNetwork() |
2436 | def test_npmsw_dev(self): | 3040 | def test_npmsw_dev(self): |
2437 | swfile = self.create_shrinkwrap_file({ | 3041 | swfile = self.create_shrinkwrap_file({ |
2438 | 'dependencies': { | 3042 | 'packages': { |
2439 | 'array-flatten': { | 3043 | 'node_modules/array-flatten': { |
2440 | 'version': '1.1.1', | 3044 | 'version': '1.1.1', |
2441 | 'resolved': 'https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz', | 3045 | 'resolved': 'https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz', |
2442 | 'integrity': 'sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=' | 3046 | 'integrity': 'sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=' |
2443 | }, | 3047 | }, |
2444 | 'content-type': { | 3048 | 'node_modules/content-type': { |
2445 | 'version': '1.0.4', | 3049 | 'version': '1.0.4', |
2446 | 'resolved': 'https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz', | 3050 | 'resolved': 'https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz', |
2447 | 'integrity': 'sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==', | 3051 | 'integrity': 'sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==', |
@@ -2460,12 +3064,11 @@ class NPMTest(FetcherTest): | |||
2460 | self.assertTrue(os.path.exists(os.path.join(self.dldir, 'npm2', 'array-flatten-1.1.1.tgz'))) | 3064 | self.assertTrue(os.path.exists(os.path.join(self.dldir, 'npm2', 'array-flatten-1.1.1.tgz'))) |
2461 | self.assertTrue(os.path.exists(os.path.join(self.dldir, 'npm2', 'content-type-1.0.4.tgz'))) | 3065 | self.assertTrue(os.path.exists(os.path.join(self.dldir, 'npm2', 'content-type-1.0.4.tgz'))) |
2462 | 3066 | ||
2463 | @skipIfNoNpm() | ||
2464 | @skipIfNoNetwork() | 3067 | @skipIfNoNetwork() |
2465 | def test_npmsw_destsuffix(self): | 3068 | def test_npmsw_destsuffix(self): |
2466 | swfile = self.create_shrinkwrap_file({ | 3069 | swfile = self.create_shrinkwrap_file({ |
2467 | 'dependencies': { | 3070 | 'packages': { |
2468 | 'array-flatten': { | 3071 | 'node_modules/array-flatten': { |
2469 | 'version': '1.1.1', | 3072 | 'version': '1.1.1', |
2470 | 'resolved': 'https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz', | 3073 | 'resolved': 'https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz', |
2471 | 'integrity': 'sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=' | 3074 | 'integrity': 'sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=' |
@@ -2479,8 +3082,8 @@ class NPMTest(FetcherTest): | |||
2479 | 3082 | ||
2480 | def test_npmsw_no_network_no_tarball(self): | 3083 | def test_npmsw_no_network_no_tarball(self): |
2481 | swfile = self.create_shrinkwrap_file({ | 3084 | swfile = self.create_shrinkwrap_file({ |
2482 | 'dependencies': { | 3085 | 'packages': { |
2483 | 'array-flatten': { | 3086 | 'node_modules/array-flatten': { |
2484 | 'version': '1.1.1', | 3087 | 'version': '1.1.1', |
2485 | 'resolved': 'https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz', | 3088 | 'resolved': 'https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz', |
2486 | 'integrity': 'sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=' | 3089 | 'integrity': 'sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=' |
@@ -2502,8 +3105,8 @@ class NPMTest(FetcherTest): | |||
2502 | self.d.setVar('BB_NO_NETWORK', '1') | 3105 | self.d.setVar('BB_NO_NETWORK', '1') |
2503 | # Fetch again | 3106 | # Fetch again |
2504 | swfile = self.create_shrinkwrap_file({ | 3107 | swfile = self.create_shrinkwrap_file({ |
2505 | 'dependencies': { | 3108 | 'packages': { |
2506 | 'array-flatten': { | 3109 | 'node_modules/array-flatten': { |
2507 | 'version': '1.1.1', | 3110 | 'version': '1.1.1', |
2508 | 'resolved': 'https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz', | 3111 | 'resolved': 'https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz', |
2509 | 'integrity': 'sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=' | 3112 | 'integrity': 'sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=' |
@@ -2513,15 +3116,14 @@ class NPMTest(FetcherTest): | |||
2513 | fetcher = bb.fetch.Fetch(['npmsw://' + swfile], self.d) | 3116 | fetcher = bb.fetch.Fetch(['npmsw://' + swfile], self.d) |
2514 | fetcher.download() | 3117 | fetcher.download() |
2515 | fetcher.unpack(self.unpackdir) | 3118 | fetcher.unpack(self.unpackdir) |
2516 | self.assertTrue(os.path.exists(os.path.join(self.sdir, 'node_modules', 'array-flatten', 'package.json'))) | 3119 | self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'node_modules', 'array-flatten', 'package.json'))) |
2517 | 3120 | ||
2518 | @skipIfNoNpm() | ||
2519 | @skipIfNoNetwork() | 3121 | @skipIfNoNetwork() |
2520 | def test_npmsw_npm_reusability(self): | 3122 | def test_npmsw_npm_reusability(self): |
2521 | # Fetch once with npmsw | 3123 | # Fetch once with npmsw |
2522 | swfile = self.create_shrinkwrap_file({ | 3124 | swfile = self.create_shrinkwrap_file({ |
2523 | 'dependencies': { | 3125 | 'packages': { |
2524 | 'array-flatten': { | 3126 | 'node_modules/array-flatten': { |
2525 | 'version': '1.1.1', | 3127 | 'version': '1.1.1', |
2526 | 'resolved': 'https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz', | 3128 | 'resolved': 'https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz', |
2527 | 'integrity': 'sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=' | 3129 | 'integrity': 'sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=' |
@@ -2538,13 +3140,12 @@ class NPMTest(FetcherTest): | |||
2538 | fetcher.unpack(self.unpackdir) | 3140 | fetcher.unpack(self.unpackdir) |
2539 | self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'npm', 'package.json'))) | 3141 | self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'npm', 'package.json'))) |
2540 | 3142 | ||
2541 | @skipIfNoNpm() | ||
2542 | @skipIfNoNetwork() | 3143 | @skipIfNoNetwork() |
2543 | def test_npmsw_bad_checksum(self): | 3144 | def test_npmsw_bad_checksum(self): |
2544 | # Try to fetch with bad checksum | 3145 | # Try to fetch with bad checksum |
2545 | swfile = self.create_shrinkwrap_file({ | 3146 | swfile = self.create_shrinkwrap_file({ |
2546 | 'dependencies': { | 3147 | 'packages': { |
2547 | 'array-flatten': { | 3148 | 'node_modules/array-flatten': { |
2548 | 'version': '1.1.1', | 3149 | 'version': '1.1.1', |
2549 | 'resolved': 'https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz', | 3150 | 'resolved': 'https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz', |
2550 | 'integrity': 'sha1-gfNEp2hqgLTFKT6P3AsBYMgsBqg=' | 3151 | 'integrity': 'sha1-gfNEp2hqgLTFKT6P3AsBYMgsBqg=' |
@@ -2556,8 +3157,8 @@ class NPMTest(FetcherTest): | |||
2556 | fetcher.download() | 3157 | fetcher.download() |
2557 | # Fetch correctly to get a tarball | 3158 | # Fetch correctly to get a tarball |
2558 | swfile = self.create_shrinkwrap_file({ | 3159 | swfile = self.create_shrinkwrap_file({ |
2559 | 'dependencies': { | 3160 | 'packages': { |
2560 | 'array-flatten': { | 3161 | 'node_modules/array-flatten': { |
2561 | 'version': '1.1.1', | 3162 | 'version': '1.1.1', |
2562 | 'resolved': 'https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz', | 3163 | 'resolved': 'https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz', |
2563 | 'integrity': 'sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=' | 3164 | 'integrity': 'sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=' |
@@ -2590,13 +3191,13 @@ class NPMTest(FetcherTest): | |||
2590 | mirrordir = os.path.join(self.tempdir, 'mirror') | 3191 | mirrordir = os.path.join(self.tempdir, 'mirror') |
2591 | bb.utils.mkdirhier(mirrordir) | 3192 | bb.utils.mkdirhier(mirrordir) |
2592 | os.replace(ud.localpath, os.path.join(mirrordir, os.path.basename(ud.localpath))) | 3193 | os.replace(ud.localpath, os.path.join(mirrordir, os.path.basename(ud.localpath))) |
2593 | self.d.setVar('PREMIRRORS', 'https?$://.*/.* file://%s/\n' % mirrordir) | 3194 | self.d.setVar('PREMIRRORS', 'https?$://.*/.* file://%s/' % mirrordir) |
2594 | self.d.setVar('BB_FETCH_PREMIRRORONLY', '1') | 3195 | self.d.setVar('BB_FETCH_PREMIRRORONLY', '1') |
2595 | # Fetch again | 3196 | # Fetch again |
2596 | self.assertFalse(os.path.exists(ud.localpath)) | 3197 | self.assertFalse(os.path.exists(ud.localpath)) |
2597 | swfile = self.create_shrinkwrap_file({ | 3198 | swfile = self.create_shrinkwrap_file({ |
2598 | 'dependencies': { | 3199 | 'packages': { |
2599 | 'array-flatten': { | 3200 | 'node_modules/array-flatten': { |
2600 | 'version': '1.1.1', | 3201 | 'version': '1.1.1', |
2601 | 'resolved': 'https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz', | 3202 | 'resolved': 'https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz', |
2602 | 'integrity': 'sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=' | 3203 | 'integrity': 'sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=' |
@@ -2619,12 +3220,12 @@ class NPMTest(FetcherTest): | |||
2619 | mirrordir = os.path.join(self.tempdir, 'mirror') | 3220 | mirrordir = os.path.join(self.tempdir, 'mirror') |
2620 | bb.utils.mkdirhier(mirrordir) | 3221 | bb.utils.mkdirhier(mirrordir) |
2621 | os.replace(ud.localpath, os.path.join(mirrordir, os.path.basename(ud.localpath))) | 3222 | os.replace(ud.localpath, os.path.join(mirrordir, os.path.basename(ud.localpath))) |
2622 | self.d.setVar('MIRRORS', 'https?$://.*/.* file://%s/\n' % mirrordir) | 3223 | self.d.setVar('MIRRORS', 'https?$://.*/.* file://%s/' % mirrordir) |
2623 | # Fetch again with invalid url | 3224 | # Fetch again with invalid url |
2624 | self.assertFalse(os.path.exists(ud.localpath)) | 3225 | self.assertFalse(os.path.exists(ud.localpath)) |
2625 | swfile = self.create_shrinkwrap_file({ | 3226 | swfile = self.create_shrinkwrap_file({ |
2626 | 'dependencies': { | 3227 | 'packages': { |
2627 | 'array-flatten': { | 3228 | 'node_modules/array-flatten': { |
2628 | 'version': '1.1.1', | 3229 | 'version': '1.1.1', |
2629 | 'resolved': 'https://invalid', | 3230 | 'resolved': 'https://invalid', |
2630 | 'integrity': 'sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=' | 3231 | 'integrity': 'sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=' |
@@ -2634,3 +3235,521 @@ class NPMTest(FetcherTest): | |||
2634 | fetcher = bb.fetch.Fetch(['npmsw://' + swfile], self.d) | 3235 | fetcher = bb.fetch.Fetch(['npmsw://' + swfile], self.d) |
2635 | fetcher.download() | 3236 | fetcher.download() |
2636 | self.assertTrue(os.path.exists(ud.localpath)) | 3237 | self.assertTrue(os.path.exists(ud.localpath)) |
3238 | |||
3239 | @skipIfNoNetwork() | ||
3240 | def test_npmsw_bundled(self): | ||
3241 | swfile = self.create_shrinkwrap_file({ | ||
3242 | 'packages': { | ||
3243 | 'node_modules/array-flatten': { | ||
3244 | 'version': '1.1.1', | ||
3245 | 'resolved': 'https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz', | ||
3246 | 'integrity': 'sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=' | ||
3247 | }, | ||
3248 | 'node_modules/content-type': { | ||
3249 | 'version': '1.0.4', | ||
3250 | 'resolved': 'https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz', | ||
3251 | 'integrity': 'sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==', | ||
3252 | 'inBundle': True | ||
3253 | } | ||
3254 | } | ||
3255 | }) | ||
3256 | fetcher = bb.fetch.Fetch(['npmsw://' + swfile], self.d) | ||
3257 | fetcher.download() | ||
3258 | self.assertTrue(os.path.exists(os.path.join(self.dldir, 'npm2', 'array-flatten-1.1.1.tgz'))) | ||
3259 | self.assertFalse(os.path.exists(os.path.join(self.dldir, 'npm2', 'content-type-1.0.4.tgz'))) | ||
3260 | |||
3261 | class GitSharedTest(FetcherTest): | ||
3262 | def setUp(self): | ||
3263 | super(GitSharedTest, self).setUp() | ||
3264 | self.recipe_url = "git://git.openembedded.org/bitbake;branch=master;protocol=https" | ||
3265 | self.d.setVar('SRCREV', '82ea737a0b42a8b53e11c9cde141e9e9c0bd8c40') | ||
3266 | self.d.setVar("__BBSRCREV_SEEN", "1") | ||
3267 | |||
3268 | @skipIfNoNetwork() | ||
3269 | def test_shared_unpack(self): | ||
3270 | fetcher = bb.fetch.Fetch([self.recipe_url], self.d) | ||
3271 | |||
3272 | fetcher.download() | ||
3273 | fetcher.unpack(self.unpackdir) | ||
3274 | alt = os.path.join(self.unpackdir, 'git/.git/objects/info/alternates') | ||
3275 | self.assertTrue(os.path.exists(alt)) | ||
3276 | |||
3277 | @skipIfNoNetwork() | ||
3278 | def test_noshared_unpack(self): | ||
3279 | self.d.setVar('BB_GIT_NOSHARED', '1') | ||
3280 | self.unpackdir += '_noshared' | ||
3281 | fetcher = bb.fetch.Fetch([self.recipe_url], self.d) | ||
3282 | |||
3283 | fetcher.download() | ||
3284 | fetcher.unpack(self.unpackdir) | ||
3285 | alt = os.path.join(self.unpackdir, 'git/.git/objects/info/alternates') | ||
3286 | self.assertFalse(os.path.exists(alt)) | ||
3287 | |||
3288 | class GitTagVerificationTests(FetcherTest): | ||
3289 | |||
3290 | @skipIfNoNetwork() | ||
3291 | def test_tag_rev_match(self): | ||
3292 | # Test a url with rev= and tag= set works | ||
3293 | fetcher = bb.fetch.Fetch(["git://git.openembedded.org/bitbake;branch=2.8;protocol=https;rev=aa0e540fc31a1c26839efd2c7785a751ce24ebfb;tag=2.8.7"], self.d) | ||
3294 | fetcher.download() | ||
3295 | fetcher.unpack(self.unpackdir) | ||
3296 | |||
3297 | def test_annotated_tag_rev_match(self): | ||
3298 | # Test a url with rev= and tag= set works | ||
3299 | # rev is the annotated tag revision in this case | ||
3300 | fetcher = bb.fetch.Fetch(["git://git.openembedded.org/bitbake;branch=2.8;protocol=https;rev=6d363159e4b7dc566fc40d069b2615e61774a7d8;tag=2.8.7"], self.d) | ||
3301 | fetcher.download() | ||
3302 | fetcher.unpack(self.unpackdir) | ||
3303 | |||
3304 | @skipIfNoNetwork() | ||
3305 | def test_tag_rev_match2(self): | ||
3306 | # Test a url with SRCREV and tag= set works | ||
3307 | self.d.setVar('SRCREV', 'aa0e540fc31a1c26839efd2c7785a751ce24ebfb') | ||
3308 | fetcher = bb.fetch.Fetch(["git://git.openembedded.org/bitbake;branch=2.8;protocol=https;tag=2.8.7"], self.d) | ||
3309 | fetcher.download() | ||
3310 | fetcher.unpack(self.unpackdir) | ||
3311 | |||
3312 | @skipIfNoNetwork() | ||
3313 | def test_tag_rev_match3(self): | ||
3314 | # Test a url with SRCREV, rev= and tag= set works | ||
3315 | self.d.setVar('SRCREV', 'aa0e540fc31a1c26839efd2c7785a751ce24ebfb') | ||
3316 | fetcher = bb.fetch.Fetch(["git://git.openembedded.org/bitbake;branch=2.8;protocol=https;rev=aa0e540fc31a1c26839efd2c7785a751ce24ebfb;tag=2.8.7"], self.d) | ||
3317 | fetcher.download() | ||
3318 | fetcher.unpack(self.unpackdir) | ||
3319 | |||
3320 | @skipIfNoNetwork() | ||
3321 | def test_tag_rev_match4(self): | ||
3322 | # Test a url with SRCREV and rev= mismatching errors | ||
3323 | self.d.setVar('SRCREV', 'bade540fc31a1c26839efd2c7785a751ce24ebfb') | ||
3324 | with self.assertRaises(bb.fetch2.FetchError): | ||
3325 | fetcher = bb.fetch.Fetch(["git://git.openembedded.org/bitbake;branch=2.8;protocol=https;rev=aa0e540fc31a1c26839efd2c7785a751ce24ebfb;tag=2.8.7"], self.d) | ||
3326 | |||
3327 | @skipIfNoNetwork() | ||
3328 | def test_tag_rev_match5(self): | ||
3329 | # Test a url with SRCREV, rev= and tag= set works when using shallow clones | ||
3330 | self.d.setVar('BB_GIT_SHALLOW', '1') | ||
3331 | self.d.setVar('SRCREV', 'aa0e540fc31a1c26839efd2c7785a751ce24ebfb') | ||
3332 | fetcher = bb.fetch.Fetch(["git://git.openembedded.org/bitbake;branch=2.8;protocol=https;rev=aa0e540fc31a1c26839efd2c7785a751ce24ebfb;tag=2.8.7"], self.d) | ||
3333 | fetcher.download() | ||
3334 | fetcher.unpack(self.unpackdir) | ||
3335 | |||
3336 | @skipIfNoNetwork() | ||
3337 | def test_tag_rev_match6(self): | ||
3338 | # Test a url with SRCREV, rev= and a mismatched tag= when using shallow clones | ||
3339 | self.d.setVar('BB_GIT_SHALLOW', '1') | ||
3340 | fetcher = bb.fetch.Fetch(["git://git.openembedded.org/bitbake;branch=2.8;protocol=https;rev=aa0e540fc31a1c26839efd2c7785a751ce24ebfb;tag=2.8.6"], self.d) | ||
3341 | fetcher.download() | ||
3342 | with self.assertRaises(bb.fetch2.FetchError): | ||
3343 | fetcher.unpack(self.unpackdir) | ||
3344 | |||
3345 | @skipIfNoNetwork() | ||
3346 | def test_tag_rev_match7(self): | ||
3347 | # Test a url with SRCREV, rev= and a mismatched tag= | ||
3348 | self.d.setVar('SRCREV', 'aa0e540fc31a1c26839efd2c7785a751ce24ebfb') | ||
3349 | fetcher = bb.fetch.Fetch(["git://git.openembedded.org/bitbake;branch=2.8;protocol=https;rev=aa0e540fc31a1c26839efd2c7785a751ce24ebfb;tag=2.8.6"], self.d) | ||
3350 | fetcher.download() | ||
3351 | with self.assertRaises(bb.fetch2.FetchError): | ||
3352 | fetcher.unpack(self.unpackdir) | ||
3353 | |||
3354 | |||
3355 | class FetchPremirroronlyLocalTest(FetcherTest): | ||
3356 | |||
3357 | def setUp(self): | ||
3358 | super(FetchPremirroronlyLocalTest, self).setUp() | ||
3359 | self.mirrordir = os.path.join(self.tempdir, "mirrors") | ||
3360 | os.mkdir(self.mirrordir) | ||
3361 | self.reponame = "bitbake" | ||
3362 | self.gitdir = os.path.join(self.tempdir, "git", self.reponame) | ||
3363 | self.recipe_url = "git://git.fake.repo/bitbake;branch=master;protocol=https" | ||
3364 | self.d.setVar("BB_FETCH_PREMIRRORONLY", "1") | ||
3365 | self.d.setVar("BB_NO_NETWORK", "1") | ||
3366 | self.d.setVar("PREMIRRORS", self.recipe_url + " " + "file://{}".format(self.mirrordir) + " \n") | ||
3367 | self.mirrorname = "git2_git.fake.repo.bitbake.tar.gz" | ||
3368 | self.mirrorfile = os.path.join(self.mirrordir, self.mirrorname) | ||
3369 | self.testfilename = "bitbake-fetch.test" | ||
3370 | |||
3371 | def make_git_repo(self): | ||
3372 | recipeurl = "git:/git.fake.repo/bitbake" | ||
3373 | os.makedirs(self.gitdir) | ||
3374 | self.git_init(cwd=self.gitdir) | ||
3375 | for i in range(0): | ||
3376 | self.git_new_commit() | ||
3377 | bb.process.run('tar -czvf {} .'.format(os.path.join(self.mirrordir, self.mirrorname)), cwd = self.gitdir) | ||
3378 | |||
3379 | def git_new_commit(self): | ||
3380 | import random | ||
3381 | os.unlink(os.path.join(self.mirrordir, self.mirrorname)) | ||
3382 | branch = self.git("branch --show-current", self.gitdir).split() | ||
3383 | with open(os.path.join(self.gitdir, self.testfilename), "w") as testfile: | ||
3384 | testfile.write("File {} from branch {}; Useless random data {}".format(self.testfilename, branch, random.random())) | ||
3385 | self.git("add {}".format(self.testfilename), self.gitdir) | ||
3386 | self.git("commit -a -m \"This random commit {} in branch {}. I'm useless.\"".format(random.random(), branch), self.gitdir) | ||
3387 | bb.process.run('tar -czvf {} .'.format(os.path.join(self.mirrordir, self.mirrorname)), cwd = self.gitdir) | ||
3388 | return self.git("rev-parse HEAD", self.gitdir).strip() | ||
3389 | |||
3390 | def git_new_branch(self, name): | ||
3391 | self.git_new_commit() | ||
3392 | head = self.git("rev-parse HEAD", self.gitdir).strip() | ||
3393 | self.git("checkout -b {}".format(name), self.gitdir) | ||
3394 | newrev = self.git_new_commit() | ||
3395 | self.git("checkout {}".format(head), self.gitdir) | ||
3396 | return newrev | ||
3397 | |||
3398 | def test_mirror_multiple_fetches(self): | ||
3399 | self.make_git_repo() | ||
3400 | self.d.setVar("SRCREV", self.git_new_commit()) | ||
3401 | fetcher = bb.fetch.Fetch([self.recipe_url], self.d) | ||
3402 | fetcher.download() | ||
3403 | fetcher.unpack(self.unpackdir) | ||
3404 | ## New commit in premirror. it's not in the download_dir | ||
3405 | self.d.setVar("SRCREV", self.git_new_commit()) | ||
3406 | fetcher2 = bb.fetch.Fetch([self.recipe_url], self.d) | ||
3407 | fetcher2.download() | ||
3408 | fetcher2.unpack(self.unpackdir) | ||
3409 | ## New commit in premirror. it's not in the download_dir | ||
3410 | self.d.setVar("SRCREV", self.git_new_commit()) | ||
3411 | fetcher3 = bb.fetch.Fetch([self.recipe_url], self.d) | ||
3412 | fetcher3.download() | ||
3413 | fetcher3.unpack(self.unpackdir) | ||
3414 | |||
3415 | |||
3416 | def test_mirror_commit_nonexistent(self): | ||
3417 | self.make_git_repo() | ||
3418 | self.d.setVar("SRCREV", "0"*40) | ||
3419 | fetcher = bb.fetch.Fetch([self.recipe_url], self.d) | ||
3420 | with self.assertRaises(bb.fetch2.NetworkAccess): | ||
3421 | fetcher.download() | ||
3422 | |||
3423 | def test_mirror_commit_exists(self): | ||
3424 | self.make_git_repo() | ||
3425 | self.d.setVar("SRCREV", self.git_new_commit()) | ||
3426 | fetcher = bb.fetch.Fetch([self.recipe_url], self.d) | ||
3427 | fetcher.download() | ||
3428 | fetcher.unpack(self.unpackdir) | ||
3429 | |||
3430 | def test_mirror_tarball_nonexistent(self): | ||
3431 | self.d.setVar("SRCREV", "0"*40) | ||
3432 | fetcher = bb.fetch.Fetch([self.recipe_url], self.d) | ||
3433 | with self.assertRaises(bb.fetch2.NetworkAccess): | ||
3434 | fetcher.download() | ||
3435 | |||
3436 | |||
3437 | class FetchPremirroronlyNetworkTest(FetcherTest): | ||
3438 | |||
3439 | def setUp(self): | ||
3440 | super(FetchPremirroronlyNetworkTest, self).setUp() | ||
3441 | self.mirrordir = os.path.join(self.tempdir, "mirrors") | ||
3442 | os.mkdir(self.mirrordir) | ||
3443 | self.reponame = "fstests" | ||
3444 | self.clonedir = os.path.join(self.tempdir, "git") | ||
3445 | self.gitdir = os.path.join(self.tempdir, "git", "{}.git".format(self.reponame)) | ||
3446 | self.recipe_url = "git://git.yoctoproject.org/fstests;protocol=https;branch=master" | ||
3447 | self.d.setVar("BB_FETCH_PREMIRRORONLY", "1") | ||
3448 | self.d.setVar("BB_NO_NETWORK", "0") | ||
3449 | self.d.setVar("PREMIRRORS", self.recipe_url + " " + "file://{}".format(self.mirrordir) + " \n") | ||
3450 | |||
3451 | def make_git_repo(self): | ||
3452 | self.mirrorname = "git2_git.yoctoproject.org.fstests.tar.gz" | ||
3453 | os.makedirs(self.clonedir) | ||
3454 | self.git("clone --bare {}".format(self.recipe_url), self.clonedir) | ||
3455 | self.git("update-ref HEAD 15413486df1f5a5b5af699b6f3ba5f0984e52a9f", self.gitdir) | ||
3456 | bb.process.run('tar -czvf {} .'.format(os.path.join(self.mirrordir, self.mirrorname)), cwd = self.gitdir) | ||
3457 | shutil.rmtree(self.clonedir) | ||
3458 | |||
3459 | @skipIfNoNetwork() | ||
3460 | def test_mirror_tarball_updated(self): | ||
3461 | self.make_git_repo() | ||
3462 | ## Upstream commit is in the mirror | ||
3463 | self.d.setVar("SRCREV", "15413486df1f5a5b5af699b6f3ba5f0984e52a9f") | ||
3464 | fetcher = bb.fetch.Fetch([self.recipe_url], self.d) | ||
3465 | fetcher.download() | ||
3466 | |||
3467 | @skipIfNoNetwork() | ||
3468 | def test_mirror_tarball_outdated(self): | ||
3469 | self.make_git_repo() | ||
3470 | ## Upstream commit not in the mirror | ||
3471 | self.d.setVar("SRCREV", "49d65d53c2bf558ae6e9185af0f3af7b79d255ec") | ||
3472 | fetcher = bb.fetch.Fetch([self.recipe_url], self.d) | ||
3473 | with self.assertRaises(bb.fetch2.NetworkAccess): | ||
3474 | fetcher.download() | ||
3475 | |||
3476 | class FetchPremirroronlyMercurialTest(FetcherTest): | ||
3477 | """ Test for premirrors with mercurial repos | ||
3478 | the test covers also basic hg:// clone (see fetch_and_create_tarball | ||
3479 | """ | ||
3480 | def skipIfNoHg(): | ||
3481 | if not shutil.which('hg'): | ||
3482 | return unittest.skip('Mercurial not installed') | ||
3483 | return lambda f: f | ||
3484 | |||
3485 | def setUp(self): | ||
3486 | super(FetchPremirroronlyMercurialTest, self).setUp() | ||
3487 | self.mirrordir = os.path.join(self.tempdir, "mirrors") | ||
3488 | os.mkdir(self.mirrordir) | ||
3489 | self.reponame = "libgnt" | ||
3490 | self.clonedir = os.path.join(self.tempdir, "hg") | ||
3491 | self.recipe_url = "hg://keep.imfreedom.org/libgnt;module=libgnt" | ||
3492 | self.d.setVar("SRCREV", "53e8b422faaf") | ||
3493 | self.mirrorname = "hg_libgnt_keep.imfreedom.org_.libgnt.tar.gz" | ||
3494 | |||
3495 | def fetch_and_create_tarball(self): | ||
3496 | """ | ||
3497 | Ask bitbake to download repo and prepare mirror tarball for us | ||
3498 | """ | ||
3499 | self.d.setVar("BB_GENERATE_MIRROR_TARBALLS", "1") | ||
3500 | fetcher = bb.fetch.Fetch([self.recipe_url], self.d) | ||
3501 | fetcher.download() | ||
3502 | mirrorfile = os.path.join(self.d.getVar("DL_DIR"), self.mirrorname) | ||
3503 | self.assertTrue(os.path.exists(mirrorfile), "Mirror tarball {} has not been created".format(mirrorfile)) | ||
3504 | ## moving tarball to mirror directory | ||
3505 | os.rename(mirrorfile, os.path.join(self.mirrordir, self.mirrorname)) | ||
3506 | self.d.setVar("BB_GENERATE_MIRROR_TARBALLS", "0") | ||
3507 | |||
3508 | |||
3509 | @skipIfNoNetwork() | ||
3510 | @skipIfNoHg() | ||
3511 | def test_premirror_mercurial(self): | ||
3512 | self.fetch_and_create_tarball() | ||
3513 | self.d.setVar("PREMIRRORS", self.recipe_url + " " + "file://{}".format(self.mirrordir) + " \n") | ||
3514 | self.d.setVar("BB_FETCH_PREMIRRORONLY", "1") | ||
3515 | self.d.setVar("BB_NO_NETWORK", "1") | ||
3516 | fetcher = bb.fetch.Fetch([self.recipe_url], self.d) | ||
3517 | fetcher.download() | ||
3518 | |||
3519 | class FetchPremirroronlyBrokenTarball(FetcherTest): | ||
3520 | |||
3521 | def setUp(self): | ||
3522 | super(FetchPremirroronlyBrokenTarball, self).setUp() | ||
3523 | self.mirrordir = os.path.join(self.tempdir, "mirrors") | ||
3524 | os.mkdir(self.mirrordir) | ||
3525 | self.reponame = "bitbake" | ||
3526 | self.gitdir = os.path.join(self.tempdir, "git", self.reponame) | ||
3527 | self.recipe_url = "git://git.fake.repo/bitbake;protocol=https;branch=master" | ||
3528 | self.d.setVar("BB_FETCH_PREMIRRORONLY", "1") | ||
3529 | self.d.setVar("BB_NO_NETWORK", "1") | ||
3530 | self.d.setVar("PREMIRRORS", self.recipe_url + " " + "file://{}".format(self.mirrordir) + " \n") | ||
3531 | self.mirrorname = "git2_git.fake.repo.bitbake.tar.gz" | ||
3532 | with open(os.path.join(self.mirrordir, self.mirrorname), 'w') as targz: | ||
3533 | targz.write("This is not tar.gz file!") | ||
3534 | |||
3535 | def test_mirror_broken_download(self): | ||
3536 | self.d.setVar("SRCREV", "0"*40) | ||
3537 | fetcher = bb.fetch.Fetch([self.recipe_url], self.d) | ||
3538 | with self.assertRaises(bb.fetch2.FetchError), self.assertLogs() as logs: | ||
3539 | fetcher.download() | ||
3540 | output = "".join(logs.output) | ||
3541 | self.assertFalse(" not a git repository (or any parent up to mount point /)" in output) | ||
3542 | |||
3543 | class GoModTest(FetcherTest): | ||
3544 | |||
3545 | @skipIfNoNetwork() | ||
3546 | def test_gomod_url(self): | ||
3547 | urls = ['gomod://github.com/Azure/azure-sdk-for-go/sdk/storage/azblob;version=v1.0.0;' | ||
3548 | 'sha256sum=9bb69aea32f1d59711701f9562d66432c9c0374205e5009d1d1a62f03fb4fdad'] | ||
3549 | |||
3550 | fetcher = bb.fetch2.Fetch(urls, self.d) | ||
3551 | ud = fetcher.ud[urls[0]] | ||
3552 | self.assertEqual(ud.url, 'https://proxy.golang.org/github.com/%21azure/azure-sdk-for-go/sdk/storage/azblob/%40v/v1.0.0.zip') | ||
3553 | self.assertEqual(ud.parm['downloadfilename'], 'github.com.Azure.azure-sdk-for-go.sdk.storage.azblob@v1.0.0.zip') | ||
3554 | self.assertEqual(ud.parm['name'], 'github.com/Azure/azure-sdk-for-go/sdk/storage/azblob@v1.0.0') | ||
3555 | |||
3556 | fetcher.download() | ||
3557 | fetcher.unpack(self.unpackdir) | ||
3558 | downloaddir = os.path.join(self.unpackdir, 'pkg/mod/cache/download') | ||
3559 | self.assertTrue(os.path.exists(os.path.join(downloaddir, 'github.com/!azure/azure-sdk-for-go/sdk/storage/azblob/@v/v1.0.0.zip'))) | ||
3560 | self.assertTrue(os.path.exists(os.path.join(downloaddir, 'github.com/!azure/azure-sdk-for-go/sdk/storage/azblob/@v/v1.0.0.mod'))) | ||
3561 | self.assertEqual(bb.utils.sha256_file(os.path.join(downloaddir, 'github.com/!azure/azure-sdk-for-go/sdk/storage/azblob/@v/v1.0.0.mod')), | ||
3562 | '7873b8544842329b4f385a3aa6cf82cc2bc8defb41a04fa5291c35fd5900e873') | ||
3563 | |||
3564 | @skipIfNoNetwork() | ||
3565 | def test_gomod_url_go_mod_only(self): | ||
3566 | urls = ['gomod://github.com/Azure/azure-sdk-for-go/sdk/storage/azblob;version=v1.0.0;mod=1;' | ||
3567 | 'sha256sum=7873b8544842329b4f385a3aa6cf82cc2bc8defb41a04fa5291c35fd5900e873'] | ||
3568 | |||
3569 | fetcher = bb.fetch2.Fetch(urls, self.d) | ||
3570 | ud = fetcher.ud[urls[0]] | ||
3571 | self.assertEqual(ud.url, 'https://proxy.golang.org/github.com/%21azure/azure-sdk-for-go/sdk/storage/azblob/%40v/v1.0.0.mod') | ||
3572 | self.assertEqual(ud.parm['downloadfilename'], 'github.com.Azure.azure-sdk-for-go.sdk.storage.azblob@v1.0.0.mod') | ||
3573 | self.assertEqual(ud.parm['name'], 'github.com/Azure/azure-sdk-for-go/sdk/storage/azblob@v1.0.0') | ||
3574 | |||
3575 | fetcher.download() | ||
3576 | fetcher.unpack(self.unpackdir) | ||
3577 | downloaddir = os.path.join(self.unpackdir, 'pkg/mod/cache/download') | ||
3578 | self.assertTrue(os.path.exists(os.path.join(downloaddir, 'github.com/!azure/azure-sdk-for-go/sdk/storage/azblob/@v/v1.0.0.mod'))) | ||
3579 | |||
3580 | @skipIfNoNetwork() | ||
3581 | def test_gomod_url_sha256sum_varflag(self): | ||
3582 | urls = ['gomod://gopkg.in/ini.v1;version=v1.67.0'] | ||
3583 | self.d.setVarFlag('SRC_URI', 'gopkg.in/ini.v1@v1.67.0.sha256sum', 'bd845dfc762a87a56e5a32a07770dc83e86976db7705d7f89c5dbafdc60b06c6') | ||
3584 | |||
3585 | fetcher = bb.fetch2.Fetch(urls, self.d) | ||
3586 | ud = fetcher.ud[urls[0]] | ||
3587 | self.assertEqual(ud.url, 'https://proxy.golang.org/gopkg.in/ini.v1/%40v/v1.67.0.zip') | ||
3588 | self.assertEqual(ud.parm['downloadfilename'], 'gopkg.in.ini.v1@v1.67.0.zip') | ||
3589 | self.assertEqual(ud.parm['name'], 'gopkg.in/ini.v1@v1.67.0') | ||
3590 | |||
3591 | fetcher.download() | ||
3592 | fetcher.unpack(self.unpackdir) | ||
3593 | downloaddir = os.path.join(self.unpackdir, 'pkg/mod/cache/download') | ||
3594 | self.assertTrue(os.path.exists(os.path.join(downloaddir, 'gopkg.in/ini.v1/@v/v1.67.0.zip'))) | ||
3595 | self.assertTrue(os.path.exists(os.path.join(downloaddir, 'gopkg.in/ini.v1/@v/v1.67.0.mod'))) | ||
3596 | self.assertEqual(bb.utils.sha256_file(os.path.join(downloaddir, 'gopkg.in/ini.v1/@v/v1.67.0.mod')), | ||
3597 | '13aedd85db8e555104108e0e613bb7e4d1242af7f27c15423dd9ab63b60b72a1') | ||
3598 | |||
3599 | @skipIfNoNetwork() | ||
3600 | def test_gomod_url_no_go_mod_in_module(self): | ||
3601 | urls = ['gomod://gopkg.in/ini.v1;version=v1.67.0;' | ||
3602 | 'sha256sum=bd845dfc762a87a56e5a32a07770dc83e86976db7705d7f89c5dbafdc60b06c6'] | ||
3603 | |||
3604 | fetcher = bb.fetch2.Fetch(urls, self.d) | ||
3605 | ud = fetcher.ud[urls[0]] | ||
3606 | self.assertEqual(ud.url, 'https://proxy.golang.org/gopkg.in/ini.v1/%40v/v1.67.0.zip') | ||
3607 | self.assertEqual(ud.parm['downloadfilename'], 'gopkg.in.ini.v1@v1.67.0.zip') | ||
3608 | self.assertEqual(ud.parm['name'], 'gopkg.in/ini.v1@v1.67.0') | ||
3609 | |||
3610 | fetcher.download() | ||
3611 | fetcher.unpack(self.unpackdir) | ||
3612 | downloaddir = os.path.join(self.unpackdir, 'pkg/mod/cache/download') | ||
3613 | self.assertTrue(os.path.exists(os.path.join(downloaddir, 'gopkg.in/ini.v1/@v/v1.67.0.zip'))) | ||
3614 | self.assertTrue(os.path.exists(os.path.join(downloaddir, 'gopkg.in/ini.v1/@v/v1.67.0.mod'))) | ||
3615 | self.assertEqual(bb.utils.sha256_file(os.path.join(downloaddir, 'gopkg.in/ini.v1/@v/v1.67.0.mod')), | ||
3616 | '13aedd85db8e555104108e0e613bb7e4d1242af7f27c15423dd9ab63b60b72a1') | ||
3617 | |||
3618 | @skipIfNoNetwork() | ||
3619 | def test_gomod_url_host_only(self): | ||
3620 | urls = ['gomod://go.opencensus.io;version=v0.24.0;' | ||
3621 | 'sha256sum=203a767d7f8e7c1ebe5588220ad168d1e15b14ae70a636de7ca9a4a88a7e0d0c'] | ||
3622 | |||
3623 | fetcher = bb.fetch2.Fetch(urls, self.d) | ||
3624 | ud = fetcher.ud[urls[0]] | ||
3625 | self.assertEqual(ud.url, 'https://proxy.golang.org/go.opencensus.io/%40v/v0.24.0.zip') | ||
3626 | self.assertEqual(ud.parm['downloadfilename'], 'go.opencensus.io@v0.24.0.zip') | ||
3627 | self.assertEqual(ud.parm['name'], 'go.opencensus.io@v0.24.0') | ||
3628 | |||
3629 | fetcher.download() | ||
3630 | fetcher.unpack(self.unpackdir) | ||
3631 | downloaddir = os.path.join(self.unpackdir, 'pkg/mod/cache/download') | ||
3632 | self.assertTrue(os.path.exists(os.path.join(downloaddir, 'go.opencensus.io/@v/v0.24.0.zip'))) | ||
3633 | self.assertTrue(os.path.exists(os.path.join(downloaddir, 'go.opencensus.io/@v/v0.24.0.mod'))) | ||
3634 | self.assertEqual(bb.utils.sha256_file(os.path.join(downloaddir, 'go.opencensus.io/@v/v0.24.0.mod')), | ||
3635 | '0dc9ccc660ad21cebaffd548f2cc6efa27891c68b4fbc1f8a3893b00f1acec96') | ||
3636 | |||
3637 | class GoModGitTest(FetcherTest): | ||
3638 | |||
3639 | @skipIfNoNetwork() | ||
3640 | def test_gomodgit_url_repo(self): | ||
3641 | urls = ['gomodgit://golang.org/x/net;version=v0.9.0;' | ||
3642 | 'repo=go.googlesource.com/net;' | ||
3643 | 'srcrev=694cff8668bac64e0864b552bffc280cd27f21b1'] | ||
3644 | |||
3645 | fetcher = bb.fetch2.Fetch(urls, self.d) | ||
3646 | ud = fetcher.ud[urls[0]] | ||
3647 | self.assertEqual(ud.host, 'go.googlesource.com') | ||
3648 | self.assertEqual(ud.path, '/net') | ||
3649 | self.assertEqual(ud.name, 'golang.org/x/net@v0.9.0') | ||
3650 | self.assertEqual(self.d.getVar('SRCREV_golang.org/x/net@v0.9.0'), '694cff8668bac64e0864b552bffc280cd27f21b1') | ||
3651 | |||
3652 | fetcher.download() | ||
3653 | self.assertTrue(os.path.exists(ud.localpath)) | ||
3654 | |||
3655 | fetcher.unpack(self.unpackdir) | ||
3656 | vcsdir = os.path.join(self.unpackdir, 'pkg/mod/cache/vcs') | ||
3657 | self.assertTrue(os.path.exists(os.path.join(vcsdir, 'ed42bd05533fd84ae290a5d33ebd3695a0a2b06131beebd5450825bee8603aca'))) | ||
3658 | downloaddir = os.path.join(self.unpackdir, 'pkg/mod/cache/download') | ||
3659 | self.assertTrue(os.path.exists(os.path.join(downloaddir, 'golang.org/x/net/@v/v0.9.0.zip'))) | ||
3660 | self.assertTrue(os.path.exists(os.path.join(downloaddir, 'golang.org/x/net/@v/v0.9.0.mod'))) | ||
3661 | self.assertEqual(bb.utils.sha256_file(os.path.join(downloaddir, 'golang.org/x/net/@v/v0.9.0.mod')), | ||
3662 | 'c5d6851ede50ec1c001afb763040194b68961bf06997e2605e8bf06dcd2aeb2e') | ||
3663 | |||
3664 | @skipIfNoNetwork() | ||
3665 | def test_gomodgit_url_subdir(self): | ||
3666 | urls = ['gomodgit://github.com/Azure/azure-sdk-for-go/sdk/storage/azblob;version=v1.0.0;' | ||
3667 | 'repo=github.com/Azure/azure-sdk-for-go;subdir=sdk/storage/azblob;' | ||
3668 | 'srcrev=ec928e0ed34db682b3f783d3739d1c538142e0c3'] | ||
3669 | |||
3670 | fetcher = bb.fetch2.Fetch(urls, self.d) | ||
3671 | ud = fetcher.ud[urls[0]] | ||
3672 | self.assertEqual(ud.host, 'github.com') | ||
3673 | self.assertEqual(ud.path, '/Azure/azure-sdk-for-go') | ||
3674 | self.assertEqual(ud.parm['subpath'], 'sdk/storage/azblob') | ||
3675 | self.assertEqual(ud.name, 'github.com/Azure/azure-sdk-for-go/sdk/storage/azblob@v1.0.0') | ||
3676 | self.assertEqual(self.d.getVar('SRCREV_github.com/Azure/azure-sdk-for-go/sdk/storage/azblob@v1.0.0'), 'ec928e0ed34db682b3f783d3739d1c538142e0c3') | ||
3677 | |||
3678 | fetcher.download() | ||
3679 | self.assertTrue(os.path.exists(ud.localpath)) | ||
3680 | |||
3681 | fetcher.unpack(self.unpackdir) | ||
3682 | vcsdir = os.path.join(self.unpackdir, 'pkg/mod/cache/vcs') | ||
3683 | self.assertTrue(os.path.exists(os.path.join(vcsdir, 'd31d6145676ed3066ce573a8198f326dea5be45a43b3d8f41ce7787fd71d66b3'))) | ||
3684 | downloaddir = os.path.join(self.unpackdir, 'pkg/mod/cache/download') | ||
3685 | self.assertTrue(os.path.exists(os.path.join(downloaddir, 'github.com/!azure/azure-sdk-for-go/sdk/storage/azblob/@v/v1.0.0.zip'))) | ||
3686 | self.assertTrue(os.path.exists(os.path.join(downloaddir, 'github.com/!azure/azure-sdk-for-go/sdk/storage/azblob/@v/v1.0.0.mod'))) | ||
3687 | self.assertEqual(bb.utils.sha256_file(os.path.join(downloaddir, 'github.com/!azure/azure-sdk-for-go/sdk/storage/azblob/@v/v1.0.0.mod')), | ||
3688 | '7873b8544842329b4f385a3aa6cf82cc2bc8defb41a04fa5291c35fd5900e873') | ||
3689 | |||
3690 | @skipIfNoNetwork() | ||
3691 | def test_gomodgit_url_srcrev_var(self): | ||
3692 | urls = ['gomodgit://gopkg.in/ini.v1;version=v1.67.0'] | ||
3693 | self.d.setVar('SRCREV_gopkg.in/ini.v1@v1.67.0', 'b2f570e5b5b844226bbefe6fb521d891f529a951') | ||
3694 | |||
3695 | fetcher = bb.fetch2.Fetch(urls, self.d) | ||
3696 | ud = fetcher.ud[urls[0]] | ||
3697 | self.assertEqual(ud.host, 'gopkg.in') | ||
3698 | self.assertEqual(ud.path, '/ini.v1') | ||
3699 | self.assertEqual(ud.name, 'gopkg.in/ini.v1@v1.67.0') | ||
3700 | self.assertEqual(ud.parm['srcrev'], 'b2f570e5b5b844226bbefe6fb521d891f529a951') | ||
3701 | |||
3702 | fetcher.download() | ||
3703 | fetcher.unpack(self.unpackdir) | ||
3704 | vcsdir = os.path.join(self.unpackdir, 'pkg/mod/cache/vcs') | ||
3705 | self.assertTrue(os.path.exists(os.path.join(vcsdir, 'b7879a4be9ba8598851b8278b14c4f71a8316be64913298d1639cce6bde59bc3'))) | ||
3706 | downloaddir = os.path.join(self.unpackdir, 'pkg/mod/cache/download') | ||
3707 | self.assertTrue(os.path.exists(os.path.join(downloaddir, 'gopkg.in/ini.v1/@v/v1.67.0.zip'))) | ||
3708 | self.assertTrue(os.path.exists(os.path.join(downloaddir, 'gopkg.in/ini.v1/@v/v1.67.0.mod'))) | ||
3709 | self.assertEqual(bb.utils.sha256_file(os.path.join(downloaddir, 'gopkg.in/ini.v1/@v/v1.67.0.mod')), | ||
3710 | '13aedd85db8e555104108e0e613bb7e4d1242af7f27c15423dd9ab63b60b72a1') | ||
3711 | |||
3712 | @skipIfNoNetwork() | ||
3713 | def test_gomodgit_url_no_go_mod_in_module(self): | ||
3714 | urls = ['gomodgit://gopkg.in/ini.v1;version=v1.67.0;' | ||
3715 | 'srcrev=b2f570e5b5b844226bbefe6fb521d891f529a951'] | ||
3716 | |||
3717 | fetcher = bb.fetch2.Fetch(urls, self.d) | ||
3718 | ud = fetcher.ud[urls[0]] | ||
3719 | self.assertEqual(ud.host, 'gopkg.in') | ||
3720 | self.assertEqual(ud.path, '/ini.v1') | ||
3721 | self.assertEqual(ud.name, 'gopkg.in/ini.v1@v1.67.0') | ||
3722 | self.assertEqual(self.d.getVar('SRCREV_gopkg.in/ini.v1@v1.67.0'), 'b2f570e5b5b844226bbefe6fb521d891f529a951') | ||
3723 | |||
3724 | fetcher.download() | ||
3725 | fetcher.unpack(self.unpackdir) | ||
3726 | vcsdir = os.path.join(self.unpackdir, 'pkg/mod/cache/vcs') | ||
3727 | self.assertTrue(os.path.exists(os.path.join(vcsdir, 'b7879a4be9ba8598851b8278b14c4f71a8316be64913298d1639cce6bde59bc3'))) | ||
3728 | downloaddir = os.path.join(self.unpackdir, 'pkg/mod/cache/download') | ||
3729 | self.assertTrue(os.path.exists(os.path.join(downloaddir, 'gopkg.in/ini.v1/@v/v1.67.0.zip'))) | ||
3730 | self.assertTrue(os.path.exists(os.path.join(downloaddir, 'gopkg.in/ini.v1/@v/v1.67.0.mod'))) | ||
3731 | self.assertEqual(bb.utils.sha256_file(os.path.join(downloaddir, 'gopkg.in/ini.v1/@v/v1.67.0.mod')), | ||
3732 | '13aedd85db8e555104108e0e613bb7e4d1242af7f27c15423dd9ab63b60b72a1') | ||
3733 | |||
3734 | @skipIfNoNetwork() | ||
3735 | def test_gomodgit_url_host_only(self): | ||
3736 | urls = ['gomodgit://go.opencensus.io;version=v0.24.0;' | ||
3737 | 'repo=github.com/census-instrumentation/opencensus-go;' | ||
3738 | 'srcrev=b1a01ee95db0e690d91d7193d037447816fae4c5'] | ||
3739 | |||
3740 | fetcher = bb.fetch2.Fetch(urls, self.d) | ||
3741 | ud = fetcher.ud[urls[0]] | ||
3742 | self.assertEqual(ud.host, 'github.com') | ||
3743 | self.assertEqual(ud.path, '/census-instrumentation/opencensus-go') | ||
3744 | self.assertEqual(ud.name, 'go.opencensus.io@v0.24.0') | ||
3745 | self.assertEqual(self.d.getVar('SRCREV_go.opencensus.io@v0.24.0'), 'b1a01ee95db0e690d91d7193d037447816fae4c5') | ||
3746 | |||
3747 | fetcher.download() | ||
3748 | fetcher.unpack(self.unpackdir) | ||
3749 | vcsdir = os.path.join(self.unpackdir, 'pkg/mod/cache/vcs') | ||
3750 | self.assertTrue(os.path.exists(os.path.join(vcsdir, 'aae3ac7b2122ed3345654e6327855e9682f4a5350d63e93dbcfc51c4419df0e1'))) | ||
3751 | downloaddir = os.path.join(self.unpackdir, 'pkg/mod/cache/download') | ||
3752 | self.assertTrue(os.path.exists(os.path.join(downloaddir, 'go.opencensus.io/@v/v0.24.0.zip'))) | ||
3753 | self.assertTrue(os.path.exists(os.path.join(downloaddir, 'go.opencensus.io/@v/v0.24.0.mod'))) | ||
3754 | self.assertEqual(bb.utils.sha256_file(os.path.join(downloaddir, 'go.opencensus.io/@v/v0.24.0.mod')), | ||
3755 | '0dc9ccc660ad21cebaffd548f2cc6efa27891c68b4fbc1f8a3893b00f1acec96') | ||
diff --git a/bitbake/lib/bb/tests/parse.py b/bitbake/lib/bb/tests/parse.py index 9e21e18425..e3cba67ad4 100644 --- a/bitbake/lib/bb/tests/parse.py +++ b/bitbake/lib/bb/tests/parse.py | |||
@@ -75,6 +75,59 @@ unset B[flag] | |||
75 | self.assertEqual(d.getVarFlag("A","flag"), None) | 75 | self.assertEqual(d.getVarFlag("A","flag"), None) |
76 | self.assertEqual(d.getVar("B"), "2") | 76 | self.assertEqual(d.getVar("B"), "2") |
77 | 77 | ||
78 | defaulttest = """ | ||
79 | A = "set value" | ||
80 | A ??= "default value" | ||
81 | |||
82 | A[flag_set_vs_question] = "set flag" | ||
83 | A[flag_set_vs_question] ?= "question flag" | ||
84 | |||
85 | A[flag_set_vs_default] = "set flag" | ||
86 | A[flag_set_vs_default] ??= "default flag" | ||
87 | |||
88 | A[flag_question] ?= "question flag" | ||
89 | |||
90 | A[flag_default] ??= "default flag" | ||
91 | |||
92 | A[flag_question_vs_default] ?= "question flag" | ||
93 | A[flag_question_vs_default] ??= "default flag" | ||
94 | |||
95 | A[flag_default_vs_question] ??= "default flag" | ||
96 | A[flag_default_vs_question] ?= "question flag" | ||
97 | |||
98 | A[flag_set_question_default] = "set flag" | ||
99 | A[flag_set_question_default] ?= "question flag" | ||
100 | A[flag_set_question_default] ??= "default flag" | ||
101 | |||
102 | A[flag_set_default_question] = "set flag" | ||
103 | A[flag_set_default_question] ??= "default flag" | ||
104 | A[flag_set_default_question] ?= "question flag" | ||
105 | |||
106 | A[flag_set_twice] = "set flag first" | ||
107 | A[flag_set_twice] = "set flag second" | ||
108 | |||
109 | A[flag_question_twice] ?= "question flag first" | ||
110 | A[flag_question_twice] ?= "question flag second" | ||
111 | |||
112 | A[flag_default_twice] ??= "default flag first" | ||
113 | A[flag_default_twice] ??= "default flag second" | ||
114 | """ | ||
115 | def test_parse_defaulttest(self): | ||
116 | f = self.parsehelper(self.defaulttest) | ||
117 | d = bb.parse.handle(f.name, self.d)[''] | ||
118 | self.assertEqual(d.getVar("A"), "set value") | ||
119 | self.assertEqual(d.getVarFlag("A","flag_set_vs_question"), "set flag") | ||
120 | self.assertEqual(d.getVarFlag("A","flag_set_vs_default"), "set flag") | ||
121 | self.assertEqual(d.getVarFlag("A","flag_question"), "question flag") | ||
122 | self.assertEqual(d.getVarFlag("A","flag_default"), "default flag") | ||
123 | self.assertEqual(d.getVarFlag("A","flag_question_vs_default"), "question flag") | ||
124 | self.assertEqual(d.getVarFlag("A","flag_default_vs_question"), "question flag") | ||
125 | self.assertEqual(d.getVarFlag("A","flag_set_question_default"), "set flag") | ||
126 | self.assertEqual(d.getVarFlag("A","flag_set_default_question"), "set flag") | ||
127 | self.assertEqual(d.getVarFlag("A","flag_set_twice"), "set flag second") | ||
128 | self.assertEqual(d.getVarFlag("A","flag_question_twice"), "question flag first") | ||
129 | self.assertEqual(d.getVarFlag("A","flag_default_twice"), "default flag second") | ||
130 | |||
78 | exporttest = """ | 131 | exporttest = """ |
79 | A = "a" | 132 | A = "a" |
80 | export B = "b" | 133 | export B = "b" |
@@ -98,8 +151,8 @@ exportD = "d" | |||
98 | 151 | ||
99 | 152 | ||
100 | overridetest = """ | 153 | overridetest = """ |
101 | RRECOMMENDS_${PN} = "a" | 154 | RRECOMMENDS:${PN} = "a" |
102 | RRECOMMENDS_${PN}_libc = "b" | 155 | RRECOMMENDS:${PN}:libc = "b" |
103 | OVERRIDES = "libc:${PN}" | 156 | OVERRIDES = "libc:${PN}" |
104 | PN = "gtk+" | 157 | PN = "gtk+" |
105 | """ | 158 | """ |
@@ -110,16 +163,16 @@ PN = "gtk+" | |||
110 | self.assertEqual(d.getVar("RRECOMMENDS"), "b") | 163 | self.assertEqual(d.getVar("RRECOMMENDS"), "b") |
111 | bb.data.expandKeys(d) | 164 | bb.data.expandKeys(d) |
112 | self.assertEqual(d.getVar("RRECOMMENDS"), "b") | 165 | self.assertEqual(d.getVar("RRECOMMENDS"), "b") |
113 | d.setVar("RRECOMMENDS_gtk+", "c") | 166 | d.setVar("RRECOMMENDS:gtk+", "c") |
114 | self.assertEqual(d.getVar("RRECOMMENDS"), "c") | 167 | self.assertEqual(d.getVar("RRECOMMENDS"), "c") |
115 | 168 | ||
116 | overridetest2 = """ | 169 | overridetest2 = """ |
117 | EXTRA_OECONF = "" | 170 | EXTRA_OECONF = "" |
118 | EXTRA_OECONF_class-target = "b" | 171 | EXTRA_OECONF:class-target = "b" |
119 | EXTRA_OECONF_append = " c" | 172 | EXTRA_OECONF:append = " c" |
120 | """ | 173 | """ |
121 | 174 | ||
122 | def test_parse_overrides(self): | 175 | def test_parse_overrides2(self): |
123 | f = self.parsehelper(self.overridetest2) | 176 | f = self.parsehelper(self.overridetest2) |
124 | d = bb.parse.handle(f.name, self.d)[''] | 177 | d = bb.parse.handle(f.name, self.d)[''] |
125 | d.appendVar("EXTRA_OECONF", " d") | 178 | d.appendVar("EXTRA_OECONF", " d") |
@@ -128,7 +181,7 @@ EXTRA_OECONF_append = " c" | |||
128 | 181 | ||
129 | overridetest3 = """ | 182 | overridetest3 = """ |
130 | DESCRIPTION = "A" | 183 | DESCRIPTION = "A" |
131 | DESCRIPTION_${PN}-dev = "${DESCRIPTION} B" | 184 | DESCRIPTION:${PN}-dev = "${DESCRIPTION} B" |
132 | PN = "bc" | 185 | PN = "bc" |
133 | """ | 186 | """ |
134 | 187 | ||
@@ -136,15 +189,15 @@ PN = "bc" | |||
136 | f = self.parsehelper(self.overridetest3) | 189 | f = self.parsehelper(self.overridetest3) |
137 | d = bb.parse.handle(f.name, self.d)[''] | 190 | d = bb.parse.handle(f.name, self.d)[''] |
138 | bb.data.expandKeys(d) | 191 | bb.data.expandKeys(d) |
139 | self.assertEqual(d.getVar("DESCRIPTION_bc-dev"), "A B") | 192 | self.assertEqual(d.getVar("DESCRIPTION:bc-dev"), "A B") |
140 | d.setVar("DESCRIPTION", "E") | 193 | d.setVar("DESCRIPTION", "E") |
141 | d.setVar("DESCRIPTION_bc-dev", "C D") | 194 | d.setVar("DESCRIPTION:bc-dev", "C D") |
142 | d.setVar("OVERRIDES", "bc-dev") | 195 | d.setVar("OVERRIDES", "bc-dev") |
143 | self.assertEqual(d.getVar("DESCRIPTION"), "C D") | 196 | self.assertEqual(d.getVar("DESCRIPTION"), "C D") |
144 | 197 | ||
145 | 198 | ||
146 | classextend = """ | 199 | classextend = """ |
147 | VAR_var_override1 = "B" | 200 | VAR_var:override1 = "B" |
148 | EXTRA = ":override1" | 201 | EXTRA = ":override1" |
149 | OVERRIDES = "nothing${EXTRA}" | 202 | OVERRIDES = "nothing${EXTRA}" |
150 | 203 | ||
@@ -164,6 +217,7 @@ python () { | |||
164 | # become unset/disappear. | 217 | # become unset/disappear. |
165 | # | 218 | # |
166 | def test_parse_classextend_contamination(self): | 219 | def test_parse_classextend_contamination(self): |
220 | self.d.setVar("__bbclasstype", "recipe") | ||
167 | cls = self.parsehelper(self.classextend_bbclass, suffix=".bbclass") | 221 | cls = self.parsehelper(self.classextend_bbclass, suffix=".bbclass") |
168 | #clsname = os.path.basename(cls.name).replace(".bbclass", "") | 222 | #clsname = os.path.basename(cls.name).replace(".bbclass", "") |
169 | self.classextend = self.classextend.replace("###CLASS###", cls.name) | 223 | self.classextend = self.classextend.replace("###CLASS###", cls.name) |
@@ -176,7 +230,19 @@ python () { | |||
176 | 230 | ||
177 | addtask_deltask = """ | 231 | addtask_deltask = """ |
178 | addtask do_patch after do_foo after do_unpack before do_configure before do_compile | 232 | addtask do_patch after do_foo after do_unpack before do_configure before do_compile |
179 | addtask do_fetch do_patch | 233 | addtask do_fetch2 do_patch2 |
234 | |||
235 | addtask do_myplaintask | ||
236 | addtask do_myplaintask2 | ||
237 | deltask do_myplaintask2 | ||
238 | addtask do_mytask# comment | ||
239 | addtask do_mytask2 # comment2 | ||
240 | addtask do_mytask3 | ||
241 | deltask do_mytask3# comment | ||
242 | deltask do_mytask4 # comment2 | ||
243 | |||
244 | # Ensure a missing task prefix on after works | ||
245 | addtask do_mytask5 after mytask | ||
180 | 246 | ||
181 | MYVAR = "do_patch" | 247 | MYVAR = "do_patch" |
182 | EMPTYVAR = "" | 248 | EMPTYVAR = "" |
@@ -184,13 +250,216 @@ deltask do_fetch ${MYVAR} ${EMPTYVAR} | |||
184 | deltask ${EMPTYVAR} | 250 | deltask ${EMPTYVAR} |
185 | """ | 251 | """ |
186 | def test_parse_addtask_deltask(self): | 252 | def test_parse_addtask_deltask(self): |
187 | import sys | 253 | |
188 | f = self.parsehelper(self.addtask_deltask) | 254 | f = self.parsehelper(self.addtask_deltask) |
189 | d = bb.parse.handle(f.name, self.d)[''] | 255 | d = bb.parse.handle(f.name, self.d)[''] |
190 | 256 | ||
191 | stdout = sys.stdout.getvalue() | 257 | self.assertSequenceEqual(['do_fetch2', 'do_patch2', 'do_myplaintask', 'do_mytask', 'do_mytask2', 'do_mytask5'], bb.build.listtasks(d)) |
192 | self.assertTrue("addtask contained multiple 'before' keywords" in stdout) | 258 | self.assertEqual(['do_mytask'], d.getVarFlag("do_mytask5", "deps")) |
193 | self.assertTrue("addtask contained multiple 'after' keywords" in stdout) | 259 | |
194 | self.assertTrue('addtask ignored: " do_patch"' in stdout) | 260 | broken_multiline_comment = """ |
195 | #self.assertTrue('dependent task do_foo for do_patch does not exist' in stdout) | 261 | # First line of comment \\ |
262 | # Second line of comment \\ | ||
263 | |||
264 | """ | ||
265 | def test_parse_broken_multiline_comment(self): | ||
266 | f = self.parsehelper(self.broken_multiline_comment) | ||
267 | with self.assertRaises(bb.BBHandledException): | ||
268 | d = bb.parse.handle(f.name, self.d)[''] | ||
269 | |||
270 | |||
271 | comment_in_var = """ | ||
272 | VAR = " \\ | ||
273 | SOMEVAL \\ | ||
274 | # some comment \\ | ||
275 | SOMEOTHERVAL \\ | ||
276 | " | ||
277 | """ | ||
278 | def test_parse_comment_in_var(self): | ||
279 | f = self.parsehelper(self.comment_in_var) | ||
280 | with self.assertRaises(bb.BBHandledException): | ||
281 | d = bb.parse.handle(f.name, self.d)[''] | ||
282 | |||
283 | |||
284 | at_sign_in_var_flag = """ | ||
285 | A[flag@.service] = "nonet" | ||
286 | B[flag@.target] = "ntb" | ||
287 | C[f] = "flag" | ||
196 | 288 | ||
289 | unset A[flag@.service] | ||
290 | """ | ||
291 | def test_parse_at_sign_in_var_flag(self): | ||
292 | f = self.parsehelper(self.at_sign_in_var_flag) | ||
293 | d = bb.parse.handle(f.name, self.d)[''] | ||
294 | self.assertEqual(d.getVar("A"), None) | ||
295 | self.assertEqual(d.getVar("B"), None) | ||
296 | self.assertEqual(d.getVarFlag("A","flag@.service"), None) | ||
297 | self.assertEqual(d.getVarFlag("B","flag@.target"), "ntb") | ||
298 | self.assertEqual(d.getVarFlag("C","f"), "flag") | ||
299 | |||
300 | def test_parse_invalid_at_sign_in_var_flag(self): | ||
301 | invalid_at_sign = self.at_sign_in_var_flag.replace("B[f", "B[@f") | ||
302 | f = self.parsehelper(invalid_at_sign) | ||
303 | with self.assertRaises(bb.parse.ParseError): | ||
304 | d = bb.parse.handle(f.name, self.d)[''] | ||
305 | |||
306 | export_function_recipe = """ | ||
307 | inherit someclass | ||
308 | """ | ||
309 | |||
310 | export_function_recipe2 = """ | ||
311 | inherit someclass | ||
312 | |||
313 | do_compile () { | ||
314 | false | ||
315 | } | ||
316 | |||
317 | python do_compilepython () { | ||
318 | bb.note("Something else") | ||
319 | } | ||
320 | |||
321 | """ | ||
322 | export_function_class = """ | ||
323 | someclass_do_compile() { | ||
324 | true | ||
325 | } | ||
326 | |||
327 | python someclass_do_compilepython () { | ||
328 | bb.note("Something") | ||
329 | } | ||
330 | |||
331 | EXPORT_FUNCTIONS do_compile do_compilepython | ||
332 | """ | ||
333 | |||
334 | export_function_class2 = """ | ||
335 | secondclass_do_compile() { | ||
336 | true | ||
337 | } | ||
338 | |||
339 | python secondclass_do_compilepython () { | ||
340 | bb.note("Something") | ||
341 | } | ||
342 | |||
343 | EXPORT_FUNCTIONS do_compile do_compilepython | ||
344 | """ | ||
345 | |||
346 | def test_parse_export_functions(self): | ||
347 | def check_function_flags(d): | ||
348 | self.assertEqual(d.getVarFlag("do_compile", "func"), 1) | ||
349 | self.assertEqual(d.getVarFlag("do_compilepython", "func"), 1) | ||
350 | self.assertEqual(d.getVarFlag("do_compile", "python"), None) | ||
351 | self.assertEqual(d.getVarFlag("do_compilepython", "python"), "1") | ||
352 | |||
353 | with tempfile.TemporaryDirectory() as tempdir: | ||
354 | self.d.setVar("__bbclasstype", "recipe") | ||
355 | recipename = tempdir + "/recipe.bb" | ||
356 | os.makedirs(tempdir + "/classes") | ||
357 | with open(tempdir + "/classes/someclass.bbclass", "w") as f: | ||
358 | f.write(self.export_function_class) | ||
359 | f.flush() | ||
360 | with open(tempdir + "/classes/secondclass.bbclass", "w") as f: | ||
361 | f.write(self.export_function_class2) | ||
362 | f.flush() | ||
363 | |||
364 | with open(recipename, "w") as f: | ||
365 | f.write(self.export_function_recipe) | ||
366 | f.flush() | ||
367 | os.chdir(tempdir) | ||
368 | d = bb.parse.handle(recipename, bb.data.createCopy(self.d))[''] | ||
369 | self.assertIn("someclass_do_compile", d.getVar("do_compile")) | ||
370 | self.assertIn("someclass_do_compilepython", d.getVar("do_compilepython")) | ||
371 | check_function_flags(d) | ||
372 | |||
373 | recipename2 = tempdir + "/recipe2.bb" | ||
374 | with open(recipename2, "w") as f: | ||
375 | f.write(self.export_function_recipe2) | ||
376 | f.flush() | ||
377 | |||
378 | d = bb.parse.handle(recipename2, bb.data.createCopy(self.d))[''] | ||
379 | self.assertNotIn("someclass_do_compile", d.getVar("do_compile")) | ||
380 | self.assertNotIn("someclass_do_compilepython", d.getVar("do_compilepython")) | ||
381 | self.assertIn("false", d.getVar("do_compile")) | ||
382 | self.assertIn("else", d.getVar("do_compilepython")) | ||
383 | check_function_flags(d) | ||
384 | |||
385 | with open(recipename, "a+") as f: | ||
386 | f.write("\ninherit secondclass\n") | ||
387 | f.flush() | ||
388 | with open(recipename2, "a+") as f: | ||
389 | f.write("\ninherit secondclass\n") | ||
390 | f.flush() | ||
391 | |||
392 | d = bb.parse.handle(recipename, bb.data.createCopy(self.d))[''] | ||
393 | self.assertIn("secondclass_do_compile", d.getVar("do_compile")) | ||
394 | self.assertIn("secondclass_do_compilepython", d.getVar("do_compilepython")) | ||
395 | check_function_flags(d) | ||
396 | |||
397 | d = bb.parse.handle(recipename2, bb.data.createCopy(self.d))[''] | ||
398 | self.assertNotIn("someclass_do_compile", d.getVar("do_compile")) | ||
399 | self.assertNotIn("someclass_do_compilepython", d.getVar("do_compilepython")) | ||
400 | self.assertIn("false", d.getVar("do_compile")) | ||
401 | self.assertIn("else", d.getVar("do_compilepython")) | ||
402 | check_function_flags(d) | ||
403 | |||
404 | export_function_unclosed_tab = """ | ||
405 | do_compile () { | ||
406 | bb.note("Something") | ||
407 | \t} | ||
408 | """ | ||
409 | export_function_unclosed_space = """ | ||
410 | do_compile () { | ||
411 | bb.note("Something") | ||
412 | } | ||
413 | """ | ||
414 | export_function_residue = """ | ||
415 | do_compile () { | ||
416 | bb.note("Something") | ||
417 | } | ||
418 | |||
419 | include \\ | ||
420 | """ | ||
421 | |||
422 | def test_unclosed_functions(self): | ||
423 | def test_helper(content, expected_error): | ||
424 | with tempfile.TemporaryDirectory() as tempdir: | ||
425 | recipename = tempdir + "/recipe_unclosed.bb" | ||
426 | with open(recipename, "w") as f: | ||
427 | f.write(content) | ||
428 | f.flush() | ||
429 | os.chdir(tempdir) | ||
430 | with self.assertRaises(bb.parse.ParseError) as error: | ||
431 | bb.parse.handle(recipename, bb.data.createCopy(self.d)) | ||
432 | self.assertIn(expected_error, str(error.exception)) | ||
433 | |||
434 | with tempfile.TemporaryDirectory() as tempdir: | ||
435 | test_helper(self.export_function_unclosed_tab, "Unparsed lines from unclosed function") | ||
436 | test_helper(self.export_function_unclosed_space, "Unparsed lines from unclosed function") | ||
437 | test_helper(self.export_function_residue, "Unparsed lines") | ||
438 | |||
439 | recipename_closed = tempdir + "/recipe_closed.bb" | ||
440 | with open(recipename_closed, "w") as in_file: | ||
441 | lines = self.export_function_unclosed_tab.split("\n") | ||
442 | lines[3] = "}" | ||
443 | in_file.write("\n".join(lines)) | ||
444 | in_file.flush() | ||
445 | bb.parse.handle(recipename_closed, bb.data.createCopy(self.d)) | ||
446 | |||
447 | special_character_assignment = """ | ||
448 | A+="a" | ||
449 | A+ = "b" | ||
450 | + = "c" | ||
451 | """ | ||
452 | ambigous_assignment = """ | ||
453 | += "d" | ||
454 | """ | ||
455 | def test_parse_special_character_assignment(self): | ||
456 | f = self.parsehelper(self.special_character_assignment) | ||
457 | d = bb.parse.handle(f.name, self.d)[''] | ||
458 | self.assertEqual(d.getVar("A"), " a") | ||
459 | self.assertEqual(d.getVar("A+"), "b") | ||
460 | self.assertEqual(d.getVar("+"), "c") | ||
461 | |||
462 | f = self.parsehelper(self.ambigous_assignment) | ||
463 | with self.assertRaises(bb.parse.ParseError) as error: | ||
464 | bb.parse.handle(f.name, self.d) | ||
465 | self.assertIn("Empty variable name in assignment", str(error.exception)) | ||
diff --git a/bitbake/lib/bb/tests/persist_data.py b/bitbake/lib/bb/tests/persist_data.py deleted file mode 100644 index f641b5acbc..0000000000 --- a/bitbake/lib/bb/tests/persist_data.py +++ /dev/null | |||
@@ -1,129 +0,0 @@ | |||
1 | # | ||
2 | # BitBake Test for lib/bb/persist_data/ | ||
3 | # | ||
4 | # Copyright (C) 2018 Garmin Ltd. | ||
5 | # | ||
6 | # SPDX-License-Identifier: GPL-2.0-only | ||
7 | # | ||
8 | |||
9 | import unittest | ||
10 | import bb.data | ||
11 | import bb.persist_data | ||
12 | import tempfile | ||
13 | import threading | ||
14 | |||
15 | class PersistDataTest(unittest.TestCase): | ||
16 | def _create_data(self): | ||
17 | return bb.persist_data.persist('TEST_PERSIST_DATA', self.d) | ||
18 | |||
19 | def setUp(self): | ||
20 | self.d = bb.data.init() | ||
21 | self.tempdir = tempfile.TemporaryDirectory() | ||
22 | self.d['PERSISTENT_DIR'] = self.tempdir.name | ||
23 | self.data = self._create_data() | ||
24 | self.items = { | ||
25 | 'A1': '1', | ||
26 | 'B1': '2', | ||
27 | 'C2': '3' | ||
28 | } | ||
29 | self.stress_count = 10000 | ||
30 | self.thread_count = 5 | ||
31 | |||
32 | for k,v in self.items.items(): | ||
33 | self.data[k] = v | ||
34 | |||
35 | def tearDown(self): | ||
36 | self.tempdir.cleanup() | ||
37 | |||
38 | def _iter_helper(self, seen, iterator): | ||
39 | with iter(iterator): | ||
40 | for v in iterator: | ||
41 | self.assertTrue(v in seen) | ||
42 | seen.remove(v) | ||
43 | self.assertEqual(len(seen), 0, '%s not seen' % seen) | ||
44 | |||
45 | def test_get(self): | ||
46 | for k, v in self.items.items(): | ||
47 | self.assertEqual(self.data[k], v) | ||
48 | |||
49 | self.assertIsNone(self.data.get('D')) | ||
50 | with self.assertRaises(KeyError): | ||
51 | self.data['D'] | ||
52 | |||
53 | def test_set(self): | ||
54 | for k, v in self.items.items(): | ||
55 | self.data[k] += '-foo' | ||
56 | |||
57 | for k, v in self.items.items(): | ||
58 | self.assertEqual(self.data[k], v + '-foo') | ||
59 | |||
60 | def test_delete(self): | ||
61 | self.data['D'] = '4' | ||
62 | self.assertEqual(self.data['D'], '4') | ||
63 | del self.data['D'] | ||
64 | self.assertIsNone(self.data.get('D')) | ||
65 | with self.assertRaises(KeyError): | ||
66 | self.data['D'] | ||
67 | |||
68 | def test_contains(self): | ||
69 | for k in self.items: | ||
70 | self.assertTrue(k in self.data) | ||
71 | self.assertTrue(self.data.has_key(k)) | ||
72 | self.assertFalse('NotFound' in self.data) | ||
73 | self.assertFalse(self.data.has_key('NotFound')) | ||
74 | |||
75 | def test_len(self): | ||
76 | self.assertEqual(len(self.data), len(self.items)) | ||
77 | |||
78 | def test_iter(self): | ||
79 | self._iter_helper(set(self.items.keys()), self.data) | ||
80 | |||
81 | def test_itervalues(self): | ||
82 | self._iter_helper(set(self.items.values()), self.data.itervalues()) | ||
83 | |||
84 | def test_iteritems(self): | ||
85 | self._iter_helper(set(self.items.items()), self.data.iteritems()) | ||
86 | |||
87 | def test_get_by_pattern(self): | ||
88 | self._iter_helper({'1', '2'}, self.data.get_by_pattern('_1')) | ||
89 | |||
90 | def _stress_read(self, data): | ||
91 | for i in range(self.stress_count): | ||
92 | for k in self.items: | ||
93 | data[k] | ||
94 | |||
95 | def _stress_write(self, data): | ||
96 | for i in range(self.stress_count): | ||
97 | for k, v in self.items.items(): | ||
98 | data[k] = v + str(i) | ||
99 | |||
100 | def _validate_stress(self): | ||
101 | for k, v in self.items.items(): | ||
102 | self.assertEqual(self.data[k], v + str(self.stress_count - 1)) | ||
103 | |||
104 | def test_stress(self): | ||
105 | self._stress_read(self.data) | ||
106 | self._stress_write(self.data) | ||
107 | self._validate_stress() | ||
108 | |||
109 | def test_stress_threads(self): | ||
110 | def read_thread(): | ||
111 | data = self._create_data() | ||
112 | self._stress_read(data) | ||
113 | |||
114 | def write_thread(): | ||
115 | data = self._create_data() | ||
116 | self._stress_write(data) | ||
117 | |||
118 | threads = [] | ||
119 | for i in range(self.thread_count): | ||
120 | threads.append(threading.Thread(target=read_thread)) | ||
121 | threads.append(threading.Thread(target=write_thread)) | ||
122 | |||
123 | for t in threads: | ||
124 | t.start() | ||
125 | self._stress_read(self.data) | ||
126 | for t in threads: | ||
127 | t.join() | ||
128 | self._validate_stress() | ||
129 | |||
diff --git a/bitbake/lib/bb/tests/runqueue-tests/classes/base.bbclass b/bitbake/lib/bb/tests/runqueue-tests/classes/base.bbclass index b57650d591..80b003b2b5 100644 --- a/bitbake/lib/bb/tests/runqueue-tests/classes/base.bbclass +++ b/bitbake/lib/bb/tests/runqueue-tests/classes/base.bbclass | |||
@@ -9,7 +9,7 @@ def stamptask(d): | |||
9 | with open(stampname, "a+") as f: | 9 | with open(stampname, "a+") as f: |
10 | f.write(d.getVar("BB_UNIHASH") + "\n") | 10 | f.write(d.getVar("BB_UNIHASH") + "\n") |
11 | 11 | ||
12 | if d.getVar("BB_CURRENT_MC") != "default": | 12 | if d.getVar("BB_CURRENT_MC") != "": |
13 | thistask = d.expand("${BB_CURRENT_MC}:${PN}:${BB_CURRENTTASK}") | 13 | thistask = d.expand("${BB_CURRENT_MC}:${PN}:${BB_CURRENTTASK}") |
14 | if thistask in d.getVar("SLOWTASKS").split(): | 14 | if thistask in d.getVar("SLOWTASKS").split(): |
15 | bb.note("Slowing task %s" % thistask) | 15 | bb.note("Slowing task %s" % thistask) |
diff --git a/bitbake/lib/bb/tests/runqueue-tests/conf/bitbake.conf b/bitbake/lib/bb/tests/runqueue-tests/conf/bitbake.conf index efebf001a9..05d7fd07dd 100644 --- a/bitbake/lib/bb/tests/runqueue-tests/conf/bitbake.conf +++ b/bitbake/lib/bb/tests/runqueue-tests/conf/bitbake.conf | |||
@@ -12,6 +12,6 @@ STAMP = "${TMPDIR}/stamps/${PN}" | |||
12 | T = "${TMPDIR}/workdir/${PN}/temp" | 12 | T = "${TMPDIR}/workdir/${PN}/temp" |
13 | BB_NUMBER_THREADS = "4" | 13 | BB_NUMBER_THREADS = "4" |
14 | 14 | ||
15 | BB_HASHBASE_WHITELIST = "BB_CURRENT_MC BB_HASHSERVE TMPDIR TOPDIR SLOWTASKS SSTATEVALID FILE" | 15 | BB_BASEHASH_IGNORE_VARS = "BB_CURRENT_MC BB_HASHSERVE TMPDIR TOPDIR SLOWTASKS SSTATEVALID FILE BB_CURRENTTASK" |
16 | 16 | ||
17 | include conf/multiconfig/${BB_CURRENT_MC}.conf | 17 | include conf/multiconfig/${BB_CURRENT_MC}.conf |
diff --git a/bitbake/lib/bb/tests/runqueue-tests/recipes/g1.bb b/bitbake/lib/bb/tests/runqueue-tests/recipes/g1.bb new file mode 100644 index 0000000000..3c7dca0257 --- /dev/null +++ b/bitbake/lib/bb/tests/runqueue-tests/recipes/g1.bb | |||
@@ -0,0 +1,2 @@ | |||
1 | do_build[mcdepends] = "mc::mc-1:h1:do_invalid" | ||
2 | |||
diff --git a/bitbake/lib/bb/tests/runqueue-tests/recipes/h1.bb b/bitbake/lib/bb/tests/runqueue-tests/recipes/h1.bb new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/bitbake/lib/bb/tests/runqueue-tests/recipes/h1.bb | |||
diff --git a/bitbake/lib/bb/tests/runqueue.py b/bitbake/lib/bb/tests/runqueue.py index 3d51779d6c..74f5ded2e6 100644 --- a/bitbake/lib/bb/tests/runqueue.py +++ b/bitbake/lib/bb/tests/runqueue.py | |||
@@ -26,20 +26,23 @@ class RunQueueTests(unittest.TestCase): | |||
26 | a1_sstatevalid = "a1:do_package a1:do_package_qa a1:do_packagedata a1:do_package_write_ipk a1:do_package_write_rpm a1:do_populate_lic a1:do_populate_sysroot" | 26 | a1_sstatevalid = "a1:do_package a1:do_package_qa a1:do_packagedata a1:do_package_write_ipk a1:do_package_write_rpm a1:do_populate_lic a1:do_populate_sysroot" |
27 | b1_sstatevalid = "b1:do_package b1:do_package_qa b1:do_packagedata b1:do_package_write_ipk b1:do_package_write_rpm b1:do_populate_lic b1:do_populate_sysroot" | 27 | b1_sstatevalid = "b1:do_package b1:do_package_qa b1:do_packagedata b1:do_package_write_ipk b1:do_package_write_rpm b1:do_populate_lic b1:do_populate_sysroot" |
28 | 28 | ||
29 | def run_bitbakecmd(self, cmd, builddir, sstatevalid="", slowtasks="", extraenv=None, cleanup=False): | 29 | def run_bitbakecmd(self, cmd, builddir, sstatevalid="", slowtasks="", extraenv=None, cleanup=False, allowfailure=False): |
30 | env = os.environ.copy() | 30 | env = os.environ.copy() |
31 | env["BBPATH"] = os.path.realpath(os.path.join(os.path.dirname(__file__), "runqueue-tests")) | 31 | env["BBPATH"] = os.path.realpath(os.path.join(os.path.dirname(__file__), "runqueue-tests")) |
32 | env["BB_ENV_EXTRAWHITE"] = "SSTATEVALID SLOWTASKS" | 32 | env["BB_ENV_PASSTHROUGH_ADDITIONS"] = "SSTATEVALID SLOWTASKS TOPDIR" |
33 | env["SSTATEVALID"] = sstatevalid | 33 | env["SSTATEVALID"] = sstatevalid |
34 | env["SLOWTASKS"] = slowtasks | 34 | env["SLOWTASKS"] = slowtasks |
35 | env["TOPDIR"] = builddir | ||
35 | if extraenv: | 36 | if extraenv: |
36 | for k in extraenv: | 37 | for k in extraenv: |
37 | env[k] = extraenv[k] | 38 | env[k] = extraenv[k] |
38 | env["BB_ENV_EXTRAWHITE"] = env["BB_ENV_EXTRAWHITE"] + " " + k | 39 | env["BB_ENV_PASSTHROUGH_ADDITIONS"] = env["BB_ENV_PASSTHROUGH_ADDITIONS"] + " " + k |
39 | try: | 40 | try: |
40 | output = subprocess.check_output(cmd, env=env, stderr=subprocess.STDOUT,universal_newlines=True, cwd=builddir) | 41 | output = subprocess.check_output(cmd, env=env, stderr=subprocess.STDOUT,universal_newlines=True, cwd=builddir) |
41 | print(output) | 42 | print(output) |
42 | except subprocess.CalledProcessError as e: | 43 | except subprocess.CalledProcessError as e: |
44 | if allowfailure: | ||
45 | return e.output | ||
43 | self.fail("Command %s failed with %s" % (cmd, e.output)) | 46 | self.fail("Command %s failed with %s" % (cmd, e.output)) |
44 | tasks = [] | 47 | tasks = [] |
45 | tasklog = builddir + "/task.log" | 48 | tasklog = builddir + "/task.log" |
@@ -58,6 +61,8 @@ class RunQueueTests(unittest.TestCase): | |||
58 | expected = ['a1:' + x for x in self.alltasks] | 61 | expected = ['a1:' + x for x in self.alltasks] |
59 | self.assertEqual(set(tasks), set(expected)) | 62 | self.assertEqual(set(tasks), set(expected)) |
60 | 63 | ||
64 | self.shutdown(tempdir) | ||
65 | |||
61 | def test_single_setscenevalid(self): | 66 | def test_single_setscenevalid(self): |
62 | with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: | 67 | with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: |
63 | cmd = ["bitbake", "a1"] | 68 | cmd = ["bitbake", "a1"] |
@@ -68,6 +73,8 @@ class RunQueueTests(unittest.TestCase): | |||
68 | 'a1:populate_sysroot', 'a1:build'] | 73 | 'a1:populate_sysroot', 'a1:build'] |
69 | self.assertEqual(set(tasks), set(expected)) | 74 | self.assertEqual(set(tasks), set(expected)) |
70 | 75 | ||
76 | self.shutdown(tempdir) | ||
77 | |||
71 | def test_intermediate_setscenevalid(self): | 78 | def test_intermediate_setscenevalid(self): |
72 | with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: | 79 | with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: |
73 | cmd = ["bitbake", "a1"] | 80 | cmd = ["bitbake", "a1"] |
@@ -77,6 +84,8 @@ class RunQueueTests(unittest.TestCase): | |||
77 | 'a1:populate_sysroot_setscene', 'a1:build'] | 84 | 'a1:populate_sysroot_setscene', 'a1:build'] |
78 | self.assertEqual(set(tasks), set(expected)) | 85 | self.assertEqual(set(tasks), set(expected)) |
79 | 86 | ||
87 | self.shutdown(tempdir) | ||
88 | |||
80 | def test_intermediate_notcovered(self): | 89 | def test_intermediate_notcovered(self): |
81 | with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: | 90 | with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: |
82 | cmd = ["bitbake", "a1"] | 91 | cmd = ["bitbake", "a1"] |
@@ -86,6 +95,8 @@ class RunQueueTests(unittest.TestCase): | |||
86 | 'a1:package_qa_setscene', 'a1:build', 'a1:populate_sysroot_setscene'] | 95 | 'a1:package_qa_setscene', 'a1:build', 'a1:populate_sysroot_setscene'] |
87 | self.assertEqual(set(tasks), set(expected)) | 96 | self.assertEqual(set(tasks), set(expected)) |
88 | 97 | ||
98 | self.shutdown(tempdir) | ||
99 | |||
89 | def test_all_setscenevalid(self): | 100 | def test_all_setscenevalid(self): |
90 | with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: | 101 | with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: |
91 | cmd = ["bitbake", "a1"] | 102 | cmd = ["bitbake", "a1"] |
@@ -95,6 +106,8 @@ class RunQueueTests(unittest.TestCase): | |||
95 | 'a1:package_qa_setscene', 'a1:build', 'a1:populate_sysroot_setscene'] | 106 | 'a1:package_qa_setscene', 'a1:build', 'a1:populate_sysroot_setscene'] |
96 | self.assertEqual(set(tasks), set(expected)) | 107 | self.assertEqual(set(tasks), set(expected)) |
97 | 108 | ||
109 | self.shutdown(tempdir) | ||
110 | |||
98 | def test_no_settasks(self): | 111 | def test_no_settasks(self): |
99 | with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: | 112 | with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: |
100 | cmd = ["bitbake", "a1", "-c", "patch"] | 113 | cmd = ["bitbake", "a1", "-c", "patch"] |
@@ -103,6 +116,8 @@ class RunQueueTests(unittest.TestCase): | |||
103 | expected = ['a1:fetch', 'a1:unpack', 'a1:patch'] | 116 | expected = ['a1:fetch', 'a1:unpack', 'a1:patch'] |
104 | self.assertEqual(set(tasks), set(expected)) | 117 | self.assertEqual(set(tasks), set(expected)) |
105 | 118 | ||
119 | self.shutdown(tempdir) | ||
120 | |||
106 | def test_mix_covered_notcovered(self): | 121 | def test_mix_covered_notcovered(self): |
107 | with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: | 122 | with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: |
108 | cmd = ["bitbake", "a1:do_patch", "a1:do_populate_sysroot"] | 123 | cmd = ["bitbake", "a1:do_patch", "a1:do_populate_sysroot"] |
@@ -111,6 +126,7 @@ class RunQueueTests(unittest.TestCase): | |||
111 | expected = ['a1:fetch', 'a1:unpack', 'a1:patch', 'a1:populate_sysroot_setscene'] | 126 | expected = ['a1:fetch', 'a1:unpack', 'a1:patch', 'a1:populate_sysroot_setscene'] |
112 | self.assertEqual(set(tasks), set(expected)) | 127 | self.assertEqual(set(tasks), set(expected)) |
113 | 128 | ||
129 | self.shutdown(tempdir) | ||
114 | 130 | ||
115 | # Test targets with intermediate setscene tasks alongside a target with no intermediate setscene tasks | 131 | # Test targets with intermediate setscene tasks alongside a target with no intermediate setscene tasks |
116 | def test_mixed_direct_tasks_setscene_tasks(self): | 132 | def test_mixed_direct_tasks_setscene_tasks(self): |
@@ -122,6 +138,8 @@ class RunQueueTests(unittest.TestCase): | |||
122 | 'a1:package_qa_setscene', 'a1:build', 'a1:populate_sysroot_setscene'] | 138 | 'a1:package_qa_setscene', 'a1:build', 'a1:populate_sysroot_setscene'] |
123 | self.assertEqual(set(tasks), set(expected)) | 139 | self.assertEqual(set(tasks), set(expected)) |
124 | 140 | ||
141 | self.shutdown(tempdir) | ||
142 | |||
125 | # This test slows down the execution of do_package_setscene until after other real tasks have | 143 | # This test slows down the execution of do_package_setscene until after other real tasks have |
126 | # started running which tests for a bug where tasks were being lost from the buildable list of real | 144 | # started running which tests for a bug where tasks were being lost from the buildable list of real |
127 | # tasks if they weren't in tasks_covered or tasks_notcovered | 145 | # tasks if they weren't in tasks_covered or tasks_notcovered |
@@ -136,12 +154,14 @@ class RunQueueTests(unittest.TestCase): | |||
136 | 'a1:populate_sysroot', 'a1:build'] | 154 | 'a1:populate_sysroot', 'a1:build'] |
137 | self.assertEqual(set(tasks), set(expected)) | 155 | self.assertEqual(set(tasks), set(expected)) |
138 | 156 | ||
139 | def test_setscenewhitelist(self): | 157 | self.shutdown(tempdir) |
158 | |||
159 | def test_setscene_ignore_tasks(self): | ||
140 | with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: | 160 | with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: |
141 | cmd = ["bitbake", "a1"] | 161 | cmd = ["bitbake", "a1"] |
142 | extraenv = { | 162 | extraenv = { |
143 | "BB_SETSCENE_ENFORCE" : "1", | 163 | "BB_SETSCENE_ENFORCE" : "1", |
144 | "BB_SETSCENE_ENFORCE_WHITELIST" : "a1:do_package_write_rpm a1:do_build" | 164 | "BB_SETSCENE_ENFORCE_IGNORE_TASKS" : "a1:do_package_write_rpm a1:do_build" |
145 | } | 165 | } |
146 | sstatevalid = "a1:do_package a1:do_package_qa a1:do_packagedata a1:do_package_write_ipk a1:do_populate_lic a1:do_populate_sysroot" | 166 | sstatevalid = "a1:do_package a1:do_package_qa a1:do_packagedata a1:do_package_write_ipk a1:do_populate_lic a1:do_populate_sysroot" |
147 | tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv) | 167 | tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv) |
@@ -149,6 +169,8 @@ class RunQueueTests(unittest.TestCase): | |||
149 | 'a1:populate_sysroot_setscene', 'a1:package_setscene'] | 169 | 'a1:populate_sysroot_setscene', 'a1:package_setscene'] |
150 | self.assertEqual(set(tasks), set(expected)) | 170 | self.assertEqual(set(tasks), set(expected)) |
151 | 171 | ||
172 | self.shutdown(tempdir) | ||
173 | |||
152 | # Tests for problems with dependencies between setscene tasks | 174 | # Tests for problems with dependencies between setscene tasks |
153 | def test_no_setscenevalid_harddeps(self): | 175 | def test_no_setscenevalid_harddeps(self): |
154 | with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: | 176 | with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: |
@@ -162,6 +184,8 @@ class RunQueueTests(unittest.TestCase): | |||
162 | 'd1:populate_sysroot', 'd1:build'] | 184 | 'd1:populate_sysroot', 'd1:build'] |
163 | self.assertEqual(set(tasks), set(expected)) | 185 | self.assertEqual(set(tasks), set(expected)) |
164 | 186 | ||
187 | self.shutdown(tempdir) | ||
188 | |||
165 | def test_no_setscenevalid_withdeps(self): | 189 | def test_no_setscenevalid_withdeps(self): |
166 | with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: | 190 | with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: |
167 | cmd = ["bitbake", "b1"] | 191 | cmd = ["bitbake", "b1"] |
@@ -172,6 +196,8 @@ class RunQueueTests(unittest.TestCase): | |||
172 | expected.remove('a1:package_qa') | 196 | expected.remove('a1:package_qa') |
173 | self.assertEqual(set(tasks), set(expected)) | 197 | self.assertEqual(set(tasks), set(expected)) |
174 | 198 | ||
199 | self.shutdown(tempdir) | ||
200 | |||
175 | def test_single_a1_setscenevalid_withdeps(self): | 201 | def test_single_a1_setscenevalid_withdeps(self): |
176 | with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: | 202 | with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: |
177 | cmd = ["bitbake", "b1"] | 203 | cmd = ["bitbake", "b1"] |
@@ -182,6 +208,8 @@ class RunQueueTests(unittest.TestCase): | |||
182 | 'a1:populate_sysroot'] + ['b1:' + x for x in self.alltasks] | 208 | 'a1:populate_sysroot'] + ['b1:' + x for x in self.alltasks] |
183 | self.assertEqual(set(tasks), set(expected)) | 209 | self.assertEqual(set(tasks), set(expected)) |
184 | 210 | ||
211 | self.shutdown(tempdir) | ||
212 | |||
185 | def test_single_b1_setscenevalid_withdeps(self): | 213 | def test_single_b1_setscenevalid_withdeps(self): |
186 | with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: | 214 | with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: |
187 | cmd = ["bitbake", "b1"] | 215 | cmd = ["bitbake", "b1"] |
@@ -193,6 +221,8 @@ class RunQueueTests(unittest.TestCase): | |||
193 | expected.remove('b1:package') | 221 | expected.remove('b1:package') |
194 | self.assertEqual(set(tasks), set(expected)) | 222 | self.assertEqual(set(tasks), set(expected)) |
195 | 223 | ||
224 | self.shutdown(tempdir) | ||
225 | |||
196 | def test_intermediate_setscenevalid_withdeps(self): | 226 | def test_intermediate_setscenevalid_withdeps(self): |
197 | with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: | 227 | with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: |
198 | cmd = ["bitbake", "b1"] | 228 | cmd = ["bitbake", "b1"] |
@@ -203,6 +233,8 @@ class RunQueueTests(unittest.TestCase): | |||
203 | expected.remove('b1:package') | 233 | expected.remove('b1:package') |
204 | self.assertEqual(set(tasks), set(expected)) | 234 | self.assertEqual(set(tasks), set(expected)) |
205 | 235 | ||
236 | self.shutdown(tempdir) | ||
237 | |||
206 | def test_all_setscenevalid_withdeps(self): | 238 | def test_all_setscenevalid_withdeps(self): |
207 | with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: | 239 | with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: |
208 | cmd = ["bitbake", "b1"] | 240 | cmd = ["bitbake", "b1"] |
@@ -213,6 +245,8 @@ class RunQueueTests(unittest.TestCase): | |||
213 | 'b1:packagedata_setscene', 'b1:package_qa_setscene', 'b1:populate_sysroot_setscene'] | 245 | 'b1:packagedata_setscene', 'b1:package_qa_setscene', 'b1:populate_sysroot_setscene'] |
214 | self.assertEqual(set(tasks), set(expected)) | 246 | self.assertEqual(set(tasks), set(expected)) |
215 | 247 | ||
248 | self.shutdown(tempdir) | ||
249 | |||
216 | def test_multiconfig_setscene_optimise(self): | 250 | def test_multiconfig_setscene_optimise(self): |
217 | with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: | 251 | with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: |
218 | extraenv = { | 252 | extraenv = { |
@@ -232,6 +266,8 @@ class RunQueueTests(unittest.TestCase): | |||
232 | expected.remove(x) | 266 | expected.remove(x) |
233 | self.assertEqual(set(tasks), set(expected)) | 267 | self.assertEqual(set(tasks), set(expected)) |
234 | 268 | ||
269 | self.shutdown(tempdir) | ||
270 | |||
235 | def test_multiconfig_bbmask(self): | 271 | def test_multiconfig_bbmask(self): |
236 | # This test validates that multiconfigs can independently mask off | 272 | # This test validates that multiconfigs can independently mask off |
237 | # recipes they do not want with BBMASK. It works by having recipes | 273 | # recipes they do not want with BBMASK. It works by having recipes |
@@ -248,11 +284,13 @@ class RunQueueTests(unittest.TestCase): | |||
248 | cmd = ["bitbake", "mc:mc-1:fails-mc2", "mc:mc_2:fails-mc1"] | 284 | cmd = ["bitbake", "mc:mc-1:fails-mc2", "mc:mc_2:fails-mc1"] |
249 | self.run_bitbakecmd(cmd, tempdir, "", extraenv=extraenv) | 285 | self.run_bitbakecmd(cmd, tempdir, "", extraenv=extraenv) |
250 | 286 | ||
287 | self.shutdown(tempdir) | ||
288 | |||
251 | def test_multiconfig_mcdepends(self): | 289 | def test_multiconfig_mcdepends(self): |
252 | with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: | 290 | with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: |
253 | extraenv = { | 291 | extraenv = { |
254 | "BBMULTICONFIG" : "mc-1 mc_2", | 292 | "BBMULTICONFIG" : "mc-1 mc_2", |
255 | "BB_SIGNATURE_HANDLER" : "TestMulticonfigDepends", | 293 | "BB_SIGNATURE_HANDLER" : "basichash", |
256 | "EXTRA_BBFILES": "${COREBASE}/recipes/fails-mc/*.bb", | 294 | "EXTRA_BBFILES": "${COREBASE}/recipes/fails-mc/*.bb", |
257 | } | 295 | } |
258 | tasks = self.run_bitbakecmd(["bitbake", "mc:mc-1:f1"], tempdir, "", extraenv=extraenv, cleanup=True) | 296 | tasks = self.run_bitbakecmd(["bitbake", "mc:mc-1:f1"], tempdir, "", extraenv=extraenv, cleanup=True) |
@@ -278,7 +316,15 @@ class RunQueueTests(unittest.TestCase): | |||
278 | ["mc_2:a1:%s" % t for t in rerun_tasks] | 316 | ["mc_2:a1:%s" % t for t in rerun_tasks] |
279 | self.assertEqual(set(tasks), set(expected)) | 317 | self.assertEqual(set(tasks), set(expected)) |
280 | 318 | ||
281 | @unittest.skipIf(sys.version_info < (3, 5, 0), 'Python 3.5 or later required') | 319 | # Check that a multiconfig that doesn't exist rasies a correct error message |
320 | error_output = self.run_bitbakecmd(["bitbake", "g1"], tempdir, "", extraenv=extraenv, cleanup=True, allowfailure=True) | ||
321 | self.assertIn("non-existent task", error_output) | ||
322 | # If the word 'Traceback' or 'KeyError' is in the output we've regressed | ||
323 | self.assertNotIn("Traceback", error_output) | ||
324 | self.assertNotIn("KeyError", error_output) | ||
325 | |||
326 | self.shutdown(tempdir) | ||
327 | |||
282 | def test_hashserv_single(self): | 328 | def test_hashserv_single(self): |
283 | with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: | 329 | with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: |
284 | extraenv = { | 330 | extraenv = { |
@@ -304,7 +350,6 @@ class RunQueueTests(unittest.TestCase): | |||
304 | 350 | ||
305 | self.shutdown(tempdir) | 351 | self.shutdown(tempdir) |
306 | 352 | ||
307 | @unittest.skipIf(sys.version_info < (3, 5, 0), 'Python 3.5 or later required') | ||
308 | def test_hashserv_double(self): | 353 | def test_hashserv_double(self): |
309 | with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: | 354 | with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: |
310 | extraenv = { | 355 | extraenv = { |
@@ -329,7 +374,6 @@ class RunQueueTests(unittest.TestCase): | |||
329 | 374 | ||
330 | self.shutdown(tempdir) | 375 | self.shutdown(tempdir) |
331 | 376 | ||
332 | @unittest.skipIf(sys.version_info < (3, 5, 0), 'Python 3.5 or later required') | ||
333 | def test_hashserv_multiple_setscene(self): | 377 | def test_hashserv_multiple_setscene(self): |
334 | # Runs e1:do_package_setscene twice | 378 | # Runs e1:do_package_setscene twice |
335 | with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: | 379 | with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: |
@@ -361,7 +405,6 @@ class RunQueueTests(unittest.TestCase): | |||
361 | 405 | ||
362 | def shutdown(self, tempdir): | 406 | def shutdown(self, tempdir): |
363 | # Wait for the hashserve socket to disappear else we'll see races with the tempdir cleanup | 407 | # Wait for the hashserve socket to disappear else we'll see races with the tempdir cleanup |
364 | while os.path.exists(tempdir + "/hashserve.sock"): | 408 | while (os.path.exists(tempdir + "/hashserve.sock") or os.path.exists(tempdir + "cache/hashserv.db-wal") or os.path.exists(tempdir + "/bitbake.lock")): |
365 | time.sleep(0.5) | 409 | time.sleep(0.5) |
366 | 410 | ||
367 | |||
diff --git a/bitbake/lib/bb/tests/siggen.py b/bitbake/lib/bb/tests/siggen.py index c21ab4e4fb..0dc67e6cc2 100644 --- a/bitbake/lib/bb/tests/siggen.py +++ b/bitbake/lib/bb/tests/siggen.py | |||
@@ -17,75 +17,12 @@ import bb.siggen | |||
17 | 17 | ||
18 | class SiggenTest(unittest.TestCase): | 18 | class SiggenTest(unittest.TestCase): |
19 | 19 | ||
20 | def test_clean_basepath_simple_target_basepath(self): | 20 | def test_build_pnid(self): |
21 | basepath = '/full/path/to/poky/meta/recipes-whatever/helloworld/helloworld_1.2.3.bb:do_sometask' | 21 | tests = { |
22 | expected_cleaned = 'helloworld/helloworld_1.2.3.bb:do_sometask' | 22 | ('', 'helloworld', 'do_sometask') : 'helloworld:do_sometask', |
23 | ('XX', 'helloworld', 'do_sometask') : 'mc:XX:helloworld:do_sometask', | ||
24 | } | ||
23 | 25 | ||
24 | actual_cleaned = bb.siggen.clean_basepath(basepath) | 26 | for t in tests: |
27 | self.assertEqual(bb.siggen.build_pnid(*t), tests[t]) | ||
25 | 28 | ||
26 | self.assertEqual(actual_cleaned, expected_cleaned) | ||
27 | |||
28 | def test_clean_basepath_basic_virtual_basepath(self): | ||
29 | basepath = 'virtual:something:/full/path/to/poky/meta/recipes-whatever/helloworld/helloworld_1.2.3.bb:do_sometask' | ||
30 | expected_cleaned = 'helloworld/helloworld_1.2.3.bb:do_sometask:virtual:something' | ||
31 | |||
32 | actual_cleaned = bb.siggen.clean_basepath(basepath) | ||
33 | |||
34 | self.assertEqual(actual_cleaned, expected_cleaned) | ||
35 | |||
36 | def test_clean_basepath_mc_basepath(self): | ||
37 | basepath = 'mc:somemachine:/full/path/to/poky/meta/recipes-whatever/helloworld/helloworld_1.2.3.bb:do_sometask' | ||
38 | expected_cleaned = 'helloworld/helloworld_1.2.3.bb:do_sometask:mc:somemachine' | ||
39 | |||
40 | actual_cleaned = bb.siggen.clean_basepath(basepath) | ||
41 | |||
42 | self.assertEqual(actual_cleaned, expected_cleaned) | ||
43 | |||
44 | def test_clean_basepath_virtual_long_prefix_basepath(self): | ||
45 | basepath = 'virtual:something:A:B:C:/full/path/to/poky/meta/recipes-whatever/helloworld/helloworld_1.2.3.bb:do_sometask' | ||
46 | expected_cleaned = 'helloworld/helloworld_1.2.3.bb:do_sometask:virtual:something:A:B:C' | ||
47 | |||
48 | actual_cleaned = bb.siggen.clean_basepath(basepath) | ||
49 | |||
50 | self.assertEqual(actual_cleaned, expected_cleaned) | ||
51 | |||
52 | def test_clean_basepath_mc_virtual_basepath(self): | ||
53 | basepath = 'mc:somemachine:virtual:something:/full/path/to/poky/meta/recipes-whatever/helloworld/helloworld_1.2.3.bb:do_sometask' | ||
54 | expected_cleaned = 'helloworld/helloworld_1.2.3.bb:do_sometask:virtual:something:mc:somemachine' | ||
55 | |||
56 | actual_cleaned = bb.siggen.clean_basepath(basepath) | ||
57 | |||
58 | self.assertEqual(actual_cleaned, expected_cleaned) | ||
59 | |||
60 | def test_clean_basepath_mc_virtual_long_prefix_basepath(self): | ||
61 | basepath = 'mc:X:virtual:something:C:B:A:/full/path/to/poky/meta/recipes-whatever/helloworld/helloworld_1.2.3.bb:do_sometask' | ||
62 | expected_cleaned = 'helloworld/helloworld_1.2.3.bb:do_sometask:virtual:something:C:B:A:mc:X' | ||
63 | |||
64 | actual_cleaned = bb.siggen.clean_basepath(basepath) | ||
65 | |||
66 | self.assertEqual(actual_cleaned, expected_cleaned) | ||
67 | |||
68 | |||
69 | # def test_clean_basepath_performance(self): | ||
70 | # input_basepaths = [ | ||
71 | # 'mc:X:/full/path/to/poky/meta/recipes-whatever/helloworld/helloworld_1.2.3.bb:do_sometask', | ||
72 | # 'mc:X:virtual:something:C:B:A:/full/path/to/poky/meta/recipes-whatever/helloworld/helloworld_1.2.3.bb:do_sometask', | ||
73 | # 'virtual:something:C:B:A:/different/path/to/poky/meta/recipes-whatever/helloworld/helloworld_1.2.3.bb:do_sometask', | ||
74 | # 'virtual:something:A:/full/path/to/poky/meta/recipes-whatever/helloworld/helloworld_1.2.3.bb:do_sometask', | ||
75 | # '/this/is/most/common/input/recipes-whatever/helloworld/helloworld_1.2.3.bb:do_sometask', | ||
76 | # '/and/should/be/tested/with/recipes-whatever/helloworld/helloworld_1.2.3.bb:do_sometask', | ||
77 | # '/more/weight/recipes-whatever/helloworld/helloworld_1.2.3.bb:do_sometask', | ||
78 | # ] | ||
79 | |||
80 | # time_start = time.time() | ||
81 | |||
82 | # i = 2000000 | ||
83 | # while i >= 0: | ||
84 | # for basepath in input_basepaths: | ||
85 | # bb.siggen.clean_basepath(basepath) | ||
86 | # i -= 1 | ||
87 | |||
88 | # elapsed = time.time() - time_start | ||
89 | # print('{} ({}s)'.format(self.id(), round(elapsed, 3))) | ||
90 | |||
91 | # self.assertTrue(False) | ||
diff --git a/bitbake/lib/bb/tests/utils.py b/bitbake/lib/bb/tests/utils.py index a7ff33db52..52b7bf85bf 100644 --- a/bitbake/lib/bb/tests/utils.py +++ b/bitbake/lib/bb/tests/utils.py | |||
@@ -130,6 +130,14 @@ class Checksum(unittest.TestCase): | |||
130 | checksum = bb.utils.sha256_file(f.name) | 130 | checksum = bb.utils.sha256_file(f.name) |
131 | self.assertEqual(checksum, "fcfbae8bf6b721dbb9d2dc6a9334a58f2031a9a9b302999243f99da4d7f12d0f") | 131 | self.assertEqual(checksum, "fcfbae8bf6b721dbb9d2dc6a9334a58f2031a9a9b302999243f99da4d7f12d0f") |
132 | 132 | ||
133 | def test_goh1(self): | ||
134 | import hashlib | ||
135 | with tempfile.NamedTemporaryFile() as f: | ||
136 | f.write(self.filler) | ||
137 | f.flush() | ||
138 | checksum = bb.utils.goh1_file(f.name) | ||
139 | self.assertEqual(checksum, "81191f04d4abf413e5badd234814e4202d9efa73e6f9437e9ddd6b8165b569ef") | ||
140 | |||
133 | class EditMetadataFile(unittest.TestCase): | 141 | class EditMetadataFile(unittest.TestCase): |
134 | _origfile = """ | 142 | _origfile = """ |
135 | # A comment | 143 | # A comment |
@@ -418,7 +426,7 @@ MULTILINE = " stuff \\ | |||
418 | ['MULTILINE'], | 426 | ['MULTILINE'], |
419 | handle_var) | 427 | handle_var) |
420 | 428 | ||
421 | testvalue = re.sub('\s+', ' ', value_in_callback.strip()) | 429 | testvalue = re.sub(r'\s+', ' ', value_in_callback.strip()) |
422 | self.assertEqual(expected_value, testvalue) | 430 | self.assertEqual(expected_value, testvalue) |
423 | 431 | ||
424 | class EditBbLayersConf(unittest.TestCase): | 432 | class EditBbLayersConf(unittest.TestCase): |
@@ -666,3 +674,32 @@ class GetReferencedVars(unittest.TestCase): | |||
666 | 674 | ||
667 | layers = [{"SRC_URI"}, {"QT_GIT", "QT_MODULE", "QT_MODULE_BRANCH_PARAM", "QT_GIT_PROTOCOL"}, {"QT_GIT_PROJECT", "QT_MODULE_BRANCH", "BPN"}, {"PN", "SPECIAL_PKGSUFFIX"}] | 675 | layers = [{"SRC_URI"}, {"QT_GIT", "QT_MODULE", "QT_MODULE_BRANCH_PARAM", "QT_GIT_PROTOCOL"}, {"QT_GIT_PROJECT", "QT_MODULE_BRANCH", "BPN"}, {"PN", "SPECIAL_PKGSUFFIX"}] |
668 | self.check_referenced("${SRC_URI}", layers) | 676 | self.check_referenced("${SRC_URI}", layers) |
677 | |||
678 | |||
679 | class EnvironmentTests(unittest.TestCase): | ||
680 | def test_environment(self): | ||
681 | os.environ["A"] = "this is A" | ||
682 | self.assertIn("A", os.environ) | ||
683 | self.assertEqual(os.environ["A"], "this is A") | ||
684 | self.assertNotIn("B", os.environ) | ||
685 | |||
686 | with bb.utils.environment(B="this is B"): | ||
687 | self.assertIn("A", os.environ) | ||
688 | self.assertEqual(os.environ["A"], "this is A") | ||
689 | self.assertIn("B", os.environ) | ||
690 | self.assertEqual(os.environ["B"], "this is B") | ||
691 | |||
692 | self.assertIn("A", os.environ) | ||
693 | self.assertEqual(os.environ["A"], "this is A") | ||
694 | self.assertNotIn("B", os.environ) | ||
695 | |||
696 | class FilemodeTests(unittest.TestCase): | ||
697 | def test_filemode_convert(self): | ||
698 | self.assertEqual(0o775, bb.utils.to_filemode("0o775")) | ||
699 | self.assertEqual(0o775, bb.utils.to_filemode(0o775)) | ||
700 | self.assertEqual(0o775, bb.utils.to_filemode("775")) | ||
701 | with self.assertRaises(ValueError): | ||
702 | bb.utils.to_filemode("xyz") | ||
703 | with self.assertRaises(ValueError): | ||
704 | bb.utils.to_filemode("999") | ||
705 | |||