xref: /OK3568_Linux_fs/yocto/poky/bitbake/lib/bb/tests/fetch.py (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun#
2*4882a593Smuzhiyun# BitBake Tests for the Fetcher (fetch2/)
3*4882a593Smuzhiyun#
4*4882a593Smuzhiyun# Copyright (C) 2012 Richard Purdie
5*4882a593Smuzhiyun#
6*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0-only
7*4882a593Smuzhiyun#
8*4882a593Smuzhiyun
9*4882a593Smuzhiyunimport unittest
10*4882a593Smuzhiyunimport hashlib
11*4882a593Smuzhiyunimport tempfile
12*4882a593Smuzhiyunimport collections
13*4882a593Smuzhiyunimport os
14*4882a593Smuzhiyunimport tarfile
15*4882a593Smuzhiyunfrom bb.fetch2 import URI
16*4882a593Smuzhiyunfrom bb.fetch2 import FetchMethod
17*4882a593Smuzhiyunimport bb
18*4882a593Smuzhiyunfrom bb.tests.support.httpserver import HTTPService
19*4882a593Smuzhiyun
20*4882a593Smuzhiyundef skipIfNoNetwork():
21*4882a593Smuzhiyun    if os.environ.get("BB_SKIP_NETTESTS") == "yes":
22*4882a593Smuzhiyun        return unittest.skip("network test")
23*4882a593Smuzhiyun    return lambda f: f
24*4882a593Smuzhiyun
25*4882a593Smuzhiyunclass URITest(unittest.TestCase):
26*4882a593Smuzhiyun    test_uris = {
27*4882a593Smuzhiyun        "http://www.google.com/index.html" : {
28*4882a593Smuzhiyun            'uri': 'http://www.google.com/index.html',
29*4882a593Smuzhiyun            'scheme': 'http',
30*4882a593Smuzhiyun            'hostname': 'www.google.com',
31*4882a593Smuzhiyun            'port': None,
32*4882a593Smuzhiyun            'hostport': 'www.google.com',
33*4882a593Smuzhiyun            'path': '/index.html',
34*4882a593Smuzhiyun            'userinfo': '',
35*4882a593Smuzhiyun            'username': '',
36*4882a593Smuzhiyun            'password': '',
37*4882a593Smuzhiyun            'params': {},
38*4882a593Smuzhiyun            'query': {},
39*4882a593Smuzhiyun            'relative': False
40*4882a593Smuzhiyun        },
41*4882a593Smuzhiyun        "http://www.google.com/index.html;param1=value1" : {
42*4882a593Smuzhiyun            'uri': 'http://www.google.com/index.html;param1=value1',
43*4882a593Smuzhiyun            'scheme': 'http',
44*4882a593Smuzhiyun            'hostname': 'www.google.com',
45*4882a593Smuzhiyun            'port': None,
46*4882a593Smuzhiyun            'hostport': 'www.google.com',
47*4882a593Smuzhiyun            'path': '/index.html',
48*4882a593Smuzhiyun            'userinfo': '',
49*4882a593Smuzhiyun            'username': '',
50*4882a593Smuzhiyun            'password': '',
51*4882a593Smuzhiyun            'params': {
52*4882a593Smuzhiyun                'param1': 'value1'
53*4882a593Smuzhiyun            },
54*4882a593Smuzhiyun            'query': {},
55*4882a593Smuzhiyun            'relative': False
56*4882a593Smuzhiyun        },
57*4882a593Smuzhiyun        "http://www.example.org/index.html?param1=value1" : {
58*4882a593Smuzhiyun            'uri': 'http://www.example.org/index.html?param1=value1',
59*4882a593Smuzhiyun            'scheme': 'http',
60*4882a593Smuzhiyun            'hostname': 'www.example.org',
61*4882a593Smuzhiyun            'port': None,
62*4882a593Smuzhiyun            'hostport': 'www.example.org',
63*4882a593Smuzhiyun            'path': '/index.html',
64*4882a593Smuzhiyun            'userinfo': '',
65*4882a593Smuzhiyun            'username': '',
66*4882a593Smuzhiyun            'password': '',
67*4882a593Smuzhiyun            'params': {},
68*4882a593Smuzhiyun            'query': {
69*4882a593Smuzhiyun                'param1': 'value1'
70*4882a593Smuzhiyun            },
71*4882a593Smuzhiyun            'relative': False
72*4882a593Smuzhiyun        },
73*4882a593Smuzhiyun        "http://www.example.org/index.html?qparam1=qvalue1;param2=value2" : {
74*4882a593Smuzhiyun            'uri': 'http://www.example.org/index.html?qparam1=qvalue1;param2=value2',
75*4882a593Smuzhiyun            'scheme': 'http',
76*4882a593Smuzhiyun            'hostname': 'www.example.org',
77*4882a593Smuzhiyun            'port': None,
78*4882a593Smuzhiyun            'hostport': 'www.example.org',
79*4882a593Smuzhiyun            'path': '/index.html',
80*4882a593Smuzhiyun            'userinfo': '',
81*4882a593Smuzhiyun            'username': '',
82*4882a593Smuzhiyun            'password': '',
83*4882a593Smuzhiyun            'params': {
84*4882a593Smuzhiyun                'param2': 'value2'
85*4882a593Smuzhiyun            },
86*4882a593Smuzhiyun            'query': {
87*4882a593Smuzhiyun                'qparam1': 'qvalue1'
88*4882a593Smuzhiyun            },
89*4882a593Smuzhiyun            'relative': False
90*4882a593Smuzhiyun        },
91*4882a593Smuzhiyun        # Check that trailing semicolons are handled correctly
92*4882a593Smuzhiyun        "http://www.example.org/index.html?qparam1=qvalue1;param2=value2;" : {
93*4882a593Smuzhiyun            'uri': 'http://www.example.org/index.html?qparam1=qvalue1;param2=value2',
94*4882a593Smuzhiyun            'scheme': 'http',
95*4882a593Smuzhiyun            'hostname': 'www.example.org',
96*4882a593Smuzhiyun            'port': None,
97*4882a593Smuzhiyun            'hostport': 'www.example.org',
98*4882a593Smuzhiyun            'path': '/index.html',
99*4882a593Smuzhiyun            'userinfo': '',
100*4882a593Smuzhiyun            'username': '',
101*4882a593Smuzhiyun            'password': '',
102*4882a593Smuzhiyun            'params': {
103*4882a593Smuzhiyun                'param2': 'value2'
104*4882a593Smuzhiyun            },
105*4882a593Smuzhiyun            'query': {
106*4882a593Smuzhiyun                'qparam1': 'qvalue1'
107*4882a593Smuzhiyun            },
108*4882a593Smuzhiyun            'relative': False
109*4882a593Smuzhiyun        },
110*4882a593Smuzhiyun        "http://www.example.com:8080/index.html" : {
111*4882a593Smuzhiyun            'uri': 'http://www.example.com:8080/index.html',
112*4882a593Smuzhiyun            'scheme': 'http',
113*4882a593Smuzhiyun            'hostname': 'www.example.com',
114*4882a593Smuzhiyun            'port': 8080,
115*4882a593Smuzhiyun            'hostport': 'www.example.com:8080',
116*4882a593Smuzhiyun            'path': '/index.html',
117*4882a593Smuzhiyun            'userinfo': '',
118*4882a593Smuzhiyun            'username': '',
119*4882a593Smuzhiyun            'password': '',
120*4882a593Smuzhiyun            'params': {},
121*4882a593Smuzhiyun            'query': {},
122*4882a593Smuzhiyun            'relative': False
123*4882a593Smuzhiyun        },
124*4882a593Smuzhiyun        "cvs://anoncvs@cvs.handhelds.org/cvs;module=familiar/dist/ipkg" : {
125*4882a593Smuzhiyun            'uri': 'cvs://anoncvs@cvs.handhelds.org/cvs;module=familiar/dist/ipkg',
126*4882a593Smuzhiyun            'scheme': 'cvs',
127*4882a593Smuzhiyun            'hostname': 'cvs.handhelds.org',
128*4882a593Smuzhiyun            'port': None,
129*4882a593Smuzhiyun            'hostport': 'cvs.handhelds.org',
130*4882a593Smuzhiyun            'path': '/cvs',
131*4882a593Smuzhiyun            'userinfo': 'anoncvs',
132*4882a593Smuzhiyun            'username': 'anoncvs',
133*4882a593Smuzhiyun            'password': '',
134*4882a593Smuzhiyun            'params': {
135*4882a593Smuzhiyun                'module': 'familiar/dist/ipkg'
136*4882a593Smuzhiyun            },
137*4882a593Smuzhiyun            'query': {},
138*4882a593Smuzhiyun            'relative': False
139*4882a593Smuzhiyun        },
140*4882a593Smuzhiyun        "cvs://anoncvs:anonymous@cvs.handhelds.org/cvs;tag=V0-99-81;module=familiar/dist/ipkg": {
141*4882a593Smuzhiyun            'uri': 'cvs://anoncvs:anonymous@cvs.handhelds.org/cvs;tag=V0-99-81;module=familiar/dist/ipkg',
142*4882a593Smuzhiyun            'scheme': 'cvs',
143*4882a593Smuzhiyun            'hostname': 'cvs.handhelds.org',
144*4882a593Smuzhiyun            'port': None,
145*4882a593Smuzhiyun            'hostport': 'cvs.handhelds.org',
146*4882a593Smuzhiyun            'path': '/cvs',
147*4882a593Smuzhiyun            'userinfo': 'anoncvs:anonymous',
148*4882a593Smuzhiyun            'username': 'anoncvs',
149*4882a593Smuzhiyun            'password': 'anonymous',
150*4882a593Smuzhiyun            'params': collections.OrderedDict([
151*4882a593Smuzhiyun                ('tag', 'V0-99-81'),
152*4882a593Smuzhiyun                ('module', 'familiar/dist/ipkg')
153*4882a593Smuzhiyun            ]),
154*4882a593Smuzhiyun            'query': {},
155*4882a593Smuzhiyun            'relative': False
156*4882a593Smuzhiyun        },
157*4882a593Smuzhiyun        "file://example.diff": { # NOTE: Not RFC compliant!
158*4882a593Smuzhiyun            'uri': 'file:example.diff',
159*4882a593Smuzhiyun            'scheme': 'file',
160*4882a593Smuzhiyun            'hostname': '',
161*4882a593Smuzhiyun            'port': None,
162*4882a593Smuzhiyun            'hostport': '',
163*4882a593Smuzhiyun            'path': 'example.diff',
164*4882a593Smuzhiyun            'userinfo': '',
165*4882a593Smuzhiyun            'username': '',
166*4882a593Smuzhiyun            'password': '',
167*4882a593Smuzhiyun            'params': {},
168*4882a593Smuzhiyun            'query': {},
169*4882a593Smuzhiyun            'relative': True
170*4882a593Smuzhiyun        },
171*4882a593Smuzhiyun        "file:example.diff": { # NOTE: RFC compliant version of the former
172*4882a593Smuzhiyun            'uri': 'file:example.diff',
173*4882a593Smuzhiyun            'scheme': 'file',
174*4882a593Smuzhiyun            'hostname': '',
175*4882a593Smuzhiyun            'port': None,
176*4882a593Smuzhiyun            'hostport': '',
177*4882a593Smuzhiyun            'path': 'example.diff',
178*4882a593Smuzhiyun            'userinfo': '',
179*4882a593Smuzhiyun            'userinfo': '',
180*4882a593Smuzhiyun            'username': '',
181*4882a593Smuzhiyun            'password': '',
182*4882a593Smuzhiyun            'params': {},
183*4882a593Smuzhiyun            'query': {},
184*4882a593Smuzhiyun            'relative': True
185*4882a593Smuzhiyun        },
186*4882a593Smuzhiyun        "file:///tmp/example.diff": {
187*4882a593Smuzhiyun            'uri': 'file:///tmp/example.diff',
188*4882a593Smuzhiyun            'scheme': 'file',
189*4882a593Smuzhiyun            'hostname': '',
190*4882a593Smuzhiyun            'port': None,
191*4882a593Smuzhiyun            'hostport': '',
192*4882a593Smuzhiyun            'path': '/tmp/example.diff',
193*4882a593Smuzhiyun            'userinfo': '',
194*4882a593Smuzhiyun            'userinfo': '',
195*4882a593Smuzhiyun            'username': '',
196*4882a593Smuzhiyun            'password': '',
197*4882a593Smuzhiyun            'params': {},
198*4882a593Smuzhiyun            'query': {},
199*4882a593Smuzhiyun            'relative': False
200*4882a593Smuzhiyun        },
201*4882a593Smuzhiyun        "git:///path/example.git": {
202*4882a593Smuzhiyun            'uri': 'git:///path/example.git',
203*4882a593Smuzhiyun            'scheme': 'git',
204*4882a593Smuzhiyun            'hostname': '',
205*4882a593Smuzhiyun            'port': None,
206*4882a593Smuzhiyun            'hostport': '',
207*4882a593Smuzhiyun            'path': '/path/example.git',
208*4882a593Smuzhiyun            'userinfo': '',
209*4882a593Smuzhiyun            'userinfo': '',
210*4882a593Smuzhiyun            'username': '',
211*4882a593Smuzhiyun            'password': '',
212*4882a593Smuzhiyun            'params': {},
213*4882a593Smuzhiyun            'query': {},
214*4882a593Smuzhiyun            'relative': False
215*4882a593Smuzhiyun        },
216*4882a593Smuzhiyun        "git:path/example.git": {
217*4882a593Smuzhiyun            'uri': 'git:path/example.git',
218*4882a593Smuzhiyun            'scheme': 'git',
219*4882a593Smuzhiyun            'hostname': '',
220*4882a593Smuzhiyun            'port': None,
221*4882a593Smuzhiyun            'hostport': '',
222*4882a593Smuzhiyun            'path': 'path/example.git',
223*4882a593Smuzhiyun            'userinfo': '',
224*4882a593Smuzhiyun            'userinfo': '',
225*4882a593Smuzhiyun            'username': '',
226*4882a593Smuzhiyun            'password': '',
227*4882a593Smuzhiyun            'params': {},
228*4882a593Smuzhiyun            'query': {},
229*4882a593Smuzhiyun            'relative': True
230*4882a593Smuzhiyun        },
231*4882a593Smuzhiyun        "git://example.net/path/example.git": {
232*4882a593Smuzhiyun            'uri': 'git://example.net/path/example.git',
233*4882a593Smuzhiyun            'scheme': 'git',
234*4882a593Smuzhiyun            'hostname': 'example.net',
235*4882a593Smuzhiyun            'port': None,
236*4882a593Smuzhiyun            'hostport': 'example.net',
237*4882a593Smuzhiyun            'path': '/path/example.git',
238*4882a593Smuzhiyun            'userinfo': '',
239*4882a593Smuzhiyun            'userinfo': '',
240*4882a593Smuzhiyun            'username': '',
241*4882a593Smuzhiyun            'password': '',
242*4882a593Smuzhiyun            'params': {},
243*4882a593Smuzhiyun            'query': {},
244*4882a593Smuzhiyun            'relative': False
245*4882a593Smuzhiyun        },
246*4882a593Smuzhiyun        "git://tfs-example.org:22/tfs/example%20path/example.git": {
247*4882a593Smuzhiyun            'uri': 'git://tfs-example.org:22/tfs/example%20path/example.git',
248*4882a593Smuzhiyun            'scheme': 'git',
249*4882a593Smuzhiyun            'hostname': 'tfs-example.org',
250*4882a593Smuzhiyun            'port': 22,
251*4882a593Smuzhiyun            'hostport': 'tfs-example.org:22',
252*4882a593Smuzhiyun            'path': '/tfs/example path/example.git',
253*4882a593Smuzhiyun            'userinfo': '',
254*4882a593Smuzhiyun            'userinfo': '',
255*4882a593Smuzhiyun            'username': '',
256*4882a593Smuzhiyun            'password': '',
257*4882a593Smuzhiyun            'params': {},
258*4882a593Smuzhiyun            'query': {},
259*4882a593Smuzhiyun            'relative': False
260*4882a593Smuzhiyun        },
261*4882a593Smuzhiyun        "http://somesite.net;someparam=1": {
262*4882a593Smuzhiyun            'uri': 'http://somesite.net;someparam=1',
263*4882a593Smuzhiyun            'scheme': 'http',
264*4882a593Smuzhiyun            'hostname': 'somesite.net',
265*4882a593Smuzhiyun            'port': None,
266*4882a593Smuzhiyun            'hostport': 'somesite.net',
267*4882a593Smuzhiyun            'path': '',
268*4882a593Smuzhiyun            'userinfo': '',
269*4882a593Smuzhiyun            'userinfo': '',
270*4882a593Smuzhiyun            'username': '',
271*4882a593Smuzhiyun            'password': '',
272*4882a593Smuzhiyun            'params': {"someparam" : "1"},
273*4882a593Smuzhiyun            'query': {},
274*4882a593Smuzhiyun            'relative': False
275*4882a593Smuzhiyun        },
276*4882a593Smuzhiyun        "file://somelocation;someparam=1": {
277*4882a593Smuzhiyun            'uri': 'file:somelocation;someparam=1',
278*4882a593Smuzhiyun            'scheme': 'file',
279*4882a593Smuzhiyun            'hostname': '',
280*4882a593Smuzhiyun            'port': None,
281*4882a593Smuzhiyun            'hostport': '',
282*4882a593Smuzhiyun            'path': 'somelocation',
283*4882a593Smuzhiyun            'userinfo': '',
284*4882a593Smuzhiyun            'userinfo': '',
285*4882a593Smuzhiyun            'username': '',
286*4882a593Smuzhiyun            'password': '',
287*4882a593Smuzhiyun            'params': {"someparam" : "1"},
288*4882a593Smuzhiyun            'query': {},
289*4882a593Smuzhiyun            'relative': True
290*4882a593Smuzhiyun        }
291*4882a593Smuzhiyun
292*4882a593Smuzhiyun    }
293*4882a593Smuzhiyun
294*4882a593Smuzhiyun    def test_uri(self):
295*4882a593Smuzhiyun        for test_uri, ref in self.test_uris.items():
296*4882a593Smuzhiyun            uri = URI(test_uri)
297*4882a593Smuzhiyun
298*4882a593Smuzhiyun            self.assertEqual(str(uri), ref['uri'])
299*4882a593Smuzhiyun
300*4882a593Smuzhiyun            # expected attributes
301*4882a593Smuzhiyun            self.assertEqual(uri.scheme, ref['scheme'])
302*4882a593Smuzhiyun
303*4882a593Smuzhiyun            self.assertEqual(uri.userinfo, ref['userinfo'])
304*4882a593Smuzhiyun            self.assertEqual(uri.username, ref['username'])
305*4882a593Smuzhiyun            self.assertEqual(uri.password, ref['password'])
306*4882a593Smuzhiyun
307*4882a593Smuzhiyun            self.assertEqual(uri.hostname, ref['hostname'])
308*4882a593Smuzhiyun            self.assertEqual(uri.port, ref['port'])
309*4882a593Smuzhiyun            self.assertEqual(uri.hostport, ref['hostport'])
310*4882a593Smuzhiyun
311*4882a593Smuzhiyun            self.assertEqual(uri.path, ref['path'])
312*4882a593Smuzhiyun            self.assertEqual(uri.params, ref['params'])
313*4882a593Smuzhiyun
314*4882a593Smuzhiyun            self.assertEqual(uri.relative, ref['relative'])
315*4882a593Smuzhiyun
316*4882a593Smuzhiyun    def test_dict(self):
317*4882a593Smuzhiyun        for test in self.test_uris.values():
318*4882a593Smuzhiyun            uri = URI()
319*4882a593Smuzhiyun
320*4882a593Smuzhiyun            self.assertEqual(uri.scheme, '')
321*4882a593Smuzhiyun            self.assertEqual(uri.userinfo, '')
322*4882a593Smuzhiyun            self.assertEqual(uri.username, '')
323*4882a593Smuzhiyun            self.assertEqual(uri.password, '')
324*4882a593Smuzhiyun            self.assertEqual(uri.hostname, '')
325*4882a593Smuzhiyun            self.assertEqual(uri.port, None)
326*4882a593Smuzhiyun            self.assertEqual(uri.path, '')
327*4882a593Smuzhiyun            self.assertEqual(uri.params, {})
328*4882a593Smuzhiyun
329*4882a593Smuzhiyun
330*4882a593Smuzhiyun            uri.scheme = test['scheme']
331*4882a593Smuzhiyun            self.assertEqual(uri.scheme, test['scheme'])
332*4882a593Smuzhiyun
333*4882a593Smuzhiyun            uri.userinfo = test['userinfo']
334*4882a593Smuzhiyun            self.assertEqual(uri.userinfo, test['userinfo'])
335*4882a593Smuzhiyun            self.assertEqual(uri.username, test['username'])
336*4882a593Smuzhiyun            self.assertEqual(uri.password, test['password'])
337*4882a593Smuzhiyun
338*4882a593Smuzhiyun            # make sure changing the values doesn't do anything unexpected
339*4882a593Smuzhiyun            uri.username = 'changeme'
340*4882a593Smuzhiyun            self.assertEqual(uri.username, 'changeme')
341*4882a593Smuzhiyun            self.assertEqual(uri.password, test['password'])
342*4882a593Smuzhiyun            uri.password = 'insecure'
343*4882a593Smuzhiyun            self.assertEqual(uri.username, 'changeme')
344*4882a593Smuzhiyun            self.assertEqual(uri.password, 'insecure')
345*4882a593Smuzhiyun
346*4882a593Smuzhiyun            # reset back after our trickery
347*4882a593Smuzhiyun            uri.userinfo = test['userinfo']
348*4882a593Smuzhiyun            self.assertEqual(uri.userinfo, test['userinfo'])
349*4882a593Smuzhiyun            self.assertEqual(uri.username, test['username'])
350*4882a593Smuzhiyun            self.assertEqual(uri.password, test['password'])
351*4882a593Smuzhiyun
352*4882a593Smuzhiyun            uri.hostname = test['hostname']
353*4882a593Smuzhiyun            self.assertEqual(uri.hostname, test['hostname'])
354*4882a593Smuzhiyun            self.assertEqual(uri.hostport, test['hostname'])
355*4882a593Smuzhiyun
356*4882a593Smuzhiyun            uri.port = test['port']
357*4882a593Smuzhiyun            self.assertEqual(uri.port, test['port'])
358*4882a593Smuzhiyun            self.assertEqual(uri.hostport, test['hostport'])
359*4882a593Smuzhiyun
360*4882a593Smuzhiyun            uri.path = test['path']
361*4882a593Smuzhiyun            self.assertEqual(uri.path, test['path'])
362*4882a593Smuzhiyun
363*4882a593Smuzhiyun            uri.params = test['params']
364*4882a593Smuzhiyun            self.assertEqual(uri.params, test['params'])
365*4882a593Smuzhiyun
366*4882a593Smuzhiyun            uri.query = test['query']
367*4882a593Smuzhiyun            self.assertEqual(uri.query, test['query'])
368*4882a593Smuzhiyun
369*4882a593Smuzhiyun            self.assertEqual(str(uri), test['uri'])
370*4882a593Smuzhiyun
371*4882a593Smuzhiyun            uri.params = {}
372*4882a593Smuzhiyun            self.assertEqual(uri.params, {})
373*4882a593Smuzhiyun            self.assertEqual(str(uri), (str(uri).split(";"))[0])
374*4882a593Smuzhiyun
375*4882a593Smuzhiyunclass FetcherTest(unittest.TestCase):
376*4882a593Smuzhiyun
377*4882a593Smuzhiyun    def setUp(self):
378*4882a593Smuzhiyun        self.origdir = os.getcwd()
379*4882a593Smuzhiyun        self.d = bb.data.init()
380*4882a593Smuzhiyun        self.tempdir = tempfile.mkdtemp(prefix="bitbake-fetch-")
381*4882a593Smuzhiyun        self.dldir = os.path.join(self.tempdir, "download")
382*4882a593Smuzhiyun        os.mkdir(self.dldir)
383*4882a593Smuzhiyun        self.d.setVar("DL_DIR", self.dldir)
384*4882a593Smuzhiyun        self.unpackdir = os.path.join(self.tempdir, "unpacked")
385*4882a593Smuzhiyun        os.mkdir(self.unpackdir)
386*4882a593Smuzhiyun        persistdir = os.path.join(self.tempdir, "persistdata")
387*4882a593Smuzhiyun        self.d.setVar("PERSISTENT_DIR", persistdir)
388*4882a593Smuzhiyun
389*4882a593Smuzhiyun    def tearDown(self):
390*4882a593Smuzhiyun        os.chdir(self.origdir)
391*4882a593Smuzhiyun        if os.environ.get("BB_TMPDIR_NOCLEAN") == "yes":
392*4882a593Smuzhiyun            print("Not cleaning up %s. Please remove manually." % self.tempdir)
393*4882a593Smuzhiyun        else:
394*4882a593Smuzhiyun            bb.process.run('chmod u+rw -R %s' % self.tempdir)
395*4882a593Smuzhiyun            bb.utils.prunedir(self.tempdir)
396*4882a593Smuzhiyun
397*4882a593Smuzhiyun    def git(self, cmd, cwd=None):
398*4882a593Smuzhiyun        if isinstance(cmd, str):
399*4882a593Smuzhiyun            cmd = 'git ' + cmd
400*4882a593Smuzhiyun        else:
401*4882a593Smuzhiyun            cmd = ['git'] + cmd
402*4882a593Smuzhiyun        if cwd is None:
403*4882a593Smuzhiyun            cwd = self.gitdir
404*4882a593Smuzhiyun        return bb.process.run(cmd, cwd=cwd)[0]
405*4882a593Smuzhiyun
406*4882a593Smuzhiyun    def git_init(self, cwd=None):
407*4882a593Smuzhiyun        self.git('init', cwd=cwd)
408*4882a593Smuzhiyun        if not self.git(['config', 'user.email'], cwd=cwd):
409*4882a593Smuzhiyun            self.git(['config', 'user.email', 'you@example.com'], cwd=cwd)
410*4882a593Smuzhiyun        if not self.git(['config', 'user.name'], cwd=cwd):
411*4882a593Smuzhiyun            self.git(['config', 'user.name', 'Your Name'], cwd=cwd)
412*4882a593Smuzhiyun
413*4882a593Smuzhiyunclass MirrorUriTest(FetcherTest):
414*4882a593Smuzhiyun
415*4882a593Smuzhiyun    replaceuris = {
416*4882a593Smuzhiyun        ("git://git.invalid.infradead.org/mtd-utils.git;tag=1234567890123456789012345678901234567890", "git://.*/.*", "http://somewhere.org/somedir/")
417*4882a593Smuzhiyun            : "http://somewhere.org/somedir/git2_git.invalid.infradead.org.mtd-utils.git.tar.gz",
418*4882a593Smuzhiyun        ("git://git.invalid.infradead.org/mtd-utils.git;tag=1234567890123456789012345678901234567890", "git://.*/([^/]+/)*([^/]*)", "git://somewhere.org/somedir/\\2;protocol=http")
419*4882a593Smuzhiyun            : "git://somewhere.org/somedir/mtd-utils.git;tag=1234567890123456789012345678901234567890;protocol=http",
420*4882a593Smuzhiyun        ("git://git.invalid.infradead.org/foo/mtd-utils.git;tag=1234567890123456789012345678901234567890", "git://.*/([^/]+/)*([^/]*)", "git://somewhere.org/somedir/\\2;protocol=http")
421*4882a593Smuzhiyun            : "git://somewhere.org/somedir/mtd-utils.git;tag=1234567890123456789012345678901234567890;protocol=http",
422*4882a593Smuzhiyun        ("git://git.invalid.infradead.org/foo/mtd-utils.git;tag=1234567890123456789012345678901234567890", "git://.*/([^/]+/)*([^/]*)", "git://somewhere.org/\\2;protocol=http")
423*4882a593Smuzhiyun            : "git://somewhere.org/mtd-utils.git;tag=1234567890123456789012345678901234567890;protocol=http",
424*4882a593Smuzhiyun        ("git://someserver.org/bitbake;tag=1234567890123456789012345678901234567890", "git://someserver.org/bitbake", "git://git.openembedded.org/bitbake")
425*4882a593Smuzhiyun            : "git://git.openembedded.org/bitbake;tag=1234567890123456789012345678901234567890",
426*4882a593Smuzhiyun        ("file://sstate-xyz.tgz", "file://.*", "file:///somewhere/1234/sstate-cache")
427*4882a593Smuzhiyun            : "file:///somewhere/1234/sstate-cache/sstate-xyz.tgz",
428*4882a593Smuzhiyun        ("file://sstate-xyz.tgz", "file://.*", "file:///somewhere/1234/sstate-cache/")
429*4882a593Smuzhiyun            : "file:///somewhere/1234/sstate-cache/sstate-xyz.tgz",
430*4882a593Smuzhiyun        ("http://somewhere.org/somedir1/somedir2/somefile_1.2.3.tar.gz", "http://.*/.*", "http://somewhere2.org/somedir3")
431*4882a593Smuzhiyun            : "http://somewhere2.org/somedir3/somefile_1.2.3.tar.gz",
432*4882a593Smuzhiyun        ("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")
433*4882a593Smuzhiyun            : "http://somewhere2.org/somedir3/somefile_1.2.3.tar.gz",
434*4882a593Smuzhiyun        ("http://www.apache.org/dist/subversion/subversion-1.7.1.tar.bz2", "http://www.apache.org/dist", "http://archive.apache.org/dist")
435*4882a593Smuzhiyun            : "http://archive.apache.org/dist/subversion/subversion-1.7.1.tar.bz2",
436*4882a593Smuzhiyun        ("http://www.apache.org/dist/subversion/subversion-1.7.1.tar.bz2", "http://.*/.*", "file:///somepath/downloads/")
437*4882a593Smuzhiyun            : "file:///somepath/downloads/subversion-1.7.1.tar.bz2",
438*4882a593Smuzhiyun        ("git://git.invalid.infradead.org/mtd-utils.git;tag=1234567890123456789012345678901234567890", "git://.*/.*", "git://somewhere.org/somedir/BASENAME;protocol=http")
439*4882a593Smuzhiyun            : "git://somewhere.org/somedir/mtd-utils.git;tag=1234567890123456789012345678901234567890;protocol=http",
440*4882a593Smuzhiyun        ("git://git.invalid.infradead.org/foo/mtd-utils.git;tag=1234567890123456789012345678901234567890", "git://.*/.*", "git://somewhere.org/somedir/BASENAME;protocol=http")
441*4882a593Smuzhiyun            : "git://somewhere.org/somedir/mtd-utils.git;tag=1234567890123456789012345678901234567890;protocol=http",
442*4882a593Smuzhiyun        ("git://git.invalid.infradead.org/foo/mtd-utils.git;tag=1234567890123456789012345678901234567890", "git://.*/.*", "git://somewhere.org/somedir/MIRRORNAME;protocol=http")
443*4882a593Smuzhiyun            : "git://somewhere.org/somedir/git.invalid.infradead.org.foo.mtd-utils.git;tag=1234567890123456789012345678901234567890;protocol=http",
444*4882a593Smuzhiyun        ("http://somewhere.org/somedir1/somedir2/somefile_1.2.3.tar.gz", "http://.*/.*", "http://somewhere2.org")
445*4882a593Smuzhiyun            : "http://somewhere2.org/somefile_1.2.3.tar.gz",
446*4882a593Smuzhiyun        ("http://somewhere.org/somedir1/somedir2/somefile_1.2.3.tar.gz", "http://.*/.*", "http://somewhere2.org/")
447*4882a593Smuzhiyun            : "http://somewhere2.org/somefile_1.2.3.tar.gz",
448*4882a593Smuzhiyun        ("git://someserver.org/bitbake;tag=1234567890123456789012345678901234567890;branch=master", "git://someserver.org/bitbake;branch=master", "git://git.openembedded.org/bitbake;protocol=http")
449*4882a593Smuzhiyun            : "git://git.openembedded.org/bitbake;tag=1234567890123456789012345678901234567890;branch=master;protocol=http",
450*4882a593Smuzhiyun        ("git://user1@someserver.org/bitbake;tag=1234567890123456789012345678901234567890;branch=master", "git://someserver.org/bitbake;branch=master", "git://user2@git.openembedded.org/bitbake;protocol=http")
451*4882a593Smuzhiyun            : "git://user2@git.openembedded.org/bitbake;tag=1234567890123456789012345678901234567890;branch=master;protocol=http",
452*4882a593Smuzhiyun        ("git://someserver.org/bitbake;tag=1234567890123456789012345678901234567890;protocol=git;branch=master", "git://someserver.org/bitbake", "git://someotherserver.org/bitbake;protocol=https")
453*4882a593Smuzhiyun            : "git://someotherserver.org/bitbake;tag=1234567890123456789012345678901234567890;protocol=https;branch=master",
454*4882a593Smuzhiyun        ("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",
455*4882a593Smuzhiyun        ("https://somewhere.org/example/1.0.0/example;downloadfilename=some-example-1.0.0.tgz", "https://.*/.*", "file:///mirror/PATH")
456*4882a593Smuzhiyun            : "file:///mirror/example/1.0.0/some-example-1.0.0.tgz;downloadfilename=some-example-1.0.0.tgz",
457*4882a593Smuzhiyun        ("https://somewhere.org/example-1.0.0.tgz;downloadfilename=some-example-1.0.0.tgz", "https://.*/.*", "file:///mirror/some-example-1.0.0.tgz")
458*4882a593Smuzhiyun            : "file:///mirror/some-example-1.0.0.tgz;downloadfilename=some-example-1.0.0.tgz",
459*4882a593Smuzhiyun
460*4882a593Smuzhiyun        #Renaming files doesn't work
461*4882a593Smuzhiyun        #("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"
462*4882a593Smuzhiyun        #("file://sstate-xyz.tgz", "file://.*/.*", "file:///somewhere/1234/sstate-cache") : "file:///somewhere/1234/sstate-cache/sstate-xyz.tgz",
463*4882a593Smuzhiyun    }
464*4882a593Smuzhiyun
465*4882a593Smuzhiyun    mirrorvar = "http://.*/.* file:///somepath/downloads/ " \
466*4882a593Smuzhiyun                "git://someserver.org/bitbake git://git.openembedded.org/bitbake " \
467*4882a593Smuzhiyun                "https://.*/.* file:///someotherpath/downloads/ " \
468*4882a593Smuzhiyun                "http://.*/.* file:///someotherpath/downloads/"
469*4882a593Smuzhiyun
470*4882a593Smuzhiyun    def test_urireplace(self):
471*4882a593Smuzhiyun        for k, v in self.replaceuris.items():
472*4882a593Smuzhiyun            ud = bb.fetch.FetchData(k[0], self.d)
473*4882a593Smuzhiyun            ud.setup_localpath(self.d)
474*4882a593Smuzhiyun            mirrors = bb.fetch2.mirror_from_string("%s %s" % (k[1], k[2]))
475*4882a593Smuzhiyun            newuris, uds = bb.fetch2.build_mirroruris(ud, mirrors, self.d)
476*4882a593Smuzhiyun            self.assertEqual([v], newuris)
477*4882a593Smuzhiyun
478*4882a593Smuzhiyun    def test_urilist1(self):
479*4882a593Smuzhiyun        fetcher = bb.fetch.FetchData("http://downloads.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz", self.d)
480*4882a593Smuzhiyun        mirrors = bb.fetch2.mirror_from_string(self.mirrorvar)
481*4882a593Smuzhiyun        uris, uds = bb.fetch2.build_mirroruris(fetcher, mirrors, self.d)
482*4882a593Smuzhiyun        self.assertEqual(uris, ['file:///somepath/downloads/bitbake-1.0.tar.gz', 'file:///someotherpath/downloads/bitbake-1.0.tar.gz'])
483*4882a593Smuzhiyun
484*4882a593Smuzhiyun    def test_urilist2(self):
485*4882a593Smuzhiyun        # Catch https:// -> files:// bug
486*4882a593Smuzhiyun        fetcher = bb.fetch.FetchData("https://downloads.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz", self.d)
487*4882a593Smuzhiyun        mirrors = bb.fetch2.mirror_from_string(self.mirrorvar)
488*4882a593Smuzhiyun        uris, uds = bb.fetch2.build_mirroruris(fetcher, mirrors, self.d)
489*4882a593Smuzhiyun        self.assertEqual(uris, ['file:///someotherpath/downloads/bitbake-1.0.tar.gz'])
490*4882a593Smuzhiyun
491*4882a593Smuzhiyun    def test_mirror_of_mirror(self):
492*4882a593Smuzhiyun        # Test if mirror of a mirror works
493*4882a593Smuzhiyun        mirrorvar = self.mirrorvar + " http://.*/.* http://otherdownloads.yoctoproject.org/downloads/"
494*4882a593Smuzhiyun        mirrorvar = mirrorvar + " http://otherdownloads.yoctoproject.org/.* http://downloads2.yoctoproject.org/downloads/"
495*4882a593Smuzhiyun        fetcher = bb.fetch.FetchData("http://downloads.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz", self.d)
496*4882a593Smuzhiyun        mirrors = bb.fetch2.mirror_from_string(mirrorvar)
497*4882a593Smuzhiyun        uris, uds = bb.fetch2.build_mirroruris(fetcher, mirrors, self.d)
498*4882a593Smuzhiyun        self.assertEqual(uris, ['file:///somepath/downloads/bitbake-1.0.tar.gz',
499*4882a593Smuzhiyun                                'file:///someotherpath/downloads/bitbake-1.0.tar.gz',
500*4882a593Smuzhiyun                                'http://otherdownloads.yoctoproject.org/downloads/bitbake-1.0.tar.gz',
501*4882a593Smuzhiyun                                'http://downloads2.yoctoproject.org/downloads/bitbake-1.0.tar.gz'])
502*4882a593Smuzhiyun
503*4882a593Smuzhiyun    recmirrorvar = "https://.*/[^/]*    http://AAAA/A/A/A/ " \
504*4882a593Smuzhiyun                   "https://.*/[^/]*    https://BBBB/B/B/B/"
505*4882a593Smuzhiyun
506*4882a593Smuzhiyun    def test_recursive(self):
507*4882a593Smuzhiyun        fetcher = bb.fetch.FetchData("https://downloads.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz", self.d)
508*4882a593Smuzhiyun        mirrors = bb.fetch2.mirror_from_string(self.recmirrorvar)
509*4882a593Smuzhiyun        uris, uds = bb.fetch2.build_mirroruris(fetcher, mirrors, self.d)
510*4882a593Smuzhiyun        self.assertEqual(uris, ['http://AAAA/A/A/A/bitbake/bitbake-1.0.tar.gz',
511*4882a593Smuzhiyun                                'https://BBBB/B/B/B/bitbake/bitbake-1.0.tar.gz',
512*4882a593Smuzhiyun                                'http://AAAA/A/A/A/B/B/bitbake/bitbake-1.0.tar.gz'])
513*4882a593Smuzhiyun
514*4882a593Smuzhiyun
515*4882a593Smuzhiyunclass GitDownloadDirectoryNamingTest(FetcherTest):
516*4882a593Smuzhiyun    def setUp(self):
517*4882a593Smuzhiyun        super(GitDownloadDirectoryNamingTest, self).setUp()
518*4882a593Smuzhiyun        self.recipe_url = "git://git.openembedded.org/bitbake;branch=master"
519*4882a593Smuzhiyun        self.recipe_dir = "git.openembedded.org.bitbake"
520*4882a593Smuzhiyun        self.mirror_url = "git://github.com/openembedded/bitbake.git;protocol=https;branch=master"
521*4882a593Smuzhiyun        self.mirror_dir = "github.com.openembedded.bitbake.git"
522*4882a593Smuzhiyun
523*4882a593Smuzhiyun        self.d.setVar('SRCREV', '82ea737a0b42a8b53e11c9cde141e9e9c0bd8c40')
524*4882a593Smuzhiyun
525*4882a593Smuzhiyun    def setup_mirror_rewrite(self):
526*4882a593Smuzhiyun        self.d.setVar("PREMIRRORS", self.recipe_url + " " + self.mirror_url)
527*4882a593Smuzhiyun
528*4882a593Smuzhiyun    @skipIfNoNetwork()
529*4882a593Smuzhiyun    def test_that_directory_is_named_after_recipe_url_when_no_mirroring_is_used(self):
530*4882a593Smuzhiyun        self.setup_mirror_rewrite()
531*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch([self.recipe_url], self.d)
532*4882a593Smuzhiyun
533*4882a593Smuzhiyun        fetcher.download()
534*4882a593Smuzhiyun
535*4882a593Smuzhiyun        dir = os.listdir(self.dldir + "/git2")
536*4882a593Smuzhiyun        self.assertIn(self.recipe_dir, dir)
537*4882a593Smuzhiyun
538*4882a593Smuzhiyun    @skipIfNoNetwork()
539*4882a593Smuzhiyun    def test_that_directory_exists_for_mirrored_url_and_recipe_url_when_mirroring_is_used(self):
540*4882a593Smuzhiyun        self.setup_mirror_rewrite()
541*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch([self.recipe_url], self.d)
542*4882a593Smuzhiyun
543*4882a593Smuzhiyun        fetcher.download()
544*4882a593Smuzhiyun
545*4882a593Smuzhiyun        dir = os.listdir(self.dldir + "/git2")
546*4882a593Smuzhiyun        self.assertIn(self.mirror_dir, dir)
547*4882a593Smuzhiyun        self.assertIn(self.recipe_dir, dir)
548*4882a593Smuzhiyun
549*4882a593Smuzhiyun    @skipIfNoNetwork()
550*4882a593Smuzhiyun    def test_that_recipe_directory_and_mirrored_directory_exists_when_mirroring_is_used_and_the_mirrored_directory_already_exists(self):
551*4882a593Smuzhiyun        self.setup_mirror_rewrite()
552*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch([self.mirror_url], self.d)
553*4882a593Smuzhiyun        fetcher.download()
554*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch([self.recipe_url], self.d)
555*4882a593Smuzhiyun
556*4882a593Smuzhiyun        fetcher.download()
557*4882a593Smuzhiyun
558*4882a593Smuzhiyun        dir = os.listdir(self.dldir + "/git2")
559*4882a593Smuzhiyun        self.assertIn(self.mirror_dir, dir)
560*4882a593Smuzhiyun        self.assertIn(self.recipe_dir, dir)
561*4882a593Smuzhiyun
562*4882a593Smuzhiyun
563*4882a593Smuzhiyunclass TarballNamingTest(FetcherTest):
564*4882a593Smuzhiyun    def setUp(self):
565*4882a593Smuzhiyun        super(TarballNamingTest, self).setUp()
566*4882a593Smuzhiyun        self.recipe_url = "git://git.openembedded.org/bitbake;branch=master"
567*4882a593Smuzhiyun        self.recipe_tarball = "git2_git.openembedded.org.bitbake.tar.gz"
568*4882a593Smuzhiyun        self.mirror_url = "git://github.com/openembedded/bitbake.git;protocol=https;branch=master"
569*4882a593Smuzhiyun        self.mirror_tarball = "git2_github.com.openembedded.bitbake.git.tar.gz"
570*4882a593Smuzhiyun
571*4882a593Smuzhiyun        self.d.setVar('BB_GENERATE_MIRROR_TARBALLS', '1')
572*4882a593Smuzhiyun        self.d.setVar('SRCREV', '82ea737a0b42a8b53e11c9cde141e9e9c0bd8c40')
573*4882a593Smuzhiyun
574*4882a593Smuzhiyun    def setup_mirror_rewrite(self):
575*4882a593Smuzhiyun        self.d.setVar("PREMIRRORS", self.recipe_url + " " + self.mirror_url)
576*4882a593Smuzhiyun
577*4882a593Smuzhiyun    @skipIfNoNetwork()
578*4882a593Smuzhiyun    def test_that_the_recipe_tarball_is_created_when_no_mirroring_is_used(self):
579*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch([self.recipe_url], self.d)
580*4882a593Smuzhiyun
581*4882a593Smuzhiyun        fetcher.download()
582*4882a593Smuzhiyun
583*4882a593Smuzhiyun        dir = os.listdir(self.dldir)
584*4882a593Smuzhiyun        self.assertIn(self.recipe_tarball, dir)
585*4882a593Smuzhiyun
586*4882a593Smuzhiyun    @skipIfNoNetwork()
587*4882a593Smuzhiyun    def test_that_the_mirror_tarball_is_created_when_mirroring_is_used(self):
588*4882a593Smuzhiyun        self.setup_mirror_rewrite()
589*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch([self.recipe_url], self.d)
590*4882a593Smuzhiyun
591*4882a593Smuzhiyun        fetcher.download()
592*4882a593Smuzhiyun
593*4882a593Smuzhiyun        dir = os.listdir(self.dldir)
594*4882a593Smuzhiyun        self.assertIn(self.mirror_tarball, dir)
595*4882a593Smuzhiyun
596*4882a593Smuzhiyun
597*4882a593Smuzhiyunclass GitShallowTarballNamingTest(FetcherTest):
598*4882a593Smuzhiyun    def setUp(self):
599*4882a593Smuzhiyun        super(GitShallowTarballNamingTest, self).setUp()
600*4882a593Smuzhiyun        self.recipe_url = "git://git.openembedded.org/bitbake;branch=master"
601*4882a593Smuzhiyun        self.recipe_tarball = "gitshallow_git.openembedded.org.bitbake_82ea737-1_master.tar.gz"
602*4882a593Smuzhiyun        self.mirror_url = "git://github.com/openembedded/bitbake.git;protocol=https;branch=master"
603*4882a593Smuzhiyun        self.mirror_tarball = "gitshallow_github.com.openembedded.bitbake.git_82ea737-1_master.tar.gz"
604*4882a593Smuzhiyun
605*4882a593Smuzhiyun        self.d.setVar('BB_GIT_SHALLOW', '1')
606*4882a593Smuzhiyun        self.d.setVar('BB_GENERATE_SHALLOW_TARBALLS', '1')
607*4882a593Smuzhiyun        self.d.setVar('SRCREV', '82ea737a0b42a8b53e11c9cde141e9e9c0bd8c40')
608*4882a593Smuzhiyun
609*4882a593Smuzhiyun    def setup_mirror_rewrite(self):
610*4882a593Smuzhiyun        self.d.setVar("PREMIRRORS", self.recipe_url + " " + self.mirror_url)
611*4882a593Smuzhiyun
612*4882a593Smuzhiyun    @skipIfNoNetwork()
613*4882a593Smuzhiyun    def test_that_the_tarball_is_named_after_recipe_url_when_no_mirroring_is_used(self):
614*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch([self.recipe_url], self.d)
615*4882a593Smuzhiyun
616*4882a593Smuzhiyun        fetcher.download()
617*4882a593Smuzhiyun
618*4882a593Smuzhiyun        dir = os.listdir(self.dldir)
619*4882a593Smuzhiyun        self.assertIn(self.recipe_tarball, dir)
620*4882a593Smuzhiyun
621*4882a593Smuzhiyun    @skipIfNoNetwork()
622*4882a593Smuzhiyun    def test_that_the_mirror_tarball_is_created_when_mirroring_is_used(self):
623*4882a593Smuzhiyun        self.setup_mirror_rewrite()
624*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch([self.recipe_url], self.d)
625*4882a593Smuzhiyun
626*4882a593Smuzhiyun        fetcher.download()
627*4882a593Smuzhiyun
628*4882a593Smuzhiyun        dir = os.listdir(self.dldir)
629*4882a593Smuzhiyun        self.assertIn(self.mirror_tarball, dir)
630*4882a593Smuzhiyun
631*4882a593Smuzhiyun
632*4882a593Smuzhiyunclass CleanTarballTest(FetcherTest):
633*4882a593Smuzhiyun    def setUp(self):
634*4882a593Smuzhiyun        super(CleanTarballTest, self).setUp()
635*4882a593Smuzhiyun        self.recipe_url = "git://git.openembedded.org/bitbake"
636*4882a593Smuzhiyun        self.recipe_tarball = "git2_git.openembedded.org.bitbake.tar.gz"
637*4882a593Smuzhiyun
638*4882a593Smuzhiyun        self.d.setVar('BB_GENERATE_MIRROR_TARBALLS', '1')
639*4882a593Smuzhiyun        self.d.setVar('SRCREV', '82ea737a0b42a8b53e11c9cde141e9e9c0bd8c40')
640*4882a593Smuzhiyun
641*4882a593Smuzhiyun    @skipIfNoNetwork()
642*4882a593Smuzhiyun    def test_that_the_tarball_contents_does_not_leak_info(self):
643*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch([self.recipe_url], self.d)
644*4882a593Smuzhiyun
645*4882a593Smuzhiyun        fetcher.download()
646*4882a593Smuzhiyun
647*4882a593Smuzhiyun        fetcher.unpack(self.unpackdir)
648*4882a593Smuzhiyun        mtime = bb.process.run('git log --all -1 --format=%ct',
649*4882a593Smuzhiyun                cwd=os.path.join(self.unpackdir, 'git'))
650*4882a593Smuzhiyun        self.assertEqual(len(mtime), 2)
651*4882a593Smuzhiyun        mtime = int(mtime[0])
652*4882a593Smuzhiyun
653*4882a593Smuzhiyun        archive = tarfile.open(os.path.join(self.dldir, self.recipe_tarball))
654*4882a593Smuzhiyun        self.assertNotEqual(len(archive.members), 0)
655*4882a593Smuzhiyun        for member in archive.members:
656*4882a593Smuzhiyun            self.assertEqual(member.uname, 'oe')
657*4882a593Smuzhiyun            self.assertEqual(member.uid, 0)
658*4882a593Smuzhiyun            self.assertEqual(member.gname, 'oe')
659*4882a593Smuzhiyun            self.assertEqual(member.gid, 0)
660*4882a593Smuzhiyun            self.assertEqual(member.mtime, mtime)
661*4882a593Smuzhiyun
662*4882a593Smuzhiyun
663*4882a593Smuzhiyunclass FetcherLocalTest(FetcherTest):
664*4882a593Smuzhiyun    def setUp(self):
665*4882a593Smuzhiyun        def touch(fn):
666*4882a593Smuzhiyun            with open(fn, 'a'):
667*4882a593Smuzhiyun                os.utime(fn, None)
668*4882a593Smuzhiyun
669*4882a593Smuzhiyun        super(FetcherLocalTest, self).setUp()
670*4882a593Smuzhiyun        self.localsrcdir = os.path.join(self.tempdir, 'localsrc')
671*4882a593Smuzhiyun        os.makedirs(self.localsrcdir)
672*4882a593Smuzhiyun        touch(os.path.join(self.localsrcdir, 'a'))
673*4882a593Smuzhiyun        touch(os.path.join(self.localsrcdir, 'b'))
674*4882a593Smuzhiyun        os.makedirs(os.path.join(self.localsrcdir, 'dir'))
675*4882a593Smuzhiyun        touch(os.path.join(self.localsrcdir, 'dir', 'c'))
676*4882a593Smuzhiyun        touch(os.path.join(self.localsrcdir, 'dir', 'd'))
677*4882a593Smuzhiyun        os.makedirs(os.path.join(self.localsrcdir, 'dir', 'subdir'))
678*4882a593Smuzhiyun        touch(os.path.join(self.localsrcdir, 'dir', 'subdir', 'e'))
679*4882a593Smuzhiyun        touch(os.path.join(self.localsrcdir, r'backslash\x2dsystemd-unit.device'))
680*4882a593Smuzhiyun        bb.process.run('tar cf archive.tar -C dir .', cwd=self.localsrcdir)
681*4882a593Smuzhiyun        bb.process.run('tar czf archive.tar.gz -C dir .', cwd=self.localsrcdir)
682*4882a593Smuzhiyun        bb.process.run('tar cjf archive.tar.bz2 -C dir .', cwd=self.localsrcdir)
683*4882a593Smuzhiyun        self.d.setVar("FILESPATH", self.localsrcdir)
684*4882a593Smuzhiyun
685*4882a593Smuzhiyun    def fetchUnpack(self, uris):
686*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch(uris, self.d)
687*4882a593Smuzhiyun        fetcher.download()
688*4882a593Smuzhiyun        fetcher.unpack(self.unpackdir)
689*4882a593Smuzhiyun        flst = []
690*4882a593Smuzhiyun        for root, dirs, files in os.walk(self.unpackdir):
691*4882a593Smuzhiyun            for f in files:
692*4882a593Smuzhiyun                flst.append(os.path.relpath(os.path.join(root, f), self.unpackdir))
693*4882a593Smuzhiyun        flst.sort()
694*4882a593Smuzhiyun        return flst
695*4882a593Smuzhiyun
696*4882a593Smuzhiyun    def test_local(self):
697*4882a593Smuzhiyun        tree = self.fetchUnpack(['file://a', 'file://dir/c'])
698*4882a593Smuzhiyun        self.assertEqual(tree, ['a', 'dir/c'])
699*4882a593Smuzhiyun
700*4882a593Smuzhiyun    def test_local_backslash(self):
701*4882a593Smuzhiyun        tree = self.fetchUnpack([r'file://backslash\x2dsystemd-unit.device'])
702*4882a593Smuzhiyun        self.assertEqual(tree, [r'backslash\x2dsystemd-unit.device'])
703*4882a593Smuzhiyun
704*4882a593Smuzhiyun    def test_local_wildcard(self):
705*4882a593Smuzhiyun        with self.assertRaises(bb.fetch2.ParameterError):
706*4882a593Smuzhiyun            tree = self.fetchUnpack(['file://a', 'file://dir/*'])
707*4882a593Smuzhiyun
708*4882a593Smuzhiyun    def test_local_dir(self):
709*4882a593Smuzhiyun        tree = self.fetchUnpack(['file://a', 'file://dir'])
710*4882a593Smuzhiyun        self.assertEqual(tree, ['a', 'dir/c', 'dir/d', 'dir/subdir/e'])
711*4882a593Smuzhiyun
712*4882a593Smuzhiyun    def test_local_subdir(self):
713*4882a593Smuzhiyun        tree = self.fetchUnpack(['file://dir/subdir'])
714*4882a593Smuzhiyun        self.assertEqual(tree, ['dir/subdir/e'])
715*4882a593Smuzhiyun
716*4882a593Smuzhiyun    def test_local_subdir_file(self):
717*4882a593Smuzhiyun        tree = self.fetchUnpack(['file://dir/subdir/e'])
718*4882a593Smuzhiyun        self.assertEqual(tree, ['dir/subdir/e'])
719*4882a593Smuzhiyun
720*4882a593Smuzhiyun    def test_local_subdirparam(self):
721*4882a593Smuzhiyun        tree = self.fetchUnpack(['file://a;subdir=bar', 'file://dir;subdir=foo/moo'])
722*4882a593Smuzhiyun        self.assertEqual(tree, ['bar/a', 'foo/moo/dir/c', 'foo/moo/dir/d', 'foo/moo/dir/subdir/e'])
723*4882a593Smuzhiyun
724*4882a593Smuzhiyun    def test_local_deepsubdirparam(self):
725*4882a593Smuzhiyun        tree = self.fetchUnpack(['file://dir/subdir/e;subdir=bar'])
726*4882a593Smuzhiyun        self.assertEqual(tree, ['bar/dir/subdir/e'])
727*4882a593Smuzhiyun
728*4882a593Smuzhiyun    def test_local_absolutedir(self):
729*4882a593Smuzhiyun        # Unpacking to an absolute path that is a subdirectory of the root
730*4882a593Smuzhiyun        # should work
731*4882a593Smuzhiyun        tree = self.fetchUnpack(['file://a;subdir=%s' % os.path.join(self.unpackdir, 'bar')])
732*4882a593Smuzhiyun
733*4882a593Smuzhiyun        # Unpacking to an absolute path outside of the root should fail
734*4882a593Smuzhiyun        with self.assertRaises(bb.fetch2.UnpackError):
735*4882a593Smuzhiyun            self.fetchUnpack(['file://a;subdir=/bin/sh'])
736*4882a593Smuzhiyun
737*4882a593Smuzhiyun    def test_local_striplevel(self):
738*4882a593Smuzhiyun        tree = self.fetchUnpack(['file://archive.tar;subdir=bar;striplevel=1'])
739*4882a593Smuzhiyun        self.assertEqual(tree, ['bar/c', 'bar/d', 'bar/subdir/e'])
740*4882a593Smuzhiyun
741*4882a593Smuzhiyun    def test_local_striplevel_gzip(self):
742*4882a593Smuzhiyun        tree = self.fetchUnpack(['file://archive.tar.gz;subdir=bar;striplevel=1'])
743*4882a593Smuzhiyun        self.assertEqual(tree, ['bar/c', 'bar/d', 'bar/subdir/e'])
744*4882a593Smuzhiyun
745*4882a593Smuzhiyun    def test_local_striplevel_bzip2(self):
746*4882a593Smuzhiyun        tree = self.fetchUnpack(['file://archive.tar.bz2;subdir=bar;striplevel=1'])
747*4882a593Smuzhiyun        self.assertEqual(tree, ['bar/c', 'bar/d', 'bar/subdir/e'])
748*4882a593Smuzhiyun
749*4882a593Smuzhiyun    def dummyGitTest(self, suffix):
750*4882a593Smuzhiyun        # Create dummy local Git repo
751*4882a593Smuzhiyun        src_dir = tempfile.mkdtemp(dir=self.tempdir,
752*4882a593Smuzhiyun                                   prefix='gitfetch_localusehead_')
753*4882a593Smuzhiyun        self.gitdir = os.path.abspath(src_dir)
754*4882a593Smuzhiyun        self.git_init()
755*4882a593Smuzhiyun        self.git(['commit', '--allow-empty', '-m', 'Dummy commit'])
756*4882a593Smuzhiyun        # Use other branch than master
757*4882a593Smuzhiyun        self.git(['checkout', '-b', 'my-devel'])
758*4882a593Smuzhiyun        self.git(['commit', '--allow-empty', '-m', 'Dummy commit 2'])
759*4882a593Smuzhiyun        orig_rev = self.git(['rev-parse', 'HEAD']).strip()
760*4882a593Smuzhiyun
761*4882a593Smuzhiyun        # Fetch and check revision
762*4882a593Smuzhiyun        self.d.setVar("SRCREV", "AUTOINC")
763*4882a593Smuzhiyun        self.d.setVar("__BBSEENSRCREV", "1")
764*4882a593Smuzhiyun        url = "git://" + self.gitdir + ";branch=master;protocol=file;" + suffix
765*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch([url], self.d)
766*4882a593Smuzhiyun        fetcher.download()
767*4882a593Smuzhiyun        fetcher.unpack(self.unpackdir)
768*4882a593Smuzhiyun        unpack_rev = self.git(['rev-parse', 'HEAD'],
769*4882a593Smuzhiyun                              cwd=os.path.join(self.unpackdir, 'git')).strip()
770*4882a593Smuzhiyun        self.assertEqual(orig_rev, unpack_rev)
771*4882a593Smuzhiyun
772*4882a593Smuzhiyun    def test_local_gitfetch_usehead(self):
773*4882a593Smuzhiyun        self.dummyGitTest("usehead=1")
774*4882a593Smuzhiyun
775*4882a593Smuzhiyun    def test_local_gitfetch_usehead_withname(self):
776*4882a593Smuzhiyun        self.dummyGitTest("usehead=1;name=newName")
777*4882a593Smuzhiyun
778*4882a593Smuzhiyun    def test_local_gitfetch_shared(self):
779*4882a593Smuzhiyun        self.dummyGitTest("usehead=1;name=sharedName")
780*4882a593Smuzhiyun        alt = os.path.join(self.unpackdir, 'git/.git/objects/info/alternates')
781*4882a593Smuzhiyun        self.assertTrue(os.path.exists(alt))
782*4882a593Smuzhiyun
783*4882a593Smuzhiyun    def test_local_gitfetch_noshared(self):
784*4882a593Smuzhiyun        self.d.setVar('BB_GIT_NOSHARED', '1')
785*4882a593Smuzhiyun        self.unpackdir += '_noshared'
786*4882a593Smuzhiyun        self.dummyGitTest("usehead=1;name=noSharedName")
787*4882a593Smuzhiyun        alt = os.path.join(self.unpackdir, 'git/.git/objects/info/alternates')
788*4882a593Smuzhiyun        self.assertFalse(os.path.exists(alt))
789*4882a593Smuzhiyun
790*4882a593Smuzhiyunclass FetcherNoNetworkTest(FetcherTest):
791*4882a593Smuzhiyun    def setUp(self):
792*4882a593Smuzhiyun        super().setUp()
793*4882a593Smuzhiyun        # all test cases are based on not having network
794*4882a593Smuzhiyun        self.d.setVar("BB_NO_NETWORK", "1")
795*4882a593Smuzhiyun
796*4882a593Smuzhiyun    def test_missing(self):
797*4882a593Smuzhiyun        string = "this is a test file\n".encode("utf-8")
798*4882a593Smuzhiyun        self.d.setVarFlag("SRC_URI", "md5sum", hashlib.md5(string).hexdigest())
799*4882a593Smuzhiyun        self.d.setVarFlag("SRC_URI", "sha256sum", hashlib.sha256(string).hexdigest())
800*4882a593Smuzhiyun
801*4882a593Smuzhiyun        self.assertFalse(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz")))
802*4882a593Smuzhiyun        self.assertFalse(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz.done")))
803*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/test-file.tar.gz"], self.d)
804*4882a593Smuzhiyun        with self.assertRaises(bb.fetch2.NetworkAccess):
805*4882a593Smuzhiyun            fetcher.download()
806*4882a593Smuzhiyun
807*4882a593Smuzhiyun    def test_valid_missing_donestamp(self):
808*4882a593Smuzhiyun        # create the file in the download directory with correct hash
809*4882a593Smuzhiyun        string = "this is a test file\n".encode("utf-8")
810*4882a593Smuzhiyun        with open(os.path.join(self.dldir, "test-file.tar.gz"), "wb") as f:
811*4882a593Smuzhiyun            f.write(string)
812*4882a593Smuzhiyun
813*4882a593Smuzhiyun        self.d.setVarFlag("SRC_URI", "md5sum", hashlib.md5(string).hexdigest())
814*4882a593Smuzhiyun        self.d.setVarFlag("SRC_URI", "sha256sum", hashlib.sha256(string).hexdigest())
815*4882a593Smuzhiyun
816*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz")))
817*4882a593Smuzhiyun        self.assertFalse(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz.done")))
818*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/test-file.tar.gz"], self.d)
819*4882a593Smuzhiyun        fetcher.download()
820*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz.done")))
821*4882a593Smuzhiyun
822*4882a593Smuzhiyun    def test_invalid_missing_donestamp(self):
823*4882a593Smuzhiyun        # create an invalid file in the download directory with incorrect hash
824*4882a593Smuzhiyun        string = "this is a test file\n".encode("utf-8")
825*4882a593Smuzhiyun        with open(os.path.join(self.dldir, "test-file.tar.gz"), "wb"):
826*4882a593Smuzhiyun            pass
827*4882a593Smuzhiyun
828*4882a593Smuzhiyun        self.d.setVarFlag("SRC_URI", "md5sum", hashlib.md5(string).hexdigest())
829*4882a593Smuzhiyun        self.d.setVarFlag("SRC_URI", "sha256sum", hashlib.sha256(string).hexdigest())
830*4882a593Smuzhiyun
831*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz")))
832*4882a593Smuzhiyun        self.assertFalse(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz.done")))
833*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/test-file.tar.gz"], self.d)
834*4882a593Smuzhiyun        with self.assertRaises(bb.fetch2.NetworkAccess):
835*4882a593Smuzhiyun            fetcher.download()
836*4882a593Smuzhiyun        # the existing file should not exist or should have be moved to "bad-checksum"
837*4882a593Smuzhiyun        self.assertFalse(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz")))
838*4882a593Smuzhiyun
839*4882a593Smuzhiyun    def test_nochecksums_missing(self):
840*4882a593Smuzhiyun        self.assertFalse(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz")))
841*4882a593Smuzhiyun        self.assertFalse(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz.done")))
842*4882a593Smuzhiyun        # ssh fetch does not support checksums
843*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch(["ssh://invalid@invalid.yoctoproject.org/test-file.tar.gz"], self.d)
844*4882a593Smuzhiyun        # attempts to download with missing donestamp
845*4882a593Smuzhiyun        with self.assertRaises(bb.fetch2.NetworkAccess):
846*4882a593Smuzhiyun            fetcher.download()
847*4882a593Smuzhiyun
848*4882a593Smuzhiyun    def test_nochecksums_missing_donestamp(self):
849*4882a593Smuzhiyun        # create a file in the download directory
850*4882a593Smuzhiyun        with open(os.path.join(self.dldir, "test-file.tar.gz"), "wb"):
851*4882a593Smuzhiyun            pass
852*4882a593Smuzhiyun
853*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz")))
854*4882a593Smuzhiyun        self.assertFalse(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz.done")))
855*4882a593Smuzhiyun        # ssh fetch does not support checksums
856*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch(["ssh://invalid@invalid.yoctoproject.org/test-file.tar.gz"], self.d)
857*4882a593Smuzhiyun        # attempts to download with missing donestamp
858*4882a593Smuzhiyun        with self.assertRaises(bb.fetch2.NetworkAccess):
859*4882a593Smuzhiyun            fetcher.download()
860*4882a593Smuzhiyun
861*4882a593Smuzhiyun    def test_nochecksums_has_donestamp(self):
862*4882a593Smuzhiyun        # create a file in the download directory with the donestamp
863*4882a593Smuzhiyun        with open(os.path.join(self.dldir, "test-file.tar.gz"), "wb"):
864*4882a593Smuzhiyun            pass
865*4882a593Smuzhiyun        with open(os.path.join(self.dldir, "test-file.tar.gz.done"), "wb"):
866*4882a593Smuzhiyun            pass
867*4882a593Smuzhiyun
868*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz")))
869*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz.done")))
870*4882a593Smuzhiyun        # ssh fetch does not support checksums
871*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch(["ssh://invalid@invalid.yoctoproject.org/test-file.tar.gz"], self.d)
872*4882a593Smuzhiyun        # should not fetch
873*4882a593Smuzhiyun        fetcher.download()
874*4882a593Smuzhiyun        # both files should still exist
875*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz")))
876*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz.done")))
877*4882a593Smuzhiyun
878*4882a593Smuzhiyun    def test_nochecksums_missing_has_donestamp(self):
879*4882a593Smuzhiyun        # create a file in the download directory with the donestamp
880*4882a593Smuzhiyun        with open(os.path.join(self.dldir, "test-file.tar.gz.done"), "wb"):
881*4882a593Smuzhiyun            pass
882*4882a593Smuzhiyun
883*4882a593Smuzhiyun        self.assertFalse(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz")))
884*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz.done")))
885*4882a593Smuzhiyun        # ssh fetch does not support checksums
886*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch(["ssh://invalid@invalid.yoctoproject.org/test-file.tar.gz"], self.d)
887*4882a593Smuzhiyun        with self.assertRaises(bb.fetch2.NetworkAccess):
888*4882a593Smuzhiyun            fetcher.download()
889*4882a593Smuzhiyun        # both files should still exist
890*4882a593Smuzhiyun        self.assertFalse(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz")))
891*4882a593Smuzhiyun        self.assertFalse(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz.done")))
892*4882a593Smuzhiyun
893*4882a593Smuzhiyunclass FetcherNetworkTest(FetcherTest):
894*4882a593Smuzhiyun    @skipIfNoNetwork()
895*4882a593Smuzhiyun    def test_fetch(self):
896*4882a593Smuzhiyun        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)
897*4882a593Smuzhiyun        fetcher.download()
898*4882a593Smuzhiyun        self.assertEqual(os.path.getsize(self.dldir + "/bitbake-1.0.tar.gz"), 57749)
899*4882a593Smuzhiyun        self.assertEqual(os.path.getsize(self.dldir + "/bitbake-1.1.tar.gz"), 57892)
900*4882a593Smuzhiyun        self.d.setVar("BB_NO_NETWORK", "1")
901*4882a593Smuzhiyun        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)
902*4882a593Smuzhiyun        fetcher.download()
903*4882a593Smuzhiyun        fetcher.unpack(self.unpackdir)
904*4882a593Smuzhiyun        self.assertEqual(len(os.listdir(self.unpackdir + "/bitbake-1.0/")), 9)
905*4882a593Smuzhiyun        self.assertEqual(len(os.listdir(self.unpackdir + "/bitbake-1.1/")), 9)
906*4882a593Smuzhiyun
907*4882a593Smuzhiyun    @skipIfNoNetwork()
908*4882a593Smuzhiyun    def test_fetch_mirror(self):
909*4882a593Smuzhiyun        self.d.setVar("MIRRORS", "http://.*/.* https://downloads.yoctoproject.org/releases/bitbake")
910*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz"], self.d)
911*4882a593Smuzhiyun        fetcher.download()
912*4882a593Smuzhiyun        self.assertEqual(os.path.getsize(self.dldir + "/bitbake-1.0.tar.gz"), 57749)
913*4882a593Smuzhiyun
914*4882a593Smuzhiyun    @skipIfNoNetwork()
915*4882a593Smuzhiyun    def test_fetch_mirror_of_mirror(self):
916*4882a593Smuzhiyun        self.d.setVar("MIRRORS", "http://.*/.* http://invalid2.yoctoproject.org/ http://invalid2.yoctoproject.org/.* https://downloads.yoctoproject.org/releases/bitbake")
917*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz"], self.d)
918*4882a593Smuzhiyun        fetcher.download()
919*4882a593Smuzhiyun        self.assertEqual(os.path.getsize(self.dldir + "/bitbake-1.0.tar.gz"), 57749)
920*4882a593Smuzhiyun
921*4882a593Smuzhiyun    @skipIfNoNetwork()
922*4882a593Smuzhiyun    def test_fetch_file_mirror_of_mirror(self):
923*4882a593Smuzhiyun        self.d.setVar("MIRRORS", "http://.*/.* file:///some1where/ file:///some1where/.* file://some2where/ file://some2where/.* https://downloads.yoctoproject.org/releases/bitbake")
924*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz"], self.d)
925*4882a593Smuzhiyun        os.mkdir(self.dldir + "/some2where")
926*4882a593Smuzhiyun        fetcher.download()
927*4882a593Smuzhiyun        self.assertEqual(os.path.getsize(self.dldir + "/bitbake-1.0.tar.gz"), 57749)
928*4882a593Smuzhiyun
929*4882a593Smuzhiyun    @skipIfNoNetwork()
930*4882a593Smuzhiyun    def test_fetch_premirror(self):
931*4882a593Smuzhiyun        self.d.setVar("PREMIRRORS", "http://.*/.* https://downloads.yoctoproject.org/releases/bitbake")
932*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz"], self.d)
933*4882a593Smuzhiyun        fetcher.download()
934*4882a593Smuzhiyun        self.assertEqual(os.path.getsize(self.dldir + "/bitbake-1.0.tar.gz"), 57749)
935*4882a593Smuzhiyun
936*4882a593Smuzhiyun    @skipIfNoNetwork()
937*4882a593Smuzhiyun    def test_fetch_specify_downloadfilename(self):
938*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch(["https://downloads.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz;downloadfilename=bitbake-v1.0.0.tar.gz"], self.d)
939*4882a593Smuzhiyun        fetcher.download()
940*4882a593Smuzhiyun        self.assertEqual(os.path.getsize(self.dldir + "/bitbake-v1.0.0.tar.gz"), 57749)
941*4882a593Smuzhiyun
942*4882a593Smuzhiyun    @skipIfNoNetwork()
943*4882a593Smuzhiyun    def test_fetch_premirror_specify_downloadfilename_regex_uri(self):
944*4882a593Smuzhiyun        self.d.setVar("PREMIRRORS", "http://.*/.* https://downloads.yoctoproject.org/releases/bitbake/")
945*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/releases/bitbake/1.0.tar.gz;downloadfilename=bitbake-1.0.tar.gz"], self.d)
946*4882a593Smuzhiyun        fetcher.download()
947*4882a593Smuzhiyun        self.assertEqual(os.path.getsize(self.dldir + "/bitbake-1.0.tar.gz"), 57749)
948*4882a593Smuzhiyun
949*4882a593Smuzhiyun    @skipIfNoNetwork()
950*4882a593Smuzhiyun    # BZ13039
951*4882a593Smuzhiyun    def test_fetch_premirror_specify_downloadfilename_specific_uri(self):
952*4882a593Smuzhiyun        self.d.setVar("PREMIRRORS", "http://invalid.yoctoproject.org/releases/bitbake https://downloads.yoctoproject.org/releases/bitbake")
953*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/releases/bitbake/1.0.tar.gz;downloadfilename=bitbake-1.0.tar.gz"], self.d)
954*4882a593Smuzhiyun        fetcher.download()
955*4882a593Smuzhiyun        self.assertEqual(os.path.getsize(self.dldir + "/bitbake-1.0.tar.gz"), 57749)
956*4882a593Smuzhiyun
957*4882a593Smuzhiyun    @skipIfNoNetwork()
958*4882a593Smuzhiyun    def test_fetch_premirror_use_downloadfilename_to_fetch(self):
959*4882a593Smuzhiyun        # Ensure downloadfilename is used when fetching from premirror.
960*4882a593Smuzhiyun        self.d.setVar("PREMIRRORS", "http://.*/.* https://downloads.yoctoproject.org/releases/bitbake")
961*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/releases/bitbake/bitbake-1.1.tar.gz;downloadfilename=bitbake-1.0.tar.gz"], self.d)
962*4882a593Smuzhiyun        fetcher.download()
963*4882a593Smuzhiyun        self.assertEqual(os.path.getsize(self.dldir + "/bitbake-1.0.tar.gz"), 57749)
964*4882a593Smuzhiyun
965*4882a593Smuzhiyun    @skipIfNoNetwork()
966*4882a593Smuzhiyun    def gitfetcher(self, url1, url2):
967*4882a593Smuzhiyun        def checkrevision(self, fetcher):
968*4882a593Smuzhiyun            fetcher.unpack(self.unpackdir)
969*4882a593Smuzhiyun            revision = self.git(['rev-parse', 'HEAD'],
970*4882a593Smuzhiyun                                cwd=os.path.join(self.unpackdir, 'git')).strip()
971*4882a593Smuzhiyun            self.assertEqual(revision, "270a05b0b4ba0959fe0624d2a4885d7b70426da5")
972*4882a593Smuzhiyun
973*4882a593Smuzhiyun        self.d.setVar("BB_GENERATE_MIRROR_TARBALLS", "1")
974*4882a593Smuzhiyun        self.d.setVar("SRCREV", "270a05b0b4ba0959fe0624d2a4885d7b70426da5")
975*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch([url1], self.d)
976*4882a593Smuzhiyun        fetcher.download()
977*4882a593Smuzhiyun        checkrevision(self, fetcher)
978*4882a593Smuzhiyun        # Wipe out the dldir clone and the unpacked source, turn off the network and check mirror tarball works
979*4882a593Smuzhiyun        bb.utils.prunedir(self.dldir + "/git2/")
980*4882a593Smuzhiyun        bb.utils.prunedir(self.unpackdir)
981*4882a593Smuzhiyun        self.d.setVar("BB_NO_NETWORK", "1")
982*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch([url2], self.d)
983*4882a593Smuzhiyun        fetcher.download()
984*4882a593Smuzhiyun        checkrevision(self, fetcher)
985*4882a593Smuzhiyun
986*4882a593Smuzhiyun    @skipIfNoNetwork()
987*4882a593Smuzhiyun    def test_gitfetch(self):
988*4882a593Smuzhiyun        url1 = url2 = "git://git.openembedded.org/bitbake;branch=master"
989*4882a593Smuzhiyun        self.gitfetcher(url1, url2)
990*4882a593Smuzhiyun
991*4882a593Smuzhiyun    @skipIfNoNetwork()
992*4882a593Smuzhiyun    def test_gitfetch_goodsrcrev(self):
993*4882a593Smuzhiyun        # SRCREV is set but matches rev= parameter
994*4882a593Smuzhiyun        url1 = url2 = "git://git.openembedded.org/bitbake;rev=270a05b0b4ba0959fe0624d2a4885d7b70426da5;branch=master"
995*4882a593Smuzhiyun        self.gitfetcher(url1, url2)
996*4882a593Smuzhiyun
997*4882a593Smuzhiyun    @skipIfNoNetwork()
998*4882a593Smuzhiyun    def test_gitfetch_badsrcrev(self):
999*4882a593Smuzhiyun        # SRCREV is set but does not match rev= parameter
1000*4882a593Smuzhiyun        url1 = url2 = "git://git.openembedded.org/bitbake;rev=dead05b0b4ba0959fe0624d2a4885d7b70426da5;branch=master"
1001*4882a593Smuzhiyun        self.assertRaises(bb.fetch.FetchError, self.gitfetcher, url1, url2)
1002*4882a593Smuzhiyun
1003*4882a593Smuzhiyun    @skipIfNoNetwork()
1004*4882a593Smuzhiyun    def test_gitfetch_tagandrev(self):
1005*4882a593Smuzhiyun        # SRCREV is set but does not match rev= parameter
1006*4882a593Smuzhiyun        url1 = url2 = "git://git.openembedded.org/bitbake;rev=270a05b0b4ba0959fe0624d2a4885d7b70426da5;tag=270a05b0b4ba0959fe0624d2a4885d7b70426da5"
1007*4882a593Smuzhiyun        self.assertRaises(bb.fetch.FetchError, self.gitfetcher, url1, url2)
1008*4882a593Smuzhiyun
1009*4882a593Smuzhiyun    @skipIfNoNetwork()
1010*4882a593Smuzhiyun    def test_gitfetch_usehead(self):
1011*4882a593Smuzhiyun        # Since self.gitfetcher() sets SRCREV we expect this to override
1012*4882a593Smuzhiyun        # `usehead=1' and instead fetch the specified SRCREV. See
1013*4882a593Smuzhiyun        # test_local_gitfetch_usehead() for a positive use of the usehead
1014*4882a593Smuzhiyun        # feature.
1015*4882a593Smuzhiyun        url = "git://git.openembedded.org/bitbake;usehead=1;branch=master"
1016*4882a593Smuzhiyun        self.assertRaises(bb.fetch.ParameterError, self.gitfetcher, url, url)
1017*4882a593Smuzhiyun
1018*4882a593Smuzhiyun    @skipIfNoNetwork()
1019*4882a593Smuzhiyun    def test_gitfetch_usehead_withname(self):
1020*4882a593Smuzhiyun        # Since self.gitfetcher() sets SRCREV we expect this to override
1021*4882a593Smuzhiyun        # `usehead=1' and instead fetch the specified SRCREV. See
1022*4882a593Smuzhiyun        # test_local_gitfetch_usehead() for a positive use of the usehead
1023*4882a593Smuzhiyun        # feature.
1024*4882a593Smuzhiyun        url = "git://git.openembedded.org/bitbake;usehead=1;name=newName;branch=master"
1025*4882a593Smuzhiyun        self.assertRaises(bb.fetch.ParameterError, self.gitfetcher, url, url)
1026*4882a593Smuzhiyun
1027*4882a593Smuzhiyun    @skipIfNoNetwork()
1028*4882a593Smuzhiyun    def test_gitfetch_finds_local_tarball_for_mirrored_url_when_previous_downloaded_by_the_recipe_url(self):
1029*4882a593Smuzhiyun        recipeurl = "git://git.openembedded.org/bitbake;branch=master"
1030*4882a593Smuzhiyun        mirrorurl = "git://someserver.org/bitbake;branch=master"
1031*4882a593Smuzhiyun        self.d.setVar("PREMIRRORS", "git://someserver.org/bitbake git://git.openembedded.org/bitbake")
1032*4882a593Smuzhiyun        self.gitfetcher(recipeurl, mirrorurl)
1033*4882a593Smuzhiyun
1034*4882a593Smuzhiyun    @skipIfNoNetwork()
1035*4882a593Smuzhiyun    def test_gitfetch_finds_local_tarball_when_previous_downloaded_from_a_premirror(self):
1036*4882a593Smuzhiyun        recipeurl = "git://someserver.org/bitbake;branch=master"
1037*4882a593Smuzhiyun        self.d.setVar("PREMIRRORS", "git://someserver.org/bitbake git://git.openembedded.org/bitbake")
1038*4882a593Smuzhiyun        self.gitfetcher(recipeurl, recipeurl)
1039*4882a593Smuzhiyun
1040*4882a593Smuzhiyun    @skipIfNoNetwork()
1041*4882a593Smuzhiyun    def test_gitfetch_finds_local_repository_when_premirror_rewrites_the_recipe_url(self):
1042*4882a593Smuzhiyun        realurl = "git://git.openembedded.org/bitbake"
1043*4882a593Smuzhiyun        recipeurl = "git://someserver.org/bitbake"
1044*4882a593Smuzhiyun        self.sourcedir = self.unpackdir.replace("unpacked", "sourcemirror.git")
1045*4882a593Smuzhiyun        os.chdir(self.tempdir)
1046*4882a593Smuzhiyun        self.git(['clone', realurl, self.sourcedir], cwd=self.tempdir)
1047*4882a593Smuzhiyun        self.d.setVar("PREMIRRORS", "%s git://%s;protocol=file" % (recipeurl, self.sourcedir))
1048*4882a593Smuzhiyun        self.gitfetcher(recipeurl, recipeurl)
1049*4882a593Smuzhiyun
1050*4882a593Smuzhiyun    @skipIfNoNetwork()
1051*4882a593Smuzhiyun    def test_git_submodule(self):
1052*4882a593Smuzhiyun        # URL with ssh submodules
1053*4882a593Smuzhiyun        url = "gitsm://git.yoctoproject.org/git-submodule-test;branch=ssh-gitsm-tests;rev=049da4a6cb198d7c0302e9e8b243a1443cb809a7;branch=master"
1054*4882a593Smuzhiyun        # Original URL (comment this if you have ssh access to git.yoctoproject.org)
1055*4882a593Smuzhiyun        url = "gitsm://git.yoctoproject.org/git-submodule-test;branch=master;rev=a2885dd7d25380d23627e7544b7bbb55014b16ee;branch=master"
1056*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch([url], self.d)
1057*4882a593Smuzhiyun        fetcher.download()
1058*4882a593Smuzhiyun        # Previous cwd has been deleted
1059*4882a593Smuzhiyun        os.chdir(os.path.dirname(self.unpackdir))
1060*4882a593Smuzhiyun        fetcher.unpack(self.unpackdir)
1061*4882a593Smuzhiyun
1062*4882a593Smuzhiyun        repo_path = os.path.join(self.tempdir, 'unpacked', 'git')
1063*4882a593Smuzhiyun        self.assertTrue(os.path.exists(repo_path), msg='Unpacked repository missing')
1064*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(repo_path, 'bitbake')), msg='bitbake submodule missing')
1065*4882a593Smuzhiyun        self.assertFalse(os.path.exists(os.path.join(repo_path, 'na')), msg='uninitialized submodule present')
1066*4882a593Smuzhiyun
1067*4882a593Smuzhiyun        # Only when we're running the extended test with a submodule's submodule, can we check this.
1068*4882a593Smuzhiyun        if os.path.exists(os.path.join(repo_path, 'bitbake-gitsm-test1')):
1069*4882a593Smuzhiyun            self.assertTrue(os.path.exists(os.path.join(repo_path, 'bitbake-gitsm-test1', 'bitbake')), msg='submodule of submodule missing')
1070*4882a593Smuzhiyun
1071*4882a593Smuzhiyun    @skipIfNoNetwork()
1072*4882a593Smuzhiyun    def test_git_submodule_dbus_broker(self):
1073*4882a593Smuzhiyun        # The following external repositories have show failures in fetch and unpack operations
1074*4882a593Smuzhiyun        # We want to avoid regressions!
1075*4882a593Smuzhiyun        url = "gitsm://github.com/bus1/dbus-broker;protocol=https;rev=fc874afa0992d0c75ec25acb43d344679f0ee7d2;branch=main"
1076*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch([url], self.d)
1077*4882a593Smuzhiyun        fetcher.download()
1078*4882a593Smuzhiyun        # Previous cwd has been deleted
1079*4882a593Smuzhiyun        os.chdir(os.path.dirname(self.unpackdir))
1080*4882a593Smuzhiyun        fetcher.unpack(self.unpackdir)
1081*4882a593Smuzhiyun
1082*4882a593Smuzhiyun        repo_path = os.path.join(self.tempdir, 'unpacked', 'git')
1083*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(repo_path, '.git/modules/subprojects/c-dvar/config')), msg='Missing submodule config "subprojects/c-dvar"')
1084*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(repo_path, '.git/modules/subprojects/c-list/config')), msg='Missing submodule config "subprojects/c-list"')
1085*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(repo_path, '.git/modules/subprojects/c-rbtree/config')), msg='Missing submodule config "subprojects/c-rbtree"')
1086*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(repo_path, '.git/modules/subprojects/c-sundry/config')), msg='Missing submodule config "subprojects/c-sundry"')
1087*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(repo_path, '.git/modules/subprojects/c-utf8/config')), msg='Missing submodule config "subprojects/c-utf8"')
1088*4882a593Smuzhiyun
1089*4882a593Smuzhiyun    @skipIfNoNetwork()
1090*4882a593Smuzhiyun    def test_git_submodule_CLI11(self):
1091*4882a593Smuzhiyun        url = "gitsm://github.com/CLIUtils/CLI11;protocol=https;rev=bd4dc911847d0cde7a6b41dfa626a85aab213baf;branch=main"
1092*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch([url], self.d)
1093*4882a593Smuzhiyun        fetcher.download()
1094*4882a593Smuzhiyun        # Previous cwd has been deleted
1095*4882a593Smuzhiyun        os.chdir(os.path.dirname(self.unpackdir))
1096*4882a593Smuzhiyun        fetcher.unpack(self.unpackdir)
1097*4882a593Smuzhiyun
1098*4882a593Smuzhiyun        repo_path = os.path.join(self.tempdir, 'unpacked', 'git')
1099*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(repo_path, '.git/modules/extern/googletest/config')), msg='Missing submodule config "extern/googletest"')
1100*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(repo_path, '.git/modules/extern/json/config')), msg='Missing submodule config "extern/json"')
1101*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(repo_path, '.git/modules/extern/sanitizers/config')), msg='Missing submodule config "extern/sanitizers"')
1102*4882a593Smuzhiyun
1103*4882a593Smuzhiyun    @skipIfNoNetwork()
1104*4882a593Smuzhiyun    def test_git_submodule_update_CLI11(self):
1105*4882a593Smuzhiyun        """ Prevent regression on update detection not finding missing submodule, or modules without needed commits """
1106*4882a593Smuzhiyun        url = "gitsm://github.com/CLIUtils/CLI11;protocol=https;rev=cf6a99fa69aaefe477cc52e3ef4a7d2d7fa40714;branch=main"
1107*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch([url], self.d)
1108*4882a593Smuzhiyun        fetcher.download()
1109*4882a593Smuzhiyun
1110*4882a593Smuzhiyun        # CLI11 that pulls in a newer nlohmann-json
1111*4882a593Smuzhiyun        url = "gitsm://github.com/CLIUtils/CLI11;protocol=https;rev=49ac989a9527ee9bb496de9ded7b4872c2e0e5ca;branch=main"
1112*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch([url], self.d)
1113*4882a593Smuzhiyun        fetcher.download()
1114*4882a593Smuzhiyun        # Previous cwd has been deleted
1115*4882a593Smuzhiyun        os.chdir(os.path.dirname(self.unpackdir))
1116*4882a593Smuzhiyun        fetcher.unpack(self.unpackdir)
1117*4882a593Smuzhiyun
1118*4882a593Smuzhiyun        repo_path = os.path.join(self.tempdir, 'unpacked', 'git')
1119*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(repo_path, '.git/modules/extern/googletest/config')), msg='Missing submodule config "extern/googletest"')
1120*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(repo_path, '.git/modules/extern/json/config')), msg='Missing submodule config "extern/json"')
1121*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(repo_path, '.git/modules/extern/sanitizers/config')), msg='Missing submodule config "extern/sanitizers"')
1122*4882a593Smuzhiyun
1123*4882a593Smuzhiyun    @skipIfNoNetwork()
1124*4882a593Smuzhiyun    def test_git_submodule_aktualizr(self):
1125*4882a593Smuzhiyun        url = "gitsm://github.com/advancedtelematic/aktualizr;branch=master;protocol=https;rev=d00d1a04cc2366d1a5f143b84b9f507f8bd32c44"
1126*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch([url], self.d)
1127*4882a593Smuzhiyun        fetcher.download()
1128*4882a593Smuzhiyun        # Previous cwd has been deleted
1129*4882a593Smuzhiyun        os.chdir(os.path.dirname(self.unpackdir))
1130*4882a593Smuzhiyun        fetcher.unpack(self.unpackdir)
1131*4882a593Smuzhiyun
1132*4882a593Smuzhiyun        repo_path = os.path.join(self.tempdir, 'unpacked', 'git')
1133*4882a593Smuzhiyun        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"')
1134*4882a593Smuzhiyun        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"')
1135*4882a593Smuzhiyun        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")
1136*4882a593Smuzhiyun        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"')
1137*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(repo_path, '.git/modules/third_party/googletest/config')), msg='Missing submodule config "third_party/googletest/config"')
1138*4882a593Smuzhiyun        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"')
1139*4882a593Smuzhiyun
1140*4882a593Smuzhiyun    @skipIfNoNetwork()
1141*4882a593Smuzhiyun    def test_git_submodule_iotedge(self):
1142*4882a593Smuzhiyun        """ Prevent regression on deeply nested submodules not being checked out properly, even though they were fetched. """
1143*4882a593Smuzhiyun
1144*4882a593Smuzhiyun        # This repository also has submodules where the module (name), path and url do not align
1145*4882a593Smuzhiyun        url = "gitsm://github.com/azure/iotedge.git;protocol=https;rev=d76e0316c6f324345d77c48a83ce836d09392699;branch=main"
1146*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch([url], self.d)
1147*4882a593Smuzhiyun        fetcher.download()
1148*4882a593Smuzhiyun        # Previous cwd has been deleted
1149*4882a593Smuzhiyun        os.chdir(os.path.dirname(self.unpackdir))
1150*4882a593Smuzhiyun        fetcher.unpack(self.unpackdir)
1151*4882a593Smuzhiyun
1152*4882a593Smuzhiyun        repo_path = os.path.join(self.tempdir, 'unpacked', 'git')
1153*4882a593Smuzhiyun
1154*4882a593Smuzhiyun        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')
1155*4882a593Smuzhiyun        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')
1156*4882a593Smuzhiyun        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')
1157*4882a593Smuzhiyun        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')
1158*4882a593Smuzhiyun        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')
1159*4882a593Smuzhiyun        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')
1160*4882a593Smuzhiyun        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')
1161*4882a593Smuzhiyun        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')
1162*4882a593Smuzhiyun        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')
1163*4882a593Smuzhiyun        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')
1164*4882a593Smuzhiyun        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')
1165*4882a593Smuzhiyun        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')
1166*4882a593Smuzhiyun        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')
1167*4882a593Smuzhiyun
1168*4882a593Smuzhiyunclass SVNTest(FetcherTest):
1169*4882a593Smuzhiyun    def skipIfNoSvn():
1170*4882a593Smuzhiyun        import shutil
1171*4882a593Smuzhiyun        if not shutil.which("svn"):
1172*4882a593Smuzhiyun            return unittest.skip("svn not installed,  tests being skipped")
1173*4882a593Smuzhiyun
1174*4882a593Smuzhiyun        if not shutil.which("svnadmin"):
1175*4882a593Smuzhiyun            return unittest.skip("svnadmin not installed,  tests being skipped")
1176*4882a593Smuzhiyun
1177*4882a593Smuzhiyun        return lambda f: f
1178*4882a593Smuzhiyun
1179*4882a593Smuzhiyun    @skipIfNoSvn()
1180*4882a593Smuzhiyun    def setUp(self):
1181*4882a593Smuzhiyun        """ Create a local repository """
1182*4882a593Smuzhiyun
1183*4882a593Smuzhiyun        super(SVNTest, self).setUp()
1184*4882a593Smuzhiyun
1185*4882a593Smuzhiyun        # Create something we can fetch
1186*4882a593Smuzhiyun        src_dir = tempfile.mkdtemp(dir=self.tempdir,
1187*4882a593Smuzhiyun                                   prefix='svnfetch_srcdir_')
1188*4882a593Smuzhiyun        src_dir = os.path.abspath(src_dir)
1189*4882a593Smuzhiyun        bb.process.run("echo readme > README.md", cwd=src_dir)
1190*4882a593Smuzhiyun
1191*4882a593Smuzhiyun        # Store it in a local SVN repository
1192*4882a593Smuzhiyun        repo_dir = tempfile.mkdtemp(dir=self.tempdir,
1193*4882a593Smuzhiyun                                   prefix='svnfetch_localrepo_')
1194*4882a593Smuzhiyun        repo_dir = os.path.abspath(repo_dir)
1195*4882a593Smuzhiyun        bb.process.run("svnadmin create project", cwd=repo_dir)
1196*4882a593Smuzhiyun
1197*4882a593Smuzhiyun        self.repo_url = "file://%s/project" % repo_dir
1198*4882a593Smuzhiyun        bb.process.run("svn import --non-interactive -m 'Initial import' %s %s/trunk" % (src_dir, self.repo_url),
1199*4882a593Smuzhiyun                       cwd=repo_dir)
1200*4882a593Smuzhiyun
1201*4882a593Smuzhiyun        bb.process.run("svn co %s svnfetch_co" % self.repo_url, cwd=self.tempdir)
1202*4882a593Smuzhiyun        # Github will emulate SVN.  Use this to check if we're downloding...
1203*4882a593Smuzhiyun        bb.process.run("svn propset svn:externals 'bitbake https://github.com/PhilipHazel/pcre2.git' .",
1204*4882a593Smuzhiyun                       cwd=os.path.join(self.tempdir, 'svnfetch_co', 'trunk'))
1205*4882a593Smuzhiyun        bb.process.run("svn commit --non-interactive -m 'Add external'",
1206*4882a593Smuzhiyun                       cwd=os.path.join(self.tempdir, 'svnfetch_co', 'trunk'))
1207*4882a593Smuzhiyun
1208*4882a593Smuzhiyun        self.src_dir = src_dir
1209*4882a593Smuzhiyun        self.repo_dir = repo_dir
1210*4882a593Smuzhiyun
1211*4882a593Smuzhiyun    @skipIfNoSvn()
1212*4882a593Smuzhiyun    def tearDown(self):
1213*4882a593Smuzhiyun        os.chdir(self.origdir)
1214*4882a593Smuzhiyun        if os.environ.get("BB_TMPDIR_NOCLEAN") == "yes":
1215*4882a593Smuzhiyun            print("Not cleaning up %s. Please remove manually." % self.tempdir)
1216*4882a593Smuzhiyun        else:
1217*4882a593Smuzhiyun            bb.utils.prunedir(self.tempdir)
1218*4882a593Smuzhiyun
1219*4882a593Smuzhiyun    @skipIfNoSvn()
1220*4882a593Smuzhiyun    @skipIfNoNetwork()
1221*4882a593Smuzhiyun    def test_noexternal_svn(self):
1222*4882a593Smuzhiyun        # Always match the rev count from setUp (currently rev 2)
1223*4882a593Smuzhiyun        url = "svn://%s;module=trunk;protocol=file;rev=2" % self.repo_url.replace('file://', '')
1224*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch([url], self.d)
1225*4882a593Smuzhiyun        fetcher.download()
1226*4882a593Smuzhiyun        os.chdir(os.path.dirname(self.unpackdir))
1227*4882a593Smuzhiyun        fetcher.unpack(self.unpackdir)
1228*4882a593Smuzhiyun
1229*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'trunk')), msg="Missing trunk")
1230*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'trunk', 'README.md')), msg="Missing contents")
1231*4882a593Smuzhiyun        self.assertFalse(os.path.exists(os.path.join(self.unpackdir, 'trunk/bitbake/trunk')), msg="External dir should NOT exist")
1232*4882a593Smuzhiyun        self.assertFalse(os.path.exists(os.path.join(self.unpackdir, 'trunk/bitbake/trunk', 'README')), msg="External README should NOT exit")
1233*4882a593Smuzhiyun
1234*4882a593Smuzhiyun    @skipIfNoSvn()
1235*4882a593Smuzhiyun    def test_external_svn(self):
1236*4882a593Smuzhiyun        # Always match the rev count from setUp (currently rev 2)
1237*4882a593Smuzhiyun        url = "svn://%s;module=trunk;protocol=file;externals=allowed;rev=2" % self.repo_url.replace('file://', '')
1238*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch([url], self.d)
1239*4882a593Smuzhiyun        fetcher.download()
1240*4882a593Smuzhiyun        os.chdir(os.path.dirname(self.unpackdir))
1241*4882a593Smuzhiyun        fetcher.unpack(self.unpackdir)
1242*4882a593Smuzhiyun
1243*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'trunk')), msg="Missing trunk")
1244*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'trunk', 'README.md')), msg="Missing contents")
1245*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'trunk/bitbake/trunk')), msg="External dir should exist")
1246*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'trunk/bitbake/trunk', 'README')), msg="External README should exit")
1247*4882a593Smuzhiyun
1248*4882a593Smuzhiyunclass TrustedNetworksTest(FetcherTest):
1249*4882a593Smuzhiyun    def test_trusted_network(self):
1250*4882a593Smuzhiyun        # Ensure trusted_network returns False when the host IS in the list.
1251*4882a593Smuzhiyun        url = "git://Someserver.org/foo;rev=1;branch=master"
1252*4882a593Smuzhiyun        self.d.setVar("BB_ALLOWED_NETWORKS", "server1.org someserver.org server2.org server3.org")
1253*4882a593Smuzhiyun        self.assertTrue(bb.fetch.trusted_network(self.d, url))
1254*4882a593Smuzhiyun
1255*4882a593Smuzhiyun    def test_wild_trusted_network(self):
1256*4882a593Smuzhiyun        # Ensure trusted_network returns true when the *.host IS in the list.
1257*4882a593Smuzhiyun        url = "git://Someserver.org/foo;rev=1;branch=master"
1258*4882a593Smuzhiyun        self.d.setVar("BB_ALLOWED_NETWORKS", "server1.org *.someserver.org server2.org server3.org")
1259*4882a593Smuzhiyun        self.assertTrue(bb.fetch.trusted_network(self.d, url))
1260*4882a593Smuzhiyun
1261*4882a593Smuzhiyun    def test_prefix_wild_trusted_network(self):
1262*4882a593Smuzhiyun        # Ensure trusted_network returns true when the prefix matches *.host.
1263*4882a593Smuzhiyun        url = "git://git.Someserver.org/foo;rev=1;branch=master"
1264*4882a593Smuzhiyun        self.d.setVar("BB_ALLOWED_NETWORKS", "server1.org *.someserver.org server2.org server3.org")
1265*4882a593Smuzhiyun        self.assertTrue(bb.fetch.trusted_network(self.d, url))
1266*4882a593Smuzhiyun
1267*4882a593Smuzhiyun    def test_two_prefix_wild_trusted_network(self):
1268*4882a593Smuzhiyun        # Ensure trusted_network returns true when the prefix matches *.host.
1269*4882a593Smuzhiyun        url = "git://something.git.Someserver.org/foo;rev=1;branch=master"
1270*4882a593Smuzhiyun        self.d.setVar("BB_ALLOWED_NETWORKS", "server1.org *.someserver.org server2.org server3.org")
1271*4882a593Smuzhiyun        self.assertTrue(bb.fetch.trusted_network(self.d, url))
1272*4882a593Smuzhiyun
1273*4882a593Smuzhiyun    def test_port_trusted_network(self):
1274*4882a593Smuzhiyun        # Ensure trusted_network returns True, even if the url specifies a port.
1275*4882a593Smuzhiyun        url = "git://someserver.org:8080/foo;rev=1;branch=master"
1276*4882a593Smuzhiyun        self.d.setVar("BB_ALLOWED_NETWORKS", "someserver.org")
1277*4882a593Smuzhiyun        self.assertTrue(bb.fetch.trusted_network(self.d, url))
1278*4882a593Smuzhiyun
1279*4882a593Smuzhiyun    def test_untrusted_network(self):
1280*4882a593Smuzhiyun        # Ensure trusted_network returns False when the host is NOT in the list.
1281*4882a593Smuzhiyun        url = "git://someserver.org/foo;rev=1;branch=master"
1282*4882a593Smuzhiyun        self.d.setVar("BB_ALLOWED_NETWORKS", "server1.org server2.org server3.org")
1283*4882a593Smuzhiyun        self.assertFalse(bb.fetch.trusted_network(self.d, url))
1284*4882a593Smuzhiyun
1285*4882a593Smuzhiyun    def test_wild_untrusted_network(self):
1286*4882a593Smuzhiyun        # Ensure trusted_network returns False when the host is NOT in the list.
1287*4882a593Smuzhiyun        url = "git://*.someserver.org/foo;rev=1;branch=master"
1288*4882a593Smuzhiyun        self.d.setVar("BB_ALLOWED_NETWORKS", "server1.org server2.org server3.org")
1289*4882a593Smuzhiyun        self.assertFalse(bb.fetch.trusted_network(self.d, url))
1290*4882a593Smuzhiyun
1291*4882a593Smuzhiyunclass URLHandle(unittest.TestCase):
1292*4882a593Smuzhiyun
1293*4882a593Smuzhiyun    datatable = {
1294*4882a593Smuzhiyun       "http://www.google.com/index.html" : ('http', 'www.google.com', '/index.html', '', '', {}),
1295*4882a593Smuzhiyun       "cvs://anoncvs@cvs.handhelds.org/cvs;module=familiar/dist/ipkg" : ('cvs', 'cvs.handhelds.org', '/cvs', 'anoncvs', '', {'module': 'familiar/dist/ipkg'}),
1296*4882a593Smuzhiyun       "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')])),
1297*4882a593Smuzhiyun       "git://git.openembedded.org/bitbake;branch=@foo" : ('git', 'git.openembedded.org', '/bitbake', '', '', {'branch': '@foo'}),
1298*4882a593Smuzhiyun       "file://somelocation;someparam=1": ('file', '', 'somelocation', '', '', {'someparam': '1'}),
1299*4882a593Smuzhiyun    }
1300*4882a593Smuzhiyun    # we require a pathname to encodeurl but users can still pass such urls to
1301*4882a593Smuzhiyun    # decodeurl and we need to handle them
1302*4882a593Smuzhiyun    decodedata = datatable.copy()
1303*4882a593Smuzhiyun    decodedata.update({
1304*4882a593Smuzhiyun       "http://somesite.net;someparam=1": ('http', 'somesite.net', '/', '', '', {'someparam': '1'}),
1305*4882a593Smuzhiyun    })
1306*4882a593Smuzhiyun
1307*4882a593Smuzhiyun    def test_decodeurl(self):
1308*4882a593Smuzhiyun        for k, v in self.decodedata.items():
1309*4882a593Smuzhiyun            result = bb.fetch.decodeurl(k)
1310*4882a593Smuzhiyun            self.assertEqual(result, v)
1311*4882a593Smuzhiyun
1312*4882a593Smuzhiyun    def test_encodeurl(self):
1313*4882a593Smuzhiyun        for k, v in self.datatable.items():
1314*4882a593Smuzhiyun            result = bb.fetch.encodeurl(v)
1315*4882a593Smuzhiyun            self.assertEqual(result, k)
1316*4882a593Smuzhiyun
1317*4882a593Smuzhiyunclass FetchLatestVersionTest(FetcherTest):
1318*4882a593Smuzhiyun
1319*4882a593Smuzhiyun    test_git_uris = {
1320*4882a593Smuzhiyun        # version pattern "X.Y.Z"
1321*4882a593Smuzhiyun        ("mx-1.0", "git://github.com/clutter-project/mx.git;branch=mx-1.4;protocol=https", "9b1db6b8060bd00b121a692f942404a24ae2960f", "")
1322*4882a593Smuzhiyun            : "1.99.4",
1323*4882a593Smuzhiyun        # version pattern "vX.Y"
1324*4882a593Smuzhiyun        # mirror of git.infradead.org since network issues interfered with testing
1325*4882a593Smuzhiyun        ("mtd-utils", "git://git.yoctoproject.org/mtd-utils.git;branch=master", "ca39eb1d98e736109c64ff9c1aa2a6ecca222d8f", "")
1326*4882a593Smuzhiyun            : "1.5.0",
1327*4882a593Smuzhiyun        # version pattern "pkg_name-X.Y"
1328*4882a593Smuzhiyun        # mirror of git://anongit.freedesktop.org/git/xorg/proto/presentproto since network issues interfered with testing
1329*4882a593Smuzhiyun        ("presentproto", "git://git.yoctoproject.org/bbfetchtests-presentproto;branch=master", "24f3a56e541b0a9e6c6ee76081f441221a120ef9", "")
1330*4882a593Smuzhiyun            : "1.0",
1331*4882a593Smuzhiyun        # version pattern "pkg_name-vX.Y.Z"
1332*4882a593Smuzhiyun        ("dtc", "git://git.yoctoproject.org/bbfetchtests-dtc.git;branch=master", "65cc4d2748a2c2e6f27f1cf39e07a5dbabd80ebf", "")
1333*4882a593Smuzhiyun            : "1.4.0",
1334*4882a593Smuzhiyun        # combination version pattern
1335*4882a593Smuzhiyun        ("sysprof", "git://gitlab.gnome.org/GNOME/sysprof.git;protocol=https;branch=master", "cd44ee6644c3641507fb53b8a2a69137f2971219", "")
1336*4882a593Smuzhiyun            : "1.2.0",
1337*4882a593Smuzhiyun        ("u-boot-mkimage", "git://git.denx.de/u-boot.git;branch=master;protocol=git", "62c175fbb8a0f9a926c88294ea9f7e88eb898f6c", "")
1338*4882a593Smuzhiyun            : "2014.01",
1339*4882a593Smuzhiyun        # version pattern "yyyymmdd"
1340*4882a593Smuzhiyun        ("mobile-broadband-provider-info", "git://gitlab.gnome.org/GNOME/mobile-broadband-provider-info.git;protocol=https;branch=master", "4ed19e11c2975105b71b956440acdb25d46a347d", "")
1341*4882a593Smuzhiyun            : "20120614",
1342*4882a593Smuzhiyun        # packages with a valid UPSTREAM_CHECK_GITTAGREGEX
1343*4882a593Smuzhiyun                # mirror of git://anongit.freedesktop.org/xorg/driver/xf86-video-omap since network issues interfered with testing
1344*4882a593Smuzhiyun        ("xf86-video-omap", "git://git.yoctoproject.org/bbfetchtests-xf86-video-omap;branch=master", "ae0394e687f1a77e966cf72f895da91840dffb8f", r"(?P<pver>(\d+\.(\d\.?)*))")
1345*4882a593Smuzhiyun            : "0.4.3",
1346*4882a593Smuzhiyun        ("build-appliance-image", "git://git.yoctoproject.org/poky;branch=master", "b37dd451a52622d5b570183a81583cc34c2ff555", r"(?P<pver>(([0-9][\.|_]?)+[0-9]))")
1347*4882a593Smuzhiyun            : "11.0.0",
1348*4882a593Smuzhiyun        ("chkconfig-alternatives-native", "git://github.com/kergoth/chkconfig;branch=sysroot;protocol=https", "cd437ecbd8986c894442f8fce1e0061e20f04dee", r"chkconfig\-(?P<pver>((\d+[\.\-_]*)+))")
1349*4882a593Smuzhiyun            : "1.3.59",
1350*4882a593Smuzhiyun        ("remake", "git://github.com/rocky/remake.git;protocol=https;branch=master", "f05508e521987c8494c92d9c2871aec46307d51d", r"(?P<pver>(\d+\.(\d+\.)*\d*(\+dbg\d+(\.\d+)*)*))")
1351*4882a593Smuzhiyun            : "3.82+dbg0.9",
1352*4882a593Smuzhiyun    }
1353*4882a593Smuzhiyun
1354*4882a593Smuzhiyun    test_wget_uris = {
1355*4882a593Smuzhiyun        #
1356*4882a593Smuzhiyun        # packages with versions inside directory name
1357*4882a593Smuzhiyun        #
1358*4882a593Smuzhiyun        # http://kernel.org/pub/linux/utils/util-linux/v2.23/util-linux-2.24.2.tar.bz2
1359*4882a593Smuzhiyun        ("util-linux", "/pub/linux/utils/util-linux/v2.23/util-linux-2.24.2.tar.bz2", "", "")
1360*4882a593Smuzhiyun            : "2.24.2",
1361*4882a593Smuzhiyun        # http://www.abisource.com/downloads/enchant/1.6.0/enchant-1.6.0.tar.gz
1362*4882a593Smuzhiyun        ("enchant", "/downloads/enchant/1.6.0/enchant-1.6.0.tar.gz", "", "")
1363*4882a593Smuzhiyun            : "1.6.0",
1364*4882a593Smuzhiyun        # http://www.cmake.org/files/v2.8/cmake-2.8.12.1.tar.gz
1365*4882a593Smuzhiyun        ("cmake", "/files/v2.8/cmake-2.8.12.1.tar.gz", "", "")
1366*4882a593Smuzhiyun            : "2.8.12.1",
1367*4882a593Smuzhiyun        #
1368*4882a593Smuzhiyun        # packages with versions only in current directory
1369*4882a593Smuzhiyun        #
1370*4882a593Smuzhiyun        # https://downloads.yoctoproject.org/releases/eglibc/eglibc-2.18-svnr23787.tar.bz2
1371*4882a593Smuzhiyun        ("eglic", "/releases/eglibc/eglibc-2.18-svnr23787.tar.bz2", "", "")
1372*4882a593Smuzhiyun            : "2.19",
1373*4882a593Smuzhiyun        # https://downloads.yoctoproject.org/releases/gnu-config/gnu-config-20120814.tar.bz2
1374*4882a593Smuzhiyun        ("gnu-config", "/releases/gnu-config/gnu-config-20120814.tar.bz2", "", "")
1375*4882a593Smuzhiyun            : "20120814",
1376*4882a593Smuzhiyun        #
1377*4882a593Smuzhiyun        # packages with "99" in the name of possible version
1378*4882a593Smuzhiyun        #
1379*4882a593Smuzhiyun        # http://freedesktop.org/software/pulseaudio/releases/pulseaudio-4.0.tar.xz
1380*4882a593Smuzhiyun        ("pulseaudio", "/software/pulseaudio/releases/pulseaudio-4.0.tar.xz", "", "")
1381*4882a593Smuzhiyun            : "5.0",
1382*4882a593Smuzhiyun        # http://xorg.freedesktop.org/releases/individual/xserver/xorg-server-1.15.1.tar.bz2
1383*4882a593Smuzhiyun        ("xserver-xorg", "/releases/individual/xserver/xorg-server-1.15.1.tar.bz2", "", "")
1384*4882a593Smuzhiyun            : "1.15.1",
1385*4882a593Smuzhiyun        #
1386*4882a593Smuzhiyun        # packages with valid UPSTREAM_CHECK_URI and UPSTREAM_CHECK_REGEX
1387*4882a593Smuzhiyun        #
1388*4882a593Smuzhiyun        # http://www.cups.org/software/1.7.2/cups-1.7.2-source.tar.bz2
1389*4882a593Smuzhiyun        # https://github.com/apple/cups/releases
1390*4882a593Smuzhiyun        ("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")
1391*4882a593Smuzhiyun            : "2.0.0",
1392*4882a593Smuzhiyun        # http://download.oracle.com/berkeley-db/db-5.3.21.tar.gz
1393*4882a593Smuzhiyun        # http://ftp.debian.org/debian/pool/main/d/db5.3/
1394*4882a593Smuzhiyun        ("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")
1395*4882a593Smuzhiyun            : "5.3.10",
1396*4882a593Smuzhiyun        #
1397*4882a593Smuzhiyun        # packages where the tarball compression changed in the new version
1398*4882a593Smuzhiyun        #
1399*4882a593Smuzhiyun        # http://ftp.debian.org/debian/pool/main/m/minicom/minicom_2.7.1.orig.tar.gz
1400*4882a593Smuzhiyun        ("minicom", "/debian/pool/main/m/minicom/minicom_2.7.1.orig.tar.gz", "", "")
1401*4882a593Smuzhiyun            : "2.8",
1402*4882a593Smuzhiyun    }
1403*4882a593Smuzhiyun
1404*4882a593Smuzhiyun    @skipIfNoNetwork()
1405*4882a593Smuzhiyun    def test_git_latest_versionstring(self):
1406*4882a593Smuzhiyun        for k, v in self.test_git_uris.items():
1407*4882a593Smuzhiyun            self.d.setVar("PN", k[0])
1408*4882a593Smuzhiyun            self.d.setVar("SRCREV", k[2])
1409*4882a593Smuzhiyun            self.d.setVar("UPSTREAM_CHECK_GITTAGREGEX", k[3])
1410*4882a593Smuzhiyun            ud = bb.fetch2.FetchData(k[1], self.d)
1411*4882a593Smuzhiyun            pupver= ud.method.latest_versionstring(ud, self.d)
1412*4882a593Smuzhiyun            verstring = pupver[0]
1413*4882a593Smuzhiyun            self.assertTrue(verstring, msg="Could not find upstream version for %s" % k[0])
1414*4882a593Smuzhiyun            r = bb.utils.vercmp_string(v, verstring)
1415*4882a593Smuzhiyun            self.assertTrue(r == -1 or r == 0, msg="Package %s, version: %s <= %s" % (k[0], v, verstring))
1416*4882a593Smuzhiyun
1417*4882a593Smuzhiyun    def test_wget_latest_versionstring(self):
1418*4882a593Smuzhiyun        testdata = os.path.dirname(os.path.abspath(__file__)) + "/fetch-testdata"
1419*4882a593Smuzhiyun        server = HTTPService(testdata)
1420*4882a593Smuzhiyun        server.start()
1421*4882a593Smuzhiyun        port = server.port
1422*4882a593Smuzhiyun        try:
1423*4882a593Smuzhiyun            for k, v in self.test_wget_uris.items():
1424*4882a593Smuzhiyun                self.d.setVar("PN", k[0])
1425*4882a593Smuzhiyun                checkuri = ""
1426*4882a593Smuzhiyun                if k[2]:
1427*4882a593Smuzhiyun                    checkuri = "http://localhost:%s/" % port + k[2]
1428*4882a593Smuzhiyun                self.d.setVar("UPSTREAM_CHECK_URI", checkuri)
1429*4882a593Smuzhiyun                self.d.setVar("UPSTREAM_CHECK_REGEX", k[3])
1430*4882a593Smuzhiyun                url = "http://localhost:%s/" % port + k[1]
1431*4882a593Smuzhiyun                ud = bb.fetch2.FetchData(url, self.d)
1432*4882a593Smuzhiyun                pupver = ud.method.latest_versionstring(ud, self.d)
1433*4882a593Smuzhiyun                verstring = pupver[0]
1434*4882a593Smuzhiyun                self.assertTrue(verstring, msg="Could not find upstream version for %s" % k[0])
1435*4882a593Smuzhiyun                r = bb.utils.vercmp_string(v, verstring)
1436*4882a593Smuzhiyun                self.assertTrue(r == -1 or r == 0, msg="Package %s, version: %s <= %s" % (k[0], v, verstring))
1437*4882a593Smuzhiyun        finally:
1438*4882a593Smuzhiyun            server.stop()
1439*4882a593Smuzhiyun
1440*4882a593Smuzhiyun
1441*4882a593Smuzhiyunclass FetchCheckStatusTest(FetcherTest):
1442*4882a593Smuzhiyun    test_wget_uris = ["https://downloads.yoctoproject.org/releases/sato/sato-engine-0.1.tar.gz",
1443*4882a593Smuzhiyun                      "https://downloads.yoctoproject.org/releases/sato/sato-engine-0.2.tar.gz",
1444*4882a593Smuzhiyun                      "https://downloads.yoctoproject.org/releases/sato/sato-engine-0.3.tar.gz",
1445*4882a593Smuzhiyun                      "https://yoctoproject.org/",
1446*4882a593Smuzhiyun                      "https://docs.yoctoproject.org",
1447*4882a593Smuzhiyun                      "https://downloads.yoctoproject.org/releases/opkg/opkg-0.1.7.tar.gz",
1448*4882a593Smuzhiyun                      "https://downloads.yoctoproject.org/releases/opkg/opkg-0.3.0.tar.gz",
1449*4882a593Smuzhiyun                      "ftp://sourceware.org/pub/libffi/libffi-1.20.tar.gz",
1450*4882a593Smuzhiyun                      # GitHub releases are hosted on Amazon S3, which doesn't support HEAD
1451*4882a593Smuzhiyun                      "https://github.com/kergoth/tslib/releases/download/1.1/tslib-1.1.tar.xz"
1452*4882a593Smuzhiyun                      ]
1453*4882a593Smuzhiyun
1454*4882a593Smuzhiyun    @skipIfNoNetwork()
1455*4882a593Smuzhiyun    def test_wget_checkstatus(self):
1456*4882a593Smuzhiyun        fetch = bb.fetch2.Fetch(self.test_wget_uris, self.d)
1457*4882a593Smuzhiyun        for u in self.test_wget_uris:
1458*4882a593Smuzhiyun            with self.subTest(url=u):
1459*4882a593Smuzhiyun                ud = fetch.ud[u]
1460*4882a593Smuzhiyun                m = ud.method
1461*4882a593Smuzhiyun                ret = m.checkstatus(fetch, ud, self.d)
1462*4882a593Smuzhiyun                self.assertTrue(ret, msg="URI %s, can't check status" % (u))
1463*4882a593Smuzhiyun
1464*4882a593Smuzhiyun    @skipIfNoNetwork()
1465*4882a593Smuzhiyun    def test_wget_checkstatus_connection_cache(self):
1466*4882a593Smuzhiyun        from bb.fetch2 import FetchConnectionCache
1467*4882a593Smuzhiyun
1468*4882a593Smuzhiyun        connection_cache = FetchConnectionCache()
1469*4882a593Smuzhiyun        fetch = bb.fetch2.Fetch(self.test_wget_uris, self.d,
1470*4882a593Smuzhiyun                    connection_cache = connection_cache)
1471*4882a593Smuzhiyun
1472*4882a593Smuzhiyun        for u in self.test_wget_uris:
1473*4882a593Smuzhiyun            with self.subTest(url=u):
1474*4882a593Smuzhiyun                ud = fetch.ud[u]
1475*4882a593Smuzhiyun                m = ud.method
1476*4882a593Smuzhiyun                ret = m.checkstatus(fetch, ud, self.d)
1477*4882a593Smuzhiyun                self.assertTrue(ret, msg="URI %s, can't check status" % (u))
1478*4882a593Smuzhiyun
1479*4882a593Smuzhiyun        connection_cache.close_connections()
1480*4882a593Smuzhiyun
1481*4882a593Smuzhiyun
1482*4882a593Smuzhiyunclass GitMakeShallowTest(FetcherTest):
1483*4882a593Smuzhiyun    def setUp(self):
1484*4882a593Smuzhiyun        FetcherTest.setUp(self)
1485*4882a593Smuzhiyun        self.gitdir = os.path.join(self.tempdir, 'gitshallow')
1486*4882a593Smuzhiyun        bb.utils.mkdirhier(self.gitdir)
1487*4882a593Smuzhiyun        self.git_init()
1488*4882a593Smuzhiyun
1489*4882a593Smuzhiyun    def assertRefs(self, expected_refs):
1490*4882a593Smuzhiyun        actual_refs = self.git(['for-each-ref', '--format=%(refname)']).splitlines()
1491*4882a593Smuzhiyun        full_expected = self.git(['rev-parse', '--symbolic-full-name'] + expected_refs).splitlines()
1492*4882a593Smuzhiyun        self.assertEqual(sorted(full_expected), sorted(actual_refs))
1493*4882a593Smuzhiyun
1494*4882a593Smuzhiyun    def assertRevCount(self, expected_count, args=None):
1495*4882a593Smuzhiyun        if args is None:
1496*4882a593Smuzhiyun            args = ['HEAD']
1497*4882a593Smuzhiyun        revs = self.git(['rev-list'] + args)
1498*4882a593Smuzhiyun        actual_count = len(revs.splitlines())
1499*4882a593Smuzhiyun        self.assertEqual(expected_count, actual_count, msg='Object count `%d` is not the expected `%d`' % (actual_count, expected_count))
1500*4882a593Smuzhiyun
1501*4882a593Smuzhiyun    def make_shallow(self, args=None):
1502*4882a593Smuzhiyun        if args is None:
1503*4882a593Smuzhiyun            args = ['HEAD']
1504*4882a593Smuzhiyun        return bb.process.run([bb.fetch2.git.Git.make_shallow_path] + args, cwd=self.gitdir)
1505*4882a593Smuzhiyun
1506*4882a593Smuzhiyun    def add_empty_file(self, path, msg=None):
1507*4882a593Smuzhiyun        if msg is None:
1508*4882a593Smuzhiyun            msg = path
1509*4882a593Smuzhiyun        open(os.path.join(self.gitdir, path), 'w').close()
1510*4882a593Smuzhiyun        self.git(['add', path])
1511*4882a593Smuzhiyun        self.git(['commit', '-m', msg, path])
1512*4882a593Smuzhiyun
1513*4882a593Smuzhiyun    def test_make_shallow_single_branch_no_merge(self):
1514*4882a593Smuzhiyun        self.add_empty_file('a')
1515*4882a593Smuzhiyun        self.add_empty_file('b')
1516*4882a593Smuzhiyun        self.assertRevCount(2)
1517*4882a593Smuzhiyun        self.make_shallow()
1518*4882a593Smuzhiyun        self.assertRevCount(1)
1519*4882a593Smuzhiyun
1520*4882a593Smuzhiyun    def test_make_shallow_single_branch_one_merge(self):
1521*4882a593Smuzhiyun        self.add_empty_file('a')
1522*4882a593Smuzhiyun        self.add_empty_file('b')
1523*4882a593Smuzhiyun        self.git('checkout -b a_branch')
1524*4882a593Smuzhiyun        self.add_empty_file('c')
1525*4882a593Smuzhiyun        self.git('checkout master')
1526*4882a593Smuzhiyun        self.add_empty_file('d')
1527*4882a593Smuzhiyun        self.git('merge --no-ff --no-edit a_branch')
1528*4882a593Smuzhiyun        self.git('branch -d a_branch')
1529*4882a593Smuzhiyun        self.add_empty_file('e')
1530*4882a593Smuzhiyun        self.assertRevCount(6)
1531*4882a593Smuzhiyun        self.make_shallow(['HEAD~2'])
1532*4882a593Smuzhiyun        self.assertRevCount(5)
1533*4882a593Smuzhiyun
1534*4882a593Smuzhiyun    def test_make_shallow_at_merge(self):
1535*4882a593Smuzhiyun        self.add_empty_file('a')
1536*4882a593Smuzhiyun        self.git('checkout -b a_branch')
1537*4882a593Smuzhiyun        self.add_empty_file('b')
1538*4882a593Smuzhiyun        self.git('checkout master')
1539*4882a593Smuzhiyun        self.git('merge --no-ff --no-edit a_branch')
1540*4882a593Smuzhiyun        self.git('branch -d a_branch')
1541*4882a593Smuzhiyun        self.assertRevCount(3)
1542*4882a593Smuzhiyun        self.make_shallow()
1543*4882a593Smuzhiyun        self.assertRevCount(1)
1544*4882a593Smuzhiyun
1545*4882a593Smuzhiyun    def test_make_shallow_annotated_tag(self):
1546*4882a593Smuzhiyun        self.add_empty_file('a')
1547*4882a593Smuzhiyun        self.add_empty_file('b')
1548*4882a593Smuzhiyun        self.git('tag -a -m a_tag a_tag')
1549*4882a593Smuzhiyun        self.assertRevCount(2)
1550*4882a593Smuzhiyun        self.make_shallow(['a_tag'])
1551*4882a593Smuzhiyun        self.assertRevCount(1)
1552*4882a593Smuzhiyun
1553*4882a593Smuzhiyun    def test_make_shallow_multi_ref(self):
1554*4882a593Smuzhiyun        self.add_empty_file('a')
1555*4882a593Smuzhiyun        self.add_empty_file('b')
1556*4882a593Smuzhiyun        self.git('checkout -b a_branch')
1557*4882a593Smuzhiyun        self.add_empty_file('c')
1558*4882a593Smuzhiyun        self.git('checkout master')
1559*4882a593Smuzhiyun        self.add_empty_file('d')
1560*4882a593Smuzhiyun        self.git('checkout -b a_branch_2')
1561*4882a593Smuzhiyun        self.add_empty_file('a_tag')
1562*4882a593Smuzhiyun        self.git('tag a_tag')
1563*4882a593Smuzhiyun        self.git('checkout master')
1564*4882a593Smuzhiyun        self.git('branch -D a_branch_2')
1565*4882a593Smuzhiyun        self.add_empty_file('e')
1566*4882a593Smuzhiyun        self.assertRevCount(6, ['--all'])
1567*4882a593Smuzhiyun        self.make_shallow()
1568*4882a593Smuzhiyun        self.assertRevCount(5, ['--all'])
1569*4882a593Smuzhiyun
1570*4882a593Smuzhiyun    def test_make_shallow_multi_ref_trim(self):
1571*4882a593Smuzhiyun        self.add_empty_file('a')
1572*4882a593Smuzhiyun        self.git('checkout -b a_branch')
1573*4882a593Smuzhiyun        self.add_empty_file('c')
1574*4882a593Smuzhiyun        self.git('checkout master')
1575*4882a593Smuzhiyun        self.assertRevCount(1)
1576*4882a593Smuzhiyun        self.assertRevCount(2, ['--all'])
1577*4882a593Smuzhiyun        self.assertRefs(['master', 'a_branch'])
1578*4882a593Smuzhiyun        self.make_shallow(['-r', 'master', 'HEAD'])
1579*4882a593Smuzhiyun        self.assertRevCount(1, ['--all'])
1580*4882a593Smuzhiyun        self.assertRefs(['master'])
1581*4882a593Smuzhiyun
1582*4882a593Smuzhiyun    def test_make_shallow_noop(self):
1583*4882a593Smuzhiyun        self.add_empty_file('a')
1584*4882a593Smuzhiyun        self.assertRevCount(1)
1585*4882a593Smuzhiyun        self.make_shallow()
1586*4882a593Smuzhiyun        self.assertRevCount(1)
1587*4882a593Smuzhiyun
1588*4882a593Smuzhiyun    @skipIfNoNetwork()
1589*4882a593Smuzhiyun    def test_make_shallow_bitbake(self):
1590*4882a593Smuzhiyun        self.git('remote add origin https://github.com/openembedded/bitbake')
1591*4882a593Smuzhiyun        self.git('fetch --tags origin')
1592*4882a593Smuzhiyun        orig_revs = len(self.git('rev-list --all').splitlines())
1593*4882a593Smuzhiyun        self.make_shallow(['refs/tags/1.10.0'])
1594*4882a593Smuzhiyun        self.assertRevCount(orig_revs - 1746, ['--all'])
1595*4882a593Smuzhiyun
1596*4882a593Smuzhiyunclass GitShallowTest(FetcherTest):
1597*4882a593Smuzhiyun    def setUp(self):
1598*4882a593Smuzhiyun        FetcherTest.setUp(self)
1599*4882a593Smuzhiyun        self.gitdir = os.path.join(self.tempdir, 'git')
1600*4882a593Smuzhiyun        self.srcdir = os.path.join(self.tempdir, 'gitsource')
1601*4882a593Smuzhiyun
1602*4882a593Smuzhiyun        bb.utils.mkdirhier(self.srcdir)
1603*4882a593Smuzhiyun        self.git_init(cwd=self.srcdir)
1604*4882a593Smuzhiyun        self.d.setVar('WORKDIR', self.tempdir)
1605*4882a593Smuzhiyun        self.d.setVar('S', self.gitdir)
1606*4882a593Smuzhiyun        self.d.delVar('PREMIRRORS')
1607*4882a593Smuzhiyun        self.d.delVar('MIRRORS')
1608*4882a593Smuzhiyun
1609*4882a593Smuzhiyun        uri = 'git://%s;protocol=file;subdir=${S};branch=master' % self.srcdir
1610*4882a593Smuzhiyun        self.d.setVar('SRC_URI', uri)
1611*4882a593Smuzhiyun        self.d.setVar('SRCREV', '${AUTOREV}')
1612*4882a593Smuzhiyun        self.d.setVar('AUTOREV', '${@bb.fetch2.get_autorev(d)}')
1613*4882a593Smuzhiyun
1614*4882a593Smuzhiyun        self.d.setVar('BB_GIT_SHALLOW', '1')
1615*4882a593Smuzhiyun        self.d.setVar('BB_GENERATE_MIRROR_TARBALLS', '0')
1616*4882a593Smuzhiyun        self.d.setVar('BB_GENERATE_SHALLOW_TARBALLS', '1')
1617*4882a593Smuzhiyun        self.d.setVar("__BBSEENSRCREV", "1")
1618*4882a593Smuzhiyun
1619*4882a593Smuzhiyun    def assertRefs(self, expected_refs, cwd=None):
1620*4882a593Smuzhiyun        if cwd is None:
1621*4882a593Smuzhiyun            cwd = self.gitdir
1622*4882a593Smuzhiyun        actual_refs = self.git(['for-each-ref', '--format=%(refname)'], cwd=cwd).splitlines()
1623*4882a593Smuzhiyun        full_expected = self.git(['rev-parse', '--symbolic-full-name'] + expected_refs, cwd=cwd).splitlines()
1624*4882a593Smuzhiyun        self.assertEqual(sorted(set(full_expected)), sorted(set(actual_refs)))
1625*4882a593Smuzhiyun
1626*4882a593Smuzhiyun    def assertRevCount(self, expected_count, args=None, cwd=None):
1627*4882a593Smuzhiyun        if args is None:
1628*4882a593Smuzhiyun            args = ['HEAD']
1629*4882a593Smuzhiyun        if cwd is None:
1630*4882a593Smuzhiyun            cwd = self.gitdir
1631*4882a593Smuzhiyun        revs = self.git(['rev-list'] + args, cwd=cwd)
1632*4882a593Smuzhiyun        actual_count = len(revs.splitlines())
1633*4882a593Smuzhiyun        self.assertEqual(expected_count, actual_count, msg='Object count `%d` is not the expected `%d`' % (actual_count, expected_count))
1634*4882a593Smuzhiyun
1635*4882a593Smuzhiyun    def add_empty_file(self, path, cwd=None, msg=None):
1636*4882a593Smuzhiyun        if msg is None:
1637*4882a593Smuzhiyun            msg = path
1638*4882a593Smuzhiyun        if cwd is None:
1639*4882a593Smuzhiyun            cwd = self.srcdir
1640*4882a593Smuzhiyun        open(os.path.join(cwd, path), 'w').close()
1641*4882a593Smuzhiyun        self.git(['add', path], cwd)
1642*4882a593Smuzhiyun        self.git(['commit', '-m', msg, path], cwd)
1643*4882a593Smuzhiyun
1644*4882a593Smuzhiyun    def fetch(self, uri=None):
1645*4882a593Smuzhiyun        if uri is None:
1646*4882a593Smuzhiyun            uris = self.d.getVar('SRC_URI').split()
1647*4882a593Smuzhiyun            uri = uris[0]
1648*4882a593Smuzhiyun            d = self.d
1649*4882a593Smuzhiyun        else:
1650*4882a593Smuzhiyun            d = self.d.createCopy()
1651*4882a593Smuzhiyun            d.setVar('SRC_URI', uri)
1652*4882a593Smuzhiyun            uri = d.expand(uri)
1653*4882a593Smuzhiyun            uris = [uri]
1654*4882a593Smuzhiyun
1655*4882a593Smuzhiyun        fetcher = bb.fetch2.Fetch(uris, d)
1656*4882a593Smuzhiyun        fetcher.download()
1657*4882a593Smuzhiyun        ud = fetcher.ud[uri]
1658*4882a593Smuzhiyun        return fetcher, ud
1659*4882a593Smuzhiyun
1660*4882a593Smuzhiyun    def fetch_and_unpack(self, uri=None):
1661*4882a593Smuzhiyun        fetcher, ud = self.fetch(uri)
1662*4882a593Smuzhiyun        fetcher.unpack(self.d.getVar('WORKDIR'))
1663*4882a593Smuzhiyun        assert os.path.exists(self.d.getVar('S'))
1664*4882a593Smuzhiyun        return fetcher, ud
1665*4882a593Smuzhiyun
1666*4882a593Smuzhiyun    def fetch_shallow(self, uri=None, disabled=False, keepclone=False):
1667*4882a593Smuzhiyun        """Fetch a uri, generating a shallow tarball, then unpack using it"""
1668*4882a593Smuzhiyun        fetcher, ud = self.fetch_and_unpack(uri)
1669*4882a593Smuzhiyun        assert os.path.exists(ud.clonedir), 'Git clone in DLDIR (%s) does not exist for uri %s' % (ud.clonedir, uri)
1670*4882a593Smuzhiyun
1671*4882a593Smuzhiyun        # Confirm that the unpacked repo is unshallow
1672*4882a593Smuzhiyun        if not disabled:
1673*4882a593Smuzhiyun            assert os.path.exists(os.path.join(self.dldir, ud.mirrortarballs[0]))
1674*4882a593Smuzhiyun
1675*4882a593Smuzhiyun        # fetch and unpack, from the shallow tarball
1676*4882a593Smuzhiyun        bb.utils.remove(self.gitdir, recurse=True)
1677*4882a593Smuzhiyun        bb.process.run('chmod u+w -R "%s"' % ud.clonedir)
1678*4882a593Smuzhiyun        bb.utils.remove(ud.clonedir, recurse=True)
1679*4882a593Smuzhiyun        bb.utils.remove(ud.clonedir.replace('gitsource', 'gitsubmodule'), recurse=True)
1680*4882a593Smuzhiyun
1681*4882a593Smuzhiyun        # confirm that the unpacked repo is used when no git clone or git
1682*4882a593Smuzhiyun        # mirror tarball is available
1683*4882a593Smuzhiyun        fetcher, ud = self.fetch_and_unpack(uri)
1684*4882a593Smuzhiyun        if not disabled:
1685*4882a593Smuzhiyun            assert os.path.exists(os.path.join(self.gitdir, '.git', 'shallow')), 'Unpacked git repository at %s is not shallow' % self.gitdir
1686*4882a593Smuzhiyun        else:
1687*4882a593Smuzhiyun            assert not os.path.exists(os.path.join(self.gitdir, '.git', 'shallow')), 'Unpacked git repository at %s is shallow' % self.gitdir
1688*4882a593Smuzhiyun        return fetcher, ud
1689*4882a593Smuzhiyun
1690*4882a593Smuzhiyun    def test_shallow_disabled(self):
1691*4882a593Smuzhiyun        self.add_empty_file('a')
1692*4882a593Smuzhiyun        self.add_empty_file('b')
1693*4882a593Smuzhiyun        self.assertRevCount(2, cwd=self.srcdir)
1694*4882a593Smuzhiyun
1695*4882a593Smuzhiyun        self.d.setVar('BB_GIT_SHALLOW', '0')
1696*4882a593Smuzhiyun        self.fetch_shallow(disabled=True)
1697*4882a593Smuzhiyun        self.assertRevCount(2)
1698*4882a593Smuzhiyun
1699*4882a593Smuzhiyun    def test_shallow_nobranch(self):
1700*4882a593Smuzhiyun        self.add_empty_file('a')
1701*4882a593Smuzhiyun        self.add_empty_file('b')
1702*4882a593Smuzhiyun        self.assertRevCount(2, cwd=self.srcdir)
1703*4882a593Smuzhiyun
1704*4882a593Smuzhiyun        srcrev = self.git('rev-parse HEAD', cwd=self.srcdir).strip()
1705*4882a593Smuzhiyun        self.d.setVar('SRCREV', srcrev)
1706*4882a593Smuzhiyun        uri = self.d.getVar('SRC_URI').split()[0]
1707*4882a593Smuzhiyun        uri = '%s;nobranch=1;bare=1' % uri
1708*4882a593Smuzhiyun
1709*4882a593Smuzhiyun        self.fetch_shallow(uri)
1710*4882a593Smuzhiyun        self.assertRevCount(1)
1711*4882a593Smuzhiyun
1712*4882a593Smuzhiyun        # shallow refs are used to ensure the srcrev sticks around when we
1713*4882a593Smuzhiyun        # have no other branches referencing it
1714*4882a593Smuzhiyun        self.assertRefs(['refs/shallow/default'])
1715*4882a593Smuzhiyun
1716*4882a593Smuzhiyun    def test_shallow_default_depth_1(self):
1717*4882a593Smuzhiyun        # Create initial git repo
1718*4882a593Smuzhiyun        self.add_empty_file('a')
1719*4882a593Smuzhiyun        self.add_empty_file('b')
1720*4882a593Smuzhiyun        self.assertRevCount(2, cwd=self.srcdir)
1721*4882a593Smuzhiyun
1722*4882a593Smuzhiyun        self.fetch_shallow()
1723*4882a593Smuzhiyun        self.assertRevCount(1)
1724*4882a593Smuzhiyun
1725*4882a593Smuzhiyun    def test_shallow_depth_0_disables(self):
1726*4882a593Smuzhiyun        self.add_empty_file('a')
1727*4882a593Smuzhiyun        self.add_empty_file('b')
1728*4882a593Smuzhiyun        self.assertRevCount(2, cwd=self.srcdir)
1729*4882a593Smuzhiyun
1730*4882a593Smuzhiyun        self.d.setVar('BB_GIT_SHALLOW_DEPTH', '0')
1731*4882a593Smuzhiyun        self.fetch_shallow(disabled=True)
1732*4882a593Smuzhiyun        self.assertRevCount(2)
1733*4882a593Smuzhiyun
1734*4882a593Smuzhiyun    def test_shallow_depth_default_override(self):
1735*4882a593Smuzhiyun        self.add_empty_file('a')
1736*4882a593Smuzhiyun        self.add_empty_file('b')
1737*4882a593Smuzhiyun        self.assertRevCount(2, cwd=self.srcdir)
1738*4882a593Smuzhiyun
1739*4882a593Smuzhiyun        self.d.setVar('BB_GIT_SHALLOW_DEPTH', '2')
1740*4882a593Smuzhiyun        self.d.setVar('BB_GIT_SHALLOW_DEPTH_default', '1')
1741*4882a593Smuzhiyun        self.fetch_shallow()
1742*4882a593Smuzhiyun        self.assertRevCount(1)
1743*4882a593Smuzhiyun
1744*4882a593Smuzhiyun    def test_shallow_depth_default_override_disable(self):
1745*4882a593Smuzhiyun        self.add_empty_file('a')
1746*4882a593Smuzhiyun        self.add_empty_file('b')
1747*4882a593Smuzhiyun        self.add_empty_file('c')
1748*4882a593Smuzhiyun        self.assertRevCount(3, cwd=self.srcdir)
1749*4882a593Smuzhiyun
1750*4882a593Smuzhiyun        self.d.setVar('BB_GIT_SHALLOW_DEPTH', '0')
1751*4882a593Smuzhiyun        self.d.setVar('BB_GIT_SHALLOW_DEPTH_default', '2')
1752*4882a593Smuzhiyun        self.fetch_shallow()
1753*4882a593Smuzhiyun        self.assertRevCount(2)
1754*4882a593Smuzhiyun
1755*4882a593Smuzhiyun    def test_current_shallow_out_of_date_clone(self):
1756*4882a593Smuzhiyun        # Create initial git repo
1757*4882a593Smuzhiyun        self.add_empty_file('a')
1758*4882a593Smuzhiyun        self.add_empty_file('b')
1759*4882a593Smuzhiyun        self.add_empty_file('c')
1760*4882a593Smuzhiyun        self.assertRevCount(3, cwd=self.srcdir)
1761*4882a593Smuzhiyun
1762*4882a593Smuzhiyun        # Clone and generate mirror tarball
1763*4882a593Smuzhiyun        fetcher, ud = self.fetch()
1764*4882a593Smuzhiyun
1765*4882a593Smuzhiyun        # Ensure we have a current mirror tarball, but an out of date clone
1766*4882a593Smuzhiyun        self.git('update-ref refs/heads/master refs/heads/master~1', cwd=ud.clonedir)
1767*4882a593Smuzhiyun        self.assertRevCount(2, cwd=ud.clonedir)
1768*4882a593Smuzhiyun
1769*4882a593Smuzhiyun        # Fetch and unpack, from the current tarball, not the out of date clone
1770*4882a593Smuzhiyun        bb.utils.remove(self.gitdir, recurse=True)
1771*4882a593Smuzhiyun        fetcher, ud = self.fetch()
1772*4882a593Smuzhiyun        fetcher.unpack(self.d.getVar('WORKDIR'))
1773*4882a593Smuzhiyun        self.assertRevCount(1)
1774*4882a593Smuzhiyun
1775*4882a593Smuzhiyun    def test_shallow_single_branch_no_merge(self):
1776*4882a593Smuzhiyun        self.add_empty_file('a')
1777*4882a593Smuzhiyun        self.add_empty_file('b')
1778*4882a593Smuzhiyun        self.assertRevCount(2, cwd=self.srcdir)
1779*4882a593Smuzhiyun
1780*4882a593Smuzhiyun        self.fetch_shallow()
1781*4882a593Smuzhiyun        self.assertRevCount(1)
1782*4882a593Smuzhiyun        assert os.path.exists(os.path.join(self.gitdir, 'a'))
1783*4882a593Smuzhiyun        assert os.path.exists(os.path.join(self.gitdir, 'b'))
1784*4882a593Smuzhiyun
1785*4882a593Smuzhiyun    def test_shallow_no_dangling(self):
1786*4882a593Smuzhiyun        self.add_empty_file('a')
1787*4882a593Smuzhiyun        self.add_empty_file('b')
1788*4882a593Smuzhiyun        self.assertRevCount(2, cwd=self.srcdir)
1789*4882a593Smuzhiyun
1790*4882a593Smuzhiyun        self.fetch_shallow()
1791*4882a593Smuzhiyun        self.assertRevCount(1)
1792*4882a593Smuzhiyun        assert not self.git('fsck --dangling')
1793*4882a593Smuzhiyun
1794*4882a593Smuzhiyun    def test_shallow_srcrev_branch_truncation(self):
1795*4882a593Smuzhiyun        self.add_empty_file('a')
1796*4882a593Smuzhiyun        self.add_empty_file('b')
1797*4882a593Smuzhiyun        b_commit = self.git('rev-parse HEAD', cwd=self.srcdir).rstrip()
1798*4882a593Smuzhiyun        self.add_empty_file('c')
1799*4882a593Smuzhiyun        self.assertRevCount(3, cwd=self.srcdir)
1800*4882a593Smuzhiyun
1801*4882a593Smuzhiyun        self.d.setVar('SRCREV', b_commit)
1802*4882a593Smuzhiyun        self.fetch_shallow()
1803*4882a593Smuzhiyun
1804*4882a593Smuzhiyun        # The 'c' commit was removed entirely, and 'a' was removed from history
1805*4882a593Smuzhiyun        self.assertRevCount(1, ['--all'])
1806*4882a593Smuzhiyun        self.assertEqual(self.git('rev-parse HEAD').strip(), b_commit)
1807*4882a593Smuzhiyun        assert os.path.exists(os.path.join(self.gitdir, 'a'))
1808*4882a593Smuzhiyun        assert os.path.exists(os.path.join(self.gitdir, 'b'))
1809*4882a593Smuzhiyun        assert not os.path.exists(os.path.join(self.gitdir, 'c'))
1810*4882a593Smuzhiyun
1811*4882a593Smuzhiyun    def test_shallow_ref_pruning(self):
1812*4882a593Smuzhiyun        self.add_empty_file('a')
1813*4882a593Smuzhiyun        self.add_empty_file('b')
1814*4882a593Smuzhiyun        self.git('branch a_branch', cwd=self.srcdir)
1815*4882a593Smuzhiyun        self.assertRefs(['master', 'a_branch'], cwd=self.srcdir)
1816*4882a593Smuzhiyun        self.assertRevCount(2, cwd=self.srcdir)
1817*4882a593Smuzhiyun
1818*4882a593Smuzhiyun        self.fetch_shallow()
1819*4882a593Smuzhiyun
1820*4882a593Smuzhiyun        self.assertRefs(['master', 'origin/master'])
1821*4882a593Smuzhiyun        self.assertRevCount(1)
1822*4882a593Smuzhiyun
1823*4882a593Smuzhiyun    def test_shallow_submodules(self):
1824*4882a593Smuzhiyun        self.add_empty_file('a')
1825*4882a593Smuzhiyun        self.add_empty_file('b')
1826*4882a593Smuzhiyun
1827*4882a593Smuzhiyun        smdir = os.path.join(self.tempdir, 'gitsubmodule')
1828*4882a593Smuzhiyun        bb.utils.mkdirhier(smdir)
1829*4882a593Smuzhiyun        self.git_init(cwd=smdir)
1830*4882a593Smuzhiyun        # Make this look like it was cloned from a remote...
1831*4882a593Smuzhiyun        self.git('config --add remote.origin.url "%s"' % smdir, cwd=smdir)
1832*4882a593Smuzhiyun        self.git('config --add remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"', cwd=smdir)
1833*4882a593Smuzhiyun        self.add_empty_file('asub', cwd=smdir)
1834*4882a593Smuzhiyun        self.add_empty_file('bsub', cwd=smdir)
1835*4882a593Smuzhiyun
1836*4882a593Smuzhiyun        self.git('submodule init', cwd=self.srcdir)
1837*4882a593Smuzhiyun        self.git('-c protocol.file.allow=always submodule add file://%s' % smdir, cwd=self.srcdir)
1838*4882a593Smuzhiyun        self.git('submodule update', cwd=self.srcdir)
1839*4882a593Smuzhiyun        self.git('commit -m submodule -a', cwd=self.srcdir)
1840*4882a593Smuzhiyun
1841*4882a593Smuzhiyun        uri = 'gitsm://%s;protocol=file;subdir=${S};branch=master' % self.srcdir
1842*4882a593Smuzhiyun        fetcher, ud = self.fetch_shallow(uri)
1843*4882a593Smuzhiyun
1844*4882a593Smuzhiyun        # Verify the main repository is shallow
1845*4882a593Smuzhiyun        self.assertRevCount(1)
1846*4882a593Smuzhiyun
1847*4882a593Smuzhiyun        # Verify the gitsubmodule directory is present
1848*4882a593Smuzhiyun        assert os.listdir(os.path.join(self.gitdir, 'gitsubmodule'))
1849*4882a593Smuzhiyun
1850*4882a593Smuzhiyun        # Verify the submodule is also shallow
1851*4882a593Smuzhiyun        self.assertRevCount(1, cwd=os.path.join(self.gitdir, 'gitsubmodule'))
1852*4882a593Smuzhiyun
1853*4882a593Smuzhiyun    def test_shallow_submodule_mirrors(self):
1854*4882a593Smuzhiyun        self.add_empty_file('a')
1855*4882a593Smuzhiyun        self.add_empty_file('b')
1856*4882a593Smuzhiyun
1857*4882a593Smuzhiyun        smdir = os.path.join(self.tempdir, 'gitsubmodule')
1858*4882a593Smuzhiyun        bb.utils.mkdirhier(smdir)
1859*4882a593Smuzhiyun        self.git_init(cwd=smdir)
1860*4882a593Smuzhiyun        # Make this look like it was cloned from a remote...
1861*4882a593Smuzhiyun        self.git('config --add remote.origin.url "%s"' % smdir, cwd=smdir)
1862*4882a593Smuzhiyun        self.git('config --add remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"', cwd=smdir)
1863*4882a593Smuzhiyun        self.add_empty_file('asub', cwd=smdir)
1864*4882a593Smuzhiyun        self.add_empty_file('bsub', cwd=smdir)
1865*4882a593Smuzhiyun
1866*4882a593Smuzhiyun        self.git('submodule init', cwd=self.srcdir)
1867*4882a593Smuzhiyun        self.git('-c protocol.file.allow=always submodule add file://%s' % smdir, cwd=self.srcdir)
1868*4882a593Smuzhiyun        self.git('submodule update', cwd=self.srcdir)
1869*4882a593Smuzhiyun        self.git('commit -m submodule -a', cwd=self.srcdir)
1870*4882a593Smuzhiyun
1871*4882a593Smuzhiyun        uri = 'gitsm://%s;protocol=file;subdir=${S}' % self.srcdir
1872*4882a593Smuzhiyun
1873*4882a593Smuzhiyun        # Fetch once to generate the shallow tarball
1874*4882a593Smuzhiyun        fetcher, ud = self.fetch(uri)
1875*4882a593Smuzhiyun
1876*4882a593Smuzhiyun        # Set up the mirror
1877*4882a593Smuzhiyun        mirrordir = os.path.join(self.tempdir, 'mirror')
1878*4882a593Smuzhiyun        bb.utils.rename(self.dldir, mirrordir)
1879*4882a593Smuzhiyun        self.d.setVar('PREMIRRORS', 'gitsm://.*/.* file://%s/' % mirrordir)
1880*4882a593Smuzhiyun
1881*4882a593Smuzhiyun        # Fetch from the mirror
1882*4882a593Smuzhiyun        bb.utils.remove(self.dldir, recurse=True)
1883*4882a593Smuzhiyun        bb.utils.remove(self.gitdir, recurse=True)
1884*4882a593Smuzhiyun        self.fetch_and_unpack(uri)
1885*4882a593Smuzhiyun
1886*4882a593Smuzhiyun        # Verify the main repository is shallow
1887*4882a593Smuzhiyun        self.assertRevCount(1)
1888*4882a593Smuzhiyun
1889*4882a593Smuzhiyun        # Verify the gitsubmodule directory is present
1890*4882a593Smuzhiyun        assert os.listdir(os.path.join(self.gitdir, 'gitsubmodule'))
1891*4882a593Smuzhiyun
1892*4882a593Smuzhiyun        # Verify the submodule is also shallow
1893*4882a593Smuzhiyun        self.assertRevCount(1, cwd=os.path.join(self.gitdir, 'gitsubmodule'))
1894*4882a593Smuzhiyun
1895*4882a593Smuzhiyun    if any(os.path.exists(os.path.join(p, 'git-annex')) for p in os.environ.get('PATH').split(':')):
1896*4882a593Smuzhiyun        def test_shallow_annex(self):
1897*4882a593Smuzhiyun            self.add_empty_file('a')
1898*4882a593Smuzhiyun            self.add_empty_file('b')
1899*4882a593Smuzhiyun            self.git('annex init', cwd=self.srcdir)
1900*4882a593Smuzhiyun            open(os.path.join(self.srcdir, 'c'), 'w').close()
1901*4882a593Smuzhiyun            self.git('annex add c', cwd=self.srcdir)
1902*4882a593Smuzhiyun            self.git('commit --author "Foo Bar <foo@bar>" -m annex-c -a', cwd=self.srcdir)
1903*4882a593Smuzhiyun            bb.process.run('chmod u+w -R %s' % self.srcdir)
1904*4882a593Smuzhiyun
1905*4882a593Smuzhiyun            uri = 'gitannex://%s;protocol=file;subdir=${S};branch=master' % self.srcdir
1906*4882a593Smuzhiyun            fetcher, ud = self.fetch_shallow(uri)
1907*4882a593Smuzhiyun
1908*4882a593Smuzhiyun            self.assertRevCount(1)
1909*4882a593Smuzhiyun            assert './.git/annex/' in bb.process.run('tar -tzf %s' % os.path.join(self.dldir, ud.mirrortarballs[0]))[0]
1910*4882a593Smuzhiyun            assert os.path.exists(os.path.join(self.gitdir, 'c'))
1911*4882a593Smuzhiyun
1912*4882a593Smuzhiyun    def test_shallow_multi_one_uri(self):
1913*4882a593Smuzhiyun        # Create initial git repo
1914*4882a593Smuzhiyun        self.add_empty_file('a')
1915*4882a593Smuzhiyun        self.add_empty_file('b')
1916*4882a593Smuzhiyun        self.git('checkout -b a_branch', cwd=self.srcdir)
1917*4882a593Smuzhiyun        self.add_empty_file('c')
1918*4882a593Smuzhiyun        self.add_empty_file('d')
1919*4882a593Smuzhiyun        self.git('checkout master', cwd=self.srcdir)
1920*4882a593Smuzhiyun        self.git('tag v0.0 a_branch', cwd=self.srcdir)
1921*4882a593Smuzhiyun        self.add_empty_file('e')
1922*4882a593Smuzhiyun        self.git('merge --no-ff --no-edit a_branch', cwd=self.srcdir)
1923*4882a593Smuzhiyun        self.add_empty_file('f')
1924*4882a593Smuzhiyun        self.assertRevCount(7, cwd=self.srcdir)
1925*4882a593Smuzhiyun
1926*4882a593Smuzhiyun        uri = self.d.getVar('SRC_URI').split()[0]
1927*4882a593Smuzhiyun        uri = '%s;branch=master,a_branch;name=master,a_branch' % uri
1928*4882a593Smuzhiyun
1929*4882a593Smuzhiyun        self.d.setVar('BB_GIT_SHALLOW_DEPTH', '0')
1930*4882a593Smuzhiyun        self.d.setVar('BB_GIT_SHALLOW_REVS', 'v0.0')
1931*4882a593Smuzhiyun        self.d.setVar('SRCREV_master', '${AUTOREV}')
1932*4882a593Smuzhiyun        self.d.setVar('SRCREV_a_branch', '${AUTOREV}')
1933*4882a593Smuzhiyun
1934*4882a593Smuzhiyun        self.fetch_shallow(uri)
1935*4882a593Smuzhiyun
1936*4882a593Smuzhiyun        self.assertRevCount(5)
1937*4882a593Smuzhiyun        self.assertRefs(['master', 'origin/master', 'origin/a_branch'])
1938*4882a593Smuzhiyun
1939*4882a593Smuzhiyun    def test_shallow_multi_one_uri_depths(self):
1940*4882a593Smuzhiyun        # Create initial git repo
1941*4882a593Smuzhiyun        self.add_empty_file('a')
1942*4882a593Smuzhiyun        self.add_empty_file('b')
1943*4882a593Smuzhiyun        self.git('checkout -b a_branch', cwd=self.srcdir)
1944*4882a593Smuzhiyun        self.add_empty_file('c')
1945*4882a593Smuzhiyun        self.add_empty_file('d')
1946*4882a593Smuzhiyun        self.git('checkout master', cwd=self.srcdir)
1947*4882a593Smuzhiyun        self.add_empty_file('e')
1948*4882a593Smuzhiyun        self.git('merge --no-ff --no-edit a_branch', cwd=self.srcdir)
1949*4882a593Smuzhiyun        self.add_empty_file('f')
1950*4882a593Smuzhiyun        self.assertRevCount(7, cwd=self.srcdir)
1951*4882a593Smuzhiyun
1952*4882a593Smuzhiyun        uri = self.d.getVar('SRC_URI').split()[0]
1953*4882a593Smuzhiyun        uri = '%s;branch=master,a_branch;name=master,a_branch' % uri
1954*4882a593Smuzhiyun
1955*4882a593Smuzhiyun        self.d.setVar('BB_GIT_SHALLOW_DEPTH', '0')
1956*4882a593Smuzhiyun        self.d.setVar('BB_GIT_SHALLOW_DEPTH_master', '3')
1957*4882a593Smuzhiyun        self.d.setVar('BB_GIT_SHALLOW_DEPTH_a_branch', '1')
1958*4882a593Smuzhiyun        self.d.setVar('SRCREV_master', '${AUTOREV}')
1959*4882a593Smuzhiyun        self.d.setVar('SRCREV_a_branch', '${AUTOREV}')
1960*4882a593Smuzhiyun
1961*4882a593Smuzhiyun        self.fetch_shallow(uri)
1962*4882a593Smuzhiyun
1963*4882a593Smuzhiyun        self.assertRevCount(4, ['--all'])
1964*4882a593Smuzhiyun        self.assertRefs(['master', 'origin/master', 'origin/a_branch'])
1965*4882a593Smuzhiyun
1966*4882a593Smuzhiyun    def test_shallow_clone_preferred_over_shallow(self):
1967*4882a593Smuzhiyun        self.add_empty_file('a')
1968*4882a593Smuzhiyun        self.add_empty_file('b')
1969*4882a593Smuzhiyun
1970*4882a593Smuzhiyun        # Fetch once to generate the shallow tarball
1971*4882a593Smuzhiyun        fetcher, ud = self.fetch()
1972*4882a593Smuzhiyun        assert os.path.exists(os.path.join(self.dldir, ud.mirrortarballs[0]))
1973*4882a593Smuzhiyun
1974*4882a593Smuzhiyun        # Fetch and unpack with both the clonedir and shallow tarball available
1975*4882a593Smuzhiyun        bb.utils.remove(self.gitdir, recurse=True)
1976*4882a593Smuzhiyun        fetcher, ud = self.fetch_and_unpack()
1977*4882a593Smuzhiyun
1978*4882a593Smuzhiyun        # The unpacked tree should *not* be shallow
1979*4882a593Smuzhiyun        self.assertRevCount(2)
1980*4882a593Smuzhiyun        assert not os.path.exists(os.path.join(self.gitdir, '.git', 'shallow'))
1981*4882a593Smuzhiyun
1982*4882a593Smuzhiyun    def test_shallow_mirrors(self):
1983*4882a593Smuzhiyun        self.add_empty_file('a')
1984*4882a593Smuzhiyun        self.add_empty_file('b')
1985*4882a593Smuzhiyun
1986*4882a593Smuzhiyun        # Fetch once to generate the shallow tarball
1987*4882a593Smuzhiyun        fetcher, ud = self.fetch()
1988*4882a593Smuzhiyun        mirrortarball = ud.mirrortarballs[0]
1989*4882a593Smuzhiyun        assert os.path.exists(os.path.join(self.dldir, mirrortarball))
1990*4882a593Smuzhiyun
1991*4882a593Smuzhiyun        # Set up the mirror
1992*4882a593Smuzhiyun        mirrordir = os.path.join(self.tempdir, 'mirror')
1993*4882a593Smuzhiyun        bb.utils.mkdirhier(mirrordir)
1994*4882a593Smuzhiyun        self.d.setVar('PREMIRRORS', 'git://.*/.* file://%s/' % mirrordir)
1995*4882a593Smuzhiyun
1996*4882a593Smuzhiyun        bb.utils.rename(os.path.join(self.dldir, mirrortarball),
1997*4882a593Smuzhiyun                  os.path.join(mirrordir, mirrortarball))
1998*4882a593Smuzhiyun
1999*4882a593Smuzhiyun        # Fetch from the mirror
2000*4882a593Smuzhiyun        bb.utils.remove(self.dldir, recurse=True)
2001*4882a593Smuzhiyun        bb.utils.remove(self.gitdir, recurse=True)
2002*4882a593Smuzhiyun        self.fetch_and_unpack()
2003*4882a593Smuzhiyun        self.assertRevCount(1)
2004*4882a593Smuzhiyun
2005*4882a593Smuzhiyun    def test_shallow_invalid_depth(self):
2006*4882a593Smuzhiyun        self.add_empty_file('a')
2007*4882a593Smuzhiyun        self.add_empty_file('b')
2008*4882a593Smuzhiyun
2009*4882a593Smuzhiyun        self.d.setVar('BB_GIT_SHALLOW_DEPTH', '-12')
2010*4882a593Smuzhiyun        with self.assertRaises(bb.fetch2.FetchError):
2011*4882a593Smuzhiyun            self.fetch()
2012*4882a593Smuzhiyun
2013*4882a593Smuzhiyun    def test_shallow_invalid_depth_default(self):
2014*4882a593Smuzhiyun        self.add_empty_file('a')
2015*4882a593Smuzhiyun        self.add_empty_file('b')
2016*4882a593Smuzhiyun
2017*4882a593Smuzhiyun        self.d.setVar('BB_GIT_SHALLOW_DEPTH_default', '-12')
2018*4882a593Smuzhiyun        with self.assertRaises(bb.fetch2.FetchError):
2019*4882a593Smuzhiyun            self.fetch()
2020*4882a593Smuzhiyun
2021*4882a593Smuzhiyun    def test_shallow_extra_refs(self):
2022*4882a593Smuzhiyun        self.add_empty_file('a')
2023*4882a593Smuzhiyun        self.add_empty_file('b')
2024*4882a593Smuzhiyun        self.git('branch a_branch', cwd=self.srcdir)
2025*4882a593Smuzhiyun        self.assertRefs(['master', 'a_branch'], cwd=self.srcdir)
2026*4882a593Smuzhiyun        self.assertRevCount(2, cwd=self.srcdir)
2027*4882a593Smuzhiyun
2028*4882a593Smuzhiyun        self.d.setVar('BB_GIT_SHALLOW_EXTRA_REFS', 'refs/heads/a_branch')
2029*4882a593Smuzhiyun        self.fetch_shallow()
2030*4882a593Smuzhiyun
2031*4882a593Smuzhiyun        self.assertRefs(['master', 'origin/master', 'origin/a_branch'])
2032*4882a593Smuzhiyun        self.assertRevCount(1)
2033*4882a593Smuzhiyun
2034*4882a593Smuzhiyun    def test_shallow_extra_refs_wildcard(self):
2035*4882a593Smuzhiyun        self.add_empty_file('a')
2036*4882a593Smuzhiyun        self.add_empty_file('b')
2037*4882a593Smuzhiyun        self.git('branch a_branch', cwd=self.srcdir)
2038*4882a593Smuzhiyun        self.git('tag v1.0', cwd=self.srcdir)
2039*4882a593Smuzhiyun        self.assertRefs(['master', 'a_branch', 'v1.0'], cwd=self.srcdir)
2040*4882a593Smuzhiyun        self.assertRevCount(2, cwd=self.srcdir)
2041*4882a593Smuzhiyun
2042*4882a593Smuzhiyun        self.d.setVar('BB_GIT_SHALLOW_EXTRA_REFS', 'refs/tags/*')
2043*4882a593Smuzhiyun        self.fetch_shallow()
2044*4882a593Smuzhiyun
2045*4882a593Smuzhiyun        self.assertRefs(['master', 'origin/master', 'v1.0'])
2046*4882a593Smuzhiyun        self.assertRevCount(1)
2047*4882a593Smuzhiyun
2048*4882a593Smuzhiyun    def test_shallow_missing_extra_refs(self):
2049*4882a593Smuzhiyun        self.add_empty_file('a')
2050*4882a593Smuzhiyun        self.add_empty_file('b')
2051*4882a593Smuzhiyun
2052*4882a593Smuzhiyun        self.d.setVar('BB_GIT_SHALLOW_EXTRA_REFS', 'refs/heads/foo')
2053*4882a593Smuzhiyun        with self.assertRaises(bb.fetch2.FetchError):
2054*4882a593Smuzhiyun            self.fetch()
2055*4882a593Smuzhiyun
2056*4882a593Smuzhiyun    def test_shallow_missing_extra_refs_wildcard(self):
2057*4882a593Smuzhiyun        self.add_empty_file('a')
2058*4882a593Smuzhiyun        self.add_empty_file('b')
2059*4882a593Smuzhiyun
2060*4882a593Smuzhiyun        self.d.setVar('BB_GIT_SHALLOW_EXTRA_REFS', 'refs/tags/*')
2061*4882a593Smuzhiyun        self.fetch()
2062*4882a593Smuzhiyun
2063*4882a593Smuzhiyun    def test_shallow_remove_revs(self):
2064*4882a593Smuzhiyun        # Create initial git repo
2065*4882a593Smuzhiyun        self.add_empty_file('a')
2066*4882a593Smuzhiyun        self.add_empty_file('b')
2067*4882a593Smuzhiyun        self.git('checkout -b a_branch', cwd=self.srcdir)
2068*4882a593Smuzhiyun        self.add_empty_file('c')
2069*4882a593Smuzhiyun        self.add_empty_file('d')
2070*4882a593Smuzhiyun        self.git('checkout master', cwd=self.srcdir)
2071*4882a593Smuzhiyun        self.git('tag v0.0 a_branch', cwd=self.srcdir)
2072*4882a593Smuzhiyun        self.add_empty_file('e')
2073*4882a593Smuzhiyun        self.git('merge --no-ff --no-edit a_branch', cwd=self.srcdir)
2074*4882a593Smuzhiyun        self.git('branch -d a_branch', cwd=self.srcdir)
2075*4882a593Smuzhiyun        self.add_empty_file('f')
2076*4882a593Smuzhiyun        self.assertRevCount(7, cwd=self.srcdir)
2077*4882a593Smuzhiyun
2078*4882a593Smuzhiyun        self.d.setVar('BB_GIT_SHALLOW_DEPTH', '0')
2079*4882a593Smuzhiyun        self.d.setVar('BB_GIT_SHALLOW_REVS', 'v0.0')
2080*4882a593Smuzhiyun
2081*4882a593Smuzhiyun        self.fetch_shallow()
2082*4882a593Smuzhiyun
2083*4882a593Smuzhiyun        self.assertRevCount(5)
2084*4882a593Smuzhiyun
2085*4882a593Smuzhiyun    def test_shallow_invalid_revs(self):
2086*4882a593Smuzhiyun        self.add_empty_file('a')
2087*4882a593Smuzhiyun        self.add_empty_file('b')
2088*4882a593Smuzhiyun
2089*4882a593Smuzhiyun        self.d.setVar('BB_GIT_SHALLOW_DEPTH', '0')
2090*4882a593Smuzhiyun        self.d.setVar('BB_GIT_SHALLOW_REVS', 'v0.0')
2091*4882a593Smuzhiyun
2092*4882a593Smuzhiyun        with self.assertRaises(bb.fetch2.FetchError):
2093*4882a593Smuzhiyun            self.fetch()
2094*4882a593Smuzhiyun
2095*4882a593Smuzhiyun    def test_shallow_fetch_missing_revs(self):
2096*4882a593Smuzhiyun        self.add_empty_file('a')
2097*4882a593Smuzhiyun        self.add_empty_file('b')
2098*4882a593Smuzhiyun        fetcher, ud = self.fetch(self.d.getVar('SRC_URI'))
2099*4882a593Smuzhiyun        self.git('tag v0.0 master', cwd=self.srcdir)
2100*4882a593Smuzhiyun        self.d.setVar('BB_GIT_SHALLOW_DEPTH', '0')
2101*4882a593Smuzhiyun        self.d.setVar('BB_GIT_SHALLOW_REVS', 'v0.0')
2102*4882a593Smuzhiyun        self.fetch_shallow()
2103*4882a593Smuzhiyun
2104*4882a593Smuzhiyun    def test_shallow_fetch_missing_revs_fails(self):
2105*4882a593Smuzhiyun        self.add_empty_file('a')
2106*4882a593Smuzhiyun        self.add_empty_file('b')
2107*4882a593Smuzhiyun        fetcher, ud = self.fetch(self.d.getVar('SRC_URI'))
2108*4882a593Smuzhiyun        self.d.setVar('BB_GIT_SHALLOW_DEPTH', '0')
2109*4882a593Smuzhiyun        self.d.setVar('BB_GIT_SHALLOW_REVS', 'v0.0')
2110*4882a593Smuzhiyun
2111*4882a593Smuzhiyun        with self.assertRaises(bb.fetch2.FetchError), self.assertLogs("BitBake.Fetcher", level="ERROR") as cm:
2112*4882a593Smuzhiyun            self.fetch_shallow()
2113*4882a593Smuzhiyun        self.assertIn("Unable to find revision v0.0 even from upstream", cm.output[0])
2114*4882a593Smuzhiyun
2115*4882a593Smuzhiyun    @skipIfNoNetwork()
2116*4882a593Smuzhiyun    def test_bitbake(self):
2117*4882a593Smuzhiyun        self.git('remote add --mirror=fetch origin https://github.com/openembedded/bitbake', cwd=self.srcdir)
2118*4882a593Smuzhiyun        self.git('config core.bare true', cwd=self.srcdir)
2119*4882a593Smuzhiyun        self.git('fetch', cwd=self.srcdir)
2120*4882a593Smuzhiyun
2121*4882a593Smuzhiyun        self.d.setVar('BB_GIT_SHALLOW_DEPTH', '0')
2122*4882a593Smuzhiyun        # Note that the 1.10.0 tag is annotated, so this also tests
2123*4882a593Smuzhiyun        # reference of an annotated vs unannotated tag
2124*4882a593Smuzhiyun        self.d.setVar('BB_GIT_SHALLOW_REVS', '1.10.0')
2125*4882a593Smuzhiyun
2126*4882a593Smuzhiyun        self.fetch_shallow()
2127*4882a593Smuzhiyun
2128*4882a593Smuzhiyun        # Confirm that the history of 1.10.0 was removed
2129*4882a593Smuzhiyun        orig_revs = len(self.git('rev-list master', cwd=self.srcdir).splitlines())
2130*4882a593Smuzhiyun        revs = len(self.git('rev-list master').splitlines())
2131*4882a593Smuzhiyun        self.assertNotEqual(orig_revs, revs)
2132*4882a593Smuzhiyun        self.assertRefs(['master', 'origin/master'])
2133*4882a593Smuzhiyun        self.assertRevCount(orig_revs - 1758)
2134*4882a593Smuzhiyun
2135*4882a593Smuzhiyun    def test_that_unpack_throws_an_error_when_the_git_clone_nor_shallow_tarball_exist(self):
2136*4882a593Smuzhiyun        self.add_empty_file('a')
2137*4882a593Smuzhiyun        fetcher, ud = self.fetch()
2138*4882a593Smuzhiyun        bb.utils.remove(self.gitdir, recurse=True)
2139*4882a593Smuzhiyun        bb.utils.remove(self.dldir, recurse=True)
2140*4882a593Smuzhiyun
2141*4882a593Smuzhiyun        with self.assertRaises(bb.fetch2.UnpackError) as context:
2142*4882a593Smuzhiyun            fetcher.unpack(self.d.getVar('WORKDIR'))
2143*4882a593Smuzhiyun
2144*4882a593Smuzhiyun        self.assertIn("No up to date source found", context.exception.msg)
2145*4882a593Smuzhiyun        self.assertIn("clone directory not available or not up to date", context.exception.msg)
2146*4882a593Smuzhiyun
2147*4882a593Smuzhiyun    @skipIfNoNetwork()
2148*4882a593Smuzhiyun    def test_that_unpack_does_work_when_using_git_shallow_tarball_but_tarball_is_not_available(self):
2149*4882a593Smuzhiyun        self.d.setVar('SRCREV', 'e5939ff608b95cdd4d0ab0e1935781ab9a276ac0')
2150*4882a593Smuzhiyun        self.d.setVar('BB_GIT_SHALLOW', '1')
2151*4882a593Smuzhiyun        self.d.setVar('BB_GENERATE_SHALLOW_TARBALLS', '1')
2152*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch(["git://git.yoctoproject.org/fstests;branch=master"], self.d)
2153*4882a593Smuzhiyun        fetcher.download()
2154*4882a593Smuzhiyun
2155*4882a593Smuzhiyun        bb.utils.remove(self.dldir + "/*.tar.gz")
2156*4882a593Smuzhiyun        fetcher.unpack(self.unpackdir)
2157*4882a593Smuzhiyun
2158*4882a593Smuzhiyun        dir = os.listdir(self.unpackdir + "/git/")
2159*4882a593Smuzhiyun        self.assertIn("fstests.doap", dir)
2160*4882a593Smuzhiyun
2161*4882a593Smuzhiyunclass GitLfsTest(FetcherTest):
2162*4882a593Smuzhiyun    def setUp(self):
2163*4882a593Smuzhiyun        FetcherTest.setUp(self)
2164*4882a593Smuzhiyun
2165*4882a593Smuzhiyun        self.gitdir = os.path.join(self.tempdir, 'git')
2166*4882a593Smuzhiyun        self.srcdir = os.path.join(self.tempdir, 'gitsource')
2167*4882a593Smuzhiyun
2168*4882a593Smuzhiyun        self.d.setVar('WORKDIR', self.tempdir)
2169*4882a593Smuzhiyun        self.d.setVar('S', self.gitdir)
2170*4882a593Smuzhiyun        self.d.delVar('PREMIRRORS')
2171*4882a593Smuzhiyun        self.d.delVar('MIRRORS')
2172*4882a593Smuzhiyun
2173*4882a593Smuzhiyun        self.d.setVar('SRCREV', '${AUTOREV}')
2174*4882a593Smuzhiyun        self.d.setVar('AUTOREV', '${@bb.fetch2.get_autorev(d)}')
2175*4882a593Smuzhiyun        self.d.setVar("__BBSEENSRCREV", "1")
2176*4882a593Smuzhiyun
2177*4882a593Smuzhiyun        bb.utils.mkdirhier(self.srcdir)
2178*4882a593Smuzhiyun        self.git_init(cwd=self.srcdir)
2179*4882a593Smuzhiyun        with open(os.path.join(self.srcdir, '.gitattributes'), 'wt') as attrs:
2180*4882a593Smuzhiyun            attrs.write('*.mp3 filter=lfs -text')
2181*4882a593Smuzhiyun        self.git(['add', '.gitattributes'], cwd=self.srcdir)
2182*4882a593Smuzhiyun        self.git(['commit', '-m', "attributes", '.gitattributes'], cwd=self.srcdir)
2183*4882a593Smuzhiyun
2184*4882a593Smuzhiyun    def fetch(self, uri=None, download=True):
2185*4882a593Smuzhiyun        uris = self.d.getVar('SRC_URI').split()
2186*4882a593Smuzhiyun        uri = uris[0]
2187*4882a593Smuzhiyun        d = self.d
2188*4882a593Smuzhiyun
2189*4882a593Smuzhiyun        fetcher = bb.fetch2.Fetch(uris, d)
2190*4882a593Smuzhiyun        if download:
2191*4882a593Smuzhiyun            fetcher.download()
2192*4882a593Smuzhiyun        ud = fetcher.ud[uri]
2193*4882a593Smuzhiyun        return fetcher, ud
2194*4882a593Smuzhiyun
2195*4882a593Smuzhiyun    def test_lfs_enabled(self):
2196*4882a593Smuzhiyun        import shutil
2197*4882a593Smuzhiyun
2198*4882a593Smuzhiyun        uri = 'git://%s;protocol=file;lfs=1;branch=master' % self.srcdir
2199*4882a593Smuzhiyun        self.d.setVar('SRC_URI', uri)
2200*4882a593Smuzhiyun
2201*4882a593Smuzhiyun        # Careful: suppress initial attempt at downloading until
2202*4882a593Smuzhiyun        # we know whether git-lfs is installed.
2203*4882a593Smuzhiyun        fetcher, ud = self.fetch(uri=None, download=False)
2204*4882a593Smuzhiyun        self.assertIsNotNone(ud.method._find_git_lfs)
2205*4882a593Smuzhiyun
2206*4882a593Smuzhiyun        # If git-lfs can be found, the unpack should be successful. Only
2207*4882a593Smuzhiyun        # attempt this with the real live copy of git-lfs installed.
2208*4882a593Smuzhiyun        if ud.method._find_git_lfs(self.d):
2209*4882a593Smuzhiyun            fetcher.download()
2210*4882a593Smuzhiyun            shutil.rmtree(self.gitdir, ignore_errors=True)
2211*4882a593Smuzhiyun            fetcher.unpack(self.d.getVar('WORKDIR'))
2212*4882a593Smuzhiyun
2213*4882a593Smuzhiyun        # If git-lfs cannot be found, the unpack should throw an error
2214*4882a593Smuzhiyun        with self.assertRaises(bb.fetch2.FetchError):
2215*4882a593Smuzhiyun            fetcher.download()
2216*4882a593Smuzhiyun            ud.method._find_git_lfs = lambda d: False
2217*4882a593Smuzhiyun            shutil.rmtree(self.gitdir, ignore_errors=True)
2218*4882a593Smuzhiyun            fetcher.unpack(self.d.getVar('WORKDIR'))
2219*4882a593Smuzhiyun
2220*4882a593Smuzhiyun    def test_lfs_disabled(self):
2221*4882a593Smuzhiyun        import shutil
2222*4882a593Smuzhiyun
2223*4882a593Smuzhiyun        uri = 'git://%s;protocol=file;lfs=0;branch=master' % self.srcdir
2224*4882a593Smuzhiyun        self.d.setVar('SRC_URI', uri)
2225*4882a593Smuzhiyun
2226*4882a593Smuzhiyun        # In contrast to test_lfs_enabled(), allow the implicit download
2227*4882a593Smuzhiyun        # done by self.fetch() to occur here. The point of this test case
2228*4882a593Smuzhiyun        # is to verify that the fetcher can survive even if the source
2229*4882a593Smuzhiyun        # repository has Git LFS usage configured.
2230*4882a593Smuzhiyun        fetcher, ud = self.fetch()
2231*4882a593Smuzhiyun        self.assertIsNotNone(ud.method._find_git_lfs)
2232*4882a593Smuzhiyun
2233*4882a593Smuzhiyun        # If git-lfs can be found, the unpack should be successful. A
2234*4882a593Smuzhiyun        # live copy of git-lfs is not required for this case, so
2235*4882a593Smuzhiyun        # unconditionally forge its presence.
2236*4882a593Smuzhiyun        ud.method._find_git_lfs = lambda d: True
2237*4882a593Smuzhiyun        shutil.rmtree(self.gitdir, ignore_errors=True)
2238*4882a593Smuzhiyun        fetcher.unpack(self.d.getVar('WORKDIR'))
2239*4882a593Smuzhiyun
2240*4882a593Smuzhiyun        # If git-lfs cannot be found, the unpack should be successful
2241*4882a593Smuzhiyun        ud.method._find_git_lfs = lambda d: False
2242*4882a593Smuzhiyun        shutil.rmtree(self.gitdir, ignore_errors=True)
2243*4882a593Smuzhiyun        fetcher.unpack(self.d.getVar('WORKDIR'))
2244*4882a593Smuzhiyun
2245*4882a593Smuzhiyunclass GitURLWithSpacesTest(FetcherTest):
2246*4882a593Smuzhiyun    test_git_urls = {
2247*4882a593Smuzhiyun        "git://tfs-example.org:22/tfs/example%20path/example.git;branch=master" : {
2248*4882a593Smuzhiyun            'url': 'git://tfs-example.org:22/tfs/example%20path/example.git;branch=master',
2249*4882a593Smuzhiyun            'gitsrcname': 'tfs-example.org.22.tfs.example_path.example.git',
2250*4882a593Smuzhiyun            'path': '/tfs/example path/example.git'
2251*4882a593Smuzhiyun        },
2252*4882a593Smuzhiyun        "git://tfs-example.org:22/tfs/example%20path/example%20repo.git;branch=master" : {
2253*4882a593Smuzhiyun            'url': 'git://tfs-example.org:22/tfs/example%20path/example%20repo.git;branch=master',
2254*4882a593Smuzhiyun            'gitsrcname': 'tfs-example.org.22.tfs.example_path.example_repo.git',
2255*4882a593Smuzhiyun            'path': '/tfs/example path/example repo.git'
2256*4882a593Smuzhiyun        }
2257*4882a593Smuzhiyun    }
2258*4882a593Smuzhiyun
2259*4882a593Smuzhiyun    def test_urls(self):
2260*4882a593Smuzhiyun
2261*4882a593Smuzhiyun        # Set fake SRCREV to stop git fetcher from trying to contact non-existent git repo
2262*4882a593Smuzhiyun        self.d.setVar('SRCREV', '82ea737a0b42a8b53e11c9cde141e9e9c0bd8c40')
2263*4882a593Smuzhiyun
2264*4882a593Smuzhiyun        for test_git_url, ref in self.test_git_urls.items():
2265*4882a593Smuzhiyun
2266*4882a593Smuzhiyun            fetcher = bb.fetch.Fetch([test_git_url], self.d)
2267*4882a593Smuzhiyun            ud = fetcher.ud[fetcher.urls[0]]
2268*4882a593Smuzhiyun
2269*4882a593Smuzhiyun            self.assertEqual(ud.url, ref['url'])
2270*4882a593Smuzhiyun            self.assertEqual(ud.path, ref['path'])
2271*4882a593Smuzhiyun            self.assertEqual(ud.localfile, os.path.join(self.dldir, "git2", ref['gitsrcname']))
2272*4882a593Smuzhiyun            self.assertEqual(ud.localpath, os.path.join(self.dldir, "git2", ref['gitsrcname']))
2273*4882a593Smuzhiyun            self.assertEqual(ud.lockfile, os.path.join(self.dldir, "git2", ref['gitsrcname'] + '.lock'))
2274*4882a593Smuzhiyun            self.assertEqual(ud.clonedir, os.path.join(self.dldir, "git2", ref['gitsrcname']))
2275*4882a593Smuzhiyun            self.assertEqual(ud.fullmirror, os.path.join(self.dldir, "git2_" + ref['gitsrcname'] + '.tar.gz'))
2276*4882a593Smuzhiyun
2277*4882a593Smuzhiyunclass CrateTest(FetcherTest):
2278*4882a593Smuzhiyun    @skipIfNoNetwork()
2279*4882a593Smuzhiyun    def test_crate_url(self):
2280*4882a593Smuzhiyun
2281*4882a593Smuzhiyun        uri = "crate://crates.io/glob/0.2.11"
2282*4882a593Smuzhiyun        self.d.setVar('SRC_URI', uri)
2283*4882a593Smuzhiyun
2284*4882a593Smuzhiyun        uris = self.d.getVar('SRC_URI').split()
2285*4882a593Smuzhiyun        d = self.d
2286*4882a593Smuzhiyun
2287*4882a593Smuzhiyun        fetcher = bb.fetch2.Fetch(uris, self.d)
2288*4882a593Smuzhiyun        fetcher.download()
2289*4882a593Smuzhiyun        fetcher.unpack(self.tempdir)
2290*4882a593Smuzhiyun        self.assertEqual(sorted(os.listdir(self.tempdir)), ['cargo_home', 'download' , 'unpacked'])
2291*4882a593Smuzhiyun        self.assertEqual(sorted(os.listdir(self.tempdir + "/download")), ['glob-0.2.11.crate', 'glob-0.2.11.crate.done'])
2292*4882a593Smuzhiyun        self.assertTrue(os.path.exists(self.tempdir + "/cargo_home/bitbake/glob-0.2.11/.cargo-checksum.json"))
2293*4882a593Smuzhiyun        self.assertTrue(os.path.exists(self.tempdir + "/cargo_home/bitbake/glob-0.2.11/src/lib.rs"))
2294*4882a593Smuzhiyun
2295*4882a593Smuzhiyun    @skipIfNoNetwork()
2296*4882a593Smuzhiyun    def test_crate_url_multi(self):
2297*4882a593Smuzhiyun
2298*4882a593Smuzhiyun        uri = "crate://crates.io/glob/0.2.11 crate://crates.io/time/0.1.35"
2299*4882a593Smuzhiyun        self.d.setVar('SRC_URI', uri)
2300*4882a593Smuzhiyun
2301*4882a593Smuzhiyun        uris = self.d.getVar('SRC_URI').split()
2302*4882a593Smuzhiyun        d = self.d
2303*4882a593Smuzhiyun
2304*4882a593Smuzhiyun        fetcher = bb.fetch2.Fetch(uris, self.d)
2305*4882a593Smuzhiyun        fetcher.download()
2306*4882a593Smuzhiyun        fetcher.unpack(self.tempdir)
2307*4882a593Smuzhiyun        self.assertEqual(sorted(os.listdir(self.tempdir)), ['cargo_home', 'download' , 'unpacked'])
2308*4882a593Smuzhiyun        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'])
2309*4882a593Smuzhiyun        self.assertTrue(os.path.exists(self.tempdir + "/cargo_home/bitbake/glob-0.2.11/.cargo-checksum.json"))
2310*4882a593Smuzhiyun        self.assertTrue(os.path.exists(self.tempdir + "/cargo_home/bitbake/glob-0.2.11/src/lib.rs"))
2311*4882a593Smuzhiyun        self.assertTrue(os.path.exists(self.tempdir + "/cargo_home/bitbake/time-0.1.35/.cargo-checksum.json"))
2312*4882a593Smuzhiyun        self.assertTrue(os.path.exists(self.tempdir + "/cargo_home/bitbake/time-0.1.35/src/lib.rs"))
2313*4882a593Smuzhiyun
2314*4882a593Smuzhiyunclass NPMTest(FetcherTest):
2315*4882a593Smuzhiyun    def skipIfNoNpm():
2316*4882a593Smuzhiyun        import shutil
2317*4882a593Smuzhiyun        if not shutil.which('npm'):
2318*4882a593Smuzhiyun            return unittest.skip('npm not installed')
2319*4882a593Smuzhiyun        return lambda f: f
2320*4882a593Smuzhiyun
2321*4882a593Smuzhiyun    @skipIfNoNpm()
2322*4882a593Smuzhiyun    @skipIfNoNetwork()
2323*4882a593Smuzhiyun    def test_npm(self):
2324*4882a593Smuzhiyun        url = 'npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=1.0.0'
2325*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch([url], self.d)
2326*4882a593Smuzhiyun        ud = fetcher.ud[fetcher.urls[0]]
2327*4882a593Smuzhiyun        fetcher.download()
2328*4882a593Smuzhiyun        self.assertTrue(os.path.exists(ud.localpath))
2329*4882a593Smuzhiyun        self.assertTrue(os.path.exists(ud.localpath + '.done'))
2330*4882a593Smuzhiyun        self.assertTrue(os.path.exists(ud.resolvefile))
2331*4882a593Smuzhiyun        fetcher.unpack(self.unpackdir)
2332*4882a593Smuzhiyun        unpackdir = os.path.join(self.unpackdir, 'npm')
2333*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(unpackdir, 'package.json')))
2334*4882a593Smuzhiyun
2335*4882a593Smuzhiyun    @skipIfNoNpm()
2336*4882a593Smuzhiyun    @skipIfNoNetwork()
2337*4882a593Smuzhiyun    def test_npm_bad_checksum(self):
2338*4882a593Smuzhiyun        url = 'npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=1.0.0'
2339*4882a593Smuzhiyun        # Fetch once to get a tarball
2340*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch([url], self.d)
2341*4882a593Smuzhiyun        ud = fetcher.ud[fetcher.urls[0]]
2342*4882a593Smuzhiyun        fetcher.download()
2343*4882a593Smuzhiyun        self.assertTrue(os.path.exists(ud.localpath))
2344*4882a593Smuzhiyun        # Modify the tarball
2345*4882a593Smuzhiyun        bad = b'bad checksum'
2346*4882a593Smuzhiyun        with open(ud.localpath, 'wb') as f:
2347*4882a593Smuzhiyun            f.write(bad)
2348*4882a593Smuzhiyun        # Verify that the tarball is fetched again
2349*4882a593Smuzhiyun        fetcher.download()
2350*4882a593Smuzhiyun        badsum = hashlib.sha512(bad).hexdigest()
2351*4882a593Smuzhiyun        self.assertTrue(os.path.exists(ud.localpath + '_bad-checksum_' + badsum))
2352*4882a593Smuzhiyun        self.assertTrue(os.path.exists(ud.localpath))
2353*4882a593Smuzhiyun
2354*4882a593Smuzhiyun    @skipIfNoNpm()
2355*4882a593Smuzhiyun    @skipIfNoNetwork()
2356*4882a593Smuzhiyun    def test_npm_premirrors(self):
2357*4882a593Smuzhiyun        url = 'npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=1.0.0'
2358*4882a593Smuzhiyun        # Fetch once to get a tarball
2359*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch([url], self.d)
2360*4882a593Smuzhiyun        ud = fetcher.ud[fetcher.urls[0]]
2361*4882a593Smuzhiyun        fetcher.download()
2362*4882a593Smuzhiyun        self.assertTrue(os.path.exists(ud.localpath))
2363*4882a593Smuzhiyun
2364*4882a593Smuzhiyun        # Setup the mirror by renaming the download directory
2365*4882a593Smuzhiyun        mirrordir = os.path.join(self.tempdir, 'mirror')
2366*4882a593Smuzhiyun        bb.utils.rename(self.dldir, mirrordir)
2367*4882a593Smuzhiyun        os.mkdir(self.dldir)
2368*4882a593Smuzhiyun
2369*4882a593Smuzhiyun        # Configure the premirror to be used
2370*4882a593Smuzhiyun        self.d.setVar('PREMIRRORS', 'https?$://.*/.* file://%s/npm2' % mirrordir)
2371*4882a593Smuzhiyun        self.d.setVar('BB_FETCH_PREMIRRORONLY', '1')
2372*4882a593Smuzhiyun
2373*4882a593Smuzhiyun        # Fetch again
2374*4882a593Smuzhiyun        self.assertFalse(os.path.exists(ud.localpath))
2375*4882a593Smuzhiyun        # The npm fetcher doesn't handle that the .resolved file disappears
2376*4882a593Smuzhiyun        # while the fetcher object exists, which it does when we rename the
2377*4882a593Smuzhiyun        # download directory to "mirror" above. Thus we need a new fetcher to go
2378*4882a593Smuzhiyun        # with the now empty download directory.
2379*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch([url], self.d)
2380*4882a593Smuzhiyun        ud = fetcher.ud[fetcher.urls[0]]
2381*4882a593Smuzhiyun        fetcher.download()
2382*4882a593Smuzhiyun        self.assertTrue(os.path.exists(ud.localpath))
2383*4882a593Smuzhiyun
2384*4882a593Smuzhiyun    @skipIfNoNpm()
2385*4882a593Smuzhiyun    @skipIfNoNetwork()
2386*4882a593Smuzhiyun    def test_npm_premirrors_with_specified_filename(self):
2387*4882a593Smuzhiyun        url = 'npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=1.0.0'
2388*4882a593Smuzhiyun        # Fetch once to get a tarball
2389*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch([url], self.d)
2390*4882a593Smuzhiyun        ud = fetcher.ud[fetcher.urls[0]]
2391*4882a593Smuzhiyun        fetcher.download()
2392*4882a593Smuzhiyun        self.assertTrue(os.path.exists(ud.localpath))
2393*4882a593Smuzhiyun        # Setup the mirror
2394*4882a593Smuzhiyun        mirrordir = os.path.join(self.tempdir, 'mirror')
2395*4882a593Smuzhiyun        bb.utils.mkdirhier(mirrordir)
2396*4882a593Smuzhiyun        mirrorfilename = os.path.join(mirrordir, os.path.basename(ud.localpath))
2397*4882a593Smuzhiyun        os.replace(ud.localpath, mirrorfilename)
2398*4882a593Smuzhiyun        self.d.setVar('PREMIRRORS', 'https?$://.*/.* file://%s' % mirrorfilename)
2399*4882a593Smuzhiyun        self.d.setVar('BB_FETCH_PREMIRRORONLY', '1')
2400*4882a593Smuzhiyun        # Fetch again
2401*4882a593Smuzhiyun        self.assertFalse(os.path.exists(ud.localpath))
2402*4882a593Smuzhiyun        fetcher.download()
2403*4882a593Smuzhiyun        self.assertTrue(os.path.exists(ud.localpath))
2404*4882a593Smuzhiyun
2405*4882a593Smuzhiyun    @skipIfNoNpm()
2406*4882a593Smuzhiyun    @skipIfNoNetwork()
2407*4882a593Smuzhiyun    def test_npm_mirrors(self):
2408*4882a593Smuzhiyun        # Fetch once to get a tarball
2409*4882a593Smuzhiyun        url = 'npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=1.0.0'
2410*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch([url], self.d)
2411*4882a593Smuzhiyun        ud = fetcher.ud[fetcher.urls[0]]
2412*4882a593Smuzhiyun        fetcher.download()
2413*4882a593Smuzhiyun        self.assertTrue(os.path.exists(ud.localpath))
2414*4882a593Smuzhiyun        # Setup the mirror
2415*4882a593Smuzhiyun        mirrordir = os.path.join(self.tempdir, 'mirror')
2416*4882a593Smuzhiyun        bb.utils.mkdirhier(mirrordir)
2417*4882a593Smuzhiyun        os.replace(ud.localpath, os.path.join(mirrordir, os.path.basename(ud.localpath)))
2418*4882a593Smuzhiyun        self.d.setVar('MIRRORS', 'https?$://.*/.* file://%s/' % mirrordir)
2419*4882a593Smuzhiyun        # Update the resolved url to an invalid url
2420*4882a593Smuzhiyun        with open(ud.resolvefile, 'r') as f:
2421*4882a593Smuzhiyun            url = f.read()
2422*4882a593Smuzhiyun        uri = URI(url)
2423*4882a593Smuzhiyun        uri.path = '/invalid'
2424*4882a593Smuzhiyun        with open(ud.resolvefile, 'w') as f:
2425*4882a593Smuzhiyun            f.write(str(uri))
2426*4882a593Smuzhiyun        # Fetch again
2427*4882a593Smuzhiyun        self.assertFalse(os.path.exists(ud.localpath))
2428*4882a593Smuzhiyun        fetcher.download()
2429*4882a593Smuzhiyun        self.assertTrue(os.path.exists(ud.localpath))
2430*4882a593Smuzhiyun
2431*4882a593Smuzhiyun    @skipIfNoNpm()
2432*4882a593Smuzhiyun    @skipIfNoNetwork()
2433*4882a593Smuzhiyun    def test_npm_destsuffix_downloadfilename(self):
2434*4882a593Smuzhiyun        url = 'npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=1.0.0;destsuffix=foo/bar;downloadfilename=foo-bar.tgz'
2435*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch([url], self.d)
2436*4882a593Smuzhiyun        fetcher.download()
2437*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(self.dldir, 'npm2', 'foo-bar.tgz')))
2438*4882a593Smuzhiyun        fetcher.unpack(self.unpackdir)
2439*4882a593Smuzhiyun        unpackdir = os.path.join(self.unpackdir, 'foo', 'bar')
2440*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(unpackdir, 'package.json')))
2441*4882a593Smuzhiyun
2442*4882a593Smuzhiyun    def test_npm_no_network_no_tarball(self):
2443*4882a593Smuzhiyun        url = 'npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=1.0.0'
2444*4882a593Smuzhiyun        self.d.setVar('BB_NO_NETWORK', '1')
2445*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch([url], self.d)
2446*4882a593Smuzhiyun        with self.assertRaises(bb.fetch2.NetworkAccess):
2447*4882a593Smuzhiyun            fetcher.download()
2448*4882a593Smuzhiyun
2449*4882a593Smuzhiyun    @skipIfNoNpm()
2450*4882a593Smuzhiyun    @skipIfNoNetwork()
2451*4882a593Smuzhiyun    def test_npm_no_network_with_tarball(self):
2452*4882a593Smuzhiyun        url = 'npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=1.0.0'
2453*4882a593Smuzhiyun        # Fetch once to get a tarball
2454*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch([url], self.d)
2455*4882a593Smuzhiyun        fetcher.download()
2456*4882a593Smuzhiyun        # Disable network access
2457*4882a593Smuzhiyun        self.d.setVar('BB_NO_NETWORK', '1')
2458*4882a593Smuzhiyun        # Fetch again
2459*4882a593Smuzhiyun        fetcher.download()
2460*4882a593Smuzhiyun        fetcher.unpack(self.unpackdir)
2461*4882a593Smuzhiyun        unpackdir = os.path.join(self.unpackdir, 'npm')
2462*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(unpackdir, 'package.json')))
2463*4882a593Smuzhiyun
2464*4882a593Smuzhiyun    @skipIfNoNpm()
2465*4882a593Smuzhiyun    @skipIfNoNetwork()
2466*4882a593Smuzhiyun    def test_npm_registry_alternate(self):
2467*4882a593Smuzhiyun        url = 'npm://skimdb.npmjs.com;package=@savoirfairelinux/node-server-example;version=1.0.0'
2468*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch([url], self.d)
2469*4882a593Smuzhiyun        fetcher.download()
2470*4882a593Smuzhiyun        fetcher.unpack(self.unpackdir)
2471*4882a593Smuzhiyun        unpackdir = os.path.join(self.unpackdir, 'npm')
2472*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(unpackdir, 'package.json')))
2473*4882a593Smuzhiyun
2474*4882a593Smuzhiyun    @skipIfNoNpm()
2475*4882a593Smuzhiyun    @skipIfNoNetwork()
2476*4882a593Smuzhiyun    def test_npm_version_latest(self):
2477*4882a593Smuzhiyun        url = 'npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=latest'
2478*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch([url], self.d)
2479*4882a593Smuzhiyun        fetcher.download()
2480*4882a593Smuzhiyun        fetcher.unpack(self.unpackdir)
2481*4882a593Smuzhiyun        unpackdir = os.path.join(self.unpackdir, 'npm')
2482*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(unpackdir, 'package.json')))
2483*4882a593Smuzhiyun
2484*4882a593Smuzhiyun    @skipIfNoNpm()
2485*4882a593Smuzhiyun    @skipIfNoNetwork()
2486*4882a593Smuzhiyun    def test_npm_registry_invalid(self):
2487*4882a593Smuzhiyun        url = 'npm://registry.invalid.org;package=@savoirfairelinux/node-server-example;version=1.0.0'
2488*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch([url], self.d)
2489*4882a593Smuzhiyun        with self.assertRaises(bb.fetch2.FetchError):
2490*4882a593Smuzhiyun            fetcher.download()
2491*4882a593Smuzhiyun
2492*4882a593Smuzhiyun    @skipIfNoNpm()
2493*4882a593Smuzhiyun    @skipIfNoNetwork()
2494*4882a593Smuzhiyun    def test_npm_package_invalid(self):
2495*4882a593Smuzhiyun        url = 'npm://registry.npmjs.org;package=@savoirfairelinux/invalid;version=1.0.0'
2496*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch([url], self.d)
2497*4882a593Smuzhiyun        with self.assertRaises(bb.fetch2.FetchError):
2498*4882a593Smuzhiyun            fetcher.download()
2499*4882a593Smuzhiyun
2500*4882a593Smuzhiyun    @skipIfNoNpm()
2501*4882a593Smuzhiyun    @skipIfNoNetwork()
2502*4882a593Smuzhiyun    def test_npm_version_invalid(self):
2503*4882a593Smuzhiyun        url = 'npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=invalid'
2504*4882a593Smuzhiyun        with self.assertRaises(bb.fetch2.ParameterError):
2505*4882a593Smuzhiyun            fetcher = bb.fetch.Fetch([url], self.d)
2506*4882a593Smuzhiyun
2507*4882a593Smuzhiyun    @skipIfNoNpm()
2508*4882a593Smuzhiyun    @skipIfNoNetwork()
2509*4882a593Smuzhiyun    def test_npm_registry_none(self):
2510*4882a593Smuzhiyun        url = 'npm://;package=@savoirfairelinux/node-server-example;version=1.0.0'
2511*4882a593Smuzhiyun        with self.assertRaises(bb.fetch2.MalformedUrl):
2512*4882a593Smuzhiyun            fetcher = bb.fetch.Fetch([url], self.d)
2513*4882a593Smuzhiyun
2514*4882a593Smuzhiyun    @skipIfNoNpm()
2515*4882a593Smuzhiyun    @skipIfNoNetwork()
2516*4882a593Smuzhiyun    def test_npm_package_none(self):
2517*4882a593Smuzhiyun        url = 'npm://registry.npmjs.org;version=1.0.0'
2518*4882a593Smuzhiyun        with self.assertRaises(bb.fetch2.MissingParameterError):
2519*4882a593Smuzhiyun            fetcher = bb.fetch.Fetch([url], self.d)
2520*4882a593Smuzhiyun
2521*4882a593Smuzhiyun    @skipIfNoNpm()
2522*4882a593Smuzhiyun    @skipIfNoNetwork()
2523*4882a593Smuzhiyun    def test_npm_version_none(self):
2524*4882a593Smuzhiyun        url = 'npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example'
2525*4882a593Smuzhiyun        with self.assertRaises(bb.fetch2.MissingParameterError):
2526*4882a593Smuzhiyun            fetcher = bb.fetch.Fetch([url], self.d)
2527*4882a593Smuzhiyun
2528*4882a593Smuzhiyun    def create_shrinkwrap_file(self, data):
2529*4882a593Smuzhiyun        import json
2530*4882a593Smuzhiyun        datadir = os.path.join(self.tempdir, 'data')
2531*4882a593Smuzhiyun        swfile = os.path.join(datadir, 'npm-shrinkwrap.json')
2532*4882a593Smuzhiyun        bb.utils.mkdirhier(datadir)
2533*4882a593Smuzhiyun        with open(swfile, 'w') as f:
2534*4882a593Smuzhiyun            json.dump(data, f)
2535*4882a593Smuzhiyun        # Also configure the S directory
2536*4882a593Smuzhiyun        self.sdir = os.path.join(self.unpackdir, 'S')
2537*4882a593Smuzhiyun        self.d.setVar('S', self.sdir)
2538*4882a593Smuzhiyun        return swfile
2539*4882a593Smuzhiyun
2540*4882a593Smuzhiyun    @skipIfNoNpm()
2541*4882a593Smuzhiyun    @skipIfNoNetwork()
2542*4882a593Smuzhiyun    def test_npmsw(self):
2543*4882a593Smuzhiyun        swfile = self.create_shrinkwrap_file({
2544*4882a593Smuzhiyun            'dependencies': {
2545*4882a593Smuzhiyun                'array-flatten': {
2546*4882a593Smuzhiyun                    'version': '1.1.1',
2547*4882a593Smuzhiyun                    'resolved': 'https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz',
2548*4882a593Smuzhiyun                    'integrity': 'sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=',
2549*4882a593Smuzhiyun                    'dependencies': {
2550*4882a593Smuzhiyun                        'content-type': {
2551*4882a593Smuzhiyun                            'version': 'https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz',
2552*4882a593Smuzhiyun                            'integrity': 'sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==',
2553*4882a593Smuzhiyun                            'dependencies': {
2554*4882a593Smuzhiyun                                'cookie': {
2555*4882a593Smuzhiyun                                    'version': 'git+https://github.com/jshttp/cookie.git#aec1177c7da67e3b3273df96cf476824dbc9ae09',
2556*4882a593Smuzhiyun                                    'from': 'git+https://github.com/jshttp/cookie.git'
2557*4882a593Smuzhiyun                                }
2558*4882a593Smuzhiyun                            }
2559*4882a593Smuzhiyun                        }
2560*4882a593Smuzhiyun                    }
2561*4882a593Smuzhiyun                }
2562*4882a593Smuzhiyun            }
2563*4882a593Smuzhiyun        })
2564*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch(['npmsw://' + swfile], self.d)
2565*4882a593Smuzhiyun        fetcher.download()
2566*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(self.dldir, 'npm2', 'array-flatten-1.1.1.tgz')))
2567*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(self.dldir, 'npm2', 'content-type-1.0.4.tgz')))
2568*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(self.dldir, 'git2', 'github.com.jshttp.cookie.git')))
2569*4882a593Smuzhiyun        fetcher.unpack(self.unpackdir)
2570*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(self.sdir, 'npm-shrinkwrap.json')))
2571*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(self.sdir, 'node_modules', 'array-flatten', 'package.json')))
2572*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(self.sdir, 'node_modules', 'array-flatten', 'node_modules', 'content-type', 'package.json')))
2573*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(self.sdir, 'node_modules', 'array-flatten', 'node_modules', 'content-type', 'node_modules', 'cookie', 'package.json')))
2574*4882a593Smuzhiyun
2575*4882a593Smuzhiyun    @skipIfNoNpm()
2576*4882a593Smuzhiyun    @skipIfNoNetwork()
2577*4882a593Smuzhiyun    def test_npmsw_dev(self):
2578*4882a593Smuzhiyun        swfile = self.create_shrinkwrap_file({
2579*4882a593Smuzhiyun            'dependencies': {
2580*4882a593Smuzhiyun                'array-flatten': {
2581*4882a593Smuzhiyun                    'version': '1.1.1',
2582*4882a593Smuzhiyun                    'resolved': 'https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz',
2583*4882a593Smuzhiyun                    'integrity': 'sha1-ml9pkFGx5wczKPKgCJaLZOopVdI='
2584*4882a593Smuzhiyun                },
2585*4882a593Smuzhiyun                'content-type': {
2586*4882a593Smuzhiyun                    'version': '1.0.4',
2587*4882a593Smuzhiyun                    'resolved': 'https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz',
2588*4882a593Smuzhiyun                    'integrity': 'sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==',
2589*4882a593Smuzhiyun                    'dev': True
2590*4882a593Smuzhiyun                }
2591*4882a593Smuzhiyun            }
2592*4882a593Smuzhiyun        })
2593*4882a593Smuzhiyun        # Fetch with dev disabled
2594*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch(['npmsw://' + swfile], self.d)
2595*4882a593Smuzhiyun        fetcher.download()
2596*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(self.dldir, 'npm2', 'array-flatten-1.1.1.tgz')))
2597*4882a593Smuzhiyun        self.assertFalse(os.path.exists(os.path.join(self.dldir, 'npm2', 'content-type-1.0.4.tgz')))
2598*4882a593Smuzhiyun        # Fetch with dev enabled
2599*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch(['npmsw://' + swfile + ';dev=1'], self.d)
2600*4882a593Smuzhiyun        fetcher.download()
2601*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(self.dldir, 'npm2', 'array-flatten-1.1.1.tgz')))
2602*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(self.dldir, 'npm2', 'content-type-1.0.4.tgz')))
2603*4882a593Smuzhiyun
2604*4882a593Smuzhiyun    @skipIfNoNpm()
2605*4882a593Smuzhiyun    @skipIfNoNetwork()
2606*4882a593Smuzhiyun    def test_npmsw_destsuffix(self):
2607*4882a593Smuzhiyun        swfile = self.create_shrinkwrap_file({
2608*4882a593Smuzhiyun            'dependencies': {
2609*4882a593Smuzhiyun                'array-flatten': {
2610*4882a593Smuzhiyun                    'version': '1.1.1',
2611*4882a593Smuzhiyun                    'resolved': 'https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz',
2612*4882a593Smuzhiyun                    'integrity': 'sha1-ml9pkFGx5wczKPKgCJaLZOopVdI='
2613*4882a593Smuzhiyun                }
2614*4882a593Smuzhiyun            }
2615*4882a593Smuzhiyun        })
2616*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch(['npmsw://' + swfile + ';destsuffix=foo/bar'], self.d)
2617*4882a593Smuzhiyun        fetcher.download()
2618*4882a593Smuzhiyun        fetcher.unpack(self.unpackdir)
2619*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'foo', 'bar', 'node_modules', 'array-flatten', 'package.json')))
2620*4882a593Smuzhiyun
2621*4882a593Smuzhiyun    def test_npmsw_no_network_no_tarball(self):
2622*4882a593Smuzhiyun        swfile = self.create_shrinkwrap_file({
2623*4882a593Smuzhiyun            'dependencies': {
2624*4882a593Smuzhiyun                'array-flatten': {
2625*4882a593Smuzhiyun                    'version': '1.1.1',
2626*4882a593Smuzhiyun                    'resolved': 'https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz',
2627*4882a593Smuzhiyun                    'integrity': 'sha1-ml9pkFGx5wczKPKgCJaLZOopVdI='
2628*4882a593Smuzhiyun                }
2629*4882a593Smuzhiyun            }
2630*4882a593Smuzhiyun        })
2631*4882a593Smuzhiyun        self.d.setVar('BB_NO_NETWORK', '1')
2632*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch(['npmsw://' + swfile], self.d)
2633*4882a593Smuzhiyun        with self.assertRaises(bb.fetch2.NetworkAccess):
2634*4882a593Smuzhiyun            fetcher.download()
2635*4882a593Smuzhiyun
2636*4882a593Smuzhiyun    @skipIfNoNpm()
2637*4882a593Smuzhiyun    @skipIfNoNetwork()
2638*4882a593Smuzhiyun    def test_npmsw_no_network_with_tarball(self):
2639*4882a593Smuzhiyun        # Fetch once to get a tarball
2640*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch(['npm://registry.npmjs.org;package=array-flatten;version=1.1.1'], self.d)
2641*4882a593Smuzhiyun        fetcher.download()
2642*4882a593Smuzhiyun        # Disable network access
2643*4882a593Smuzhiyun        self.d.setVar('BB_NO_NETWORK', '1')
2644*4882a593Smuzhiyun        # Fetch again
2645*4882a593Smuzhiyun        swfile = self.create_shrinkwrap_file({
2646*4882a593Smuzhiyun            'dependencies': {
2647*4882a593Smuzhiyun                'array-flatten': {
2648*4882a593Smuzhiyun                    'version': '1.1.1',
2649*4882a593Smuzhiyun                    'resolved': 'https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz',
2650*4882a593Smuzhiyun                    'integrity': 'sha1-ml9pkFGx5wczKPKgCJaLZOopVdI='
2651*4882a593Smuzhiyun                }
2652*4882a593Smuzhiyun            }
2653*4882a593Smuzhiyun        })
2654*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch(['npmsw://' + swfile], self.d)
2655*4882a593Smuzhiyun        fetcher.download()
2656*4882a593Smuzhiyun        fetcher.unpack(self.unpackdir)
2657*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(self.sdir, 'node_modules', 'array-flatten', 'package.json')))
2658*4882a593Smuzhiyun
2659*4882a593Smuzhiyun    @skipIfNoNpm()
2660*4882a593Smuzhiyun    @skipIfNoNetwork()
2661*4882a593Smuzhiyun    def test_npmsw_npm_reusability(self):
2662*4882a593Smuzhiyun        # Fetch once with npmsw
2663*4882a593Smuzhiyun        swfile = self.create_shrinkwrap_file({
2664*4882a593Smuzhiyun            'dependencies': {
2665*4882a593Smuzhiyun                'array-flatten': {
2666*4882a593Smuzhiyun                    'version': '1.1.1',
2667*4882a593Smuzhiyun                    'resolved': 'https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz',
2668*4882a593Smuzhiyun                    'integrity': 'sha1-ml9pkFGx5wczKPKgCJaLZOopVdI='
2669*4882a593Smuzhiyun                }
2670*4882a593Smuzhiyun            }
2671*4882a593Smuzhiyun        })
2672*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch(['npmsw://' + swfile], self.d)
2673*4882a593Smuzhiyun        fetcher.download()
2674*4882a593Smuzhiyun        # Disable network access
2675*4882a593Smuzhiyun        self.d.setVar('BB_NO_NETWORK', '1')
2676*4882a593Smuzhiyun        # Fetch again with npm
2677*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch(['npm://registry.npmjs.org;package=array-flatten;version=1.1.1'], self.d)
2678*4882a593Smuzhiyun        fetcher.download()
2679*4882a593Smuzhiyun        fetcher.unpack(self.unpackdir)
2680*4882a593Smuzhiyun        self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'npm', 'package.json')))
2681*4882a593Smuzhiyun
2682*4882a593Smuzhiyun    @skipIfNoNpm()
2683*4882a593Smuzhiyun    @skipIfNoNetwork()
2684*4882a593Smuzhiyun    def test_npmsw_bad_checksum(self):
2685*4882a593Smuzhiyun        # Try to fetch with bad checksum
2686*4882a593Smuzhiyun        swfile = self.create_shrinkwrap_file({
2687*4882a593Smuzhiyun            'dependencies': {
2688*4882a593Smuzhiyun                'array-flatten': {
2689*4882a593Smuzhiyun                    'version': '1.1.1',
2690*4882a593Smuzhiyun                    'resolved': 'https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz',
2691*4882a593Smuzhiyun                    'integrity': 'sha1-gfNEp2hqgLTFKT6P3AsBYMgsBqg='
2692*4882a593Smuzhiyun                }
2693*4882a593Smuzhiyun            }
2694*4882a593Smuzhiyun        })
2695*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch(['npmsw://' + swfile], self.d)
2696*4882a593Smuzhiyun        with self.assertRaises(bb.fetch2.FetchError):
2697*4882a593Smuzhiyun            fetcher.download()
2698*4882a593Smuzhiyun        # Fetch correctly to get a tarball
2699*4882a593Smuzhiyun        swfile = self.create_shrinkwrap_file({
2700*4882a593Smuzhiyun            'dependencies': {
2701*4882a593Smuzhiyun                'array-flatten': {
2702*4882a593Smuzhiyun                    'version': '1.1.1',
2703*4882a593Smuzhiyun                    'resolved': 'https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz',
2704*4882a593Smuzhiyun                    'integrity': 'sha1-ml9pkFGx5wczKPKgCJaLZOopVdI='
2705*4882a593Smuzhiyun                }
2706*4882a593Smuzhiyun            }
2707*4882a593Smuzhiyun        })
2708*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch(['npmsw://' + swfile], self.d)
2709*4882a593Smuzhiyun        fetcher.download()
2710*4882a593Smuzhiyun        localpath = os.path.join(self.dldir, 'npm2', 'array-flatten-1.1.1.tgz')
2711*4882a593Smuzhiyun        self.assertTrue(os.path.exists(localpath))
2712*4882a593Smuzhiyun        # Modify the tarball
2713*4882a593Smuzhiyun        bad = b'bad checksum'
2714*4882a593Smuzhiyun        with open(localpath, 'wb') as f:
2715*4882a593Smuzhiyun            f.write(bad)
2716*4882a593Smuzhiyun        # Verify that the tarball is fetched again
2717*4882a593Smuzhiyun        fetcher.download()
2718*4882a593Smuzhiyun        badsum = hashlib.sha1(bad).hexdigest()
2719*4882a593Smuzhiyun        self.assertTrue(os.path.exists(localpath + '_bad-checksum_' + badsum))
2720*4882a593Smuzhiyun        self.assertTrue(os.path.exists(localpath))
2721*4882a593Smuzhiyun
2722*4882a593Smuzhiyun    @skipIfNoNpm()
2723*4882a593Smuzhiyun    @skipIfNoNetwork()
2724*4882a593Smuzhiyun    def test_npmsw_premirrors(self):
2725*4882a593Smuzhiyun        # Fetch once to get a tarball
2726*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch(['npm://registry.npmjs.org;package=array-flatten;version=1.1.1'], self.d)
2727*4882a593Smuzhiyun        ud = fetcher.ud[fetcher.urls[0]]
2728*4882a593Smuzhiyun        fetcher.download()
2729*4882a593Smuzhiyun        self.assertTrue(os.path.exists(ud.localpath))
2730*4882a593Smuzhiyun        # Setup the mirror
2731*4882a593Smuzhiyun        mirrordir = os.path.join(self.tempdir, 'mirror')
2732*4882a593Smuzhiyun        bb.utils.mkdirhier(mirrordir)
2733*4882a593Smuzhiyun        os.replace(ud.localpath, os.path.join(mirrordir, os.path.basename(ud.localpath)))
2734*4882a593Smuzhiyun        self.d.setVar('PREMIRRORS', 'https?$://.*/.* file://%s/' % mirrordir)
2735*4882a593Smuzhiyun        self.d.setVar('BB_FETCH_PREMIRRORONLY', '1')
2736*4882a593Smuzhiyun        # Fetch again
2737*4882a593Smuzhiyun        self.assertFalse(os.path.exists(ud.localpath))
2738*4882a593Smuzhiyun        swfile = self.create_shrinkwrap_file({
2739*4882a593Smuzhiyun            'dependencies': {
2740*4882a593Smuzhiyun                'array-flatten': {
2741*4882a593Smuzhiyun                    'version': '1.1.1',
2742*4882a593Smuzhiyun                    'resolved': 'https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz',
2743*4882a593Smuzhiyun                    'integrity': 'sha1-ml9pkFGx5wczKPKgCJaLZOopVdI='
2744*4882a593Smuzhiyun                }
2745*4882a593Smuzhiyun            }
2746*4882a593Smuzhiyun        })
2747*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch(['npmsw://' + swfile], self.d)
2748*4882a593Smuzhiyun        fetcher.download()
2749*4882a593Smuzhiyun        self.assertTrue(os.path.exists(ud.localpath))
2750*4882a593Smuzhiyun
2751*4882a593Smuzhiyun    @skipIfNoNpm()
2752*4882a593Smuzhiyun    @skipIfNoNetwork()
2753*4882a593Smuzhiyun    def test_npmsw_mirrors(self):
2754*4882a593Smuzhiyun        # Fetch once to get a tarball
2755*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch(['npm://registry.npmjs.org;package=array-flatten;version=1.1.1'], self.d)
2756*4882a593Smuzhiyun        ud = fetcher.ud[fetcher.urls[0]]
2757*4882a593Smuzhiyun        fetcher.download()
2758*4882a593Smuzhiyun        self.assertTrue(os.path.exists(ud.localpath))
2759*4882a593Smuzhiyun        # Setup the mirror
2760*4882a593Smuzhiyun        mirrordir = os.path.join(self.tempdir, 'mirror')
2761*4882a593Smuzhiyun        bb.utils.mkdirhier(mirrordir)
2762*4882a593Smuzhiyun        os.replace(ud.localpath, os.path.join(mirrordir, os.path.basename(ud.localpath)))
2763*4882a593Smuzhiyun        self.d.setVar('MIRRORS', 'https?$://.*/.* file://%s/' % mirrordir)
2764*4882a593Smuzhiyun        # Fetch again with invalid url
2765*4882a593Smuzhiyun        self.assertFalse(os.path.exists(ud.localpath))
2766*4882a593Smuzhiyun        swfile = self.create_shrinkwrap_file({
2767*4882a593Smuzhiyun            'dependencies': {
2768*4882a593Smuzhiyun                'array-flatten': {
2769*4882a593Smuzhiyun                    'version': '1.1.1',
2770*4882a593Smuzhiyun                    'resolved': 'https://invalid',
2771*4882a593Smuzhiyun                    'integrity': 'sha1-ml9pkFGx5wczKPKgCJaLZOopVdI='
2772*4882a593Smuzhiyun                }
2773*4882a593Smuzhiyun            }
2774*4882a593Smuzhiyun        })
2775*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch(['npmsw://' + swfile], self.d)
2776*4882a593Smuzhiyun        fetcher.download()
2777*4882a593Smuzhiyun        self.assertTrue(os.path.exists(ud.localpath))
2778*4882a593Smuzhiyun
2779*4882a593Smuzhiyunclass GitSharedTest(FetcherTest):
2780*4882a593Smuzhiyun    def setUp(self):
2781*4882a593Smuzhiyun        super(GitSharedTest, self).setUp()
2782*4882a593Smuzhiyun        self.recipe_url = "git://git.openembedded.org/bitbake;branch=master"
2783*4882a593Smuzhiyun        self.d.setVar('SRCREV', '82ea737a0b42a8b53e11c9cde141e9e9c0bd8c40')
2784*4882a593Smuzhiyun        self.d.setVar("__BBSEENSRCREV", "1")
2785*4882a593Smuzhiyun
2786*4882a593Smuzhiyun    @skipIfNoNetwork()
2787*4882a593Smuzhiyun    def test_shared_unpack(self):
2788*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch([self.recipe_url], self.d)
2789*4882a593Smuzhiyun
2790*4882a593Smuzhiyun        fetcher.download()
2791*4882a593Smuzhiyun        fetcher.unpack(self.unpackdir)
2792*4882a593Smuzhiyun        alt = os.path.join(self.unpackdir, 'git/.git/objects/info/alternates')
2793*4882a593Smuzhiyun        self.assertTrue(os.path.exists(alt))
2794*4882a593Smuzhiyun
2795*4882a593Smuzhiyun    @skipIfNoNetwork()
2796*4882a593Smuzhiyun    def test_noshared_unpack(self):
2797*4882a593Smuzhiyun        self.d.setVar('BB_GIT_NOSHARED', '1')
2798*4882a593Smuzhiyun        self.unpackdir += '_noshared'
2799*4882a593Smuzhiyun        fetcher = bb.fetch.Fetch([self.recipe_url], self.d)
2800*4882a593Smuzhiyun
2801*4882a593Smuzhiyun        fetcher.download()
2802*4882a593Smuzhiyun        fetcher.unpack(self.unpackdir)
2803*4882a593Smuzhiyun        alt = os.path.join(self.unpackdir, 'git/.git/objects/info/alternates')
2804*4882a593Smuzhiyun        self.assertFalse(os.path.exists(alt))
2805