blob: 85c1f79ff32c9e25722ab7a311b5be98ddefdd13 [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001#
2# BitBake Tests for the Fetcher (fetch2/)
3#
4# Copyright (C) 2012 Richard Purdie
5#
Brad Bishopc342db32019-05-15 21:57:59 -04006# SPDX-License-Identifier: GPL-2.0-only
Patrick Williamsc124f4f2015-09-15 14:41:29 -05007#
8
Patrick Williams39653562024-03-01 08:54:02 -06009import contextlib
Patrick Williamsc124f4f2015-09-15 14:41:29 -050010import unittest
Brad Bishop316dfdd2018-06-25 12:45:53 -040011import hashlib
Patrick Williamsc124f4f2015-09-15 14:41:29 -050012import tempfile
Patrick Williamsc0f7c042017-02-23 20:41:17 -060013import collections
Patrick Williamsc124f4f2015-09-15 14:41:29 -050014import os
Patrick Williams92b42cb2022-09-03 06:53:57 -050015import signal
Andrew Geissler9aee5002022-03-30 16:27:02 +000016import tarfile
Patrick Williamsc124f4f2015-09-15 14:41:29 -050017from bb.fetch2 import URI
18from bb.fetch2 import FetchMethod
19import bb
Andrew Geissler82c905d2020-04-13 13:39:40 -050020from bb.tests.support.httpserver import HTTPService
Patrick Williamsc124f4f2015-09-15 14:41:29 -050021
Brad Bishopd7bf8c12018-02-25 22:55:05 -050022def skipIfNoNetwork():
23 if os.environ.get("BB_SKIP_NETTESTS") == "yes":
Andrew Geissler7e0e3c02022-02-25 20:34:39 +000024 return unittest.skip("network test")
Brad Bishopd7bf8c12018-02-25 22:55:05 -050025 return lambda f: f
26
Patrick Williams92b42cb2022-09-03 06:53:57 -050027class TestTimeout(Exception):
Andrew Geissler8f840682023-07-21 09:09:43 -050028 # Indicate to pytest that this is not a test suite
29 __test__ = False
Patrick Williams92b42cb2022-09-03 06:53:57 -050030
31class Timeout():
32
33 def __init__(self, seconds):
34 self.seconds = seconds
35
36 def handle_timeout(self, signum, frame):
37 raise TestTimeout("Test failed: timeout reached")
38
39 def __enter__(self):
40 signal.signal(signal.SIGALRM, self.handle_timeout)
41 signal.alarm(self.seconds)
42
43 def __exit__(self, exc_type, exc_val, exc_tb):
44 signal.alarm(0)
45
Patrick Williamsc124f4f2015-09-15 14:41:29 -050046class URITest(unittest.TestCase):
47 test_uris = {
48 "http://www.google.com/index.html" : {
49 'uri': 'http://www.google.com/index.html',
50 'scheme': 'http',
51 'hostname': 'www.google.com',
52 'port': None,
53 'hostport': 'www.google.com',
54 'path': '/index.html',
55 'userinfo': '',
56 'username': '',
57 'password': '',
58 'params': {},
59 'query': {},
60 'relative': False
61 },
62 "http://www.google.com/index.html;param1=value1" : {
63 'uri': 'http://www.google.com/index.html;param1=value1',
64 'scheme': 'http',
65 'hostname': 'www.google.com',
66 'port': None,
67 'hostport': 'www.google.com',
68 'path': '/index.html',
69 'userinfo': '',
70 'username': '',
71 'password': '',
72 'params': {
73 'param1': 'value1'
74 },
75 'query': {},
76 'relative': False
77 },
78 "http://www.example.org/index.html?param1=value1" : {
79 'uri': 'http://www.example.org/index.html?param1=value1',
80 'scheme': 'http',
81 'hostname': 'www.example.org',
82 'port': None,
83 'hostport': 'www.example.org',
84 'path': '/index.html',
85 'userinfo': '',
86 'username': '',
87 'password': '',
88 'params': {},
89 'query': {
90 'param1': 'value1'
91 },
92 'relative': False
93 },
94 "http://www.example.org/index.html?qparam1=qvalue1;param2=value2" : {
95 'uri': 'http://www.example.org/index.html?qparam1=qvalue1;param2=value2',
96 'scheme': 'http',
97 'hostname': 'www.example.org',
98 'port': None,
99 'hostport': 'www.example.org',
100 'path': '/index.html',
101 'userinfo': '',
102 'username': '',
103 'password': '',
104 'params': {
105 'param2': 'value2'
106 },
107 'query': {
108 'qparam1': 'qvalue1'
109 },
110 'relative': False
111 },
Andrew Geisslerd1e89492021-02-12 15:35:20 -0600112 # Check that trailing semicolons are handled correctly
113 "http://www.example.org/index.html?qparam1=qvalue1;param2=value2;" : {
114 'uri': 'http://www.example.org/index.html?qparam1=qvalue1;param2=value2',
115 'scheme': 'http',
116 'hostname': 'www.example.org',
117 'port': None,
118 'hostport': 'www.example.org',
119 'path': '/index.html',
120 'userinfo': '',
121 'username': '',
122 'password': '',
123 'params': {
124 'param2': 'value2'
125 },
126 'query': {
127 'qparam1': 'qvalue1'
128 },
129 'relative': False
130 },
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500131 "http://www.example.com:8080/index.html" : {
132 'uri': 'http://www.example.com:8080/index.html',
133 'scheme': 'http',
134 'hostname': 'www.example.com',
135 'port': 8080,
136 'hostport': 'www.example.com:8080',
137 'path': '/index.html',
138 'userinfo': '',
139 'username': '',
140 'password': '',
141 'params': {},
142 'query': {},
143 'relative': False
144 },
145 "cvs://anoncvs@cvs.handhelds.org/cvs;module=familiar/dist/ipkg" : {
146 'uri': 'cvs://anoncvs@cvs.handhelds.org/cvs;module=familiar/dist/ipkg',
147 'scheme': 'cvs',
148 'hostname': 'cvs.handhelds.org',
149 'port': None,
150 'hostport': 'cvs.handhelds.org',
151 'path': '/cvs',
152 'userinfo': 'anoncvs',
153 'username': 'anoncvs',
154 'password': '',
155 'params': {
156 'module': 'familiar/dist/ipkg'
157 },
158 'query': {},
159 'relative': False
160 },
161 "cvs://anoncvs:anonymous@cvs.handhelds.org/cvs;tag=V0-99-81;module=familiar/dist/ipkg": {
162 'uri': 'cvs://anoncvs:anonymous@cvs.handhelds.org/cvs;tag=V0-99-81;module=familiar/dist/ipkg',
163 'scheme': 'cvs',
164 'hostname': 'cvs.handhelds.org',
165 'port': None,
166 'hostport': 'cvs.handhelds.org',
167 'path': '/cvs',
168 'userinfo': 'anoncvs:anonymous',
169 'username': 'anoncvs',
170 'password': 'anonymous',
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600171 'params': collections.OrderedDict([
172 ('tag', 'V0-99-81'),
173 ('module', 'familiar/dist/ipkg')
174 ]),
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500175 'query': {},
176 'relative': False
177 },
178 "file://example.diff": { # NOTE: Not RFC compliant!
179 'uri': 'file:example.diff',
180 'scheme': 'file',
181 'hostname': '',
182 'port': None,
183 'hostport': '',
184 'path': 'example.diff',
185 'userinfo': '',
186 'username': '',
187 'password': '',
188 'params': {},
189 'query': {},
190 'relative': True
191 },
192 "file:example.diff": { # NOTE: RFC compliant version of the former
193 'uri': 'file:example.diff',
194 'scheme': 'file',
195 'hostname': '',
196 'port': None,
197 'hostport': '',
198 'path': 'example.diff',
199 'userinfo': '',
200 'userinfo': '',
201 'username': '',
202 'password': '',
203 'params': {},
204 'query': {},
205 'relative': True
206 },
207 "file:///tmp/example.diff": {
208 'uri': 'file:///tmp/example.diff',
209 'scheme': 'file',
210 'hostname': '',
211 'port': None,
212 'hostport': '',
213 'path': '/tmp/example.diff',
214 'userinfo': '',
215 'userinfo': '',
216 'username': '',
217 'password': '',
218 'params': {},
219 'query': {},
220 'relative': False
221 },
222 "git:///path/example.git": {
223 'uri': 'git:///path/example.git',
224 'scheme': 'git',
225 'hostname': '',
226 'port': None,
227 'hostport': '',
228 'path': '/path/example.git',
229 'userinfo': '',
230 'userinfo': '',
231 'username': '',
232 'password': '',
233 'params': {},
234 'query': {},
235 'relative': False
236 },
237 "git:path/example.git": {
238 'uri': 'git:path/example.git',
239 'scheme': 'git',
240 'hostname': '',
241 'port': None,
242 'hostport': '',
243 'path': 'path/example.git',
244 'userinfo': '',
245 'userinfo': '',
246 'username': '',
247 'password': '',
248 'params': {},
249 'query': {},
250 'relative': True
251 },
252 "git://example.net/path/example.git": {
253 'uri': 'git://example.net/path/example.git',
254 'scheme': 'git',
255 'hostname': 'example.net',
256 'port': None,
257 'hostport': 'example.net',
258 'path': '/path/example.git',
259 'userinfo': '',
260 'userinfo': '',
261 'username': '',
262 'password': '',
263 'params': {},
264 'query': {},
265 'relative': False
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500266 },
Andrew Geisslerc3d88e42020-10-02 09:45:00 -0500267 "git://tfs-example.org:22/tfs/example%20path/example.git": {
268 'uri': 'git://tfs-example.org:22/tfs/example%20path/example.git',
269 'scheme': 'git',
270 'hostname': 'tfs-example.org',
271 'port': 22,
272 'hostport': 'tfs-example.org:22',
273 'path': '/tfs/example path/example.git',
274 'userinfo': '',
275 'userinfo': '',
276 'username': '',
277 'password': '',
278 'params': {},
279 'query': {},
280 'relative': False
281 },
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500282 "http://somesite.net;someparam=1": {
283 'uri': 'http://somesite.net;someparam=1',
284 'scheme': 'http',
285 'hostname': 'somesite.net',
286 'port': None,
287 'hostport': 'somesite.net',
288 'path': '',
289 'userinfo': '',
290 'userinfo': '',
291 'username': '',
292 'password': '',
293 'params': {"someparam" : "1"},
294 'query': {},
295 'relative': False
296 },
297 "file://somelocation;someparam=1": {
298 'uri': 'file:somelocation;someparam=1',
299 'scheme': 'file',
300 'hostname': '',
301 'port': None,
302 'hostport': '',
303 'path': 'somelocation',
304 'userinfo': '',
305 'userinfo': '',
306 'username': '',
307 'password': '',
308 'params': {"someparam" : "1"},
309 'query': {},
310 'relative': True
Patrick Williams03514f12024-04-05 07:04:11 -0500311 },
312 "https://www.innodisk.com/Download_file?9BE0BF6657;downloadfilename=EGPL-T101.zip": {
313 'uri': 'https://www.innodisk.com/Download_file?9BE0BF6657;downloadfilename=EGPL-T101.zip',
314 'scheme': 'https',
315 'hostname': 'www.innodisk.com',
316 'port': None,
317 'hostport': 'www.innodisk.com',
318 'path': '/Download_file',
319 'userinfo': '',
320 'userinfo': '',
321 'username': '',
322 'password': '',
323 'params': {"downloadfilename" : "EGPL-T101.zip"},
324 'query': {"9BE0BF6657": None},
325 'relative': False
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500326 }
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500327
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500328 }
329
330 def test_uri(self):
331 for test_uri, ref in self.test_uris.items():
332 uri = URI(test_uri)
333
334 self.assertEqual(str(uri), ref['uri'])
335
336 # expected attributes
337 self.assertEqual(uri.scheme, ref['scheme'])
338
339 self.assertEqual(uri.userinfo, ref['userinfo'])
340 self.assertEqual(uri.username, ref['username'])
341 self.assertEqual(uri.password, ref['password'])
342
343 self.assertEqual(uri.hostname, ref['hostname'])
344 self.assertEqual(uri.port, ref['port'])
345 self.assertEqual(uri.hostport, ref['hostport'])
346
347 self.assertEqual(uri.path, ref['path'])
348 self.assertEqual(uri.params, ref['params'])
349
350 self.assertEqual(uri.relative, ref['relative'])
351
352 def test_dict(self):
353 for test in self.test_uris.values():
354 uri = URI()
355
356 self.assertEqual(uri.scheme, '')
357 self.assertEqual(uri.userinfo, '')
358 self.assertEqual(uri.username, '')
359 self.assertEqual(uri.password, '')
360 self.assertEqual(uri.hostname, '')
361 self.assertEqual(uri.port, None)
362 self.assertEqual(uri.path, '')
363 self.assertEqual(uri.params, {})
364
365
366 uri.scheme = test['scheme']
367 self.assertEqual(uri.scheme, test['scheme'])
368
369 uri.userinfo = test['userinfo']
370 self.assertEqual(uri.userinfo, test['userinfo'])
371 self.assertEqual(uri.username, test['username'])
372 self.assertEqual(uri.password, test['password'])
373
374 # make sure changing the values doesn't do anything unexpected
375 uri.username = 'changeme'
376 self.assertEqual(uri.username, 'changeme')
377 self.assertEqual(uri.password, test['password'])
378 uri.password = 'insecure'
379 self.assertEqual(uri.username, 'changeme')
380 self.assertEqual(uri.password, 'insecure')
381
382 # reset back after our trickery
383 uri.userinfo = test['userinfo']
384 self.assertEqual(uri.userinfo, test['userinfo'])
385 self.assertEqual(uri.username, test['username'])
386 self.assertEqual(uri.password, test['password'])
387
388 uri.hostname = test['hostname']
389 self.assertEqual(uri.hostname, test['hostname'])
390 self.assertEqual(uri.hostport, test['hostname'])
391
392 uri.port = test['port']
393 self.assertEqual(uri.port, test['port'])
394 self.assertEqual(uri.hostport, test['hostport'])
395
396 uri.path = test['path']
397 self.assertEqual(uri.path, test['path'])
398
399 uri.params = test['params']
400 self.assertEqual(uri.params, test['params'])
401
402 uri.query = test['query']
403 self.assertEqual(uri.query, test['query'])
404
405 self.assertEqual(str(uri), test['uri'])
406
407 uri.params = {}
408 self.assertEqual(uri.params, {})
409 self.assertEqual(str(uri), (str(uri).split(";"))[0])
410
411class FetcherTest(unittest.TestCase):
412
413 def setUp(self):
414 self.origdir = os.getcwd()
415 self.d = bb.data.init()
Andrew Geisslereff27472021-10-29 15:35:00 -0500416 self.tempdir = tempfile.mkdtemp(prefix="bitbake-fetch-")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500417 self.dldir = os.path.join(self.tempdir, "download")
418 os.mkdir(self.dldir)
419 self.d.setVar("DL_DIR", self.dldir)
420 self.unpackdir = os.path.join(self.tempdir, "unpacked")
421 os.mkdir(self.unpackdir)
422 persistdir = os.path.join(self.tempdir, "persistdata")
423 self.d.setVar("PERSISTENT_DIR", persistdir)
424
425 def tearDown(self):
426 os.chdir(self.origdir)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600427 if os.environ.get("BB_TMPDIR_NOCLEAN") == "yes":
428 print("Not cleaning up %s. Please remove manually." % self.tempdir)
429 else:
Andrew Geisslerc926e172021-05-07 16:11:35 -0500430 bb.process.run('chmod u+rw -R %s' % self.tempdir)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600431 bb.utils.prunedir(self.tempdir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500432
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000433 def git(self, cmd, cwd=None):
434 if isinstance(cmd, str):
Patrick Williams73bd93f2024-02-20 08:07:48 -0600435 cmd = 'git -c safe.bareRepository=all ' + cmd
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000436 else:
Patrick Williams73bd93f2024-02-20 08:07:48 -0600437 cmd = ['git', '-c', 'safe.bareRepository=all'] + cmd
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000438 if cwd is None:
439 cwd = self.gitdir
440 return bb.process.run(cmd, cwd=cwd)[0]
441
442 def git_init(self, cwd=None):
443 self.git('init', cwd=cwd)
Patrick Williamse760df82023-05-26 11:10:49 -0500444 # Explicitly set initial branch to master as
445 # a common setup is to use other default
446 # branch than master.
447 self.git(['checkout', '-b', 'master'], cwd=cwd)
Andrew Geissler8f840682023-07-21 09:09:43 -0500448
449 try:
450 self.git(['config', 'user.email'], cwd=cwd)
451 except bb.process.ExecutionError:
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000452 self.git(['config', 'user.email', 'you@example.com'], cwd=cwd)
Andrew Geissler8f840682023-07-21 09:09:43 -0500453
454 try:
455 self.git(['config', 'user.name'], cwd=cwd)
456 except bb.process.ExecutionError:
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000457 self.git(['config', 'user.name', 'Your Name'], cwd=cwd)
458
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500459class MirrorUriTest(FetcherTest):
460
461 replaceuris = {
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000462 ("git://git.invalid.infradead.org/mtd-utils.git;tag=1234567890123456789012345678901234567890", "git://.*/.*", "http://somewhere.org/somedir/")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500463 : "http://somewhere.org/somedir/git2_git.invalid.infradead.org.mtd-utils.git.tar.gz",
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000464 ("git://git.invalid.infradead.org/mtd-utils.git;tag=1234567890123456789012345678901234567890", "git://.*/([^/]+/)*([^/]*)", "git://somewhere.org/somedir/\\2;protocol=http")
465 : "git://somewhere.org/somedir/mtd-utils.git;tag=1234567890123456789012345678901234567890;protocol=http",
466 ("git://git.invalid.infradead.org/foo/mtd-utils.git;tag=1234567890123456789012345678901234567890", "git://.*/([^/]+/)*([^/]*)", "git://somewhere.org/somedir/\\2;protocol=http")
467 : "git://somewhere.org/somedir/mtd-utils.git;tag=1234567890123456789012345678901234567890;protocol=http",
468 ("git://git.invalid.infradead.org/foo/mtd-utils.git;tag=1234567890123456789012345678901234567890", "git://.*/([^/]+/)*([^/]*)", "git://somewhere.org/\\2;protocol=http")
469 : "git://somewhere.org/mtd-utils.git;tag=1234567890123456789012345678901234567890;protocol=http",
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500470 ("git://someserver.org/bitbake;tag=1234567890123456789012345678901234567890", "git://someserver.org/bitbake", "git://git.openembedded.org/bitbake")
471 : "git://git.openembedded.org/bitbake;tag=1234567890123456789012345678901234567890",
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000472 ("file://sstate-xyz.tgz", "file://.*", "file:///somewhere/1234/sstate-cache")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500473 : "file:///somewhere/1234/sstate-cache/sstate-xyz.tgz",
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000474 ("file://sstate-xyz.tgz", "file://.*", "file:///somewhere/1234/sstate-cache/")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500475 : "file:///somewhere/1234/sstate-cache/sstate-xyz.tgz",
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000476 ("http://somewhere.org/somedir1/somedir2/somefile_1.2.3.tar.gz", "http://.*/.*", "http://somewhere2.org/somedir3")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500477 : "http://somewhere2.org/somedir3/somefile_1.2.3.tar.gz",
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000478 ("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")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500479 : "http://somewhere2.org/somedir3/somefile_1.2.3.tar.gz",
480 ("http://www.apache.org/dist/subversion/subversion-1.7.1.tar.bz2", "http://www.apache.org/dist", "http://archive.apache.org/dist")
481 : "http://archive.apache.org/dist/subversion/subversion-1.7.1.tar.bz2",
482 ("http://www.apache.org/dist/subversion/subversion-1.7.1.tar.bz2", "http://.*/.*", "file:///somepath/downloads/")
483 : "file:///somepath/downloads/subversion-1.7.1.tar.bz2",
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000484 ("git://git.invalid.infradead.org/mtd-utils.git;tag=1234567890123456789012345678901234567890", "git://.*/.*", "git://somewhere.org/somedir/BASENAME;protocol=http")
485 : "git://somewhere.org/somedir/mtd-utils.git;tag=1234567890123456789012345678901234567890;protocol=http",
486 ("git://git.invalid.infradead.org/foo/mtd-utils.git;tag=1234567890123456789012345678901234567890", "git://.*/.*", "git://somewhere.org/somedir/BASENAME;protocol=http")
487 : "git://somewhere.org/somedir/mtd-utils.git;tag=1234567890123456789012345678901234567890;protocol=http",
488 ("git://git.invalid.infradead.org/foo/mtd-utils.git;tag=1234567890123456789012345678901234567890", "git://.*/.*", "git://somewhere.org/somedir/MIRRORNAME;protocol=http")
489 : "git://somewhere.org/somedir/git.invalid.infradead.org.foo.mtd-utils.git;tag=1234567890123456789012345678901234567890;protocol=http",
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800490 ("http://somewhere.org/somedir1/somedir2/somefile_1.2.3.tar.gz", "http://.*/.*", "http://somewhere2.org")
491 : "http://somewhere2.org/somefile_1.2.3.tar.gz",
492 ("http://somewhere.org/somedir1/somedir2/somefile_1.2.3.tar.gz", "http://.*/.*", "http://somewhere2.org/")
493 : "http://somewhere2.org/somefile_1.2.3.tar.gz",
494 ("git://someserver.org/bitbake;tag=1234567890123456789012345678901234567890;branch=master", "git://someserver.org/bitbake;branch=master", "git://git.openembedded.org/bitbake;protocol=http")
495 : "git://git.openembedded.org/bitbake;tag=1234567890123456789012345678901234567890;branch=master;protocol=http",
Andrew Geissler595f6302022-01-24 19:11:47 +0000496 ("git://user1@someserver.org/bitbake;tag=1234567890123456789012345678901234567890;branch=master", "git://someserver.org/bitbake;branch=master", "git://user2@git.openembedded.org/bitbake;protocol=http")
497 : "git://user2@git.openembedded.org/bitbake;tag=1234567890123456789012345678901234567890;branch=master;protocol=http",
498 ("git://someserver.org/bitbake;tag=1234567890123456789012345678901234567890;protocol=git;branch=master", "git://someserver.org/bitbake", "git://someotherserver.org/bitbake;protocol=https")
499 : "git://someotherserver.org/bitbake;tag=1234567890123456789012345678901234567890;protocol=https;branch=master",
Andrew Geissler595f6302022-01-24 19:11:47 +0000500 ("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",
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000501 ("https://somewhere.org/example/1.0.0/example;downloadfilename=some-example-1.0.0.tgz", "https://.*/.*", "file:///mirror/PATH")
502 : "file:///mirror/example/1.0.0/some-example-1.0.0.tgz;downloadfilename=some-example-1.0.0.tgz",
503 ("https://somewhere.org/example-1.0.0.tgz;downloadfilename=some-example-1.0.0.tgz", "https://.*/.*", "file:///mirror/some-example-1.0.0.tgz")
504 : "file:///mirror/some-example-1.0.0.tgz;downloadfilename=some-example-1.0.0.tgz",
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500505
506 #Renaming files doesn't work
507 #("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"
508 #("file://sstate-xyz.tgz", "file://.*/.*", "file:///somewhere/1234/sstate-cache") : "file:///somewhere/1234/sstate-cache/sstate-xyz.tgz",
509 }
510
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000511 mirrorvar = "http://.*/.* file:///somepath/downloads/ " \
512 "git://someserver.org/bitbake git://git.openembedded.org/bitbake " \
513 "https://.*/.* file:///someotherpath/downloads/ " \
514 "http://.*/.* file:///someotherpath/downloads/"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500515
516 def test_urireplace(self):
Andrew Geissler615f2f12022-07-15 14:00:58 -0500517 self.d.setVar("FILESPATH", ".")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500518 for k, v in self.replaceuris.items():
519 ud = bb.fetch.FetchData(k[0], self.d)
520 ud.setup_localpath(self.d)
521 mirrors = bb.fetch2.mirror_from_string("%s %s" % (k[1], k[2]))
522 newuris, uds = bb.fetch2.build_mirroruris(ud, mirrors, self.d)
523 self.assertEqual([v], newuris)
524
525 def test_urilist1(self):
526 fetcher = bb.fetch.FetchData("http://downloads.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz", self.d)
527 mirrors = bb.fetch2.mirror_from_string(self.mirrorvar)
528 uris, uds = bb.fetch2.build_mirroruris(fetcher, mirrors, self.d)
529 self.assertEqual(uris, ['file:///somepath/downloads/bitbake-1.0.tar.gz', 'file:///someotherpath/downloads/bitbake-1.0.tar.gz'])
530
531 def test_urilist2(self):
532 # Catch https:// -> files:// bug
533 fetcher = bb.fetch.FetchData("https://downloads.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz", self.d)
534 mirrors = bb.fetch2.mirror_from_string(self.mirrorvar)
535 uris, uds = bb.fetch2.build_mirroruris(fetcher, mirrors, self.d)
536 self.assertEqual(uris, ['file:///someotherpath/downloads/bitbake-1.0.tar.gz'])
537
538 def test_mirror_of_mirror(self):
539 # Test if mirror of a mirror works
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000540 mirrorvar = self.mirrorvar + " http://.*/.* http://otherdownloads.yoctoproject.org/downloads/"
541 mirrorvar = mirrorvar + " http://otherdownloads.yoctoproject.org/.* http://downloads2.yoctoproject.org/downloads/"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500542 fetcher = bb.fetch.FetchData("http://downloads.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz", self.d)
543 mirrors = bb.fetch2.mirror_from_string(mirrorvar)
544 uris, uds = bb.fetch2.build_mirroruris(fetcher, mirrors, self.d)
545 self.assertEqual(uris, ['file:///somepath/downloads/bitbake-1.0.tar.gz',
546 'file:///someotherpath/downloads/bitbake-1.0.tar.gz',
547 'http://otherdownloads.yoctoproject.org/downloads/bitbake-1.0.tar.gz',
548 'http://downloads2.yoctoproject.org/downloads/bitbake-1.0.tar.gz'])
549
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000550 recmirrorvar = "https://.*/[^/]* http://AAAA/A/A/A/ " \
551 "https://.*/[^/]* https://BBBB/B/B/B/"
Patrick Williamsd7e96312015-09-22 08:09:05 -0500552
553 def test_recursive(self):
554 fetcher = bb.fetch.FetchData("https://downloads.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz", self.d)
555 mirrors = bb.fetch2.mirror_from_string(self.recmirrorvar)
556 uris, uds = bb.fetch2.build_mirroruris(fetcher, mirrors, self.d)
557 self.assertEqual(uris, ['http://AAAA/A/A/A/bitbake/bitbake-1.0.tar.gz',
558 'https://BBBB/B/B/B/bitbake/bitbake-1.0.tar.gz',
559 'http://AAAA/A/A/A/B/B/bitbake/bitbake-1.0.tar.gz'])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500560
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800561
562class GitDownloadDirectoryNamingTest(FetcherTest):
563 def setUp(self):
564 super(GitDownloadDirectoryNamingTest, self).setUp()
Andrew Geissler028142b2023-05-05 11:29:21 -0500565 self.recipe_url = "git://git.openembedded.org/bitbake;branch=master;protocol=https"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800566 self.recipe_dir = "git.openembedded.org.bitbake"
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000567 self.mirror_url = "git://github.com/openembedded/bitbake.git;protocol=https;branch=master"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800568 self.mirror_dir = "github.com.openembedded.bitbake.git"
569
570 self.d.setVar('SRCREV', '82ea737a0b42a8b53e11c9cde141e9e9c0bd8c40')
571
572 def setup_mirror_rewrite(self):
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000573 self.d.setVar("PREMIRRORS", self.recipe_url + " " + self.mirror_url)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800574
575 @skipIfNoNetwork()
576 def test_that_directory_is_named_after_recipe_url_when_no_mirroring_is_used(self):
577 self.setup_mirror_rewrite()
578 fetcher = bb.fetch.Fetch([self.recipe_url], self.d)
579
580 fetcher.download()
581
582 dir = os.listdir(self.dldir + "/git2")
583 self.assertIn(self.recipe_dir, dir)
584
585 @skipIfNoNetwork()
586 def test_that_directory_exists_for_mirrored_url_and_recipe_url_when_mirroring_is_used(self):
587 self.setup_mirror_rewrite()
588 fetcher = bb.fetch.Fetch([self.recipe_url], self.d)
589
590 fetcher.download()
591
592 dir = os.listdir(self.dldir + "/git2")
593 self.assertIn(self.mirror_dir, dir)
594 self.assertIn(self.recipe_dir, dir)
595
596 @skipIfNoNetwork()
597 def test_that_recipe_directory_and_mirrored_directory_exists_when_mirroring_is_used_and_the_mirrored_directory_already_exists(self):
598 self.setup_mirror_rewrite()
599 fetcher = bb.fetch.Fetch([self.mirror_url], self.d)
600 fetcher.download()
601 fetcher = bb.fetch.Fetch([self.recipe_url], self.d)
602
603 fetcher.download()
604
605 dir = os.listdir(self.dldir + "/git2")
606 self.assertIn(self.mirror_dir, dir)
607 self.assertIn(self.recipe_dir, dir)
608
609
610class TarballNamingTest(FetcherTest):
611 def setUp(self):
612 super(TarballNamingTest, self).setUp()
Andrew Geissler028142b2023-05-05 11:29:21 -0500613 self.recipe_url = "git://git.openembedded.org/bitbake;branch=master;protocol=https"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800614 self.recipe_tarball = "git2_git.openembedded.org.bitbake.tar.gz"
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000615 self.mirror_url = "git://github.com/openembedded/bitbake.git;protocol=https;branch=master"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800616 self.mirror_tarball = "git2_github.com.openembedded.bitbake.git.tar.gz"
617
618 self.d.setVar('BB_GENERATE_MIRROR_TARBALLS', '1')
619 self.d.setVar('SRCREV', '82ea737a0b42a8b53e11c9cde141e9e9c0bd8c40')
620
621 def setup_mirror_rewrite(self):
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000622 self.d.setVar("PREMIRRORS", self.recipe_url + " " + self.mirror_url)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800623
624 @skipIfNoNetwork()
625 def test_that_the_recipe_tarball_is_created_when_no_mirroring_is_used(self):
626 fetcher = bb.fetch.Fetch([self.recipe_url], self.d)
627
628 fetcher.download()
629
630 dir = os.listdir(self.dldir)
631 self.assertIn(self.recipe_tarball, dir)
632
633 @skipIfNoNetwork()
634 def test_that_the_mirror_tarball_is_created_when_mirroring_is_used(self):
635 self.setup_mirror_rewrite()
636 fetcher = bb.fetch.Fetch([self.recipe_url], self.d)
637
638 fetcher.download()
639
640 dir = os.listdir(self.dldir)
641 self.assertIn(self.mirror_tarball, dir)
642
643
644class GitShallowTarballNamingTest(FetcherTest):
645 def setUp(self):
646 super(GitShallowTarballNamingTest, self).setUp()
Andrew Geissler028142b2023-05-05 11:29:21 -0500647 self.recipe_url = "git://git.openembedded.org/bitbake;branch=master;protocol=https"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800648 self.recipe_tarball = "gitshallow_git.openembedded.org.bitbake_82ea737-1_master.tar.gz"
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000649 self.mirror_url = "git://github.com/openembedded/bitbake.git;protocol=https;branch=master"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800650 self.mirror_tarball = "gitshallow_github.com.openembedded.bitbake.git_82ea737-1_master.tar.gz"
651
652 self.d.setVar('BB_GIT_SHALLOW', '1')
653 self.d.setVar('BB_GENERATE_SHALLOW_TARBALLS', '1')
654 self.d.setVar('SRCREV', '82ea737a0b42a8b53e11c9cde141e9e9c0bd8c40')
655
656 def setup_mirror_rewrite(self):
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000657 self.d.setVar("PREMIRRORS", self.recipe_url + " " + self.mirror_url)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800658
659 @skipIfNoNetwork()
660 def test_that_the_tarball_is_named_after_recipe_url_when_no_mirroring_is_used(self):
661 fetcher = bb.fetch.Fetch([self.recipe_url], self.d)
662
663 fetcher.download()
664
665 dir = os.listdir(self.dldir)
666 self.assertIn(self.recipe_tarball, dir)
667
668 @skipIfNoNetwork()
669 def test_that_the_mirror_tarball_is_created_when_mirroring_is_used(self):
670 self.setup_mirror_rewrite()
671 fetcher = bb.fetch.Fetch([self.recipe_url], self.d)
672
673 fetcher.download()
674
675 dir = os.listdir(self.dldir)
676 self.assertIn(self.mirror_tarball, dir)
677
678
Andrew Geissler9aee5002022-03-30 16:27:02 +0000679class CleanTarballTest(FetcherTest):
680 def setUp(self):
681 super(CleanTarballTest, self).setUp()
Andrew Geissler028142b2023-05-05 11:29:21 -0500682 self.recipe_url = "git://git.openembedded.org/bitbake;protocol=https"
Andrew Geissler9aee5002022-03-30 16:27:02 +0000683 self.recipe_tarball = "git2_git.openembedded.org.bitbake.tar.gz"
684
685 self.d.setVar('BB_GENERATE_MIRROR_TARBALLS', '1')
686 self.d.setVar('SRCREV', '82ea737a0b42a8b53e11c9cde141e9e9c0bd8c40')
687
688 @skipIfNoNetwork()
689 def test_that_the_tarball_contents_does_not_leak_info(self):
690 fetcher = bb.fetch.Fetch([self.recipe_url], self.d)
691
692 fetcher.download()
693
694 fetcher.unpack(self.unpackdir)
695 mtime = bb.process.run('git log --all -1 --format=%ct',
696 cwd=os.path.join(self.unpackdir, 'git'))
697 self.assertEqual(len(mtime), 2)
698 mtime = int(mtime[0])
699
700 archive = tarfile.open(os.path.join(self.dldir, self.recipe_tarball))
701 self.assertNotEqual(len(archive.members), 0)
702 for member in archive.members:
Andrew Geissler20137392023-10-12 04:59:14 -0600703 if member.name == ".":
704 continue
705 self.assertEqual(member.uname, 'oe', "user name for %s differs" % member.name)
706 self.assertEqual(member.uid, 0, "uid for %s differs" % member.name)
707 self.assertEqual(member.gname, 'oe', "group name for %s differs" % member.name)
708 self.assertEqual(member.gid, 0, "gid for %s differs" % member.name)
709 self.assertEqual(member.mtime, mtime, "mtime for %s differs" % member.name)
Andrew Geissler9aee5002022-03-30 16:27:02 +0000710
711
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500712class FetcherLocalTest(FetcherTest):
713 def setUp(self):
714 def touch(fn):
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600715 with open(fn, 'a'):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500716 os.utime(fn, None)
717
718 super(FetcherLocalTest, self).setUp()
719 self.localsrcdir = os.path.join(self.tempdir, 'localsrc')
720 os.makedirs(self.localsrcdir)
721 touch(os.path.join(self.localsrcdir, 'a'))
722 touch(os.path.join(self.localsrcdir, 'b'))
723 os.makedirs(os.path.join(self.localsrcdir, 'dir'))
724 touch(os.path.join(self.localsrcdir, 'dir', 'c'))
725 touch(os.path.join(self.localsrcdir, 'dir', 'd'))
726 os.makedirs(os.path.join(self.localsrcdir, 'dir', 'subdir'))
727 touch(os.path.join(self.localsrcdir, 'dir', 'subdir', 'e'))
Andrew Geisslerc3d88e42020-10-02 09:45:00 -0500728 touch(os.path.join(self.localsrcdir, r'backslash\x2dsystemd-unit.device'))
Andrew Geissler595f6302022-01-24 19:11:47 +0000729 bb.process.run('tar cf archive.tar -C dir .', cwd=self.localsrcdir)
730 bb.process.run('tar czf archive.tar.gz -C dir .', cwd=self.localsrcdir)
731 bb.process.run('tar cjf archive.tar.bz2 -C dir .', cwd=self.localsrcdir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500732 self.d.setVar("FILESPATH", self.localsrcdir)
733
734 def fetchUnpack(self, uris):
735 fetcher = bb.fetch.Fetch(uris, self.d)
736 fetcher.download()
737 fetcher.unpack(self.unpackdir)
738 flst = []
739 for root, dirs, files in os.walk(self.unpackdir):
740 for f in files:
741 flst.append(os.path.relpath(os.path.join(root, f), self.unpackdir))
742 flst.sort()
743 return flst
744
Andrew Geissler615f2f12022-07-15 14:00:58 -0500745 def test_local_checksum_fails_no_file(self):
746 self.d.setVar("SRC_URI", "file://404")
747 with self.assertRaises(bb.BBHandledException):
748 bb.fetch.get_checksum_file_list(self.d)
749
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500750 def test_local(self):
751 tree = self.fetchUnpack(['file://a', 'file://dir/c'])
752 self.assertEqual(tree, ['a', 'dir/c'])
753
Andrew Geisslerc3d88e42020-10-02 09:45:00 -0500754 def test_local_backslash(self):
755 tree = self.fetchUnpack([r'file://backslash\x2dsystemd-unit.device'])
756 self.assertEqual(tree, [r'backslash\x2dsystemd-unit.device'])
757
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500758 def test_local_wildcard(self):
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500759 with self.assertRaises(bb.fetch2.ParameterError):
760 tree = self.fetchUnpack(['file://a', 'file://dir/*'])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500761
762 def test_local_dir(self):
763 tree = self.fetchUnpack(['file://a', 'file://dir'])
764 self.assertEqual(tree, ['a', 'dir/c', 'dir/d', 'dir/subdir/e'])
765
766 def test_local_subdir(self):
767 tree = self.fetchUnpack(['file://dir/subdir'])
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500768 self.assertEqual(tree, ['dir/subdir/e'])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500769
770 def test_local_subdir_file(self):
771 tree = self.fetchUnpack(['file://dir/subdir/e'])
772 self.assertEqual(tree, ['dir/subdir/e'])
773
774 def test_local_subdirparam(self):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500775 tree = self.fetchUnpack(['file://a;subdir=bar', 'file://dir;subdir=foo/moo'])
776 self.assertEqual(tree, ['bar/a', 'foo/moo/dir/c', 'foo/moo/dir/d', 'foo/moo/dir/subdir/e'])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500777
778 def test_local_deepsubdirparam(self):
779 tree = self.fetchUnpack(['file://dir/subdir/e;subdir=bar'])
780 self.assertEqual(tree, ['bar/dir/subdir/e'])
781
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600782 def test_local_absolutedir(self):
783 # Unpacking to an absolute path that is a subdirectory of the root
784 # should work
785 tree = self.fetchUnpack(['file://a;subdir=%s' % os.path.join(self.unpackdir, 'bar')])
786
787 # Unpacking to an absolute path outside of the root should fail
788 with self.assertRaises(bb.fetch2.UnpackError):
789 self.fetchUnpack(['file://a;subdir=/bin/sh'])
790
Andrew Geissler595f6302022-01-24 19:11:47 +0000791 def test_local_striplevel(self):
792 tree = self.fetchUnpack(['file://archive.tar;subdir=bar;striplevel=1'])
793 self.assertEqual(tree, ['bar/c', 'bar/d', 'bar/subdir/e'])
794
795 def test_local_striplevel_gzip(self):
796 tree = self.fetchUnpack(['file://archive.tar.gz;subdir=bar;striplevel=1'])
797 self.assertEqual(tree, ['bar/c', 'bar/d', 'bar/subdir/e'])
798
799 def test_local_striplevel_bzip2(self):
800 tree = self.fetchUnpack(['file://archive.tar.bz2;subdir=bar;striplevel=1'])
801 self.assertEqual(tree, ['bar/c', 'bar/d', 'bar/subdir/e'])
802
Andrew Geisslerc926e172021-05-07 16:11:35 -0500803 def dummyGitTest(self, suffix):
Andrew Geisslerd1e89492021-02-12 15:35:20 -0600804 # Create dummy local Git repo
805 src_dir = tempfile.mkdtemp(dir=self.tempdir,
806 prefix='gitfetch_localusehead_')
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000807 self.gitdir = os.path.abspath(src_dir)
808 self.git_init()
809 self.git(['commit', '--allow-empty', '-m', 'Dummy commit'])
Andrew Geisslerd1e89492021-02-12 15:35:20 -0600810 # Use other branch than master
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000811 self.git(['checkout', '-b', 'my-devel'])
812 self.git(['commit', '--allow-empty', '-m', 'Dummy commit 2'])
813 orig_rev = self.git(['rev-parse', 'HEAD']).strip()
Andrew Geisslerd1e89492021-02-12 15:35:20 -0600814
815 # Fetch and check revision
816 self.d.setVar("SRCREV", "AUTOINC")
Andrew Geisslerfc113ea2023-03-31 09:59:46 -0500817 self.d.setVar("__BBSRCREV_SEEN", "1")
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000818 url = "git://" + self.gitdir + ";branch=master;protocol=file;" + suffix
Andrew Geisslerd1e89492021-02-12 15:35:20 -0600819 fetcher = bb.fetch.Fetch([url], self.d)
820 fetcher.download()
821 fetcher.unpack(self.unpackdir)
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000822 unpack_rev = self.git(['rev-parse', 'HEAD'],
823 cwd=os.path.join(self.unpackdir, 'git')).strip()
Andrew Geisslerd1e89492021-02-12 15:35:20 -0600824 self.assertEqual(orig_rev, unpack_rev)
825
Andrew Geisslerc926e172021-05-07 16:11:35 -0500826 def test_local_gitfetch_usehead(self):
827 self.dummyGitTest("usehead=1")
828
Andrew Geisslerd1e89492021-02-12 15:35:20 -0600829 def test_local_gitfetch_usehead_withname(self):
Andrew Geisslerc926e172021-05-07 16:11:35 -0500830 self.dummyGitTest("usehead=1;name=newName")
Andrew Geisslerd1e89492021-02-12 15:35:20 -0600831
Andrew Geisslerc926e172021-05-07 16:11:35 -0500832 def test_local_gitfetch_shared(self):
833 self.dummyGitTest("usehead=1;name=sharedName")
834 alt = os.path.join(self.unpackdir, 'git/.git/objects/info/alternates')
835 self.assertTrue(os.path.exists(alt))
836
837 def test_local_gitfetch_noshared(self):
838 self.d.setVar('BB_GIT_NOSHARED', '1')
839 self.unpackdir += '_noshared'
840 self.dummyGitTest("usehead=1;name=noSharedName")
841 alt = os.path.join(self.unpackdir, 'git/.git/objects/info/alternates')
842 self.assertFalse(os.path.exists(alt))
Andrew Geisslerd1e89492021-02-12 15:35:20 -0600843
Brad Bishop316dfdd2018-06-25 12:45:53 -0400844class FetcherNoNetworkTest(FetcherTest):
845 def setUp(self):
846 super().setUp()
847 # all test cases are based on not having network
848 self.d.setVar("BB_NO_NETWORK", "1")
849
850 def test_missing(self):
851 string = "this is a test file\n".encode("utf-8")
852 self.d.setVarFlag("SRC_URI", "md5sum", hashlib.md5(string).hexdigest())
853 self.d.setVarFlag("SRC_URI", "sha256sum", hashlib.sha256(string).hexdigest())
854
855 self.assertFalse(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz")))
856 self.assertFalse(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz.done")))
857 fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/test-file.tar.gz"], self.d)
858 with self.assertRaises(bb.fetch2.NetworkAccess):
859 fetcher.download()
860
861 def test_valid_missing_donestamp(self):
862 # create the file in the download directory with correct hash
863 string = "this is a test file\n".encode("utf-8")
864 with open(os.path.join(self.dldir, "test-file.tar.gz"), "wb") as f:
865 f.write(string)
866
867 self.d.setVarFlag("SRC_URI", "md5sum", hashlib.md5(string).hexdigest())
868 self.d.setVarFlag("SRC_URI", "sha256sum", hashlib.sha256(string).hexdigest())
869
870 self.assertTrue(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz")))
871 self.assertFalse(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz.done")))
872 fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/test-file.tar.gz"], self.d)
873 fetcher.download()
874 self.assertTrue(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz.done")))
875
876 def test_invalid_missing_donestamp(self):
877 # create an invalid file in the download directory with incorrect hash
878 string = "this is a test file\n".encode("utf-8")
879 with open(os.path.join(self.dldir, "test-file.tar.gz"), "wb"):
880 pass
881
882 self.d.setVarFlag("SRC_URI", "md5sum", hashlib.md5(string).hexdigest())
883 self.d.setVarFlag("SRC_URI", "sha256sum", hashlib.sha256(string).hexdigest())
884
885 self.assertTrue(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz")))
886 self.assertFalse(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz.done")))
887 fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/test-file.tar.gz"], self.d)
888 with self.assertRaises(bb.fetch2.NetworkAccess):
889 fetcher.download()
890 # the existing file should not exist or should have be moved to "bad-checksum"
891 self.assertFalse(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz")))
892
893 def test_nochecksums_missing(self):
894 self.assertFalse(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz")))
895 self.assertFalse(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz.done")))
896 # ssh fetch does not support checksums
897 fetcher = bb.fetch.Fetch(["ssh://invalid@invalid.yoctoproject.org/test-file.tar.gz"], self.d)
898 # attempts to download with missing donestamp
899 with self.assertRaises(bb.fetch2.NetworkAccess):
900 fetcher.download()
901
902 def test_nochecksums_missing_donestamp(self):
903 # create a file in the download directory
904 with open(os.path.join(self.dldir, "test-file.tar.gz"), "wb"):
905 pass
906
907 self.assertTrue(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz")))
908 self.assertFalse(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz.done")))
909 # ssh fetch does not support checksums
910 fetcher = bb.fetch.Fetch(["ssh://invalid@invalid.yoctoproject.org/test-file.tar.gz"], self.d)
911 # attempts to download with missing donestamp
912 with self.assertRaises(bb.fetch2.NetworkAccess):
913 fetcher.download()
914
915 def test_nochecksums_has_donestamp(self):
916 # create a file in the download directory with the donestamp
917 with open(os.path.join(self.dldir, "test-file.tar.gz"), "wb"):
918 pass
919 with open(os.path.join(self.dldir, "test-file.tar.gz.done"), "wb"):
920 pass
921
922 self.assertTrue(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz")))
923 self.assertTrue(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz.done")))
924 # ssh fetch does not support checksums
925 fetcher = bb.fetch.Fetch(["ssh://invalid@invalid.yoctoproject.org/test-file.tar.gz"], self.d)
926 # should not fetch
927 fetcher.download()
928 # both files should still exist
929 self.assertTrue(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz")))
930 self.assertTrue(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz.done")))
931
932 def test_nochecksums_missing_has_donestamp(self):
933 # create a file in the download directory with the donestamp
934 with open(os.path.join(self.dldir, "test-file.tar.gz.done"), "wb"):
935 pass
936
937 self.assertFalse(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz")))
938 self.assertTrue(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz.done")))
939 # ssh fetch does not support checksums
940 fetcher = bb.fetch.Fetch(["ssh://invalid@invalid.yoctoproject.org/test-file.tar.gz"], self.d)
941 with self.assertRaises(bb.fetch2.NetworkAccess):
942 fetcher.download()
943 # both files should still exist
944 self.assertFalse(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz")))
945 self.assertFalse(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz.done")))
946
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500947class FetcherNetworkTest(FetcherTest):
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500948 @skipIfNoNetwork()
949 def test_fetch(self):
Andrew Geisslereff27472021-10-29 15:35:00 -0500950 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)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500951 fetcher.download()
952 self.assertEqual(os.path.getsize(self.dldir + "/bitbake-1.0.tar.gz"), 57749)
953 self.assertEqual(os.path.getsize(self.dldir + "/bitbake-1.1.tar.gz"), 57892)
954 self.d.setVar("BB_NO_NETWORK", "1")
Andrew Geisslereff27472021-10-29 15:35:00 -0500955 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)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500956 fetcher.download()
957 fetcher.unpack(self.unpackdir)
958 self.assertEqual(len(os.listdir(self.unpackdir + "/bitbake-1.0/")), 9)
959 self.assertEqual(len(os.listdir(self.unpackdir + "/bitbake-1.1/")), 9)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500960
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500961 @skipIfNoNetwork()
962 def test_fetch_mirror(self):
Andrew Geisslereff27472021-10-29 15:35:00 -0500963 self.d.setVar("MIRRORS", "http://.*/.* https://downloads.yoctoproject.org/releases/bitbake")
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500964 fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz"], self.d)
965 fetcher.download()
966 self.assertEqual(os.path.getsize(self.dldir + "/bitbake-1.0.tar.gz"), 57749)
967
968 @skipIfNoNetwork()
969 def test_fetch_mirror_of_mirror(self):
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000970 self.d.setVar("MIRRORS", "http://.*/.* http://invalid2.yoctoproject.org/ http://invalid2.yoctoproject.org/.* https://downloads.yoctoproject.org/releases/bitbake")
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500971 fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz"], self.d)
972 fetcher.download()
973 self.assertEqual(os.path.getsize(self.dldir + "/bitbake-1.0.tar.gz"), 57749)
974
975 @skipIfNoNetwork()
976 def test_fetch_file_mirror_of_mirror(self):
Andrew Geissler615f2f12022-07-15 14:00:58 -0500977 self.d.setVar("FILESPATH", ".")
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000978 self.d.setVar("MIRRORS", "http://.*/.* file:///some1where/ file:///some1where/.* file://some2where/ file://some2where/.* https://downloads.yoctoproject.org/releases/bitbake")
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500979 fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz"], self.d)
980 os.mkdir(self.dldir + "/some2where")
981 fetcher.download()
982 self.assertEqual(os.path.getsize(self.dldir + "/bitbake-1.0.tar.gz"), 57749)
983
984 @skipIfNoNetwork()
985 def test_fetch_premirror(self):
Andrew Geisslereff27472021-10-29 15:35:00 -0500986 self.d.setVar("PREMIRRORS", "http://.*/.* https://downloads.yoctoproject.org/releases/bitbake")
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500987 fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz"], self.d)
988 fetcher.download()
989 self.assertEqual(os.path.getsize(self.dldir + "/bitbake-1.0.tar.gz"), 57749)
990
991 @skipIfNoNetwork()
Andrew Geissler5199d832021-09-24 16:47:35 -0500992 def test_fetch_specify_downloadfilename(self):
Andrew Geisslereff27472021-10-29 15:35:00 -0500993 fetcher = bb.fetch.Fetch(["https://downloads.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz;downloadfilename=bitbake-v1.0.0.tar.gz"], self.d)
Andrew Geissler5199d832021-09-24 16:47:35 -0500994 fetcher.download()
995 self.assertEqual(os.path.getsize(self.dldir + "/bitbake-v1.0.0.tar.gz"), 57749)
996
997 @skipIfNoNetwork()
998 def test_fetch_premirror_specify_downloadfilename_regex_uri(self):
Andrew Geisslereff27472021-10-29 15:35:00 -0500999 self.d.setVar("PREMIRRORS", "http://.*/.* https://downloads.yoctoproject.org/releases/bitbake/")
Andrew Geissler595f6302022-01-24 19:11:47 +00001000 fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/releases/bitbake/1.0.tar.gz;downloadfilename=bitbake-1.0.tar.gz"], self.d)
Andrew Geissler5199d832021-09-24 16:47:35 -05001001 fetcher.download()
Andrew Geissler595f6302022-01-24 19:11:47 +00001002 self.assertEqual(os.path.getsize(self.dldir + "/bitbake-1.0.tar.gz"), 57749)
Andrew Geissler5199d832021-09-24 16:47:35 -05001003
1004 @skipIfNoNetwork()
1005 # BZ13039
1006 def test_fetch_premirror_specify_downloadfilename_specific_uri(self):
Andrew Geisslereff27472021-10-29 15:35:00 -05001007 self.d.setVar("PREMIRRORS", "http://invalid.yoctoproject.org/releases/bitbake https://downloads.yoctoproject.org/releases/bitbake")
Andrew Geissler595f6302022-01-24 19:11:47 +00001008 fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/releases/bitbake/1.0.tar.gz;downloadfilename=bitbake-1.0.tar.gz"], self.d)
Andrew Geissler5199d832021-09-24 16:47:35 -05001009 fetcher.download()
Andrew Geissler595f6302022-01-24 19:11:47 +00001010 self.assertEqual(os.path.getsize(self.dldir + "/bitbake-1.0.tar.gz"), 57749)
1011
1012 @skipIfNoNetwork()
1013 def test_fetch_premirror_use_downloadfilename_to_fetch(self):
1014 # Ensure downloadfilename is used when fetching from premirror.
1015 self.d.setVar("PREMIRRORS", "http://.*/.* https://downloads.yoctoproject.org/releases/bitbake")
1016 fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/releases/bitbake/bitbake-1.1.tar.gz;downloadfilename=bitbake-1.0.tar.gz"], self.d)
1017 fetcher.download()
1018 self.assertEqual(os.path.getsize(self.dldir + "/bitbake-1.0.tar.gz"), 57749)
Andrew Geissler5199d832021-09-24 16:47:35 -05001019
1020 @skipIfNoNetwork()
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001021 def gitfetcher(self, url1, url2):
1022 def checkrevision(self, fetcher):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001023 fetcher.unpack(self.unpackdir)
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001024 revision = self.git(['rev-parse', 'HEAD'],
1025 cwd=os.path.join(self.unpackdir, 'git')).strip()
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001026 self.assertEqual(revision, "270a05b0b4ba0959fe0624d2a4885d7b70426da5")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001027
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001028 self.d.setVar("BB_GENERATE_MIRROR_TARBALLS", "1")
1029 self.d.setVar("SRCREV", "270a05b0b4ba0959fe0624d2a4885d7b70426da5")
1030 fetcher = bb.fetch.Fetch([url1], self.d)
1031 fetcher.download()
1032 checkrevision(self, fetcher)
1033 # Wipe out the dldir clone and the unpacked source, turn off the network and check mirror tarball works
1034 bb.utils.prunedir(self.dldir + "/git2/")
1035 bb.utils.prunedir(self.unpackdir)
1036 self.d.setVar("BB_NO_NETWORK", "1")
1037 fetcher = bb.fetch.Fetch([url2], self.d)
1038 fetcher.download()
1039 checkrevision(self, fetcher)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001040
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001041 @skipIfNoNetwork()
1042 def test_gitfetch(self):
Andrew Geissler028142b2023-05-05 11:29:21 -05001043 url1 = url2 = "git://git.openembedded.org/bitbake;branch=master;protocol=https"
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001044 self.gitfetcher(url1, url2)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001045
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001046 @skipIfNoNetwork()
1047 def test_gitfetch_goodsrcrev(self):
1048 # SRCREV is set but matches rev= parameter
Andrew Geissler028142b2023-05-05 11:29:21 -05001049 url1 = url2 = "git://git.openembedded.org/bitbake;rev=270a05b0b4ba0959fe0624d2a4885d7b70426da5;branch=master;protocol=https"
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001050 self.gitfetcher(url1, url2)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001051
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001052 @skipIfNoNetwork()
1053 def test_gitfetch_badsrcrev(self):
1054 # SRCREV is set but does not match rev= parameter
Andrew Geissler028142b2023-05-05 11:29:21 -05001055 url1 = url2 = "git://git.openembedded.org/bitbake;rev=dead05b0b4ba0959fe0624d2a4885d7b70426da5;branch=master;protocol=https"
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001056 self.assertRaises(bb.fetch.FetchError, self.gitfetcher, url1, url2)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001057
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001058 @skipIfNoNetwork()
1059 def test_gitfetch_tagandrev(self):
1060 # SRCREV is set but does not match rev= parameter
Andrew Geissler028142b2023-05-05 11:29:21 -05001061 url1 = url2 = "git://git.openembedded.org/bitbake;rev=270a05b0b4ba0959fe0624d2a4885d7b70426da5;tag=270a05b0b4ba0959fe0624d2a4885d7b70426da5;protocol=https"
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001062 self.assertRaises(bb.fetch.FetchError, self.gitfetcher, url1, url2)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001063
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001064 @skipIfNoNetwork()
Andrew Geisslerd1e89492021-02-12 15:35:20 -06001065 def test_gitfetch_usehead(self):
1066 # Since self.gitfetcher() sets SRCREV we expect this to override
1067 # `usehead=1' and instead fetch the specified SRCREV. See
1068 # test_local_gitfetch_usehead() for a positive use of the usehead
1069 # feature.
Andrew Geissler028142b2023-05-05 11:29:21 -05001070 url = "git://git.openembedded.org/bitbake;usehead=1;branch=master;protocol=https"
Andrew Geisslerd1e89492021-02-12 15:35:20 -06001071 self.assertRaises(bb.fetch.ParameterError, self.gitfetcher, url, url)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001072
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001073 @skipIfNoNetwork()
Andrew Geisslerd1e89492021-02-12 15:35:20 -06001074 def test_gitfetch_usehead_withname(self):
1075 # Since self.gitfetcher() sets SRCREV we expect this to override
1076 # `usehead=1' and instead fetch the specified SRCREV. See
1077 # test_local_gitfetch_usehead() for a positive use of the usehead
1078 # feature.
Andrew Geissler028142b2023-05-05 11:29:21 -05001079 url = "git://git.openembedded.org/bitbake;usehead=1;name=newName;branch=master;protocol=https"
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001080 self.assertRaises(bb.fetch.ParameterError, self.gitfetcher, url, url)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001081
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001082 @skipIfNoNetwork()
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001083 def test_gitfetch_finds_local_tarball_for_mirrored_url_when_previous_downloaded_by_the_recipe_url(self):
Andrew Geissler028142b2023-05-05 11:29:21 -05001084 recipeurl = "git://git.openembedded.org/bitbake;branch=master;protocol=https"
1085 mirrorurl = "git://someserver.org/bitbake;branch=master;protocol=https"
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001086 self.d.setVar("PREMIRRORS", "git://someserver.org/bitbake git://git.openembedded.org/bitbake")
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001087 self.gitfetcher(recipeurl, mirrorurl)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001088
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001089 @skipIfNoNetwork()
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001090 def test_gitfetch_finds_local_tarball_when_previous_downloaded_from_a_premirror(self):
Andrew Geissler028142b2023-05-05 11:29:21 -05001091 recipeurl = "git://someserver.org/bitbake;branch=master;protocol=https"
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001092 self.d.setVar("PREMIRRORS", "git://someserver.org/bitbake git://git.openembedded.org/bitbake")
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001093 self.gitfetcher(recipeurl, recipeurl)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001094
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001095 @skipIfNoNetwork()
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001096 def test_gitfetch_finds_local_repository_when_premirror_rewrites_the_recipe_url(self):
Andrew Geissler028142b2023-05-05 11:29:21 -05001097 realurl = "https://git.openembedded.org/bitbake"
1098 recipeurl = "git://someserver.org/bitbake;protocol=https"
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001099 self.sourcedir = self.unpackdir.replace("unpacked", "sourcemirror.git")
1100 os.chdir(self.tempdir)
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001101 self.git(['clone', realurl, self.sourcedir], cwd=self.tempdir)
1102 self.d.setVar("PREMIRRORS", "%s git://%s;protocol=file" % (recipeurl, self.sourcedir))
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001103 self.gitfetcher(recipeurl, recipeurl)
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001104
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001105 @skipIfNoNetwork()
1106 def test_git_submodule(self):
Brad Bishopf8caae32019-03-25 13:13:56 -04001107 # URL with ssh submodules
Andrew Geissler028142b2023-05-05 11:29:21 -05001108 url = "gitsm://git.yoctoproject.org/git-submodule-test;branch=ssh-gitsm-tests;rev=049da4a6cb198d7c0302e9e8b243a1443cb809a7;branch=master;protocol=https"
Brad Bishopf8caae32019-03-25 13:13:56 -04001109 # Original URL (comment this if you have ssh access to git.yoctoproject.org)
Andrew Geissler028142b2023-05-05 11:29:21 -05001110 url = "gitsm://git.yoctoproject.org/git-submodule-test;branch=master;rev=a2885dd7d25380d23627e7544b7bbb55014b16ee;branch=master;protocol=https"
Brad Bishopf8caae32019-03-25 13:13:56 -04001111 fetcher = bb.fetch.Fetch([url], self.d)
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001112 fetcher.download()
1113 # Previous cwd has been deleted
1114 os.chdir(os.path.dirname(self.unpackdir))
1115 fetcher.unpack(self.unpackdir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001116
Brad Bishopf8caae32019-03-25 13:13:56 -04001117 repo_path = os.path.join(self.tempdir, 'unpacked', 'git')
1118 self.assertTrue(os.path.exists(repo_path), msg='Unpacked repository missing')
1119 self.assertTrue(os.path.exists(os.path.join(repo_path, 'bitbake')), msg='bitbake submodule missing')
1120 self.assertFalse(os.path.exists(os.path.join(repo_path, 'na')), msg='uninitialized submodule present')
1121
1122 # Only when we're running the extended test with a submodule's submodule, can we check this.
1123 if os.path.exists(os.path.join(repo_path, 'bitbake-gitsm-test1')):
1124 self.assertTrue(os.path.exists(os.path.join(repo_path, 'bitbake-gitsm-test1', 'bitbake')), msg='submodule of submodule missing')
1125
Brad Bishop96ff1982019-08-19 13:50:42 -04001126 @skipIfNoNetwork()
Patrick Williams73bd93f2024-02-20 08:07:48 -06001127 def test_git_submodule_restricted_network_premirrors(self):
1128 # this test is to ensure that premirrors will be tried in restricted network
1129 # that is, BB_ALLOWED_NETWORKS does not contain the domain the url uses
1130 url = "gitsm://github.com/grpc/grpc.git;protocol=https;name=grpc;branch=v1.60.x;rev=0ef13a7555dbaadd4633399242524129eef5e231"
1131 # create a download directory to be used as premirror later
1132 tempdir = tempfile.mkdtemp(prefix="bitbake-fetch-")
1133 dl_premirror = os.path.join(tempdir, "download-premirror")
1134 os.mkdir(dl_premirror)
1135 self.d.setVar("DL_DIR", dl_premirror)
1136 fetcher = bb.fetch.Fetch([url], self.d)
1137 fetcher.download()
1138 # now use the premirror in restricted network
1139 self.d.setVar("DL_DIR", self.dldir)
1140 self.d.setVar("PREMIRRORS", "gitsm://.*/.* gitsm://%s/git2/MIRRORNAME;protocol=file" % dl_premirror)
1141 self.d.setVar("BB_ALLOWED_NETWORKS", "*.some.domain")
1142 fetcher = bb.fetch.Fetch([url], self.d)
1143 fetcher.download()
1144
1145 @skipIfNoNetwork()
Brad Bishopf8caae32019-03-25 13:13:56 -04001146 def test_git_submodule_dbus_broker(self):
1147 # The following external repositories have show failures in fetch and unpack operations
1148 # We want to avoid regressions!
Andrew Geissler595f6302022-01-24 19:11:47 +00001149 url = "gitsm://github.com/bus1/dbus-broker;protocol=https;rev=fc874afa0992d0c75ec25acb43d344679f0ee7d2;branch=main"
Brad Bishopf8caae32019-03-25 13:13:56 -04001150 fetcher = bb.fetch.Fetch([url], self.d)
1151 fetcher.download()
1152 # Previous cwd has been deleted
1153 os.chdir(os.path.dirname(self.unpackdir))
1154 fetcher.unpack(self.unpackdir)
1155
1156 repo_path = os.path.join(self.tempdir, 'unpacked', 'git')
1157 self.assertTrue(os.path.exists(os.path.join(repo_path, '.git/modules/subprojects/c-dvar/config')), msg='Missing submodule config "subprojects/c-dvar"')
1158 self.assertTrue(os.path.exists(os.path.join(repo_path, '.git/modules/subprojects/c-list/config')), msg='Missing submodule config "subprojects/c-list"')
1159 self.assertTrue(os.path.exists(os.path.join(repo_path, '.git/modules/subprojects/c-rbtree/config')), msg='Missing submodule config "subprojects/c-rbtree"')
1160 self.assertTrue(os.path.exists(os.path.join(repo_path, '.git/modules/subprojects/c-sundry/config')), msg='Missing submodule config "subprojects/c-sundry"')
1161 self.assertTrue(os.path.exists(os.path.join(repo_path, '.git/modules/subprojects/c-utf8/config')), msg='Missing submodule config "subprojects/c-utf8"')
1162
Brad Bishop96ff1982019-08-19 13:50:42 -04001163 @skipIfNoNetwork()
Brad Bishopf8caae32019-03-25 13:13:56 -04001164 def test_git_submodule_CLI11(self):
Andrew Geissler595f6302022-01-24 19:11:47 +00001165 url = "gitsm://github.com/CLIUtils/CLI11;protocol=https;rev=bd4dc911847d0cde7a6b41dfa626a85aab213baf;branch=main"
Brad Bishopf8caae32019-03-25 13:13:56 -04001166 fetcher = bb.fetch.Fetch([url], self.d)
1167 fetcher.download()
1168 # Previous cwd has been deleted
1169 os.chdir(os.path.dirname(self.unpackdir))
1170 fetcher.unpack(self.unpackdir)
1171
1172 repo_path = os.path.join(self.tempdir, 'unpacked', 'git')
1173 self.assertTrue(os.path.exists(os.path.join(repo_path, '.git/modules/extern/googletest/config')), msg='Missing submodule config "extern/googletest"')
1174 self.assertTrue(os.path.exists(os.path.join(repo_path, '.git/modules/extern/json/config')), msg='Missing submodule config "extern/json"')
1175 self.assertTrue(os.path.exists(os.path.join(repo_path, '.git/modules/extern/sanitizers/config')), msg='Missing submodule config "extern/sanitizers"')
1176
Brad Bishop96ff1982019-08-19 13:50:42 -04001177 @skipIfNoNetwork()
Brad Bishop19323692019-04-05 15:28:33 -04001178 def test_git_submodule_update_CLI11(self):
1179 """ Prevent regression on update detection not finding missing submodule, or modules without needed commits """
Andrew Geissler595f6302022-01-24 19:11:47 +00001180 url = "gitsm://github.com/CLIUtils/CLI11;protocol=https;rev=cf6a99fa69aaefe477cc52e3ef4a7d2d7fa40714;branch=main"
Brad Bishop19323692019-04-05 15:28:33 -04001181 fetcher = bb.fetch.Fetch([url], self.d)
1182 fetcher.download()
1183
1184 # CLI11 that pulls in a newer nlohmann-json
Andrew Geissler595f6302022-01-24 19:11:47 +00001185 url = "gitsm://github.com/CLIUtils/CLI11;protocol=https;rev=49ac989a9527ee9bb496de9ded7b4872c2e0e5ca;branch=main"
Brad Bishop19323692019-04-05 15:28:33 -04001186 fetcher = bb.fetch.Fetch([url], self.d)
1187 fetcher.download()
1188 # Previous cwd has been deleted
1189 os.chdir(os.path.dirname(self.unpackdir))
1190 fetcher.unpack(self.unpackdir)
1191
1192 repo_path = os.path.join(self.tempdir, 'unpacked', 'git')
1193 self.assertTrue(os.path.exists(os.path.join(repo_path, '.git/modules/extern/googletest/config')), msg='Missing submodule config "extern/googletest"')
1194 self.assertTrue(os.path.exists(os.path.join(repo_path, '.git/modules/extern/json/config')), msg='Missing submodule config "extern/json"')
1195 self.assertTrue(os.path.exists(os.path.join(repo_path, '.git/modules/extern/sanitizers/config')), msg='Missing submodule config "extern/sanitizers"')
1196
Brad Bishop96ff1982019-08-19 13:50:42 -04001197 @skipIfNoNetwork()
Brad Bishopf8caae32019-03-25 13:13:56 -04001198 def test_git_submodule_aktualizr(self):
Andrew Geissler595f6302022-01-24 19:11:47 +00001199 url = "gitsm://github.com/advancedtelematic/aktualizr;branch=master;protocol=https;rev=d00d1a04cc2366d1a5f143b84b9f507f8bd32c44"
Brad Bishopf8caae32019-03-25 13:13:56 -04001200 fetcher = bb.fetch.Fetch([url], self.d)
1201 fetcher.download()
1202 # Previous cwd has been deleted
1203 os.chdir(os.path.dirname(self.unpackdir))
1204 fetcher.unpack(self.unpackdir)
1205
1206 repo_path = os.path.join(self.tempdir, 'unpacked', 'git')
1207 self.assertTrue(os.path.exists(os.path.join(repo_path, '.git/modules/partial/extern/isotp-c/config')), msg='Missing submodule config "partial/extern/isotp-c/config"')
1208 self.assertTrue(os.path.exists(os.path.join(repo_path, '.git/modules/partial/extern/isotp-c/modules/deps/bitfield-c/config')), msg='Missing submodule config "partial/extern/isotp-c/modules/deps/bitfield-c/config"')
1209 self.assertTrue(os.path.exists(os.path.join(repo_path, 'partial/extern/isotp-c/deps/bitfield-c/.git')), msg="Submodule of submodule isotp-c did not unpack properly")
1210 self.assertTrue(os.path.exists(os.path.join(repo_path, '.git/modules/tests/tuf-test-vectors/config')), msg='Missing submodule config "tests/tuf-test-vectors/config"')
1211 self.assertTrue(os.path.exists(os.path.join(repo_path, '.git/modules/third_party/googletest/config')), msg='Missing submodule config "third_party/googletest/config"')
1212 self.assertTrue(os.path.exists(os.path.join(repo_path, '.git/modules/third_party/HdrHistogram_c/config')), msg='Missing submodule config "third_party/HdrHistogram_c/config"')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001213
Brad Bishop96ff1982019-08-19 13:50:42 -04001214 @skipIfNoNetwork()
Brad Bishop393846f2019-05-20 12:24:11 -04001215 def test_git_submodule_iotedge(self):
1216 """ Prevent regression on deeply nested submodules not being checked out properly, even though they were fetched. """
1217
1218 # This repository also has submodules where the module (name), path and url do not align
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001219 url = "gitsm://github.com/azure/iotedge.git;protocol=https;rev=d76e0316c6f324345d77c48a83ce836d09392699;branch=main"
Brad Bishop393846f2019-05-20 12:24:11 -04001220 fetcher = bb.fetch.Fetch([url], self.d)
1221 fetcher.download()
1222 # Previous cwd has been deleted
1223 os.chdir(os.path.dirname(self.unpackdir))
1224 fetcher.unpack(self.unpackdir)
1225
1226 repo_path = os.path.join(self.tempdir, 'unpacked', 'git')
1227
1228 self.assertTrue(os.path.exists(os.path.join(repo_path, 'edgelet/hsm-sys/azure-iot-hsm-c/deps/c-shared/README.md')), msg='Missing submodule checkout')
1229 self.assertTrue(os.path.exists(os.path.join(repo_path, 'edgelet/hsm-sys/azure-iot-hsm-c/deps/c-shared/testtools/ctest/README.md')), msg='Missing submodule checkout')
1230 self.assertTrue(os.path.exists(os.path.join(repo_path, 'edgelet/hsm-sys/azure-iot-hsm-c/deps/c-shared/testtools/testrunner/readme.md')), msg='Missing submodule checkout')
1231 self.assertTrue(os.path.exists(os.path.join(repo_path, 'edgelet/hsm-sys/azure-iot-hsm-c/deps/c-shared/testtools/umock-c/readme.md')), msg='Missing submodule checkout')
1232 self.assertTrue(os.path.exists(os.path.join(repo_path, 'edgelet/hsm-sys/azure-iot-hsm-c/deps/c-shared/testtools/umock-c/deps/ctest/README.md')), msg='Missing submodule checkout')
1233 self.assertTrue(os.path.exists(os.path.join(repo_path, 'edgelet/hsm-sys/azure-iot-hsm-c/deps/c-shared/testtools/umock-c/deps/testrunner/readme.md')), msg='Missing submodule checkout')
1234 self.assertTrue(os.path.exists(os.path.join(repo_path, 'edgelet/hsm-sys/azure-iot-hsm-c/deps/utpm/README.md')), msg='Missing submodule checkout')
1235 self.assertTrue(os.path.exists(os.path.join(repo_path, 'edgelet/hsm-sys/azure-iot-hsm-c/deps/utpm/deps/c-utility/README.md')), msg='Missing submodule checkout')
1236 self.assertTrue(os.path.exists(os.path.join(repo_path, 'edgelet/hsm-sys/azure-iot-hsm-c/deps/utpm/deps/c-utility/testtools/ctest/README.md')), msg='Missing submodule checkout')
1237 self.assertTrue(os.path.exists(os.path.join(repo_path, 'edgelet/hsm-sys/azure-iot-hsm-c/deps/utpm/deps/c-utility/testtools/testrunner/readme.md')), msg='Missing submodule checkout')
1238 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/readme.md')), msg='Missing submodule checkout')
1239 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')
1240 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')
1241
Patrick Williams92b42cb2022-09-03 06:53:57 -05001242 @skipIfNoNetwork()
1243 def test_git_submodule_reference_to_parent(self):
1244 self.recipe_url = "gitsm://github.com/gflags/gflags.git;protocol=https;branch=master"
1245 self.d.setVar("SRCREV", "14e1138441bbbb584160cb1c0a0426ec1bac35f1")
1246 with Timeout(60):
1247 fetcher = bb.fetch.Fetch([self.recipe_url], self.d)
1248 with self.assertRaises(bb.fetch2.FetchError):
1249 fetcher.download()
1250
Brad Bishop15ae2502019-06-18 21:44:24 -04001251class SVNTest(FetcherTest):
1252 def skipIfNoSvn():
1253 import shutil
1254 if not shutil.which("svn"):
1255 return unittest.skip("svn not installed, tests being skipped")
1256
1257 if not shutil.which("svnadmin"):
1258 return unittest.skip("svnadmin not installed, tests being skipped")
1259
1260 return lambda f: f
1261
1262 @skipIfNoSvn()
1263 def setUp(self):
1264 """ Create a local repository """
1265
1266 super(SVNTest, self).setUp()
1267
1268 # Create something we can fetch
1269 src_dir = tempfile.mkdtemp(dir=self.tempdir,
1270 prefix='svnfetch_srcdir_')
1271 src_dir = os.path.abspath(src_dir)
1272 bb.process.run("echo readme > README.md", cwd=src_dir)
1273
1274 # Store it in a local SVN repository
1275 repo_dir = tempfile.mkdtemp(dir=self.tempdir,
1276 prefix='svnfetch_localrepo_')
1277 repo_dir = os.path.abspath(repo_dir)
1278 bb.process.run("svnadmin create project", cwd=repo_dir)
1279
1280 self.repo_url = "file://%s/project" % repo_dir
1281 bb.process.run("svn import --non-interactive -m 'Initial import' %s %s/trunk" % (src_dir, self.repo_url),
1282 cwd=repo_dir)
1283
1284 bb.process.run("svn co %s svnfetch_co" % self.repo_url, cwd=self.tempdir)
Patrick Williams73bd93f2024-02-20 08:07:48 -06001285 # Github won't emulate SVN anymore (see https://github.blog/2023-01-20-sunsetting-subversion-support/)
1286 # Use still accessible svn repo (only trunk to avoid longer downloads)
1287 bb.process.run("svn propset svn:externals 'bitbake https://svn.apache.org/repos/asf/serf/trunk' .",
Brad Bishop15ae2502019-06-18 21:44:24 -04001288 cwd=os.path.join(self.tempdir, 'svnfetch_co', 'trunk'))
1289 bb.process.run("svn commit --non-interactive -m 'Add external'",
1290 cwd=os.path.join(self.tempdir, 'svnfetch_co', 'trunk'))
1291
1292 self.src_dir = src_dir
1293 self.repo_dir = repo_dir
1294
1295 @skipIfNoSvn()
1296 def tearDown(self):
1297 os.chdir(self.origdir)
1298 if os.environ.get("BB_TMPDIR_NOCLEAN") == "yes":
1299 print("Not cleaning up %s. Please remove manually." % self.tempdir)
1300 else:
1301 bb.utils.prunedir(self.tempdir)
1302
1303 @skipIfNoSvn()
1304 @skipIfNoNetwork()
1305 def test_noexternal_svn(self):
1306 # Always match the rev count from setUp (currently rev 2)
1307 url = "svn://%s;module=trunk;protocol=file;rev=2" % self.repo_url.replace('file://', '')
1308 fetcher = bb.fetch.Fetch([url], self.d)
1309 fetcher.download()
1310 os.chdir(os.path.dirname(self.unpackdir))
1311 fetcher.unpack(self.unpackdir)
1312
1313 self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'trunk')), msg="Missing trunk")
1314 self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'trunk', 'README.md')), msg="Missing contents")
Patrick Williams73bd93f2024-02-20 08:07:48 -06001315 self.assertFalse(os.path.exists(os.path.join(self.unpackdir, 'trunk/bitbake/protocols')), msg="External dir should NOT exist")
1316 self.assertFalse(os.path.exists(os.path.join(self.unpackdir, 'trunk/bitbake/protocols', 'fcgi_buckets.h')), msg="External fcgi_buckets.h should NOT exit")
Brad Bishop15ae2502019-06-18 21:44:24 -04001317
1318 @skipIfNoSvn()
1319 def test_external_svn(self):
1320 # Always match the rev count from setUp (currently rev 2)
1321 url = "svn://%s;module=trunk;protocol=file;externals=allowed;rev=2" % self.repo_url.replace('file://', '')
1322 fetcher = bb.fetch.Fetch([url], self.d)
1323 fetcher.download()
1324 os.chdir(os.path.dirname(self.unpackdir))
1325 fetcher.unpack(self.unpackdir)
1326
1327 self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'trunk')), msg="Missing trunk")
1328 self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'trunk', 'README.md')), msg="Missing contents")
Patrick Williams73bd93f2024-02-20 08:07:48 -06001329 self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'trunk/bitbake/protocols')), msg="External dir should exist")
1330 self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'trunk/bitbake/protocols', 'fcgi_buckets.h')), msg="External fcgi_buckets.h should exit")
Brad Bishop15ae2502019-06-18 21:44:24 -04001331
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001332class TrustedNetworksTest(FetcherTest):
1333 def test_trusted_network(self):
1334 # Ensure trusted_network returns False when the host IS in the list.
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001335 url = "git://Someserver.org/foo;rev=1;branch=master"
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001336 self.d.setVar("BB_ALLOWED_NETWORKS", "server1.org someserver.org server2.org server3.org")
1337 self.assertTrue(bb.fetch.trusted_network(self.d, url))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001338
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001339 def test_wild_trusted_network(self):
1340 # Ensure trusted_network returns true when the *.host IS in the list.
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001341 url = "git://Someserver.org/foo;rev=1;branch=master"
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001342 self.d.setVar("BB_ALLOWED_NETWORKS", "server1.org *.someserver.org server2.org server3.org")
1343 self.assertTrue(bb.fetch.trusted_network(self.d, url))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001344
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001345 def test_prefix_wild_trusted_network(self):
1346 # Ensure trusted_network returns true when the prefix matches *.host.
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001347 url = "git://git.Someserver.org/foo;rev=1;branch=master"
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001348 self.d.setVar("BB_ALLOWED_NETWORKS", "server1.org *.someserver.org server2.org server3.org")
1349 self.assertTrue(bb.fetch.trusted_network(self.d, url))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001350
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001351 def test_two_prefix_wild_trusted_network(self):
1352 # Ensure trusted_network returns true when the prefix matches *.host.
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001353 url = "git://something.git.Someserver.org/foo;rev=1;branch=master"
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001354 self.d.setVar("BB_ALLOWED_NETWORKS", "server1.org *.someserver.org server2.org server3.org")
1355 self.assertTrue(bb.fetch.trusted_network(self.d, url))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001356
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001357 def test_port_trusted_network(self):
1358 # Ensure trusted_network returns True, even if the url specifies a port.
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001359 url = "git://someserver.org:8080/foo;rev=1;branch=master"
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001360 self.d.setVar("BB_ALLOWED_NETWORKS", "someserver.org")
1361 self.assertTrue(bb.fetch.trusted_network(self.d, url))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001362
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001363 def test_untrusted_network(self):
1364 # Ensure trusted_network returns False when the host is NOT in the list.
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001365 url = "git://someserver.org/foo;rev=1;branch=master"
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001366 self.d.setVar("BB_ALLOWED_NETWORKS", "server1.org server2.org server3.org")
1367 self.assertFalse(bb.fetch.trusted_network(self.d, url))
1368
1369 def test_wild_untrusted_network(self):
1370 # Ensure trusted_network returns False when the host is NOT in the list.
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001371 url = "git://*.someserver.org/foo;rev=1;branch=master"
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001372 self.d.setVar("BB_ALLOWED_NETWORKS", "server1.org server2.org server3.org")
1373 self.assertFalse(bb.fetch.trusted_network(self.d, url))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001374
1375class URLHandle(unittest.TestCase):
1376
1377 datatable = {
1378 "http://www.google.com/index.html" : ('http', 'www.google.com', '/index.html', '', '', {}),
1379 "cvs://anoncvs@cvs.handhelds.org/cvs;module=familiar/dist/ipkg" : ('cvs', 'cvs.handhelds.org', '/cvs', 'anoncvs', '', {'module': 'familiar/dist/ipkg'}),
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001380 "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')])),
Andrew Geissler028142b2023-05-05 11:29:21 -05001381 "git://git.openembedded.org/bitbake;branch=@foo;protocol=https" : ('git', 'git.openembedded.org', '/bitbake', '', '', {'branch': '@foo', 'protocol' : 'https'}),
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001382 "file://somelocation;someparam=1": ('file', '', 'somelocation', '', '', {'someparam': '1'}),
Patrick Williams2a254922023-08-11 09:48:11 -05001383 "https://somesite.com/somerepo.git;user=anyUser:idtoken=1234" : ('https', 'somesite.com', '/somerepo.git', '', '', {'user': 'anyUser:idtoken=1234'}),
Andrew Geissler028142b2023-05-05 11:29:21 -05001384 r'git://s.o-me_ONE:!#$%^&*()-_={}[]\|:?,.<>~`@git.openembedded.org/bitbake;branch=main;protocol=https': ('git', 'git.openembedded.org', '/bitbake', 's.o-me_ONE', r'!#$%^&*()-_={}[]\|:?,.<>~`', {'branch': 'main', 'protocol' : 'https'}),
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001385 }
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001386 # we require a pathname to encodeurl but users can still pass such urls to
1387 # decodeurl and we need to handle them
1388 decodedata = datatable.copy()
1389 decodedata.update({
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001390 "http://somesite.net;someparam=1": ('http', 'somesite.net', '/', '', '', {'someparam': '1'}),
Patrick Williams2390b1b2022-11-03 13:47:49 -05001391 "npmsw://some.registry.url;package=@pkg;version=latest": ('npmsw', 'some.registry.url', '/', '', '', {'package': '@pkg', 'version': 'latest'}),
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001392 })
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001393
1394 def test_decodeurl(self):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001395 for k, v in self.decodedata.items():
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001396 result = bb.fetch.decodeurl(k)
1397 self.assertEqual(result, v)
1398
1399 def test_encodeurl(self):
1400 for k, v in self.datatable.items():
1401 result = bb.fetch.encodeurl(v)
1402 self.assertEqual(result, k)
1403
1404class FetchLatestVersionTest(FetcherTest):
1405
1406 test_git_uris = {
1407 # version pattern "X.Y.Z"
Patrick Williams73bd93f2024-02-20 08:07:48 -06001408 ("mx-1.0", "git://github.com/clutter-project/mx.git;branch=mx-1.4;protocol=https", "9b1db6b8060bd00b121a692f942404a24ae2960f", "", "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001409 : "1.99.4",
1410 # version pattern "vX.Y"
Andrew Geisslerd25ed322020-06-27 00:28:28 -05001411 # mirror of git.infradead.org since network issues interfered with testing
Patrick Williams73bd93f2024-02-20 08:07:48 -06001412 ("mtd-utils", "git://git.yoctoproject.org/mtd-utils.git;branch=master;protocol=https", "ca39eb1d98e736109c64ff9c1aa2a6ecca222d8f", "", "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001413 : "1.5.0",
1414 # version pattern "pkg_name-X.Y"
Andrew Geisslerc9f78652020-09-18 14:11:35 -05001415 # mirror of git://anongit.freedesktop.org/git/xorg/proto/presentproto since network issues interfered with testing
Patrick Williams73bd93f2024-02-20 08:07:48 -06001416 ("presentproto", "git://git.yoctoproject.org/bbfetchtests-presentproto;branch=master;protocol=https", "24f3a56e541b0a9e6c6ee76081f441221a120ef9", "", "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001417 : "1.0",
1418 # version pattern "pkg_name-vX.Y.Z"
Patrick Williams73bd93f2024-02-20 08:07:48 -06001419 ("dtc", "git://git.yoctoproject.org/bbfetchtests-dtc.git;branch=master;protocol=https", "65cc4d2748a2c2e6f27f1cf39e07a5dbabd80ebf", "", "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001420 : "1.4.0",
1421 # combination version pattern
Patrick Williams73bd93f2024-02-20 08:07:48 -06001422 ("sysprof", "git://gitlab.gnome.org/GNOME/sysprof.git;protocol=https;branch=master", "cd44ee6644c3641507fb53b8a2a69137f2971219", "", "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001423 : "1.2.0",
Patrick Williams73bd93f2024-02-20 08:07:48 -06001424 ("u-boot-mkimage", "git://git.denx.de/u-boot.git;branch=master;protocol=git", "62c175fbb8a0f9a926c88294ea9f7e88eb898f6c", "", "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001425 : "2014.01",
1426 # version pattern "yyyymmdd"
Patrick Williams73bd93f2024-02-20 08:07:48 -06001427 ("mobile-broadband-provider-info", "git://gitlab.gnome.org/GNOME/mobile-broadband-provider-info.git;protocol=https;branch=master", "4ed19e11c2975105b71b956440acdb25d46a347d", "", "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001428 : "20120614",
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001429 # packages with a valid UPSTREAM_CHECK_GITTAGREGEX
Andrew Geisslerc9f78652020-09-18 14:11:35 -05001430 # mirror of git://anongit.freedesktop.org/xorg/driver/xf86-video-omap since network issues interfered with testing
Patrick Williams73bd93f2024-02-20 08:07:48 -06001431 ("xf86-video-omap", "git://git.yoctoproject.org/bbfetchtests-xf86-video-omap;branch=master;protocol=https", "ae0394e687f1a77e966cf72f895da91840dffb8f", r"(?P<pver>(\d+\.(\d\.?)*))", "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001432 : "0.4.3",
Patrick Williams73bd93f2024-02-20 08:07:48 -06001433 ("build-appliance-image", "git://git.yoctoproject.org/poky;branch=master;protocol=https", "b37dd451a52622d5b570183a81583cc34c2ff555", r"(?P<pver>(([0-9][\.|_]?)+[0-9]))", "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001434 : "11.0.0",
Patrick Williams73bd93f2024-02-20 08:07:48 -06001435 ("chkconfig-alternatives-native", "git://github.com/kergoth/chkconfig;branch=sysroot;protocol=https", "cd437ecbd8986c894442f8fce1e0061e20f04dee", r"chkconfig\-(?P<pver>((\d+[\.\-_]*)+))", "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001436 : "1.3.59",
Patrick Williams73bd93f2024-02-20 08:07:48 -06001437 ("remake", "git://github.com/rocky/remake.git;protocol=https;branch=master", "f05508e521987c8494c92d9c2871aec46307d51d", r"(?P<pver>(\d+\.(\d+\.)*\d*(\+dbg\d+(\.\d+)*)*))", "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001438 : "3.82+dbg0.9",
Patrick Williams73bd93f2024-02-20 08:07:48 -06001439 ("sysdig", "git://github.com/draios/sysdig.git;branch=dev;protocol=https", "4fb6288275f567f63515df0ff0a6518043ecfa9b", r"^(?P<pver>\d+(\.\d+)+)", "10.0.0")
1440 : "0.28.0",
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001441 }
1442
1443 test_wget_uris = {
Andrew Geissler82c905d2020-04-13 13:39:40 -05001444 #
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001445 # packages with versions inside directory name
Andrew Geissler82c905d2020-04-13 13:39:40 -05001446 #
1447 # http://kernel.org/pub/linux/utils/util-linux/v2.23/util-linux-2.24.2.tar.bz2
1448 ("util-linux", "/pub/linux/utils/util-linux/v2.23/util-linux-2.24.2.tar.bz2", "", "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001449 : "2.24.2",
Andrew Geissler82c905d2020-04-13 13:39:40 -05001450 # http://www.abisource.com/downloads/enchant/1.6.0/enchant-1.6.0.tar.gz
1451 ("enchant", "/downloads/enchant/1.6.0/enchant-1.6.0.tar.gz", "", "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001452 : "1.6.0",
Andrew Geissler82c905d2020-04-13 13:39:40 -05001453 # http://www.cmake.org/files/v2.8/cmake-2.8.12.1.tar.gz
1454 ("cmake", "/files/v2.8/cmake-2.8.12.1.tar.gz", "", "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001455 : "2.8.12.1",
Andrew Geissler517393d2023-01-13 08:55:19 -06001456 # https://download.gnome.org/sources/libxml2/2.9/libxml2-2.9.14.tar.xz
1457 ("libxml2", "/software/libxml2/2.9/libxml2-2.9.14.tar.xz", "", "")
1458 : "2.10.3",
Andrew Geissler82c905d2020-04-13 13:39:40 -05001459 #
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001460 # packages with versions only in current directory
Andrew Geissler82c905d2020-04-13 13:39:40 -05001461 #
Andrew Geisslereff27472021-10-29 15:35:00 -05001462 # https://downloads.yoctoproject.org/releases/eglibc/eglibc-2.18-svnr23787.tar.bz2
Andrew Geissler82c905d2020-04-13 13:39:40 -05001463 ("eglic", "/releases/eglibc/eglibc-2.18-svnr23787.tar.bz2", "", "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001464 : "2.19",
Andrew Geisslereff27472021-10-29 15:35:00 -05001465 # https://downloads.yoctoproject.org/releases/gnu-config/gnu-config-20120814.tar.bz2
Andrew Geissler82c905d2020-04-13 13:39:40 -05001466 ("gnu-config", "/releases/gnu-config/gnu-config-20120814.tar.bz2", "", "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001467 : "20120814",
Andrew Geissler82c905d2020-04-13 13:39:40 -05001468 #
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001469 # packages with "99" in the name of possible version
Andrew Geissler82c905d2020-04-13 13:39:40 -05001470 #
1471 # http://freedesktop.org/software/pulseaudio/releases/pulseaudio-4.0.tar.xz
1472 ("pulseaudio", "/software/pulseaudio/releases/pulseaudio-4.0.tar.xz", "", "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001473 : "5.0",
Andrew Geissler82c905d2020-04-13 13:39:40 -05001474 # http://xorg.freedesktop.org/releases/individual/xserver/xorg-server-1.15.1.tar.bz2
1475 ("xserver-xorg", "/releases/individual/xserver/xorg-server-1.15.1.tar.bz2", "", "")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001476 : "1.15.1",
Andrew Geissler82c905d2020-04-13 13:39:40 -05001477 #
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001478 # packages with valid UPSTREAM_CHECK_URI and UPSTREAM_CHECK_REGEX
Andrew Geissler82c905d2020-04-13 13:39:40 -05001479 #
1480 # http://www.cups.org/software/1.7.2/cups-1.7.2-source.tar.bz2
1481 # https://github.com/apple/cups/releases
Andrew Geissler5199d832021-09-24 16:47:35 -05001482 ("cups", "/software/1.7.2/cups-1.7.2-source.tar.bz2", "/apple/cups/releases", r"(?P<name>cups\-)(?P<pver>((\d+[\.\-_]*)+))\-source\.tar\.gz")
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001483 : "2.0.0",
Andrew Geissler82c905d2020-04-13 13:39:40 -05001484 # http://download.oracle.com/berkeley-db/db-5.3.21.tar.gz
1485 # http://ftp.debian.org/debian/pool/main/d/db5.3/
Andrew Geissler5199d832021-09-24 16:47:35 -05001486 ("db", "/berkeley-db/db-5.3.21.tar.gz", "/debian/pool/main/d/db5.3/", r"(?P<name>db5\.3_)(?P<pver>\d+(\.\d+)+).+\.orig\.tar\.xz")
Brad Bishop79641f22019-09-10 07:20:22 -04001487 : "5.3.10",
Andrew Geissler595f6302022-01-24 19:11:47 +00001488 #
1489 # packages where the tarball compression changed in the new version
1490 #
1491 # http://ftp.debian.org/debian/pool/main/m/minicom/minicom_2.7.1.orig.tar.gz
1492 ("minicom", "/debian/pool/main/m/minicom/minicom_2.7.1.orig.tar.gz", "", "")
1493 : "2.8",
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001494 }
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001495
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001496 @skipIfNoNetwork()
1497 def test_git_latest_versionstring(self):
1498 for k, v in self.test_git_uris.items():
1499 self.d.setVar("PN", k[0])
1500 self.d.setVar("SRCREV", k[2])
1501 self.d.setVar("UPSTREAM_CHECK_GITTAGREGEX", k[3])
1502 ud = bb.fetch2.FetchData(k[1], self.d)
1503 pupver= ud.method.latest_versionstring(ud, self.d)
1504 verstring = pupver[0]
Brad Bishop316dfdd2018-06-25 12:45:53 -04001505 self.assertTrue(verstring, msg="Could not find upstream version for %s" % k[0])
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001506 r = bb.utils.vercmp_string(v, verstring)
1507 self.assertTrue(r == -1 or r == 0, msg="Package %s, version: %s <= %s" % (k[0], v, verstring))
Patrick Williams73bd93f2024-02-20 08:07:48 -06001508 if k[4]:
1509 r = bb.utils.vercmp_string(verstring, k[4])
1510 self.assertTrue(r == -1 or r == 0, msg="Package %s, version: %s <= %s" % (k[0], verstring, k[4]))
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001511
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001512 def test_wget_latest_versionstring(self):
Andrew Geissler82c905d2020-04-13 13:39:40 -05001513 testdata = os.path.dirname(os.path.abspath(__file__)) + "/fetch-testdata"
1514 server = HTTPService(testdata)
1515 server.start()
1516 port = server.port
1517 try:
1518 for k, v in self.test_wget_uris.items():
1519 self.d.setVar("PN", k[0])
1520 checkuri = ""
1521 if k[2]:
1522 checkuri = "http://localhost:%s/" % port + k[2]
1523 self.d.setVar("UPSTREAM_CHECK_URI", checkuri)
1524 self.d.setVar("UPSTREAM_CHECK_REGEX", k[3])
1525 url = "http://localhost:%s/" % port + k[1]
1526 ud = bb.fetch2.FetchData(url, self.d)
1527 pupver = ud.method.latest_versionstring(ud, self.d)
1528 verstring = pupver[0]
1529 self.assertTrue(verstring, msg="Could not find upstream version for %s" % k[0])
1530 r = bb.utils.vercmp_string(v, verstring)
1531 self.assertTrue(r == -1 or r == 0, msg="Package %s, version: %s <= %s" % (k[0], v, verstring))
1532 finally:
1533 server.stop()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001534
1535
1536class FetchCheckStatusTest(FetcherTest):
Andrew Geisslereff27472021-10-29 15:35:00 -05001537 test_wget_uris = ["https://downloads.yoctoproject.org/releases/sato/sato-engine-0.1.tar.gz",
1538 "https://downloads.yoctoproject.org/releases/sato/sato-engine-0.2.tar.gz",
1539 "https://downloads.yoctoproject.org/releases/sato/sato-engine-0.3.tar.gz",
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001540 "https://yoctoproject.org/",
Andrew Geissler95ac1b82021-03-31 14:34:31 -05001541 "https://docs.yoctoproject.org",
Andrew Geisslereff27472021-10-29 15:35:00 -05001542 "https://downloads.yoctoproject.org/releases/opkg/opkg-0.1.7.tar.gz",
1543 "https://downloads.yoctoproject.org/releases/opkg/opkg-0.3.0.tar.gz",
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001544 "ftp://sourceware.org/pub/libffi/libffi-1.20.tar.gz",
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001545 # GitHub releases are hosted on Amazon S3, which doesn't support HEAD
1546 "https://github.com/kergoth/tslib/releases/download/1.1/tslib-1.1.tar.xz"
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001547 ]
1548
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001549 @skipIfNoNetwork()
1550 def test_wget_checkstatus(self):
1551 fetch = bb.fetch2.Fetch(self.test_wget_uris, self.d)
1552 for u in self.test_wget_uris:
1553 with self.subTest(url=u):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001554 ud = fetch.ud[u]
1555 m = ud.method
1556 ret = m.checkstatus(fetch, ud, self.d)
1557 self.assertTrue(ret, msg="URI %s, can't check status" % (u))
1558
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001559 @skipIfNoNetwork()
1560 def test_wget_checkstatus_connection_cache(self):
1561 from bb.fetch2 import FetchConnectionCache
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001562
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001563 connection_cache = FetchConnectionCache()
1564 fetch = bb.fetch2.Fetch(self.test_wget_uris, self.d,
1565 connection_cache = connection_cache)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001566
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001567 for u in self.test_wget_uris:
1568 with self.subTest(url=u):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001569 ud = fetch.ud[u]
1570 m = ud.method
1571 ret = m.checkstatus(fetch, ud, self.d)
1572 self.assertTrue(ret, msg="URI %s, can't check status" % (u))
1573
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001574 connection_cache.close_connections()
1575
1576
1577class GitMakeShallowTest(FetcherTest):
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001578 def setUp(self):
1579 FetcherTest.setUp(self)
1580 self.gitdir = os.path.join(self.tempdir, 'gitshallow')
1581 bb.utils.mkdirhier(self.gitdir)
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001582 self.git_init()
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001583
1584 def assertRefs(self, expected_refs):
1585 actual_refs = self.git(['for-each-ref', '--format=%(refname)']).splitlines()
1586 full_expected = self.git(['rev-parse', '--symbolic-full-name'] + expected_refs).splitlines()
1587 self.assertEqual(sorted(full_expected), sorted(actual_refs))
1588
1589 def assertRevCount(self, expected_count, args=None):
1590 if args is None:
1591 args = ['HEAD']
1592 revs = self.git(['rev-list'] + args)
1593 actual_count = len(revs.splitlines())
1594 self.assertEqual(expected_count, actual_count, msg='Object count `%d` is not the expected `%d`' % (actual_count, expected_count))
1595
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001596 def make_shallow(self, args=None):
1597 if args is None:
1598 args = ['HEAD']
Brad Bishop316dfdd2018-06-25 12:45:53 -04001599 return bb.process.run([bb.fetch2.git.Git.make_shallow_path] + args, cwd=self.gitdir)
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001600
1601 def add_empty_file(self, path, msg=None):
1602 if msg is None:
1603 msg = path
1604 open(os.path.join(self.gitdir, path), 'w').close()
1605 self.git(['add', path])
1606 self.git(['commit', '-m', msg, path])
1607
1608 def test_make_shallow_single_branch_no_merge(self):
1609 self.add_empty_file('a')
1610 self.add_empty_file('b')
1611 self.assertRevCount(2)
1612 self.make_shallow()
1613 self.assertRevCount(1)
1614
1615 def test_make_shallow_single_branch_one_merge(self):
1616 self.add_empty_file('a')
1617 self.add_empty_file('b')
1618 self.git('checkout -b a_branch')
1619 self.add_empty_file('c')
1620 self.git('checkout master')
1621 self.add_empty_file('d')
1622 self.git('merge --no-ff --no-edit a_branch')
1623 self.git('branch -d a_branch')
1624 self.add_empty_file('e')
1625 self.assertRevCount(6)
1626 self.make_shallow(['HEAD~2'])
1627 self.assertRevCount(5)
1628
1629 def test_make_shallow_at_merge(self):
1630 self.add_empty_file('a')
1631 self.git('checkout -b a_branch')
1632 self.add_empty_file('b')
1633 self.git('checkout master')
1634 self.git('merge --no-ff --no-edit a_branch')
1635 self.git('branch -d a_branch')
1636 self.assertRevCount(3)
1637 self.make_shallow()
1638 self.assertRevCount(1)
1639
1640 def test_make_shallow_annotated_tag(self):
1641 self.add_empty_file('a')
1642 self.add_empty_file('b')
1643 self.git('tag -a -m a_tag a_tag')
1644 self.assertRevCount(2)
1645 self.make_shallow(['a_tag'])
1646 self.assertRevCount(1)
1647
1648 def test_make_shallow_multi_ref(self):
1649 self.add_empty_file('a')
1650 self.add_empty_file('b')
1651 self.git('checkout -b a_branch')
1652 self.add_empty_file('c')
1653 self.git('checkout master')
1654 self.add_empty_file('d')
1655 self.git('checkout -b a_branch_2')
1656 self.add_empty_file('a_tag')
1657 self.git('tag a_tag')
1658 self.git('checkout master')
1659 self.git('branch -D a_branch_2')
1660 self.add_empty_file('e')
1661 self.assertRevCount(6, ['--all'])
1662 self.make_shallow()
1663 self.assertRevCount(5, ['--all'])
1664
1665 def test_make_shallow_multi_ref_trim(self):
1666 self.add_empty_file('a')
1667 self.git('checkout -b a_branch')
1668 self.add_empty_file('c')
1669 self.git('checkout master')
1670 self.assertRevCount(1)
1671 self.assertRevCount(2, ['--all'])
1672 self.assertRefs(['master', 'a_branch'])
1673 self.make_shallow(['-r', 'master', 'HEAD'])
1674 self.assertRevCount(1, ['--all'])
1675 self.assertRefs(['master'])
1676
1677 def test_make_shallow_noop(self):
1678 self.add_empty_file('a')
1679 self.assertRevCount(1)
1680 self.make_shallow()
1681 self.assertRevCount(1)
1682
1683 @skipIfNoNetwork()
1684 def test_make_shallow_bitbake(self):
1685 self.git('remote add origin https://github.com/openembedded/bitbake')
1686 self.git('fetch --tags origin')
1687 orig_revs = len(self.git('rev-list --all').splitlines())
1688 self.make_shallow(['refs/tags/1.10.0'])
1689 self.assertRevCount(orig_revs - 1746, ['--all'])
1690
1691class GitShallowTest(FetcherTest):
1692 def setUp(self):
1693 FetcherTest.setUp(self)
1694 self.gitdir = os.path.join(self.tempdir, 'git')
1695 self.srcdir = os.path.join(self.tempdir, 'gitsource')
1696
1697 bb.utils.mkdirhier(self.srcdir)
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001698 self.git_init(cwd=self.srcdir)
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001699 self.d.setVar('WORKDIR', self.tempdir)
1700 self.d.setVar('S', self.gitdir)
1701 self.d.delVar('PREMIRRORS')
1702 self.d.delVar('MIRRORS')
1703
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001704 uri = 'git://%s;protocol=file;subdir=${S};branch=master' % self.srcdir
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001705 self.d.setVar('SRC_URI', uri)
1706 self.d.setVar('SRCREV', '${AUTOREV}')
1707 self.d.setVar('AUTOREV', '${@bb.fetch2.get_autorev(d)}')
1708
1709 self.d.setVar('BB_GIT_SHALLOW', '1')
1710 self.d.setVar('BB_GENERATE_MIRROR_TARBALLS', '0')
1711 self.d.setVar('BB_GENERATE_SHALLOW_TARBALLS', '1')
Andrew Geisslerfc113ea2023-03-31 09:59:46 -05001712 self.d.setVar("__BBSRCREV_SEEN", "1")
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001713
1714 def assertRefs(self, expected_refs, cwd=None):
1715 if cwd is None:
1716 cwd = self.gitdir
1717 actual_refs = self.git(['for-each-ref', '--format=%(refname)'], cwd=cwd).splitlines()
1718 full_expected = self.git(['rev-parse', '--symbolic-full-name'] + expected_refs, cwd=cwd).splitlines()
1719 self.assertEqual(sorted(set(full_expected)), sorted(set(actual_refs)))
1720
1721 def assertRevCount(self, expected_count, args=None, cwd=None):
1722 if args is None:
1723 args = ['HEAD']
1724 if cwd is None:
1725 cwd = self.gitdir
1726 revs = self.git(['rev-list'] + args, cwd=cwd)
1727 actual_count = len(revs.splitlines())
1728 self.assertEqual(expected_count, actual_count, msg='Object count `%d` is not the expected `%d`' % (actual_count, expected_count))
1729
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001730 def add_empty_file(self, path, cwd=None, msg=None):
1731 if msg is None:
1732 msg = path
1733 if cwd is None:
1734 cwd = self.srcdir
1735 open(os.path.join(cwd, path), 'w').close()
1736 self.git(['add', path], cwd)
1737 self.git(['commit', '-m', msg, path], cwd)
1738
1739 def fetch(self, uri=None):
1740 if uri is None:
Brad Bishop19323692019-04-05 15:28:33 -04001741 uris = self.d.getVar('SRC_URI').split()
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001742 uri = uris[0]
1743 d = self.d
1744 else:
1745 d = self.d.createCopy()
1746 d.setVar('SRC_URI', uri)
1747 uri = d.expand(uri)
1748 uris = [uri]
1749
1750 fetcher = bb.fetch2.Fetch(uris, d)
1751 fetcher.download()
1752 ud = fetcher.ud[uri]
1753 return fetcher, ud
1754
1755 def fetch_and_unpack(self, uri=None):
1756 fetcher, ud = self.fetch(uri)
1757 fetcher.unpack(self.d.getVar('WORKDIR'))
1758 assert os.path.exists(self.d.getVar('S'))
1759 return fetcher, ud
1760
1761 def fetch_shallow(self, uri=None, disabled=False, keepclone=False):
1762 """Fetch a uri, generating a shallow tarball, then unpack using it"""
1763 fetcher, ud = self.fetch_and_unpack(uri)
1764 assert os.path.exists(ud.clonedir), 'Git clone in DLDIR (%s) does not exist for uri %s' % (ud.clonedir, uri)
1765
1766 # Confirm that the unpacked repo is unshallow
1767 if not disabled:
1768 assert os.path.exists(os.path.join(self.dldir, ud.mirrortarballs[0]))
1769
1770 # fetch and unpack, from the shallow tarball
1771 bb.utils.remove(self.gitdir, recurse=True)
Andrew Geisslerc926e172021-05-07 16:11:35 -05001772 bb.process.run('chmod u+w -R "%s"' % ud.clonedir)
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001773 bb.utils.remove(ud.clonedir, recurse=True)
Brad Bishopf8caae32019-03-25 13:13:56 -04001774 bb.utils.remove(ud.clonedir.replace('gitsource', 'gitsubmodule'), recurse=True)
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001775
1776 # confirm that the unpacked repo is used when no git clone or git
1777 # mirror tarball is available
1778 fetcher, ud = self.fetch_and_unpack(uri)
1779 if not disabled:
1780 assert os.path.exists(os.path.join(self.gitdir, '.git', 'shallow')), 'Unpacked git repository at %s is not shallow' % self.gitdir
1781 else:
1782 assert not os.path.exists(os.path.join(self.gitdir, '.git', 'shallow')), 'Unpacked git repository at %s is shallow' % self.gitdir
1783 return fetcher, ud
1784
1785 def test_shallow_disabled(self):
1786 self.add_empty_file('a')
1787 self.add_empty_file('b')
1788 self.assertRevCount(2, cwd=self.srcdir)
1789
1790 self.d.setVar('BB_GIT_SHALLOW', '0')
1791 self.fetch_shallow(disabled=True)
1792 self.assertRevCount(2)
1793
1794 def test_shallow_nobranch(self):
1795 self.add_empty_file('a')
1796 self.add_empty_file('b')
1797 self.assertRevCount(2, cwd=self.srcdir)
1798
1799 srcrev = self.git('rev-parse HEAD', cwd=self.srcdir).strip()
1800 self.d.setVar('SRCREV', srcrev)
Brad Bishop19323692019-04-05 15:28:33 -04001801 uri = self.d.getVar('SRC_URI').split()[0]
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001802 uri = '%s;nobranch=1;bare=1' % uri
1803
1804 self.fetch_shallow(uri)
1805 self.assertRevCount(1)
1806
1807 # shallow refs are used to ensure the srcrev sticks around when we
1808 # have no other branches referencing it
1809 self.assertRefs(['refs/shallow/default'])
1810
1811 def test_shallow_default_depth_1(self):
1812 # Create initial git repo
1813 self.add_empty_file('a')
1814 self.add_empty_file('b')
1815 self.assertRevCount(2, cwd=self.srcdir)
1816
1817 self.fetch_shallow()
1818 self.assertRevCount(1)
1819
1820 def test_shallow_depth_0_disables(self):
1821 self.add_empty_file('a')
1822 self.add_empty_file('b')
1823 self.assertRevCount(2, cwd=self.srcdir)
1824
1825 self.d.setVar('BB_GIT_SHALLOW_DEPTH', '0')
1826 self.fetch_shallow(disabled=True)
1827 self.assertRevCount(2)
1828
1829 def test_shallow_depth_default_override(self):
1830 self.add_empty_file('a')
1831 self.add_empty_file('b')
1832 self.assertRevCount(2, cwd=self.srcdir)
1833
1834 self.d.setVar('BB_GIT_SHALLOW_DEPTH', '2')
1835 self.d.setVar('BB_GIT_SHALLOW_DEPTH_default', '1')
1836 self.fetch_shallow()
1837 self.assertRevCount(1)
1838
1839 def test_shallow_depth_default_override_disable(self):
1840 self.add_empty_file('a')
1841 self.add_empty_file('b')
1842 self.add_empty_file('c')
1843 self.assertRevCount(3, cwd=self.srcdir)
1844
1845 self.d.setVar('BB_GIT_SHALLOW_DEPTH', '0')
1846 self.d.setVar('BB_GIT_SHALLOW_DEPTH_default', '2')
1847 self.fetch_shallow()
1848 self.assertRevCount(2)
1849
1850 def test_current_shallow_out_of_date_clone(self):
1851 # Create initial git repo
1852 self.add_empty_file('a')
1853 self.add_empty_file('b')
1854 self.add_empty_file('c')
1855 self.assertRevCount(3, cwd=self.srcdir)
1856
1857 # Clone and generate mirror tarball
1858 fetcher, ud = self.fetch()
1859
1860 # Ensure we have a current mirror tarball, but an out of date clone
1861 self.git('update-ref refs/heads/master refs/heads/master~1', cwd=ud.clonedir)
1862 self.assertRevCount(2, cwd=ud.clonedir)
1863
1864 # Fetch and unpack, from the current tarball, not the out of date clone
1865 bb.utils.remove(self.gitdir, recurse=True)
1866 fetcher, ud = self.fetch()
1867 fetcher.unpack(self.d.getVar('WORKDIR'))
1868 self.assertRevCount(1)
1869
1870 def test_shallow_single_branch_no_merge(self):
1871 self.add_empty_file('a')
1872 self.add_empty_file('b')
1873 self.assertRevCount(2, cwd=self.srcdir)
1874
1875 self.fetch_shallow()
1876 self.assertRevCount(1)
1877 assert os.path.exists(os.path.join(self.gitdir, 'a'))
1878 assert os.path.exists(os.path.join(self.gitdir, 'b'))
1879
1880 def test_shallow_no_dangling(self):
1881 self.add_empty_file('a')
1882 self.add_empty_file('b')
1883 self.assertRevCount(2, cwd=self.srcdir)
1884
1885 self.fetch_shallow()
1886 self.assertRevCount(1)
1887 assert not self.git('fsck --dangling')
1888
1889 def test_shallow_srcrev_branch_truncation(self):
1890 self.add_empty_file('a')
1891 self.add_empty_file('b')
1892 b_commit = self.git('rev-parse HEAD', cwd=self.srcdir).rstrip()
1893 self.add_empty_file('c')
1894 self.assertRevCount(3, cwd=self.srcdir)
1895
1896 self.d.setVar('SRCREV', b_commit)
1897 self.fetch_shallow()
1898
1899 # The 'c' commit was removed entirely, and 'a' was removed from history
1900 self.assertRevCount(1, ['--all'])
1901 self.assertEqual(self.git('rev-parse HEAD').strip(), b_commit)
1902 assert os.path.exists(os.path.join(self.gitdir, 'a'))
1903 assert os.path.exists(os.path.join(self.gitdir, 'b'))
1904 assert not os.path.exists(os.path.join(self.gitdir, 'c'))
1905
1906 def test_shallow_ref_pruning(self):
1907 self.add_empty_file('a')
1908 self.add_empty_file('b')
1909 self.git('branch a_branch', cwd=self.srcdir)
1910 self.assertRefs(['master', 'a_branch'], cwd=self.srcdir)
1911 self.assertRevCount(2, cwd=self.srcdir)
1912
1913 self.fetch_shallow()
1914
1915 self.assertRefs(['master', 'origin/master'])
1916 self.assertRevCount(1)
1917
1918 def test_shallow_submodules(self):
1919 self.add_empty_file('a')
1920 self.add_empty_file('b')
1921
1922 smdir = os.path.join(self.tempdir, 'gitsubmodule')
1923 bb.utils.mkdirhier(smdir)
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001924 self.git_init(cwd=smdir)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001925 # Make this look like it was cloned from a remote...
1926 self.git('config --add remote.origin.url "%s"' % smdir, cwd=smdir)
1927 self.git('config --add remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"', cwd=smdir)
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001928 self.add_empty_file('asub', cwd=smdir)
Brad Bishopf8caae32019-03-25 13:13:56 -04001929 self.add_empty_file('bsub', cwd=smdir)
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001930
1931 self.git('submodule init', cwd=self.srcdir)
Patrick Williams2390b1b2022-11-03 13:47:49 -05001932 self.git('-c protocol.file.allow=always submodule add file://%s' % smdir, cwd=self.srcdir)
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001933 self.git('submodule update', cwd=self.srcdir)
1934 self.git('commit -m submodule -a', cwd=self.srcdir)
1935
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001936 uri = 'gitsm://%s;protocol=file;subdir=${S};branch=master' % self.srcdir
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001937 fetcher, ud = self.fetch_shallow(uri)
1938
Brad Bishopf8caae32019-03-25 13:13:56 -04001939 # Verify the main repository is shallow
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001940 self.assertRevCount(1)
Brad Bishopf8caae32019-03-25 13:13:56 -04001941
1942 # Verify the gitsubmodule directory is present
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001943 assert os.listdir(os.path.join(self.gitdir, 'gitsubmodule'))
1944
Brad Bishopf8caae32019-03-25 13:13:56 -04001945 # Verify the submodule is also shallow
1946 self.assertRevCount(1, cwd=os.path.join(self.gitdir, 'gitsubmodule'))
1947
Andrew Geissler82c905d2020-04-13 13:39:40 -05001948 def test_shallow_submodule_mirrors(self):
1949 self.add_empty_file('a')
1950 self.add_empty_file('b')
1951
1952 smdir = os.path.join(self.tempdir, 'gitsubmodule')
1953 bb.utils.mkdirhier(smdir)
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001954 self.git_init(cwd=smdir)
Andrew Geissler82c905d2020-04-13 13:39:40 -05001955 # Make this look like it was cloned from a remote...
1956 self.git('config --add remote.origin.url "%s"' % smdir, cwd=smdir)
1957 self.git('config --add remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"', cwd=smdir)
1958 self.add_empty_file('asub', cwd=smdir)
1959 self.add_empty_file('bsub', cwd=smdir)
1960
1961 self.git('submodule init', cwd=self.srcdir)
Patrick Williams2390b1b2022-11-03 13:47:49 -05001962 self.git('-c protocol.file.allow=always submodule add file://%s' % smdir, cwd=self.srcdir)
Andrew Geissler82c905d2020-04-13 13:39:40 -05001963 self.git('submodule update', cwd=self.srcdir)
1964 self.git('commit -m submodule -a', cwd=self.srcdir)
1965
1966 uri = 'gitsm://%s;protocol=file;subdir=${S}' % self.srcdir
1967
1968 # Fetch once to generate the shallow tarball
1969 fetcher, ud = self.fetch(uri)
1970
1971 # Set up the mirror
1972 mirrordir = os.path.join(self.tempdir, 'mirror')
Andrew Geisslerc926e172021-05-07 16:11:35 -05001973 bb.utils.rename(self.dldir, mirrordir)
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00001974 self.d.setVar('PREMIRRORS', 'gitsm://.*/.* file://%s/' % mirrordir)
Andrew Geissler82c905d2020-04-13 13:39:40 -05001975
1976 # Fetch from the mirror
1977 bb.utils.remove(self.dldir, recurse=True)
1978 bb.utils.remove(self.gitdir, recurse=True)
1979 self.fetch_and_unpack(uri)
1980
1981 # Verify the main repository is shallow
1982 self.assertRevCount(1)
1983
1984 # Verify the gitsubmodule directory is present
1985 assert os.listdir(os.path.join(self.gitdir, 'gitsubmodule'))
1986
1987 # Verify the submodule is also shallow
1988 self.assertRevCount(1, cwd=os.path.join(self.gitdir, 'gitsubmodule'))
Brad Bishopf8caae32019-03-25 13:13:56 -04001989
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001990 if any(os.path.exists(os.path.join(p, 'git-annex')) for p in os.environ.get('PATH').split(':')):
1991 def test_shallow_annex(self):
1992 self.add_empty_file('a')
1993 self.add_empty_file('b')
1994 self.git('annex init', cwd=self.srcdir)
1995 open(os.path.join(self.srcdir, 'c'), 'w').close()
1996 self.git('annex add c', cwd=self.srcdir)
Andrew Geisslerc926e172021-05-07 16:11:35 -05001997 self.git('commit --author "Foo Bar <foo@bar>" -m annex-c -a', cwd=self.srcdir)
1998 bb.process.run('chmod u+w -R %s' % self.srcdir)
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001999
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00002000 uri = 'gitannex://%s;protocol=file;subdir=${S};branch=master' % self.srcdir
Brad Bishopd7bf8c12018-02-25 22:55:05 -05002001 fetcher, ud = self.fetch_shallow(uri)
2002
2003 self.assertRevCount(1)
2004 assert './.git/annex/' in bb.process.run('tar -tzf %s' % os.path.join(self.dldir, ud.mirrortarballs[0]))[0]
2005 assert os.path.exists(os.path.join(self.gitdir, 'c'))
2006
2007 def test_shallow_multi_one_uri(self):
2008 # Create initial git repo
2009 self.add_empty_file('a')
2010 self.add_empty_file('b')
2011 self.git('checkout -b a_branch', cwd=self.srcdir)
2012 self.add_empty_file('c')
2013 self.add_empty_file('d')
2014 self.git('checkout master', cwd=self.srcdir)
2015 self.git('tag v0.0 a_branch', cwd=self.srcdir)
2016 self.add_empty_file('e')
2017 self.git('merge --no-ff --no-edit a_branch', cwd=self.srcdir)
2018 self.add_empty_file('f')
2019 self.assertRevCount(7, cwd=self.srcdir)
2020
Brad Bishop19323692019-04-05 15:28:33 -04002021 uri = self.d.getVar('SRC_URI').split()[0]
Brad Bishopd7bf8c12018-02-25 22:55:05 -05002022 uri = '%s;branch=master,a_branch;name=master,a_branch' % uri
2023
2024 self.d.setVar('BB_GIT_SHALLOW_DEPTH', '0')
2025 self.d.setVar('BB_GIT_SHALLOW_REVS', 'v0.0')
2026 self.d.setVar('SRCREV_master', '${AUTOREV}')
2027 self.d.setVar('SRCREV_a_branch', '${AUTOREV}')
2028
2029 self.fetch_shallow(uri)
2030
2031 self.assertRevCount(5)
2032 self.assertRefs(['master', 'origin/master', 'origin/a_branch'])
2033
2034 def test_shallow_multi_one_uri_depths(self):
2035 # Create initial git repo
2036 self.add_empty_file('a')
2037 self.add_empty_file('b')
2038 self.git('checkout -b a_branch', cwd=self.srcdir)
2039 self.add_empty_file('c')
2040 self.add_empty_file('d')
2041 self.git('checkout master', cwd=self.srcdir)
2042 self.add_empty_file('e')
2043 self.git('merge --no-ff --no-edit a_branch', cwd=self.srcdir)
2044 self.add_empty_file('f')
2045 self.assertRevCount(7, cwd=self.srcdir)
2046
Brad Bishop19323692019-04-05 15:28:33 -04002047 uri = self.d.getVar('SRC_URI').split()[0]
Brad Bishopd7bf8c12018-02-25 22:55:05 -05002048 uri = '%s;branch=master,a_branch;name=master,a_branch' % uri
2049
2050 self.d.setVar('BB_GIT_SHALLOW_DEPTH', '0')
2051 self.d.setVar('BB_GIT_SHALLOW_DEPTH_master', '3')
2052 self.d.setVar('BB_GIT_SHALLOW_DEPTH_a_branch', '1')
2053 self.d.setVar('SRCREV_master', '${AUTOREV}')
2054 self.d.setVar('SRCREV_a_branch', '${AUTOREV}')
2055
2056 self.fetch_shallow(uri)
2057
2058 self.assertRevCount(4, ['--all'])
2059 self.assertRefs(['master', 'origin/master', 'origin/a_branch'])
2060
2061 def test_shallow_clone_preferred_over_shallow(self):
2062 self.add_empty_file('a')
2063 self.add_empty_file('b')
2064
2065 # Fetch once to generate the shallow tarball
2066 fetcher, ud = self.fetch()
2067 assert os.path.exists(os.path.join(self.dldir, ud.mirrortarballs[0]))
2068
2069 # Fetch and unpack with both the clonedir and shallow tarball available
2070 bb.utils.remove(self.gitdir, recurse=True)
2071 fetcher, ud = self.fetch_and_unpack()
2072
2073 # The unpacked tree should *not* be shallow
2074 self.assertRevCount(2)
2075 assert not os.path.exists(os.path.join(self.gitdir, '.git', 'shallow'))
2076
2077 def test_shallow_mirrors(self):
2078 self.add_empty_file('a')
2079 self.add_empty_file('b')
2080
2081 # Fetch once to generate the shallow tarball
2082 fetcher, ud = self.fetch()
2083 mirrortarball = ud.mirrortarballs[0]
2084 assert os.path.exists(os.path.join(self.dldir, mirrortarball))
2085
2086 # Set up the mirror
2087 mirrordir = os.path.join(self.tempdir, 'mirror')
2088 bb.utils.mkdirhier(mirrordir)
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00002089 self.d.setVar('PREMIRRORS', 'git://.*/.* file://%s/' % mirrordir)
Brad Bishopd7bf8c12018-02-25 22:55:05 -05002090
Andrew Geisslerc926e172021-05-07 16:11:35 -05002091 bb.utils.rename(os.path.join(self.dldir, mirrortarball),
Brad Bishopd7bf8c12018-02-25 22:55:05 -05002092 os.path.join(mirrordir, mirrortarball))
2093
2094 # Fetch from the mirror
2095 bb.utils.remove(self.dldir, recurse=True)
2096 bb.utils.remove(self.gitdir, recurse=True)
2097 self.fetch_and_unpack()
2098 self.assertRevCount(1)
2099
2100 def test_shallow_invalid_depth(self):
2101 self.add_empty_file('a')
2102 self.add_empty_file('b')
2103
2104 self.d.setVar('BB_GIT_SHALLOW_DEPTH', '-12')
2105 with self.assertRaises(bb.fetch2.FetchError):
2106 self.fetch()
2107
2108 def test_shallow_invalid_depth_default(self):
2109 self.add_empty_file('a')
2110 self.add_empty_file('b')
2111
2112 self.d.setVar('BB_GIT_SHALLOW_DEPTH_default', '-12')
2113 with self.assertRaises(bb.fetch2.FetchError):
2114 self.fetch()
2115
2116 def test_shallow_extra_refs(self):
2117 self.add_empty_file('a')
2118 self.add_empty_file('b')
2119 self.git('branch a_branch', cwd=self.srcdir)
2120 self.assertRefs(['master', 'a_branch'], cwd=self.srcdir)
2121 self.assertRevCount(2, cwd=self.srcdir)
2122
2123 self.d.setVar('BB_GIT_SHALLOW_EXTRA_REFS', 'refs/heads/a_branch')
2124 self.fetch_shallow()
2125
2126 self.assertRefs(['master', 'origin/master', 'origin/a_branch'])
2127 self.assertRevCount(1)
2128
2129 def test_shallow_extra_refs_wildcard(self):
2130 self.add_empty_file('a')
2131 self.add_empty_file('b')
2132 self.git('branch a_branch', cwd=self.srcdir)
2133 self.git('tag v1.0', cwd=self.srcdir)
2134 self.assertRefs(['master', 'a_branch', 'v1.0'], cwd=self.srcdir)
2135 self.assertRevCount(2, cwd=self.srcdir)
2136
2137 self.d.setVar('BB_GIT_SHALLOW_EXTRA_REFS', 'refs/tags/*')
2138 self.fetch_shallow()
2139
2140 self.assertRefs(['master', 'origin/master', 'v1.0'])
2141 self.assertRevCount(1)
2142
2143 def test_shallow_missing_extra_refs(self):
2144 self.add_empty_file('a')
2145 self.add_empty_file('b')
2146
2147 self.d.setVar('BB_GIT_SHALLOW_EXTRA_REFS', 'refs/heads/foo')
2148 with self.assertRaises(bb.fetch2.FetchError):
2149 self.fetch()
2150
2151 def test_shallow_missing_extra_refs_wildcard(self):
2152 self.add_empty_file('a')
2153 self.add_empty_file('b')
2154
2155 self.d.setVar('BB_GIT_SHALLOW_EXTRA_REFS', 'refs/tags/*')
2156 self.fetch()
2157
2158 def test_shallow_remove_revs(self):
2159 # Create initial git repo
2160 self.add_empty_file('a')
2161 self.add_empty_file('b')
2162 self.git('checkout -b a_branch', cwd=self.srcdir)
2163 self.add_empty_file('c')
2164 self.add_empty_file('d')
2165 self.git('checkout master', cwd=self.srcdir)
2166 self.git('tag v0.0 a_branch', cwd=self.srcdir)
2167 self.add_empty_file('e')
2168 self.git('merge --no-ff --no-edit a_branch', cwd=self.srcdir)
2169 self.git('branch -d a_branch', cwd=self.srcdir)
2170 self.add_empty_file('f')
2171 self.assertRevCount(7, cwd=self.srcdir)
2172
2173 self.d.setVar('BB_GIT_SHALLOW_DEPTH', '0')
2174 self.d.setVar('BB_GIT_SHALLOW_REVS', 'v0.0')
2175
2176 self.fetch_shallow()
2177
2178 self.assertRevCount(5)
2179
2180 def test_shallow_invalid_revs(self):
2181 self.add_empty_file('a')
2182 self.add_empty_file('b')
2183
2184 self.d.setVar('BB_GIT_SHALLOW_DEPTH', '0')
2185 self.d.setVar('BB_GIT_SHALLOW_REVS', 'v0.0')
2186
2187 with self.assertRaises(bb.fetch2.FetchError):
2188 self.fetch()
2189
Brad Bishop64c979e2019-11-04 13:55:29 -05002190 def test_shallow_fetch_missing_revs(self):
2191 self.add_empty_file('a')
2192 self.add_empty_file('b')
2193 fetcher, ud = self.fetch(self.d.getVar('SRC_URI'))
2194 self.git('tag v0.0 master', cwd=self.srcdir)
2195 self.d.setVar('BB_GIT_SHALLOW_DEPTH', '0')
2196 self.d.setVar('BB_GIT_SHALLOW_REVS', 'v0.0')
2197 self.fetch_shallow()
2198
2199 def test_shallow_fetch_missing_revs_fails(self):
2200 self.add_empty_file('a')
2201 self.add_empty_file('b')
2202 fetcher, ud = self.fetch(self.d.getVar('SRC_URI'))
2203 self.d.setVar('BB_GIT_SHALLOW_DEPTH', '0')
2204 self.d.setVar('BB_GIT_SHALLOW_REVS', 'v0.0')
2205
2206 with self.assertRaises(bb.fetch2.FetchError), self.assertLogs("BitBake.Fetcher", level="ERROR") as cm:
2207 self.fetch_shallow()
2208 self.assertIn("Unable to find revision v0.0 even from upstream", cm.output[0])
2209
Brad Bishopd7bf8c12018-02-25 22:55:05 -05002210 @skipIfNoNetwork()
2211 def test_bitbake(self):
Andrew Geissler595f6302022-01-24 19:11:47 +00002212 self.git('remote add --mirror=fetch origin https://github.com/openembedded/bitbake', cwd=self.srcdir)
Brad Bishopd7bf8c12018-02-25 22:55:05 -05002213 self.git('config core.bare true', cwd=self.srcdir)
2214 self.git('fetch', cwd=self.srcdir)
2215
2216 self.d.setVar('BB_GIT_SHALLOW_DEPTH', '0')
2217 # Note that the 1.10.0 tag is annotated, so this also tests
2218 # reference of an annotated vs unannotated tag
2219 self.d.setVar('BB_GIT_SHALLOW_REVS', '1.10.0')
2220
2221 self.fetch_shallow()
2222
2223 # Confirm that the history of 1.10.0 was removed
2224 orig_revs = len(self.git('rev-list master', cwd=self.srcdir).splitlines())
2225 revs = len(self.git('rev-list master').splitlines())
2226 self.assertNotEqual(orig_revs, revs)
2227 self.assertRefs(['master', 'origin/master'])
2228 self.assertRevCount(orig_revs - 1758)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08002229
2230 def test_that_unpack_throws_an_error_when_the_git_clone_nor_shallow_tarball_exist(self):
2231 self.add_empty_file('a')
2232 fetcher, ud = self.fetch()
2233 bb.utils.remove(self.gitdir, recurse=True)
2234 bb.utils.remove(self.dldir, recurse=True)
2235
2236 with self.assertRaises(bb.fetch2.UnpackError) as context:
2237 fetcher.unpack(self.d.getVar('WORKDIR'))
2238
2239 self.assertIn("No up to date source found", context.exception.msg)
2240 self.assertIn("clone directory not available or not up to date", context.exception.msg)
2241
2242 @skipIfNoNetwork()
2243 def test_that_unpack_does_work_when_using_git_shallow_tarball_but_tarball_is_not_available(self):
2244 self.d.setVar('SRCREV', 'e5939ff608b95cdd4d0ab0e1935781ab9a276ac0')
2245 self.d.setVar('BB_GIT_SHALLOW', '1')
2246 self.d.setVar('BB_GENERATE_SHALLOW_TARBALLS', '1')
Andrew Geissler028142b2023-05-05 11:29:21 -05002247 fetcher = bb.fetch.Fetch(["git://git.yoctoproject.org/fstests;branch=master;protocol=https"], self.d)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08002248 fetcher.download()
2249
2250 bb.utils.remove(self.dldir + "/*.tar.gz")
2251 fetcher.unpack(self.unpackdir)
2252
2253 dir = os.listdir(self.unpackdir + "/git/")
2254 self.assertIn("fstests.doap", dir)
Brad Bishop00e122a2019-10-05 11:10:57 -04002255
2256class GitLfsTest(FetcherTest):
Andrew Geissler6aa7eec2023-03-03 12:41:14 -06002257 def skipIfNoGitLFS():
2258 import shutil
2259 if not shutil.which('git-lfs'):
2260 return unittest.skip('git-lfs not installed')
2261 return lambda f: f
2262
Brad Bishop00e122a2019-10-05 11:10:57 -04002263 def setUp(self):
2264 FetcherTest.setUp(self)
2265
2266 self.gitdir = os.path.join(self.tempdir, 'git')
2267 self.srcdir = os.path.join(self.tempdir, 'gitsource')
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00002268
Brad Bishop00e122a2019-10-05 11:10:57 -04002269 self.d.setVar('WORKDIR', self.tempdir)
2270 self.d.setVar('S', self.gitdir)
2271 self.d.delVar('PREMIRRORS')
2272 self.d.delVar('MIRRORS')
2273
2274 self.d.setVar('SRCREV', '${AUTOREV}')
2275 self.d.setVar('AUTOREV', '${@bb.fetch2.get_autorev(d)}')
Andrew Geisslerfc113ea2023-03-31 09:59:46 -05002276 self.d.setVar("__BBSRCREV_SEEN", "1")
Brad Bishop00e122a2019-10-05 11:10:57 -04002277
2278 bb.utils.mkdirhier(self.srcdir)
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00002279 self.git_init(cwd=self.srcdir)
Patrick Williams39653562024-03-01 08:54:02 -06002280 self.commit_file('.gitattributes', '*.mp3 filter=lfs -text')
2281
2282 def commit_file(self, filename, content):
2283 with open(os.path.join(self.srcdir, filename), "w") as f:
2284 f.write(content)
2285 self.git(["add", filename], cwd=self.srcdir)
2286 self.git(["commit", "-m", "Change"], cwd=self.srcdir)
2287 return self.git(["rev-parse", "HEAD"], cwd=self.srcdir).strip()
Brad Bishop00e122a2019-10-05 11:10:57 -04002288
Andrew Geisslerd1e89492021-02-12 15:35:20 -06002289 def fetch(self, uri=None, download=True):
Brad Bishop00e122a2019-10-05 11:10:57 -04002290 uris = self.d.getVar('SRC_URI').split()
2291 uri = uris[0]
2292 d = self.d
2293
2294 fetcher = bb.fetch2.Fetch(uris, d)
Andrew Geisslerd1e89492021-02-12 15:35:20 -06002295 if download:
2296 fetcher.download()
Brad Bishop00e122a2019-10-05 11:10:57 -04002297 ud = fetcher.ud[uri]
2298 return fetcher, ud
2299
Andrew Geissler6aa7eec2023-03-03 12:41:14 -06002300 def get_real_git_lfs_file(self):
2301 self.d.setVar('PATH', os.environ.get('PATH'))
2302 fetcher, ud = self.fetch()
2303 fetcher.unpack(self.d.getVar('WORKDIR'))
2304 unpacked_lfs_file = os.path.join(self.d.getVar('WORKDIR'), 'git', "Cat_poster_1.jpg")
2305 return unpacked_lfs_file
2306
2307 @skipIfNoGitLFS()
Patrick Williams39653562024-03-01 08:54:02 -06002308 def test_fetch_lfs_on_srcrev_change(self):
2309 """Test if fetch downloads missing LFS objects when a different revision within an existing repository is requested"""
2310 self.git(["lfs", "install", "--local"], cwd=self.srcdir)
2311
2312 @contextlib.contextmanager
2313 def hide_upstream_repository():
2314 """Hide the upstream repository to make sure that git lfs cannot pull from it"""
2315 temp_name = self.srcdir + ".bak"
2316 os.rename(self.srcdir, temp_name)
2317 try:
2318 yield
2319 finally:
2320 os.rename(temp_name, self.srcdir)
2321
2322 def fetch_and_verify(revision, filename, content):
2323 self.d.setVar('SRCREV', revision)
2324 fetcher, ud = self.fetch()
2325
2326 with hide_upstream_repository():
2327 workdir = self.d.getVar('WORKDIR')
2328 fetcher.unpack(workdir)
2329
2330 with open(os.path.join(workdir, "git", filename)) as f:
2331 self.assertEqual(f.read(), content)
2332
2333 commit_1 = self.commit_file("a.mp3", "version 1")
2334 commit_2 = self.commit_file("a.mp3", "version 2")
2335
2336 self.d.setVar('SRC_URI', "git://%s;protocol=file;lfs=1;branch=master" % self.srcdir)
2337
2338 # Seed the local download folder by fetching the latest commit and verifying that the LFS contents are
2339 # available even when the upstream repository disappears.
2340 fetch_and_verify(commit_2, "a.mp3", "version 2")
2341 # Verify that even when an older revision is fetched, the needed LFS objects are fetched into the download
2342 # folder.
2343 fetch_and_verify(commit_1, "a.mp3", "version 1")
2344
2345 @skipIfNoGitLFS()
Andrew Geissler6aa7eec2023-03-03 12:41:14 -06002346 @skipIfNoNetwork()
2347 def test_real_git_lfs_repo_succeeds_without_lfs_param(self):
2348 self.d.setVar('SRC_URI', "git://gitlab.com/gitlab-examples/lfs.git;protocol=https;branch=master")
2349 f = self.get_real_git_lfs_file()
2350 self.assertTrue(os.path.exists(f))
2351 self.assertEqual("c0baab607a97839c9a328b4310713307", bb.utils.md5_file(f))
2352
2353 @skipIfNoGitLFS()
2354 @skipIfNoNetwork()
2355 def test_real_git_lfs_repo_succeeds(self):
2356 self.d.setVar('SRC_URI', "git://gitlab.com/gitlab-examples/lfs.git;protocol=https;branch=master;lfs=1")
2357 f = self.get_real_git_lfs_file()
2358 self.assertTrue(os.path.exists(f))
2359 self.assertEqual("c0baab607a97839c9a328b4310713307", bb.utils.md5_file(f))
2360
2361 @skipIfNoGitLFS()
2362 @skipIfNoNetwork()
Patrick Williamsac13d5f2023-11-24 18:59:46 -06002363 def test_real_git_lfs_repo_skips(self):
Andrew Geissler6aa7eec2023-03-03 12:41:14 -06002364 self.d.setVar('SRC_URI', "git://gitlab.com/gitlab-examples/lfs.git;protocol=https;branch=master;lfs=0")
2365 f = self.get_real_git_lfs_file()
2366 # This is the actual non-smudged placeholder file on the repo if git-lfs does not run
2367 lfs_file = (
2368 'version https://git-lfs.github.com/spec/v1\n'
2369 'oid sha256:34be66b1a39a1955b46a12588df9d5f6fc1da790e05cf01f3c7422f4bbbdc26b\n'
2370 'size 11423554\n'
2371 )
2372
2373 with open(f) as fh:
2374 self.assertEqual(lfs_file, fh.read())
2375
Patrick Williamsac13d5f2023-11-24 18:59:46 -06002376 @skipIfNoGitLFS()
Brad Bishop00e122a2019-10-05 11:10:57 -04002377 def test_lfs_enabled(self):
2378 import shutil
2379
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00002380 uri = 'git://%s;protocol=file;lfs=1;branch=master' % self.srcdir
Brad Bishop00e122a2019-10-05 11:10:57 -04002381 self.d.setVar('SRC_URI', uri)
2382
Patrick Williamsac13d5f2023-11-24 18:59:46 -06002383 # With git-lfs installed, test that we can fetch and unpack
2384 fetcher, ud = self.fetch()
2385 shutil.rmtree(self.gitdir, ignore_errors=True)
2386 fetcher.unpack(self.d.getVar('WORKDIR'))
2387
2388 @skipIfNoGitLFS()
2389 def test_lfs_disabled(self):
2390 import shutil
2391
2392 uri = 'git://%s;protocol=file;lfs=0;branch=master' % self.srcdir
2393 self.d.setVar('SRC_URI', uri)
2394
2395 # Verify that the fetcher can survive even if the source
2396 # repository has Git LFS usage configured.
2397 fetcher, ud = self.fetch()
2398 fetcher.unpack(self.d.getVar('WORKDIR'))
2399
2400 def test_lfs_enabled_not_installed(self):
2401 import shutil
2402
2403 uri = 'git://%s;protocol=file;lfs=1;branch=master' % self.srcdir
2404 self.d.setVar('SRC_URI', uri)
2405
2406 # Careful: suppress initial attempt at downloading
Andrew Geisslerd1e89492021-02-12 15:35:20 -06002407 fetcher, ud = self.fetch(uri=None, download=False)
Brad Bishop00e122a2019-10-05 11:10:57 -04002408
Patrick Williamsac13d5f2023-11-24 18:59:46 -06002409 # Artificially assert that git-lfs is not installed, so
2410 # we can verify a failure to unpack in it's absence.
Andrew Geissler6aa7eec2023-03-03 12:41:14 -06002411 old_find_git_lfs = ud.method._find_git_lfs
2412 try:
2413 # If git-lfs cannot be found, the unpack should throw an error
2414 with self.assertRaises(bb.fetch2.FetchError):
2415 fetcher.download()
2416 ud.method._find_git_lfs = lambda d: False
2417 shutil.rmtree(self.gitdir, ignore_errors=True)
2418 fetcher.unpack(self.d.getVar('WORKDIR'))
2419 finally:
2420 ud.method._find_git_lfs = old_find_git_lfs
Brad Bishop00e122a2019-10-05 11:10:57 -04002421
Patrick Williamsac13d5f2023-11-24 18:59:46 -06002422 def test_lfs_disabled_not_installed(self):
Brad Bishop00e122a2019-10-05 11:10:57 -04002423 import shutil
2424
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00002425 uri = 'git://%s;protocol=file;lfs=0;branch=master' % self.srcdir
Brad Bishop00e122a2019-10-05 11:10:57 -04002426 self.d.setVar('SRC_URI', uri)
2427
Patrick Williamsac13d5f2023-11-24 18:59:46 -06002428 # Careful: suppress initial attempt at downloading
2429 fetcher, ud = self.fetch(uri=None, download=False)
Brad Bishop00e122a2019-10-05 11:10:57 -04002430
Patrick Williamsac13d5f2023-11-24 18:59:46 -06002431 # Artificially assert that git-lfs is not installed, so
2432 # we can verify a failure to unpack in it's absence.
Andrew Geissler6aa7eec2023-03-03 12:41:14 -06002433 old_find_git_lfs = ud.method._find_git_lfs
2434 try:
Patrick Williamsac13d5f2023-11-24 18:59:46 -06002435 # Even if git-lfs cannot be found, the unpack should be successful
2436 fetcher.download()
Andrew Geissler6aa7eec2023-03-03 12:41:14 -06002437 ud.method._find_git_lfs = lambda d: False
2438 shutil.rmtree(self.gitdir, ignore_errors=True)
2439 fetcher.unpack(self.d.getVar('WORKDIR'))
2440 finally:
2441 ud.method._find_git_lfs = old_find_git_lfs
Andrew Geissler82c905d2020-04-13 13:39:40 -05002442
Andrew Geisslerc3d88e42020-10-02 09:45:00 -05002443class GitURLWithSpacesTest(FetcherTest):
2444 test_git_urls = {
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00002445 "git://tfs-example.org:22/tfs/example%20path/example.git;branch=master" : {
2446 'url': 'git://tfs-example.org:22/tfs/example%20path/example.git;branch=master',
Andrew Geisslerc3d88e42020-10-02 09:45:00 -05002447 'gitsrcname': 'tfs-example.org.22.tfs.example_path.example.git',
2448 'path': '/tfs/example path/example.git'
2449 },
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00002450 "git://tfs-example.org:22/tfs/example%20path/example%20repo.git;branch=master" : {
2451 'url': 'git://tfs-example.org:22/tfs/example%20path/example%20repo.git;branch=master',
Andrew Geisslerc3d88e42020-10-02 09:45:00 -05002452 'gitsrcname': 'tfs-example.org.22.tfs.example_path.example_repo.git',
2453 'path': '/tfs/example path/example repo.git'
2454 }
2455 }
2456
2457 def test_urls(self):
2458
2459 # Set fake SRCREV to stop git fetcher from trying to contact non-existent git repo
2460 self.d.setVar('SRCREV', '82ea737a0b42a8b53e11c9cde141e9e9c0bd8c40')
2461
2462 for test_git_url, ref in self.test_git_urls.items():
2463
2464 fetcher = bb.fetch.Fetch([test_git_url], self.d)
2465 ud = fetcher.ud[fetcher.urls[0]]
2466
2467 self.assertEqual(ud.url, ref['url'])
2468 self.assertEqual(ud.path, ref['path'])
2469 self.assertEqual(ud.localfile, os.path.join(self.dldir, "git2", ref['gitsrcname']))
2470 self.assertEqual(ud.localpath, os.path.join(self.dldir, "git2", ref['gitsrcname']))
2471 self.assertEqual(ud.lockfile, os.path.join(self.dldir, "git2", ref['gitsrcname'] + '.lock'))
2472 self.assertEqual(ud.clonedir, os.path.join(self.dldir, "git2", ref['gitsrcname']))
2473 self.assertEqual(ud.fullmirror, os.path.join(self.dldir, "git2_" + ref['gitsrcname'] + '.tar.gz'))
2474
Andrew Geissler595f6302022-01-24 19:11:47 +00002475class CrateTest(FetcherTest):
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00002476 @skipIfNoNetwork()
Andrew Geissler595f6302022-01-24 19:11:47 +00002477 def test_crate_url(self):
2478
2479 uri = "crate://crates.io/glob/0.2.11"
2480 self.d.setVar('SRC_URI', uri)
2481
2482 uris = self.d.getVar('SRC_URI').split()
2483 d = self.d
2484
2485 fetcher = bb.fetch2.Fetch(uris, self.d)
Andrew Geisslerfc113ea2023-03-31 09:59:46 -05002486 ud = fetcher.ud[fetcher.urls[0]]
2487
2488 self.assertIn("name", ud.parm)
Patrick Williams8e7b46e2023-05-01 14:19:06 -05002489 self.assertEqual(ud.parm["name"], "glob-0.2.11")
Andrew Geisslerfc113ea2023-03-31 09:59:46 -05002490 self.assertIn("downloadfilename", ud.parm)
2491 self.assertEqual(ud.parm["downloadfilename"], "glob-0.2.11.crate")
2492
Andrew Geissler595f6302022-01-24 19:11:47 +00002493 fetcher.download()
2494 fetcher.unpack(self.tempdir)
2495 self.assertEqual(sorted(os.listdir(self.tempdir)), ['cargo_home', 'download' , 'unpacked'])
2496 self.assertEqual(sorted(os.listdir(self.tempdir + "/download")), ['glob-0.2.11.crate', 'glob-0.2.11.crate.done'])
2497 self.assertTrue(os.path.exists(self.tempdir + "/cargo_home/bitbake/glob-0.2.11/.cargo-checksum.json"))
2498 self.assertTrue(os.path.exists(self.tempdir + "/cargo_home/bitbake/glob-0.2.11/src/lib.rs"))
2499
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00002500 @skipIfNoNetwork()
Patrick Williamse760df82023-05-26 11:10:49 -05002501 def test_crate_url_matching_recipe(self):
2502
2503 self.d.setVar('BP', 'glob-0.2.11')
2504
2505 uri = "crate://crates.io/glob/0.2.11"
2506 self.d.setVar('SRC_URI', uri)
2507
2508 uris = self.d.getVar('SRC_URI').split()
2509 d = self.d
2510
2511 fetcher = bb.fetch2.Fetch(uris, self.d)
2512 ud = fetcher.ud[fetcher.urls[0]]
2513
2514 self.assertIn("name", ud.parm)
2515 self.assertEqual(ud.parm["name"], "glob-0.2.11")
2516 self.assertIn("downloadfilename", ud.parm)
2517 self.assertEqual(ud.parm["downloadfilename"], "glob-0.2.11.crate")
2518
2519 fetcher.download()
2520 fetcher.unpack(self.tempdir)
2521 self.assertEqual(sorted(os.listdir(self.tempdir)), ['download', 'glob-0.2.11', 'unpacked'])
2522 self.assertEqual(sorted(os.listdir(self.tempdir + "/download")), ['glob-0.2.11.crate', 'glob-0.2.11.crate.done'])
2523 self.assertTrue(os.path.exists(self.tempdir + "/glob-0.2.11/src/lib.rs"))
2524
2525 @skipIfNoNetwork()
Andrew Geisslerfc113ea2023-03-31 09:59:46 -05002526 def test_crate_url_params(self):
2527
2528 uri = "crate://crates.io/aho-corasick/0.7.20;name=aho-corasick-renamed"
2529 self.d.setVar('SRC_URI', uri)
2530
2531 uris = self.d.getVar('SRC_URI').split()
2532 d = self.d
2533
2534 fetcher = bb.fetch2.Fetch(uris, self.d)
2535 ud = fetcher.ud[fetcher.urls[0]]
2536
2537 self.assertIn("name", ud.parm)
2538 self.assertEqual(ud.parm["name"], "aho-corasick-renamed")
2539 self.assertIn("downloadfilename", ud.parm)
2540 self.assertEqual(ud.parm["downloadfilename"], "aho-corasick-0.7.20.crate")
2541
2542 fetcher.download()
2543 fetcher.unpack(self.tempdir)
2544 self.assertEqual(sorted(os.listdir(self.tempdir)), ['cargo_home', 'download' , 'unpacked'])
2545 self.assertEqual(sorted(os.listdir(self.tempdir + "/download")), ['aho-corasick-0.7.20.crate', 'aho-corasick-0.7.20.crate.done'])
2546 self.assertTrue(os.path.exists(self.tempdir + "/cargo_home/bitbake/aho-corasick-0.7.20/.cargo-checksum.json"))
2547 self.assertTrue(os.path.exists(self.tempdir + "/cargo_home/bitbake/aho-corasick-0.7.20/src/lib.rs"))
2548
2549 @skipIfNoNetwork()
Andrew Geissler595f6302022-01-24 19:11:47 +00002550 def test_crate_url_multi(self):
2551
2552 uri = "crate://crates.io/glob/0.2.11 crate://crates.io/time/0.1.35"
2553 self.d.setVar('SRC_URI', uri)
2554
2555 uris = self.d.getVar('SRC_URI').split()
2556 d = self.d
2557
2558 fetcher = bb.fetch2.Fetch(uris, self.d)
Andrew Geisslerfc113ea2023-03-31 09:59:46 -05002559 ud = fetcher.ud[fetcher.urls[0]]
2560
2561 self.assertIn("name", ud.parm)
Patrick Williams8e7b46e2023-05-01 14:19:06 -05002562 self.assertEqual(ud.parm["name"], "glob-0.2.11")
Andrew Geisslerfc113ea2023-03-31 09:59:46 -05002563 self.assertIn("downloadfilename", ud.parm)
2564 self.assertEqual(ud.parm["downloadfilename"], "glob-0.2.11.crate")
2565
2566 ud = fetcher.ud[fetcher.urls[1]]
2567 self.assertIn("name", ud.parm)
Patrick Williams8e7b46e2023-05-01 14:19:06 -05002568 self.assertEqual(ud.parm["name"], "time-0.1.35")
Andrew Geisslerfc113ea2023-03-31 09:59:46 -05002569 self.assertIn("downloadfilename", ud.parm)
2570 self.assertEqual(ud.parm["downloadfilename"], "time-0.1.35.crate")
2571
Andrew Geissler595f6302022-01-24 19:11:47 +00002572 fetcher.download()
2573 fetcher.unpack(self.tempdir)
2574 self.assertEqual(sorted(os.listdir(self.tempdir)), ['cargo_home', 'download' , 'unpacked'])
2575 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'])
2576 self.assertTrue(os.path.exists(self.tempdir + "/cargo_home/bitbake/glob-0.2.11/.cargo-checksum.json"))
2577 self.assertTrue(os.path.exists(self.tempdir + "/cargo_home/bitbake/glob-0.2.11/src/lib.rs"))
2578 self.assertTrue(os.path.exists(self.tempdir + "/cargo_home/bitbake/time-0.1.35/.cargo-checksum.json"))
2579 self.assertTrue(os.path.exists(self.tempdir + "/cargo_home/bitbake/time-0.1.35/src/lib.rs"))
2580
Andrew Geisslerfc113ea2023-03-31 09:59:46 -05002581 @skipIfNoNetwork()
2582 def test_crate_incorrect_cksum(self):
2583 uri = "crate://crates.io/aho-corasick/0.7.20"
2584 self.d.setVar('SRC_URI', uri)
Patrick Williams8e7b46e2023-05-01 14:19:06 -05002585 self.d.setVarFlag("SRC_URI", "aho-corasick-0.7.20.sha256sum", hashlib.sha256("Invalid".encode("utf-8")).hexdigest())
Andrew Geisslerfc113ea2023-03-31 09:59:46 -05002586
2587 uris = self.d.getVar('SRC_URI').split()
2588
2589 fetcher = bb.fetch2.Fetch(uris, self.d)
Andrew Geissler8f840682023-07-21 09:09:43 -05002590 with self.assertRaisesRegex(bb.fetch2.FetchError, "Fetcher failure for URL"):
Andrew Geisslerfc113ea2023-03-31 09:59:46 -05002591 fetcher.download()
2592
Andrew Geissler82c905d2020-04-13 13:39:40 -05002593class NPMTest(FetcherTest):
2594 def skipIfNoNpm():
2595 import shutil
2596 if not shutil.which('npm'):
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00002597 return unittest.skip('npm not installed')
Andrew Geissler82c905d2020-04-13 13:39:40 -05002598 return lambda f: f
2599
2600 @skipIfNoNpm()
2601 @skipIfNoNetwork()
2602 def test_npm(self):
2603 url = 'npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=1.0.0'
2604 fetcher = bb.fetch.Fetch([url], self.d)
2605 ud = fetcher.ud[fetcher.urls[0]]
2606 fetcher.download()
2607 self.assertTrue(os.path.exists(ud.localpath))
2608 self.assertTrue(os.path.exists(ud.localpath + '.done'))
2609 self.assertTrue(os.path.exists(ud.resolvefile))
2610 fetcher.unpack(self.unpackdir)
2611 unpackdir = os.path.join(self.unpackdir, 'npm')
2612 self.assertTrue(os.path.exists(os.path.join(unpackdir, 'package.json')))
2613
2614 @skipIfNoNpm()
2615 @skipIfNoNetwork()
2616 def test_npm_bad_checksum(self):
2617 url = 'npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=1.0.0'
2618 # Fetch once to get a tarball
2619 fetcher = bb.fetch.Fetch([url], self.d)
2620 ud = fetcher.ud[fetcher.urls[0]]
2621 fetcher.download()
2622 self.assertTrue(os.path.exists(ud.localpath))
2623 # Modify the tarball
2624 bad = b'bad checksum'
2625 with open(ud.localpath, 'wb') as f:
2626 f.write(bad)
2627 # Verify that the tarball is fetched again
2628 fetcher.download()
2629 badsum = hashlib.sha512(bad).hexdigest()
2630 self.assertTrue(os.path.exists(ud.localpath + '_bad-checksum_' + badsum))
2631 self.assertTrue(os.path.exists(ud.localpath))
2632
2633 @skipIfNoNpm()
2634 @skipIfNoNetwork()
2635 def test_npm_premirrors(self):
2636 url = 'npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=1.0.0'
2637 # Fetch once to get a tarball
2638 fetcher = bb.fetch.Fetch([url], self.d)
2639 ud = fetcher.ud[fetcher.urls[0]]
2640 fetcher.download()
2641 self.assertTrue(os.path.exists(ud.localpath))
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00002642
2643 # Setup the mirror by renaming the download directory
Andrew Geissler82c905d2020-04-13 13:39:40 -05002644 mirrordir = os.path.join(self.tempdir, 'mirror')
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00002645 bb.utils.rename(self.dldir, mirrordir)
2646 os.mkdir(self.dldir)
2647
2648 # Configure the premirror to be used
2649 self.d.setVar('PREMIRRORS', 'https?$://.*/.* file://%s/npm2' % mirrordir)
Andrew Geissler82c905d2020-04-13 13:39:40 -05002650 self.d.setVar('BB_FETCH_PREMIRRORONLY', '1')
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00002651
Andrew Geissler82c905d2020-04-13 13:39:40 -05002652 # Fetch again
2653 self.assertFalse(os.path.exists(ud.localpath))
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00002654 # The npm fetcher doesn't handle that the .resolved file disappears
2655 # while the fetcher object exists, which it does when we rename the
2656 # download directory to "mirror" above. Thus we need a new fetcher to go
2657 # with the now empty download directory.
2658 fetcher = bb.fetch.Fetch([url], self.d)
2659 ud = fetcher.ud[fetcher.urls[0]]
Andrew Geissler82c905d2020-04-13 13:39:40 -05002660 fetcher.download()
2661 self.assertTrue(os.path.exists(ud.localpath))
2662
2663 @skipIfNoNpm()
2664 @skipIfNoNetwork()
Andrew Geissler5199d832021-09-24 16:47:35 -05002665 def test_npm_premirrors_with_specified_filename(self):
2666 url = 'npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=1.0.0'
2667 # Fetch once to get a tarball
2668 fetcher = bb.fetch.Fetch([url], self.d)
2669 ud = fetcher.ud[fetcher.urls[0]]
2670 fetcher.download()
2671 self.assertTrue(os.path.exists(ud.localpath))
2672 # Setup the mirror
2673 mirrordir = os.path.join(self.tempdir, 'mirror')
2674 bb.utils.mkdirhier(mirrordir)
2675 mirrorfilename = os.path.join(mirrordir, os.path.basename(ud.localpath))
2676 os.replace(ud.localpath, mirrorfilename)
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00002677 self.d.setVar('PREMIRRORS', 'https?$://.*/.* file://%s' % mirrorfilename)
Andrew Geissler5199d832021-09-24 16:47:35 -05002678 self.d.setVar('BB_FETCH_PREMIRRORONLY', '1')
2679 # Fetch again
2680 self.assertFalse(os.path.exists(ud.localpath))
2681 fetcher.download()
2682 self.assertTrue(os.path.exists(ud.localpath))
2683
2684 @skipIfNoNpm()
2685 @skipIfNoNetwork()
Andrew Geissler82c905d2020-04-13 13:39:40 -05002686 def test_npm_mirrors(self):
2687 # Fetch once to get a tarball
2688 url = 'npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=1.0.0'
2689 fetcher = bb.fetch.Fetch([url], self.d)
2690 ud = fetcher.ud[fetcher.urls[0]]
2691 fetcher.download()
2692 self.assertTrue(os.path.exists(ud.localpath))
2693 # Setup the mirror
2694 mirrordir = os.path.join(self.tempdir, 'mirror')
2695 bb.utils.mkdirhier(mirrordir)
2696 os.replace(ud.localpath, os.path.join(mirrordir, os.path.basename(ud.localpath)))
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00002697 self.d.setVar('MIRRORS', 'https?$://.*/.* file://%s/' % mirrordir)
Andrew Geissler82c905d2020-04-13 13:39:40 -05002698 # Update the resolved url to an invalid url
2699 with open(ud.resolvefile, 'r') as f:
2700 url = f.read()
2701 uri = URI(url)
2702 uri.path = '/invalid'
2703 with open(ud.resolvefile, 'w') as f:
2704 f.write(str(uri))
2705 # Fetch again
2706 self.assertFalse(os.path.exists(ud.localpath))
2707 fetcher.download()
2708 self.assertTrue(os.path.exists(ud.localpath))
2709
2710 @skipIfNoNpm()
2711 @skipIfNoNetwork()
2712 def test_npm_destsuffix_downloadfilename(self):
2713 url = 'npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=1.0.0;destsuffix=foo/bar;downloadfilename=foo-bar.tgz'
2714 fetcher = bb.fetch.Fetch([url], self.d)
2715 fetcher.download()
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00002716 self.assertTrue(os.path.exists(os.path.join(self.dldir, 'npm2', 'foo-bar.tgz')))
Andrew Geissler82c905d2020-04-13 13:39:40 -05002717 fetcher.unpack(self.unpackdir)
2718 unpackdir = os.path.join(self.unpackdir, 'foo', 'bar')
2719 self.assertTrue(os.path.exists(os.path.join(unpackdir, 'package.json')))
2720
2721 def test_npm_no_network_no_tarball(self):
2722 url = 'npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=1.0.0'
2723 self.d.setVar('BB_NO_NETWORK', '1')
2724 fetcher = bb.fetch.Fetch([url], self.d)
2725 with self.assertRaises(bb.fetch2.NetworkAccess):
2726 fetcher.download()
2727
2728 @skipIfNoNpm()
2729 @skipIfNoNetwork()
2730 def test_npm_no_network_with_tarball(self):
2731 url = 'npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=1.0.0'
2732 # Fetch once to get a tarball
2733 fetcher = bb.fetch.Fetch([url], self.d)
2734 fetcher.download()
2735 # Disable network access
2736 self.d.setVar('BB_NO_NETWORK', '1')
2737 # Fetch again
2738 fetcher.download()
2739 fetcher.unpack(self.unpackdir)
2740 unpackdir = os.path.join(self.unpackdir, 'npm')
2741 self.assertTrue(os.path.exists(os.path.join(unpackdir, 'package.json')))
2742
2743 @skipIfNoNpm()
2744 @skipIfNoNetwork()
2745 def test_npm_registry_alternate(self):
Andrew Geissler5199d832021-09-24 16:47:35 -05002746 url = 'npm://skimdb.npmjs.com;package=@savoirfairelinux/node-server-example;version=1.0.0'
Andrew Geissler82c905d2020-04-13 13:39:40 -05002747 fetcher = bb.fetch.Fetch([url], self.d)
2748 fetcher.download()
2749 fetcher.unpack(self.unpackdir)
2750 unpackdir = os.path.join(self.unpackdir, 'npm')
2751 self.assertTrue(os.path.exists(os.path.join(unpackdir, 'package.json')))
2752
2753 @skipIfNoNpm()
2754 @skipIfNoNetwork()
2755 def test_npm_version_latest(self):
2756 url = 'npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=latest'
2757 fetcher = bb.fetch.Fetch([url], self.d)
2758 fetcher.download()
2759 fetcher.unpack(self.unpackdir)
2760 unpackdir = os.path.join(self.unpackdir, 'npm')
2761 self.assertTrue(os.path.exists(os.path.join(unpackdir, 'package.json')))
2762
2763 @skipIfNoNpm()
2764 @skipIfNoNetwork()
2765 def test_npm_registry_invalid(self):
2766 url = 'npm://registry.invalid.org;package=@savoirfairelinux/node-server-example;version=1.0.0'
2767 fetcher = bb.fetch.Fetch([url], self.d)
2768 with self.assertRaises(bb.fetch2.FetchError):
2769 fetcher.download()
2770
2771 @skipIfNoNpm()
2772 @skipIfNoNetwork()
2773 def test_npm_package_invalid(self):
2774 url = 'npm://registry.npmjs.org;package=@savoirfairelinux/invalid;version=1.0.0'
2775 fetcher = bb.fetch.Fetch([url], self.d)
2776 with self.assertRaises(bb.fetch2.FetchError):
2777 fetcher.download()
2778
2779 @skipIfNoNpm()
2780 @skipIfNoNetwork()
2781 def test_npm_version_invalid(self):
2782 url = 'npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=invalid'
2783 with self.assertRaises(bb.fetch2.ParameterError):
2784 fetcher = bb.fetch.Fetch([url], self.d)
2785
2786 @skipIfNoNpm()
2787 @skipIfNoNetwork()
2788 def test_npm_registry_none(self):
2789 url = 'npm://;package=@savoirfairelinux/node-server-example;version=1.0.0'
2790 with self.assertRaises(bb.fetch2.MalformedUrl):
2791 fetcher = bb.fetch.Fetch([url], self.d)
2792
2793 @skipIfNoNpm()
2794 @skipIfNoNetwork()
2795 def test_npm_package_none(self):
2796 url = 'npm://registry.npmjs.org;version=1.0.0'
2797 with self.assertRaises(bb.fetch2.MissingParameterError):
2798 fetcher = bb.fetch.Fetch([url], self.d)
2799
2800 @skipIfNoNpm()
2801 @skipIfNoNetwork()
2802 def test_npm_version_none(self):
2803 url = 'npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example'
2804 with self.assertRaises(bb.fetch2.MissingParameterError):
2805 fetcher = bb.fetch.Fetch([url], self.d)
2806
2807 def create_shrinkwrap_file(self, data):
2808 import json
2809 datadir = os.path.join(self.tempdir, 'data')
2810 swfile = os.path.join(datadir, 'npm-shrinkwrap.json')
2811 bb.utils.mkdirhier(datadir)
2812 with open(swfile, 'w') as f:
2813 json.dump(data, f)
2814 # Also configure the S directory
2815 self.sdir = os.path.join(self.unpackdir, 'S')
2816 self.d.setVar('S', self.sdir)
2817 return swfile
2818
2819 @skipIfNoNpm()
2820 @skipIfNoNetwork()
2821 def test_npmsw(self):
2822 swfile = self.create_shrinkwrap_file({
2823 'dependencies': {
2824 'array-flatten': {
2825 'version': '1.1.1',
2826 'resolved': 'https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz',
2827 'integrity': 'sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=',
2828 'dependencies': {
2829 'content-type': {
2830 'version': 'https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz',
2831 'integrity': 'sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==',
2832 'dependencies': {
2833 'cookie': {
2834 'version': 'git+https://github.com/jshttp/cookie.git#aec1177c7da67e3b3273df96cf476824dbc9ae09',
2835 'from': 'git+https://github.com/jshttp/cookie.git'
2836 }
2837 }
2838 }
2839 }
2840 }
2841 }
2842 })
2843 fetcher = bb.fetch.Fetch(['npmsw://' + swfile], self.d)
2844 fetcher.download()
2845 self.assertTrue(os.path.exists(os.path.join(self.dldir, 'npm2', 'array-flatten-1.1.1.tgz')))
2846 self.assertTrue(os.path.exists(os.path.join(self.dldir, 'npm2', 'content-type-1.0.4.tgz')))
2847 self.assertTrue(os.path.exists(os.path.join(self.dldir, 'git2', 'github.com.jshttp.cookie.git')))
2848 fetcher.unpack(self.unpackdir)
2849 self.assertTrue(os.path.exists(os.path.join(self.sdir, 'npm-shrinkwrap.json')))
2850 self.assertTrue(os.path.exists(os.path.join(self.sdir, 'node_modules', 'array-flatten', 'package.json')))
2851 self.assertTrue(os.path.exists(os.path.join(self.sdir, 'node_modules', 'array-flatten', 'node_modules', 'content-type', 'package.json')))
2852 self.assertTrue(os.path.exists(os.path.join(self.sdir, 'node_modules', 'array-flatten', 'node_modules', 'content-type', 'node_modules', 'cookie', 'package.json')))
2853
2854 @skipIfNoNpm()
2855 @skipIfNoNetwork()
Andrew Geissler6aa7eec2023-03-03 12:41:14 -06002856 def test_npmsw_git(self):
2857 swfile = self.create_shrinkwrap_file({
2858 'dependencies': {
2859 'cookie': {
2860 'version': 'github:jshttp/cookie.git#aec1177c7da67e3b3273df96cf476824dbc9ae09',
2861 'from': 'github:jshttp/cookie.git'
2862 }
2863 }
2864 })
2865 fetcher = bb.fetch.Fetch(['npmsw://' + swfile], self.d)
2866 fetcher.download()
2867 self.assertTrue(os.path.exists(os.path.join(self.dldir, 'git2', 'github.com.jshttp.cookie.git')))
2868
2869 swfile = self.create_shrinkwrap_file({
2870 'dependencies': {
2871 'cookie': {
2872 'version': 'jshttp/cookie.git#aec1177c7da67e3b3273df96cf476824dbc9ae09',
2873 'from': 'jshttp/cookie.git'
2874 }
2875 }
2876 })
2877 fetcher = bb.fetch.Fetch(['npmsw://' + swfile], self.d)
2878 fetcher.download()
2879 self.assertTrue(os.path.exists(os.path.join(self.dldir, 'git2', 'github.com.jshttp.cookie.git')))
2880
2881 swfile = self.create_shrinkwrap_file({
2882 'dependencies': {
2883 'nodejs': {
2884 'version': 'gitlab:gitlab-examples/nodejs.git#892a1f16725e56cc3a2cb0d677be42935c8fc262',
2885 'from': 'gitlab:gitlab-examples/nodejs'
2886 }
2887 }
2888 })
2889 fetcher = bb.fetch.Fetch(['npmsw://' + swfile], self.d)
2890 fetcher.download()
2891 self.assertTrue(os.path.exists(os.path.join(self.dldir, 'git2', 'gitlab.com.gitlab-examples.nodejs.git')))
2892
2893 @skipIfNoNpm()
2894 @skipIfNoNetwork()
Andrew Geissler82c905d2020-04-13 13:39:40 -05002895 def test_npmsw_dev(self):
2896 swfile = self.create_shrinkwrap_file({
2897 'dependencies': {
2898 'array-flatten': {
2899 'version': '1.1.1',
2900 'resolved': 'https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz',
2901 'integrity': 'sha1-ml9pkFGx5wczKPKgCJaLZOopVdI='
2902 },
2903 'content-type': {
2904 'version': '1.0.4',
2905 'resolved': 'https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz',
2906 'integrity': 'sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==',
2907 'dev': True
2908 }
2909 }
2910 })
2911 # Fetch with dev disabled
2912 fetcher = bb.fetch.Fetch(['npmsw://' + swfile], self.d)
2913 fetcher.download()
2914 self.assertTrue(os.path.exists(os.path.join(self.dldir, 'npm2', 'array-flatten-1.1.1.tgz')))
2915 self.assertFalse(os.path.exists(os.path.join(self.dldir, 'npm2', 'content-type-1.0.4.tgz')))
2916 # Fetch with dev enabled
2917 fetcher = bb.fetch.Fetch(['npmsw://' + swfile + ';dev=1'], self.d)
2918 fetcher.download()
2919 self.assertTrue(os.path.exists(os.path.join(self.dldir, 'npm2', 'array-flatten-1.1.1.tgz')))
2920 self.assertTrue(os.path.exists(os.path.join(self.dldir, 'npm2', 'content-type-1.0.4.tgz')))
2921
2922 @skipIfNoNpm()
2923 @skipIfNoNetwork()
2924 def test_npmsw_destsuffix(self):
2925 swfile = self.create_shrinkwrap_file({
2926 'dependencies': {
2927 'array-flatten': {
2928 'version': '1.1.1',
2929 'resolved': 'https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz',
2930 'integrity': 'sha1-ml9pkFGx5wczKPKgCJaLZOopVdI='
2931 }
2932 }
2933 })
2934 fetcher = bb.fetch.Fetch(['npmsw://' + swfile + ';destsuffix=foo/bar'], self.d)
2935 fetcher.download()
2936 fetcher.unpack(self.unpackdir)
2937 self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'foo', 'bar', 'node_modules', 'array-flatten', 'package.json')))
2938
2939 def test_npmsw_no_network_no_tarball(self):
2940 swfile = self.create_shrinkwrap_file({
2941 'dependencies': {
2942 'array-flatten': {
2943 'version': '1.1.1',
2944 'resolved': 'https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz',
2945 'integrity': 'sha1-ml9pkFGx5wczKPKgCJaLZOopVdI='
2946 }
2947 }
2948 })
2949 self.d.setVar('BB_NO_NETWORK', '1')
2950 fetcher = bb.fetch.Fetch(['npmsw://' + swfile], self.d)
2951 with self.assertRaises(bb.fetch2.NetworkAccess):
2952 fetcher.download()
2953
2954 @skipIfNoNpm()
2955 @skipIfNoNetwork()
2956 def test_npmsw_no_network_with_tarball(self):
2957 # Fetch once to get a tarball
2958 fetcher = bb.fetch.Fetch(['npm://registry.npmjs.org;package=array-flatten;version=1.1.1'], self.d)
2959 fetcher.download()
2960 # Disable network access
2961 self.d.setVar('BB_NO_NETWORK', '1')
2962 # Fetch again
2963 swfile = self.create_shrinkwrap_file({
2964 'dependencies': {
2965 'array-flatten': {
2966 'version': '1.1.1',
2967 'resolved': 'https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz',
2968 'integrity': 'sha1-ml9pkFGx5wczKPKgCJaLZOopVdI='
2969 }
2970 }
2971 })
2972 fetcher = bb.fetch.Fetch(['npmsw://' + swfile], self.d)
2973 fetcher.download()
2974 fetcher.unpack(self.unpackdir)
2975 self.assertTrue(os.path.exists(os.path.join(self.sdir, 'node_modules', 'array-flatten', 'package.json')))
2976
2977 @skipIfNoNpm()
2978 @skipIfNoNetwork()
2979 def test_npmsw_npm_reusability(self):
2980 # Fetch once with npmsw
2981 swfile = self.create_shrinkwrap_file({
2982 'dependencies': {
2983 'array-flatten': {
2984 'version': '1.1.1',
2985 'resolved': 'https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz',
2986 'integrity': 'sha1-ml9pkFGx5wczKPKgCJaLZOopVdI='
2987 }
2988 }
2989 })
2990 fetcher = bb.fetch.Fetch(['npmsw://' + swfile], self.d)
2991 fetcher.download()
2992 # Disable network access
2993 self.d.setVar('BB_NO_NETWORK', '1')
2994 # Fetch again with npm
2995 fetcher = bb.fetch.Fetch(['npm://registry.npmjs.org;package=array-flatten;version=1.1.1'], self.d)
2996 fetcher.download()
2997 fetcher.unpack(self.unpackdir)
2998 self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'npm', 'package.json')))
2999
3000 @skipIfNoNpm()
3001 @skipIfNoNetwork()
3002 def test_npmsw_bad_checksum(self):
3003 # Try to fetch with bad checksum
3004 swfile = self.create_shrinkwrap_file({
3005 'dependencies': {
3006 'array-flatten': {
3007 'version': '1.1.1',
3008 'resolved': 'https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz',
3009 'integrity': 'sha1-gfNEp2hqgLTFKT6P3AsBYMgsBqg='
3010 }
3011 }
3012 })
3013 fetcher = bb.fetch.Fetch(['npmsw://' + swfile], self.d)
3014 with self.assertRaises(bb.fetch2.FetchError):
3015 fetcher.download()
3016 # Fetch correctly to get a tarball
3017 swfile = self.create_shrinkwrap_file({
3018 'dependencies': {
3019 'array-flatten': {
3020 'version': '1.1.1',
3021 'resolved': 'https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz',
3022 'integrity': 'sha1-ml9pkFGx5wczKPKgCJaLZOopVdI='
3023 }
3024 }
3025 })
3026 fetcher = bb.fetch.Fetch(['npmsw://' + swfile], self.d)
3027 fetcher.download()
3028 localpath = os.path.join(self.dldir, 'npm2', 'array-flatten-1.1.1.tgz')
3029 self.assertTrue(os.path.exists(localpath))
3030 # Modify the tarball
3031 bad = b'bad checksum'
3032 with open(localpath, 'wb') as f:
3033 f.write(bad)
3034 # Verify that the tarball is fetched again
3035 fetcher.download()
3036 badsum = hashlib.sha1(bad).hexdigest()
3037 self.assertTrue(os.path.exists(localpath + '_bad-checksum_' + badsum))
3038 self.assertTrue(os.path.exists(localpath))
3039
3040 @skipIfNoNpm()
3041 @skipIfNoNetwork()
3042 def test_npmsw_premirrors(self):
3043 # Fetch once to get a tarball
3044 fetcher = bb.fetch.Fetch(['npm://registry.npmjs.org;package=array-flatten;version=1.1.1'], self.d)
3045 ud = fetcher.ud[fetcher.urls[0]]
3046 fetcher.download()
3047 self.assertTrue(os.path.exists(ud.localpath))
3048 # Setup the mirror
3049 mirrordir = os.path.join(self.tempdir, 'mirror')
3050 bb.utils.mkdirhier(mirrordir)
3051 os.replace(ud.localpath, os.path.join(mirrordir, os.path.basename(ud.localpath)))
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00003052 self.d.setVar('PREMIRRORS', 'https?$://.*/.* file://%s/' % mirrordir)
Andrew Geissler82c905d2020-04-13 13:39:40 -05003053 self.d.setVar('BB_FETCH_PREMIRRORONLY', '1')
3054 # Fetch again
3055 self.assertFalse(os.path.exists(ud.localpath))
3056 swfile = self.create_shrinkwrap_file({
3057 'dependencies': {
3058 'array-flatten': {
3059 'version': '1.1.1',
3060 'resolved': 'https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz',
3061 'integrity': 'sha1-ml9pkFGx5wczKPKgCJaLZOopVdI='
3062 }
3063 }
3064 })
3065 fetcher = bb.fetch.Fetch(['npmsw://' + swfile], self.d)
3066 fetcher.download()
3067 self.assertTrue(os.path.exists(ud.localpath))
3068
3069 @skipIfNoNpm()
3070 @skipIfNoNetwork()
3071 def test_npmsw_mirrors(self):
3072 # Fetch once to get a tarball
3073 fetcher = bb.fetch.Fetch(['npm://registry.npmjs.org;package=array-flatten;version=1.1.1'], self.d)
3074 ud = fetcher.ud[fetcher.urls[0]]
3075 fetcher.download()
3076 self.assertTrue(os.path.exists(ud.localpath))
3077 # Setup the mirror
3078 mirrordir = os.path.join(self.tempdir, 'mirror')
3079 bb.utils.mkdirhier(mirrordir)
3080 os.replace(ud.localpath, os.path.join(mirrordir, os.path.basename(ud.localpath)))
Andrew Geissler7e0e3c02022-02-25 20:34:39 +00003081 self.d.setVar('MIRRORS', 'https?$://.*/.* file://%s/' % mirrordir)
Andrew Geissler82c905d2020-04-13 13:39:40 -05003082 # Fetch again with invalid url
3083 self.assertFalse(os.path.exists(ud.localpath))
3084 swfile = self.create_shrinkwrap_file({
3085 'dependencies': {
3086 'array-flatten': {
3087 'version': '1.1.1',
3088 'resolved': 'https://invalid',
3089 'integrity': 'sha1-ml9pkFGx5wczKPKgCJaLZOopVdI='
3090 }
3091 }
3092 })
3093 fetcher = bb.fetch.Fetch(['npmsw://' + swfile], self.d)
3094 fetcher.download()
3095 self.assertTrue(os.path.exists(ud.localpath))
Andrew Geisslerc926e172021-05-07 16:11:35 -05003096
3097class GitSharedTest(FetcherTest):
3098 def setUp(self):
3099 super(GitSharedTest, self).setUp()
Andrew Geissler028142b2023-05-05 11:29:21 -05003100 self.recipe_url = "git://git.openembedded.org/bitbake;branch=master;protocol=https"
Andrew Geisslerc926e172021-05-07 16:11:35 -05003101 self.d.setVar('SRCREV', '82ea737a0b42a8b53e11c9cde141e9e9c0bd8c40')
Andrew Geisslerfc113ea2023-03-31 09:59:46 -05003102 self.d.setVar("__BBSRCREV_SEEN", "1")
Andrew Geisslerc926e172021-05-07 16:11:35 -05003103
3104 @skipIfNoNetwork()
3105 def test_shared_unpack(self):
3106 fetcher = bb.fetch.Fetch([self.recipe_url], self.d)
3107
3108 fetcher.download()
3109 fetcher.unpack(self.unpackdir)
3110 alt = os.path.join(self.unpackdir, 'git/.git/objects/info/alternates')
3111 self.assertTrue(os.path.exists(alt))
3112
3113 @skipIfNoNetwork()
3114 def test_noshared_unpack(self):
3115 self.d.setVar('BB_GIT_NOSHARED', '1')
3116 self.unpackdir += '_noshared'
3117 fetcher = bb.fetch.Fetch([self.recipe_url], self.d)
3118
3119 fetcher.download()
3120 fetcher.unpack(self.unpackdir)
3121 alt = os.path.join(self.unpackdir, 'git/.git/objects/info/alternates')
3122 self.assertFalse(os.path.exists(alt))
Andrew Geissler78b72792022-06-14 06:47:25 -05003123
3124
3125class FetchPremirroronlyLocalTest(FetcherTest):
3126
3127 def setUp(self):
3128 super(FetchPremirroronlyLocalTest, self).setUp()
3129 self.mirrordir = os.path.join(self.tempdir, "mirrors")
3130 os.mkdir(self.mirrordir)
3131 self.reponame = "bitbake"
3132 self.gitdir = os.path.join(self.tempdir, "git", self.reponame)
Andrew Geissler028142b2023-05-05 11:29:21 -05003133 self.recipe_url = "git://git.fake.repo/bitbake;branch=master;protocol=https"
Andrew Geissler78b72792022-06-14 06:47:25 -05003134 self.d.setVar("BB_FETCH_PREMIRRORONLY", "1")
3135 self.d.setVar("BB_NO_NETWORK", "1")
3136 self.d.setVar("PREMIRRORS", self.recipe_url + " " + "file://{}".format(self.mirrordir) + " \n")
Patrick Williamsac13d5f2023-11-24 18:59:46 -06003137 self.mirrorname = "git2_git.fake.repo.bitbake.tar.gz"
3138 self.mirrorfile = os.path.join(self.mirrordir, self.mirrorname)
3139 self.testfilename = "bitbake-fetch.test"
Andrew Geissler78b72792022-06-14 06:47:25 -05003140
3141 def make_git_repo(self):
Andrew Geissler78b72792022-06-14 06:47:25 -05003142 recipeurl = "git:/git.fake.repo/bitbake"
3143 os.makedirs(self.gitdir)
Andrew Geissler8f840682023-07-21 09:09:43 -05003144 self.git_init(cwd=self.gitdir)
Andrew Geissler78b72792022-06-14 06:47:25 -05003145 for i in range(0):
3146 self.git_new_commit()
3147 bb.process.run('tar -czvf {} .'.format(os.path.join(self.mirrordir, self.mirrorname)), cwd = self.gitdir)
3148
3149 def git_new_commit(self):
3150 import random
Andrew Geissler78b72792022-06-14 06:47:25 -05003151 os.unlink(os.path.join(self.mirrordir, self.mirrorname))
Patrick Williamsac13d5f2023-11-24 18:59:46 -06003152 branch = self.git("branch --show-current", self.gitdir).split()
3153 with open(os.path.join(self.gitdir, self.testfilename), "w") as testfile:
3154 testfile.write("File {} from branch {}; Useless random data {}".format(self.testfilename, branch, random.random()))
3155 self.git("add {}".format(self.testfilename), self.gitdir)
3156 self.git("commit -a -m \"This random commit {} in branch {}. I'm useless.\"".format(random.random(), branch), self.gitdir)
Andrew Geissler78b72792022-06-14 06:47:25 -05003157 bb.process.run('tar -czvf {} .'.format(os.path.join(self.mirrordir, self.mirrorname)), cwd = self.gitdir)
3158 return self.git("rev-parse HEAD", self.gitdir).strip()
3159
Patrick Williamsac13d5f2023-11-24 18:59:46 -06003160 def git_new_branch(self, name):
3161 self.git_new_commit()
3162 head = self.git("rev-parse HEAD", self.gitdir).strip()
3163 self.git("checkout -b {}".format(name), self.gitdir)
3164 newrev = self.git_new_commit()
3165 self.git("checkout {}".format(head), self.gitdir)
3166 return newrev
3167
Patrick Williams73bd93f2024-02-20 08:07:48 -06003168 def test_mirror_multiple_fetches(self):
3169 self.make_git_repo()
3170 self.d.setVar("SRCREV", self.git_new_commit())
3171 fetcher = bb.fetch.Fetch([self.recipe_url], self.d)
3172 fetcher.download()
3173 fetcher.unpack(self.unpackdir)
3174 ## New commit in premirror. it's not in the download_dir
3175 self.d.setVar("SRCREV", self.git_new_commit())
3176 fetcher2 = bb.fetch.Fetch([self.recipe_url], self.d)
3177 fetcher2.download()
3178 fetcher2.unpack(self.unpackdir)
3179 ## New commit in premirror. it's not in the download_dir
3180 self.d.setVar("SRCREV", self.git_new_commit())
3181 fetcher3 = bb.fetch.Fetch([self.recipe_url], self.d)
3182 fetcher3.download()
3183 fetcher3.unpack(self.unpackdir)
3184
3185
Andrew Geissler78b72792022-06-14 06:47:25 -05003186 def test_mirror_commit_nonexistent(self):
3187 self.make_git_repo()
3188 self.d.setVar("SRCREV", "0"*40)
3189 fetcher = bb.fetch.Fetch([self.recipe_url], self.d)
3190 with self.assertRaises(bb.fetch2.NetworkAccess):
3191 fetcher.download()
3192
3193 def test_mirror_commit_exists(self):
3194 self.make_git_repo()
3195 self.d.setVar("SRCREV", self.git_new_commit())
3196 fetcher = bb.fetch.Fetch([self.recipe_url], self.d)
3197 fetcher.download()
3198 fetcher.unpack(self.unpackdir)
3199
3200 def test_mirror_tarball_nonexistent(self):
3201 self.d.setVar("SRCREV", "0"*40)
3202 fetcher = bb.fetch.Fetch([self.recipe_url], self.d)
3203 with self.assertRaises(bb.fetch2.NetworkAccess):
3204 fetcher.download()
3205
Patrick Williamsac13d5f2023-11-24 18:59:46 -06003206 def test_mirror_tarball_multiple_branches(self):
3207 """
3208 test if PREMIRRORS can handle multiple name/branches correctly
3209 both branches have required revisions
3210 """
3211 self.make_git_repo()
3212 branch1rev = self.git_new_branch("testbranch1")
3213 branch2rev = self.git_new_branch("testbranch2")
3214 self.recipe_url = "git://git.fake.repo/bitbake;branch=testbranch1,testbranch2;protocol=https;name=branch1,branch2"
3215 self.d.setVar("SRCREV_branch1", branch1rev)
3216 self.d.setVar("SRCREV_branch2", branch2rev)
3217 fetcher = bb.fetch.Fetch([self.recipe_url], self.d)
3218 self.assertTrue(os.path.exists(self.mirrorfile), "Mirror file doesn't exist")
3219 fetcher.download()
3220 fetcher.unpack(os.path.join(self.tempdir, "unpacked"))
3221 unpacked = os.path.join(self.tempdir, "unpacked", "git", self.testfilename)
3222 self.assertTrue(os.path.exists(unpacked), "Repo has not been unpackaged properly!")
3223 with open(unpacked, 'r') as f:
3224 content = f.read()
3225 ## We expect to see testbranch1 in the file, not master, not testbranch2
3226 self.assertTrue(content.find("testbranch1") != -1, "Wrong branch has been checked out!")
3227
3228 def test_mirror_tarball_multiple_branches_nobranch(self):
3229 """
3230 test if PREMIRRORS can handle multiple name/branches correctly
3231 Unbalanced name/branches raises ParameterError
3232 """
3233 self.make_git_repo()
3234 branch1rev = self.git_new_branch("testbranch1")
3235 branch2rev = self.git_new_branch("testbranch2")
3236 self.recipe_url = "git://git.fake.repo/bitbake;branch=testbranch1;protocol=https;name=branch1,branch2"
3237 self.d.setVar("SRCREV_branch1", branch1rev)
3238 self.d.setVar("SRCREV_branch2", branch2rev)
3239 with self.assertRaises(bb.fetch2.ParameterError):
3240 fetcher = bb.fetch.Fetch([self.recipe_url], self.d)
3241
3242 def test_mirror_tarball_multiple_branches_norev(self):
3243 """
3244 test if PREMIRRORS can handle multiple name/branches correctly
3245 one of the branches specifies non existing SRCREV
3246 """
3247 self.make_git_repo()
3248 branch1rev = self.git_new_branch("testbranch1")
3249 branch2rev = self.git_new_branch("testbranch2")
3250 self.recipe_url = "git://git.fake.repo/bitbake;branch=testbranch1,testbranch2;protocol=https;name=branch1,branch2"
3251 self.d.setVar("SRCREV_branch1", branch1rev)
3252 self.d.setVar("SRCREV_branch2", "0"*40)
3253 fetcher = bb.fetch.Fetch([self.recipe_url], self.d)
3254 self.assertTrue(os.path.exists(self.mirrorfile), "Mirror file doesn't exist")
3255 with self.assertRaises(bb.fetch2.NetworkAccess):
3256 fetcher.download()
3257
3258
Andrew Geissler78b72792022-06-14 06:47:25 -05003259class FetchPremirroronlyNetworkTest(FetcherTest):
3260
3261 def setUp(self):
3262 super(FetchPremirroronlyNetworkTest, self).setUp()
3263 self.mirrordir = os.path.join(self.tempdir, "mirrors")
3264 os.mkdir(self.mirrordir)
3265 self.reponame = "fstests"
3266 self.clonedir = os.path.join(self.tempdir, "git")
3267 self.gitdir = os.path.join(self.tempdir, "git", "{}.git".format(self.reponame))
Andrew Geissler028142b2023-05-05 11:29:21 -05003268 self.recipe_url = "git://git.yoctoproject.org/fstests;protocol=https"
Andrew Geissler78b72792022-06-14 06:47:25 -05003269 self.d.setVar("BB_FETCH_PREMIRRORONLY", "1")
3270 self.d.setVar("BB_NO_NETWORK", "0")
3271 self.d.setVar("PREMIRRORS", self.recipe_url + " " + "file://{}".format(self.mirrordir) + " \n")
3272
3273 def make_git_repo(self):
3274 import shutil
3275 self.mirrorname = "git2_git.yoctoproject.org.fstests.tar.gz"
3276 os.makedirs(self.clonedir)
3277 self.git("clone --bare --shallow-since=\"01.01.2013\" {}".format(self.recipe_url), self.clonedir)
3278 bb.process.run('tar -czvf {} .'.format(os.path.join(self.mirrordir, self.mirrorname)), cwd = self.gitdir)
3279 shutil.rmtree(self.clonedir)
3280
3281 @skipIfNoNetwork()
3282 def test_mirror_tarball_updated(self):
3283 self.make_git_repo()
3284 ## Upstream commit is in the mirror
3285 self.d.setVar("SRCREV", "49d65d53c2bf558ae6e9185af0f3af7b79d255ec")
3286 fetcher = bb.fetch.Fetch([self.recipe_url], self.d)
3287 fetcher.download()
3288
3289 @skipIfNoNetwork()
3290 def test_mirror_tarball_outdated(self):
3291 self.make_git_repo()
3292 ## Upstream commit not in the mirror
3293 self.d.setVar("SRCREV", "15413486df1f5a5b5af699b6f3ba5f0984e52a9f")
3294 fetcher = bb.fetch.Fetch([self.recipe_url], self.d)
3295 with self.assertRaises(bb.fetch2.NetworkAccess):
3296 fetcher.download()
Andrew Geissler615f2f12022-07-15 14:00:58 -05003297
Andrew Geisslerc5535c92023-01-27 16:10:19 -06003298class FetchPremirroronlyMercurialTest(FetcherTest):
3299 """ Test for premirrors with mercurial repos
3300 the test covers also basic hg:// clone (see fetch_and_create_tarball
3301 """
3302 def skipIfNoHg():
3303 import shutil
3304 if not shutil.which('hg'):
3305 return unittest.skip('Mercurial not installed')
3306 return lambda f: f
3307
3308 def setUp(self):
3309 super(FetchPremirroronlyMercurialTest, self).setUp()
3310 self.mirrordir = os.path.join(self.tempdir, "mirrors")
3311 os.mkdir(self.mirrordir)
3312 self.reponame = "libgnt"
3313 self.clonedir = os.path.join(self.tempdir, "hg")
3314 self.recipe_url = "hg://keep.imfreedom.org/libgnt;module=libgnt"
3315 self.d.setVar("SRCREV", "53e8b422faaf")
3316 self.mirrorname = "hg_libgnt_keep.imfreedom.org_.libgnt.tar.gz"
3317
3318 def fetch_and_create_tarball(self):
3319 """
3320 Ask bitbake to download repo and prepare mirror tarball for us
3321 """
3322 self.d.setVar("BB_GENERATE_MIRROR_TARBALLS", "1")
3323 fetcher = bb.fetch.Fetch([self.recipe_url], self.d)
3324 fetcher.download()
3325 mirrorfile = os.path.join(self.d.getVar("DL_DIR"), self.mirrorname)
3326 self.assertTrue(os.path.exists(mirrorfile), "Mirror tarball {} has not been created".format(mirrorfile))
3327 ## moving tarball to mirror directory
3328 os.rename(mirrorfile, os.path.join(self.mirrordir, self.mirrorname))
3329 self.d.setVar("BB_GENERATE_MIRROR_TARBALLS", "0")
3330
3331
3332 @skipIfNoNetwork()
3333 @skipIfNoHg()
3334 def test_premirror_mercurial(self):
3335 self.fetch_and_create_tarball()
3336 self.d.setVar("PREMIRRORS", self.recipe_url + " " + "file://{}".format(self.mirrordir) + " \n")
3337 self.d.setVar("BB_FETCH_PREMIRRORONLY", "1")
3338 self.d.setVar("BB_NO_NETWORK", "1")
3339 fetcher = bb.fetch.Fetch([self.recipe_url], self.d)
3340 fetcher.download()
3341
Andrew Geissler615f2f12022-07-15 14:00:58 -05003342class FetchPremirroronlyBrokenTarball(FetcherTest):
3343
3344 def setUp(self):
3345 super(FetchPremirroronlyBrokenTarball, self).setUp()
3346 self.mirrordir = os.path.join(self.tempdir, "mirrors")
3347 os.mkdir(self.mirrordir)
3348 self.reponame = "bitbake"
3349 self.gitdir = os.path.join(self.tempdir, "git", self.reponame)
Andrew Geissler028142b2023-05-05 11:29:21 -05003350 self.recipe_url = "git://git.fake.repo/bitbake;protocol=https"
Andrew Geissler615f2f12022-07-15 14:00:58 -05003351 self.d.setVar("BB_FETCH_PREMIRRORONLY", "1")
3352 self.d.setVar("BB_NO_NETWORK", "1")
3353 self.d.setVar("PREMIRRORS", self.recipe_url + " " + "file://{}".format(self.mirrordir) + " \n")
3354 self.mirrorname = "git2_git.fake.repo.bitbake.tar.gz"
3355 with open(os.path.join(self.mirrordir, self.mirrorname), 'w') as targz:
3356 targz.write("This is not tar.gz file!")
3357
3358 def test_mirror_broken_download(self):
3359 import sys
3360 self.d.setVar("SRCREV", "0"*40)
3361 fetcher = bb.fetch.Fetch([self.recipe_url], self.d)
Andrew Geissler8f840682023-07-21 09:09:43 -05003362 with self.assertRaises(bb.fetch2.FetchError), self.assertLogs() as logs:
Andrew Geissler615f2f12022-07-15 14:00:58 -05003363 fetcher.download()
Andrew Geissler8f840682023-07-21 09:09:43 -05003364 output = "".join(logs.output)
3365 self.assertFalse(" not a git repository (or any parent up to mount point /)" in output)