fetch.py 174 KB

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