__init__.py 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734
  1. # -*- coding: utf-8 -*-
  2. """
  3. (c) 2015-2017 - Copyright Red Hat Inc
  4. Authors:
  5. Pierre-Yves Chibon <pingou@pingoured.fr>
  6. """
  7. __requires__ = ['SQLAlchemy >= 0.7']
  8. import pkg_resources
  9. import logging
  10. import unittest
  11. import shutil
  12. import subprocess
  13. import sys
  14. import tempfile
  15. import os
  16. logging.basicConfig(stream=sys.stderr)
  17. # Always enable performance counting for tests
  18. os.environ['PAGURE_PERFREPO'] = 'true'
  19. from datetime import date
  20. from datetime import datetime
  21. from datetime import timedelta
  22. from functools import wraps
  23. import pygit2
  24. from contextlib import contextmanager
  25. from sqlalchemy import create_engine
  26. from sqlalchemy.orm import sessionmaker
  27. from sqlalchemy.orm import scoped_session
  28. sys.path.insert(0, os.path.join(os.path.dirname(
  29. os.path.abspath(__file__)), '..'))
  30. import pagure
  31. import pagure.lib
  32. import pagure.lib.model
  33. from pagure.lib.repo import PagureRepo
  34. import pagure.perfrepo as perfrepo
  35. DB_PATH = None
  36. FAITOUT_URL = 'http://faitout.fedorainfracloud.org/'
  37. if os.environ.get('FAITOUT_URL'):
  38. FAITOUT_URL = os.environ.get('FAITOUT_URL')
  39. HERE = os.path.join(os.path.dirname(os.path.abspath(__file__)))
  40. LOG = logging.getLogger(__name__)
  41. LOG.setLevel(logging.DEBUG)
  42. PAGLOG = logging.getLogger('pagure')
  43. PAGLOG.setLevel(logging.CRITICAL)
  44. PAGLOG.handlers = []
  45. CONFIG_TEMPLATE = """
  46. GIT_FOLDER = '%(path)s/repos'
  47. DOCS_FOLDER = '%(path)s/docs'
  48. TICKETS_FOLDER = '%(path)s/tickets'
  49. REQUESTS_FOLDER = '%(path)s/requests'
  50. REMOTE_GIT_FOLDER = '%(path)s/remotes'
  51. ATTACHMENTS_FOLDER = '%(path)s/attachments'
  52. DB_URL = '%(dburl)s'
  53. """
  54. LOG.info('BUILD_ID: %s', os.environ.get('BUILD_ID'))
  55. if os.environ.get('BUILD_ID')or os.environ.get('FAITOUT_URL'):
  56. try:
  57. import requests
  58. req = requests.get('%s/new' % FAITOUT_URL)
  59. if req.status_code == 200:
  60. DB_PATH = req.text
  61. LOG.info('Using faitout at: %s', DB_PATH)
  62. else:
  63. LOG.info('faitout returned: %s : %s', req.status_code, req.text)
  64. except Exception as err:
  65. LOG.info('Error while querying faitout: %s', err)
  66. pass
  67. # Remove the log handlers for the tests
  68. pagure.APP.logger.handlers = []
  69. @contextmanager
  70. def user_set(APP, user):
  71. """ Set the provided user as fas_user in the provided application."""
  72. # Hack used to remove the before_request function set by
  73. # flask.ext.fas_openid.FAS which otherwise kills our effort to set a
  74. # flask.g.fas_user.
  75. from flask import appcontext_pushed, g
  76. keep = []
  77. for meth in APP.before_request_funcs[None]:
  78. if 'flask_fas_openid.FAS' in str(meth):
  79. continue
  80. keep.append(meth)
  81. APP.before_request_funcs[None] = keep
  82. def handler(sender, **kwargs):
  83. g.fas_user = user
  84. g.fas_session_id = b'123'
  85. with appcontext_pushed.connected_to(handler, APP):
  86. yield
  87. class Modeltests(unittest.TestCase):
  88. """ Model tests. """
  89. def __init__(self, method_name='runTest'):
  90. """ Constructor. """
  91. unittest.TestCase.__init__(self, method_name)
  92. self.session = None
  93. self.path = None
  94. self.gitrepo = None
  95. self.gitrepos = None
  96. def perfMaxWalks(self, max_walks, max_steps):
  97. """ Check that we have not performed too many walks/steps. """
  98. num_walks = 0
  99. num_steps = 0
  100. for reqstat in perfrepo.REQUESTS:
  101. for walk in reqstat['walks'].values():
  102. num_walks += 1
  103. num_steps += walk['steps']
  104. self.assertLessEqual(num_walks, max_walks,
  105. '%s git repo walks performed, at most %s allowed'
  106. % (num_walks, max_walks))
  107. self.assertLessEqual(num_steps, max_steps,
  108. '%s git repo steps performed, at most %s allowed'
  109. % (num_steps, max_steps))
  110. def perfReset(self):
  111. """ Reset perfrepo stats. """
  112. perfrepo.reset_stats()
  113. perfrepo.REQUESTS = []
  114. def setUp(self): # pylint: disable=invalid-name
  115. """ Set up the environnment, ran before every tests. """
  116. # Clean up test performance info
  117. perfrepo.reset_stats()
  118. perfrepo.REQUESTS = []
  119. pagure.REDIS = None
  120. pagure.lib.REDIS = None
  121. if self.path is not None:
  122. raise Exception('Double init?!')
  123. self.path = tempfile.mkdtemp(prefix='pagure-tests-path-')
  124. LOG.info('Testdir: %s', self.path)
  125. for folder in ['tickets', 'repos', 'forks', 'docs', 'requests',
  126. 'releases', 'remotes', 'attachments']:
  127. os.mkdir(os.path.join(self.path, folder))
  128. if DB_PATH:
  129. self.dbpath = DB_PATH
  130. else:
  131. self.dbpath = 'sqlite:///%s' % os.path.join(self.path,
  132. 'db.sqlite')
  133. # Write a config file
  134. config_values = {'path': self.path,
  135. 'dburl': self.dbpath}
  136. with open(os.path.join(self.path, 'config'), 'w') as f:
  137. f.write(CONFIG_TEMPLATE % config_values)
  138. # Create a broker
  139. broker_url = os.path.join(self.path, 'broker')
  140. self.broker = subprocess.Popen(
  141. ['/usr/bin/redis-server', '--unixsocket', broker_url, '--port',
  142. '0', '--loglevel', 'warning', '--logfile', '/dev/null'],
  143. stdout=None, stderr=None)
  144. self.broker.poll()
  145. if self.broker.returncode is not None:
  146. raise Exception('Broker failed to start')
  147. self.session = pagure.lib.model.create_tables(
  148. self.dbpath, acls=pagure.APP.config.get('ACLS', {}))
  149. reload(pagure.lib.tasks)
  150. celery_broker_url = 'redis+socket://' + broker_url
  151. pagure.lib.tasks.conn.conf.broker_url = celery_broker_url
  152. pagure.lib.tasks.conn.conf.result_backend = celery_broker_url
  153. # Start a worker
  154. # Using cocurrency 2 to test with some concurrency, but not be heavy
  155. # Using eventlet so that worker.terminate kills everything
  156. self.workerlog = open(os.path.join(self.path, 'worker.log'), 'w')
  157. self.worker = subprocess.Popen(
  158. ['/usr/bin/celery', '-A', 'pagure.lib.tasks', 'worker',
  159. '--loglevel=info', '--concurrency=2', '--pool=eventlet',
  160. '--without-gossip', '--without-mingle', '--quiet'],
  161. env={'PAGURE_BROKER_URL': celery_broker_url,
  162. 'PAGURE_CONFIG': os.path.join(self.path, 'config'),
  163. 'PYTHONPATH': '.'},
  164. cwd=os.path.normpath(os.path.join(os.path.dirname(__file__),
  165. '..')),
  166. stdout=self.workerlog,
  167. stderr=self.workerlog)
  168. self.worker.poll()
  169. if self.worker.returncode is not None:
  170. raise Exception('Worker failed to start')
  171. # Create a couple of users
  172. item = pagure.lib.model.User(
  173. user='pingou',
  174. fullname='PY C',
  175. password='foo',
  176. default_email='bar@pingou.com',
  177. )
  178. self.session.add(item)
  179. item = pagure.lib.model.UserEmail(
  180. user_id=1,
  181. email='bar@pingou.com')
  182. self.session.add(item)
  183. item = pagure.lib.model.UserEmail(
  184. user_id=1,
  185. email='foo@pingou.com')
  186. self.session.add(item)
  187. item = pagure.lib.model.User(
  188. user='foo',
  189. fullname='foo bar',
  190. password='foo',
  191. default_email='foo@bar.com',
  192. )
  193. self.session.add(item)
  194. item = pagure.lib.model.UserEmail(
  195. user_id=2,
  196. email='foo@bar.com')
  197. self.session.add(item)
  198. self.session.commit()
  199. # Prevent unit-tests to send email, globally
  200. pagure.APP.config['EMAIL_SEND'] = False
  201. pagure.APP.config['TESTING'] = True
  202. pagure.APP.config['GIT_FOLDER'] = os.path.join(
  203. self.path, 'repos')
  204. pagure.APP.config['TICKETS_FOLDER'] = os.path.join(
  205. self.path, 'tickets')
  206. pagure.APP.config['DOCS_FOLDER'] = os.path.join(
  207. self.path, 'docs')
  208. pagure.APP.config['REQUESTS_FOLDER'] = os.path.join(
  209. self.path, 'requests')
  210. pagure.APP.config['ATTACHMENTS_FOLDER'] = os.path.join(
  211. self.path, 'attachments')
  212. self.app = pagure.APP.test_client()
  213. def tearDown(self): # pylint: disable=invalid-name
  214. """ Remove the test.db database if there is one. """
  215. self.session.close()
  216. # Clear DB
  217. if self.dbpath.startswith('postgres'):
  218. if 'localhost' not in self.dbpath:
  219. db_name = self.dbpath.rsplit('/', 1)[1]
  220. requests.get('%s/clean/%s' % (FAITOUT_URL, db_name))
  221. # Terminate worker and broker
  222. self.worker.terminate()
  223. self.worker.wait()
  224. self.broker.terminate()
  225. self.broker.wait()
  226. # Remove testdir
  227. shutil.rmtree(self.path)
  228. self.path = None
  229. def get_csrf(self, url='/new'):
  230. """Retrieve a CSRF token from given URL."""
  231. output = self.app.get(url)
  232. self.assertEqual(output.status_code, 200)
  233. return output.data.split(
  234. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  235. class FakeGroup(object): # pylint: disable=too-few-public-methods
  236. """ Fake object used to make the FakeUser object closer to the
  237. expectations.
  238. """
  239. def __init__(self, name):
  240. """ Constructor.
  241. :arg name: the name given to the name attribute of this object.
  242. """
  243. self.name = name
  244. self.group_type = 'cla'
  245. class FakeUser(object): # pylint: disable=too-few-public-methods
  246. """ Fake user used to test the fedocallib library. """
  247. def __init__(self, groups=[], username='username', cla_done=True, id=1):
  248. """ Constructor.
  249. :arg groups: list of the groups in which this fake user is
  250. supposed to be.
  251. """
  252. if isinstance(groups, basestring):
  253. groups = [groups]
  254. self.id = id
  255. self.groups = groups
  256. self.user = username
  257. self.username = username
  258. self.name = username
  259. self.email = 'foo@bar.com'
  260. self.approved_memberships = [
  261. FakeGroup('packager'),
  262. FakeGroup('design-team')
  263. ]
  264. self.dic = {}
  265. self.dic['timezone'] = 'Europe/Paris'
  266. self.login_time = datetime.utcnow()
  267. self.cla_done = cla_done
  268. def __getitem__(self, key):
  269. return self.dic[key]
  270. def create_projects(session):
  271. """ Create some projects in the database. """
  272. item = pagure.lib.model.Project(
  273. user_id=1, # pingou
  274. name='test',
  275. description='test project #1',
  276. hook_token='aaabbbccc',
  277. )
  278. item.close_status = ['Invalid', 'Insufficient data', 'Fixed', 'Duplicate']
  279. session.add(item)
  280. item = pagure.lib.model.Project(
  281. user_id=1, # pingou
  282. name='test2',
  283. description='test project #2',
  284. hook_token='aaabbbddd',
  285. )
  286. item.close_status = ['Invalid', 'Insufficient data', 'Fixed', 'Duplicate']
  287. session.add(item)
  288. item = pagure.lib.model.Project(
  289. user_id=1, # pingou
  290. name='test3',
  291. description='namespaced test project',
  292. hook_token='aaabbbeee',
  293. namespace='somenamespace',
  294. )
  295. item.close_status = ['Invalid', 'Insufficient data', 'Fixed', 'Duplicate']
  296. session.add(item)
  297. session.commit()
  298. def create_projects_git(folder, bare=False):
  299. """ Create some projects in the database. """
  300. repos = []
  301. for project in ['test.git', 'test2.git',
  302. os.path.join('somenamespace', 'test3.git')]:
  303. repo_path = os.path.join(folder, project)
  304. repos.append(repo_path)
  305. if not os.path.exists(repo_path):
  306. os.makedirs(repo_path)
  307. pygit2.init_repository(repo_path, bare=bare)
  308. return repos
  309. def create_tokens(session, user_id=1, project_id=1):
  310. """ Create some tokens for the project in the database. """
  311. item = pagure.lib.model.Token(
  312. id='aaabbbcccddd',
  313. user_id=user_id,
  314. project_id=project_id,
  315. expiration=datetime.utcnow() + timedelta(days=30)
  316. )
  317. session.add(item)
  318. item = pagure.lib.model.Token(
  319. id='foo_token',
  320. user_id=user_id,
  321. project_id=project_id,
  322. expiration=datetime.utcnow() + timedelta(days=30)
  323. )
  324. session.add(item)
  325. item = pagure.lib.model.Token(
  326. id='expired_token',
  327. user_id=user_id,
  328. project_id=project_id,
  329. expiration=datetime.utcnow() - timedelta(days=1)
  330. )
  331. session.add(item)
  332. session.commit()
  333. def create_tokens_acl(session, token_id='aaabbbcccddd'):
  334. """ Create some acls for the tokens. """
  335. for aclid in range(len(pagure.APP.config['ACLS'])):
  336. item = pagure.lib.model.TokenAcl(
  337. token_id=token_id,
  338. acl_id=aclid + 1,
  339. )
  340. session.add(item)
  341. session.commit()
  342. def add_content_git_repo(folder, branch='master'):
  343. """ Create some content for the specified git repo. """
  344. if not os.path.exists(folder):
  345. os.makedirs(folder)
  346. brepo = pygit2.init_repository(folder, bare=True)
  347. newfolder = tempfile.mkdtemp(prefix='pagure-tests')
  348. repo = pygit2.clone_repository(folder, newfolder)
  349. # Create a file in that git repo
  350. with open(os.path.join(newfolder, 'sources'), 'w') as stream:
  351. stream.write('foo\n bar')
  352. repo.index.add('sources')
  353. repo.index.write()
  354. parents = []
  355. commit = None
  356. try:
  357. commit = repo.revparse_single(
  358. 'HEAD' if branch == 'master' else branch)
  359. except KeyError:
  360. pass
  361. if commit:
  362. parents = [commit.oid.hex]
  363. # Commits the files added
  364. tree = repo.index.write_tree()
  365. author = pygit2.Signature(
  366. 'Alice Author', 'alice@authors.tld')
  367. committer = pygit2.Signature(
  368. 'Cecil Committer', 'cecil@committers.tld')
  369. repo.create_commit(
  370. 'refs/heads/%s' % branch, # the name of the reference to update
  371. author,
  372. committer,
  373. 'Add sources file for testing',
  374. # binary string representing the tree object ID
  375. tree,
  376. # list of binary strings representing parents of the new commit
  377. parents,
  378. )
  379. parents = []
  380. commit = None
  381. try:
  382. commit = repo.revparse_single(
  383. 'HEAD' if branch == 'master' else branch)
  384. except KeyError:
  385. pass
  386. if commit:
  387. parents = [commit.oid.hex]
  388. subfolder = os.path.join('folder1', 'folder2')
  389. if not os.path.exists(os.path.join(newfolder, subfolder)):
  390. os.makedirs(os.path.join(newfolder, subfolder))
  391. # Create a file in that git repo
  392. with open(os.path.join(newfolder, subfolder, 'file'), 'w') as stream:
  393. stream.write('foo\n bar\nbaz')
  394. repo.index.add(os.path.join(subfolder, 'file'))
  395. with open(os.path.join(newfolder, subfolder, 'fileŠ'), 'w') as stream:
  396. stream.write('foo\n bar\nbaz')
  397. repo.index.add(os.path.join(subfolder, 'fileŠ'))
  398. repo.index.write()
  399. # Commits the files added
  400. tree = repo.index.write_tree()
  401. author = pygit2.Signature(
  402. 'Alice Author', 'alice@authors.tld')
  403. committer = pygit2.Signature(
  404. 'Cecil Committer', 'cecil@committers.tld')
  405. repo.create_commit(
  406. 'refs/heads/%s' % branch, # the name of the reference to update
  407. author,
  408. committer,
  409. 'Add some directory and a file for more testing',
  410. # binary string representing the tree object ID
  411. tree,
  412. # list of binary strings representing parents of the new commit
  413. parents
  414. )
  415. # Push to origin
  416. ori_remote = repo.remotes[0]
  417. master_ref = repo.lookup_reference(
  418. 'HEAD' if branch == 'master' else 'refs/heads/%s' % branch).resolve()
  419. refname = '%s:%s' % (master_ref.name, master_ref.name)
  420. PagureRepo.push(ori_remote, refname)
  421. shutil.rmtree(newfolder)
  422. def add_readme_git_repo(folder):
  423. """ Create a README file for the specified git repo. """
  424. if not os.path.exists(folder):
  425. os.makedirs(folder)
  426. brepo = pygit2.init_repository(folder, bare=True)
  427. newfolder = tempfile.mkdtemp(prefix='pagure-tests')
  428. repo = pygit2.clone_repository(folder, newfolder)
  429. content = """Pagure
  430. ======
  431. :Author: Pierre-Yves Chibon <pingou@pingoured.fr>
  432. Pagure is a light-weight git-centered forge based on pygit2.
  433. Currently, Pagure offers a web-interface for git repositories, a ticket
  434. system and possibilities to create new projects, fork existing ones and
  435. create/merge pull-requests across or within projects.
  436. Homepage: https://github.com/pypingou/pagure
  437. Dev instance: http://209.132.184.222/ (/!\\ May change unexpectedly, it's a dev instance ;-))
  438. """
  439. parents = []
  440. commit = None
  441. try:
  442. commit = repo.revparse_single('HEAD')
  443. except KeyError:
  444. pass
  445. if commit:
  446. parents = [commit.oid.hex]
  447. # Create a file in that git repo
  448. with open(os.path.join(newfolder, 'README.rst'), 'w') as stream:
  449. stream.write(content)
  450. repo.index.add('README.rst')
  451. repo.index.write()
  452. # Commits the files added
  453. tree = repo.index.write_tree()
  454. author = pygit2.Signature(
  455. 'Alice Author', 'alice@authors.tld')
  456. committer = pygit2.Signature(
  457. 'Cecil Committer', 'cecil@committers.tld')
  458. repo.create_commit(
  459. 'refs/heads/master', # the name of the reference to update
  460. author,
  461. committer,
  462. 'Add a README file',
  463. # binary string representing the tree object ID
  464. tree,
  465. # list of binary strings representing parents of the new commit
  466. parents
  467. )
  468. # Push to origin
  469. ori_remote = repo.remotes[0]
  470. master_ref = repo.lookup_reference('HEAD').resolve()
  471. refname = '%s:%s' % (master_ref.name, master_ref.name)
  472. PagureRepo.push(ori_remote, refname)
  473. shutil.rmtree(newfolder)
  474. def add_commit_git_repo(folder, ncommits=10, filename='sources',
  475. branch='master'):
  476. """ Create some more commits for the specified git repo. """
  477. if not os.path.exists(folder):
  478. os.makedirs(folder)
  479. pygit2.init_repository(folder, bare=True)
  480. newfolder = tempfile.mkdtemp(prefix='pagure-tests')
  481. repo = pygit2.clone_repository(folder, newfolder)
  482. for index in range(ncommits):
  483. # Create a file in that git repo
  484. with open(os.path.join(newfolder, filename), 'a') as stream:
  485. stream.write('Row %s\n' % index)
  486. repo.index.add(filename)
  487. repo.index.write()
  488. parents = []
  489. commit = None
  490. try:
  491. commit = repo.revparse_single('HEAD')
  492. except KeyError:
  493. pass
  494. if commit:
  495. parents = [commit.oid.hex]
  496. # Commits the files added
  497. tree = repo.index.write_tree()
  498. author = pygit2.Signature(
  499. 'Alice Author', 'alice@authors.tld')
  500. committer = pygit2.Signature(
  501. 'Cecil Committer', 'cecil@committers.tld')
  502. repo.create_commit(
  503. 'refs/heads/master',
  504. author,
  505. committer,
  506. 'Add row %s to %s file' % (index, filename),
  507. # binary string representing the tree object ID
  508. tree,
  509. # list of binary strings representing parents of the new commit
  510. parents,
  511. )
  512. # Push to origin
  513. ori_remote = repo.remotes[0]
  514. PagureRepo.push(ori_remote, 'HEAD:refs/heads/%s' % branch)
  515. shutil.rmtree(newfolder)
  516. def add_content_to_git(folder, filename='sources', content='foo'):
  517. """ Create some more commits for the specified git repo. """
  518. if not os.path.exists(folder):
  519. os.makedirs(folder)
  520. brepo = pygit2.init_repository(folder, bare=True)
  521. newfolder = tempfile.mkdtemp(prefix='pagure-tests')
  522. repo = pygit2.clone_repository(folder, newfolder)
  523. # Create a file in that git repo
  524. with open(os.path.join(newfolder, filename), 'a') as stream:
  525. stream.write('%s\n' % content)
  526. repo.index.add(filename)
  527. repo.index.write()
  528. parents = []
  529. commit = None
  530. try:
  531. commit = repo.revparse_single('HEAD')
  532. except KeyError:
  533. pass
  534. if commit:
  535. parents = [commit.oid.hex]
  536. # Commits the files added
  537. tree = repo.index.write_tree()
  538. author = pygit2.Signature(
  539. 'Alice Author', 'alice@authors.tld')
  540. committer = pygit2.Signature(
  541. 'Cecil Committer', 'cecil@committers.tld')
  542. repo.create_commit(
  543. 'refs/heads/master', # the name of the reference to update
  544. author,
  545. committer,
  546. 'Add content to file %s' % (filename),
  547. # binary string representing the tree object ID
  548. tree,
  549. # list of binary strings representing parents of the new commit
  550. parents,
  551. )
  552. # Push to origin
  553. ori_remote = repo.remotes[0]
  554. master_ref = repo.lookup_reference('HEAD').resolve()
  555. refname = '%s:%s' % (master_ref.name, master_ref.name)
  556. PagureRepo.push(ori_remote, refname)
  557. shutil.rmtree(newfolder)
  558. def add_binary_git_repo(folder, filename):
  559. """ Create a fake image file for the specified git repo. """
  560. if not os.path.exists(folder):
  561. os.makedirs(folder)
  562. brepo = pygit2.init_repository(folder, bare=True)
  563. newfolder = tempfile.mkdtemp(prefix='pagure-tests')
  564. repo = pygit2.clone_repository(folder, newfolder)
  565. content = b"""\x00\x00\x01\x00\x01\x00\x18\x18\x00\x00\x01\x00 \x00\x88
  566. \t\x00\x00\x16\x00\x00\x00(\x00\x00\x00\x18\x00x00\x00\x01\x00 \x00\x00\x00
  567. \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
  568. 00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7lM\x01\xa6kM\t\xa6kM\x01
  569. \xa4fF\x04\xa2dE\x95\xa2cD8\xa1a
  570. """
  571. parents = []
  572. commit = None
  573. try:
  574. commit = repo.revparse_single('HEAD')
  575. except KeyError:
  576. pass
  577. if commit:
  578. parents = [commit.oid.hex]
  579. # Create a file in that git repo
  580. with open(os.path.join(newfolder, filename), 'wb') as stream:
  581. stream.write(content)
  582. repo.index.add(filename)
  583. repo.index.write()
  584. # Commits the files added
  585. tree = repo.index.write_tree()
  586. author = pygit2.Signature(
  587. 'Alice Author', 'alice@authors.tld')
  588. committer = pygit2.Signature(
  589. 'Cecil Committer', 'cecil@committers.tld')
  590. repo.create_commit(
  591. 'refs/heads/master', # the name of the reference to update
  592. author,
  593. committer,
  594. 'Add a fake image file',
  595. # binary string representing the tree object ID
  596. tree,
  597. # list of binary strings representing parents of the new commit
  598. parents
  599. )
  600. # Push to origin
  601. ori_remote = repo.remotes[0]
  602. master_ref = repo.lookup_reference('HEAD').resolve()
  603. refname = '%s:%s' % (master_ref.name, master_ref.name)
  604. PagureRepo.push(ori_remote, refname)
  605. shutil.rmtree(newfolder)
  606. if __name__ == '__main__':
  607. SUITE = unittest.TestLoader().loadTestsFromTestCase(Modeltests)
  608. unittest.TextTestRunner(verbosity=2).run(SUITE)