Blame tests/__init__.py

Pierre-Yves Chibon 33b534
# -*- coding: utf-8 -*-
Pierre-Yves Chibon 413073
Pierre-Yves Chibon 413073
"""
Pierre-Yves Chibon f4149e
 (c) 2015-2017 - Copyright Red Hat Inc
Pierre-Yves Chibon 413073
Pierre-Yves Chibon 413073
 Authors:
Pierre-Yves Chibon 413073
   Pierre-Yves Chibon <pingou@pingoured.fr></pingou@pingoured.fr>
Pierre-Yves Chibon 413073
Pierre-Yves Chibon 413073
"""
Pierre-Yves Chibon 413073
Pierre-Yves Chibon 413073
__requires__ = ['SQLAlchemy >= 0.7']
Pierre-Yves Chibon 413073
import pkg_resources
Pierre-Yves Chibon 413073
Aurélien Bompard f61bb3
import json
Pierre-Yves Chibon 59df6f
import logging
Pierre-Yves Chibon 59e3b9
import os
Pierre-Yves Chibon 59e3b9
import re
Pierre-Yves Chibon 59e3b9
import resource
Pierre-Yves Chibon 59d644
import shutil
Patrick Uiterwijk 55e7e0
import subprocess
Pierre-Yves Chibon 413073
import sys
Pierre-Yves Chibon c27b0d
import tempfile
Patrick Uiterwijk 114ca2
import time
Pierre-Yves Chibon 59e3b9
import unittest
Pierre-Yves Chibon 59df6f
logging.basicConfig(stream=sys.stderr)
Pierre-Yves Chibon 413073
Patrick Uiterwijk fcd520
# Always enable performance counting for tests
Patrick Uiterwijk fcd520
os.environ['PAGURE_PERFREPO'] = 'true'
Patrick Uiterwijk fcd520
Pierre-Yves Chibon a324b4
from contextlib import contextmanager
Pierre-Yves Chibon 413073
from datetime import date
Pierre-Yves Chibon 21f499
from datetime import datetime
Pierre-Yves Chibon 413073
from datetime import timedelta
Pierre-Yves Chibon 413073
from functools import wraps
Aurélien Bompard f61bb3
from urlparse import urlparse, parse_qs
Pierre-Yves Chibon 413073
Pierre-Yves Chibon a324b4
import mock
Pierre-Yves Chibon 4e9b76
import pygit2
Pierre-Yves Chibon 4e9b76
Pierre-Yves Chibon 413073
from sqlalchemy import create_engine
Pierre-Yves Chibon 413073
from sqlalchemy.orm import sessionmaker
Pierre-Yves Chibon 413073
from sqlalchemy.orm import scoped_session
Pierre-Yves Chibon 413073
Pierre-Yves Chibon 413073
sys.path.insert(0, os.path.join(os.path.dirname(
Pierre-Yves Chibon 413073
    os.path.abspath(__file__)), '..'))
Pierre-Yves Chibon 413073
Pierre-Yves Chibon fe5017
import pagure
Pierre-Yves Chibon b130e5
import pagure.api
Pierre-Yves Chibon b130e5
import pagure.flask_app
Pierre-Yves Chibon fe5017
import pagure.lib
Pierre-Yves Chibon fe5017
import pagure.lib.model
Patrick Uiterwijk fcd520
import pagure.perfrepo as perfrepo
Aurélien Bompard e78d79
from pagure.config import config as pagure_config, reload_config
Pierre-Yves Chibon b130e5
from pagure.lib.repo import PagureRepo
Pierre-Yves Chibon 413073
Pierre-Yves Chibon f62635
HERE = os.path.join(os.path.dirname(os.path.abspath(__file__)))
Pierre-Yves Chibon b73de8
LOG = logging.getLogger(__name__)
Pierre-Yves Chibon b130e5
LOG.setLevel(logging.INFO)
Pierre-Yves Chibon 413073
Pierre-Yves Chibon b73de8
PAGLOG = logging.getLogger('pagure')
Pierre-Yves Chibon b73de8
PAGLOG.setLevel(logging.CRITICAL)
Pierre-Yves Chibon b73de8
PAGLOG.handlers = []
Pierre-Yves Chibon b73de8
Patrick Uiterwijk 55e7e0
CONFIG_TEMPLATE = """
Patrick Uiterwijk 55e7e0
GIT_FOLDER = '%(path)s/repos'
Aurélien Bompard e78d79
ENABLE_DOCS = %(enable_docs)s
Aurélien Bompard e78d79
ENABLE_TICKETS = %(enable_tickets)s
Patrick Uiterwijk 55e7e0
REMOTE_GIT_FOLDER = '%(path)s/remotes'
Patrick Uiterwijk 55e7e0
DB_URL = '%(dburl)s'
Patrick Uiterwijk 7b9080
ALLOW_PROJECT_DOWAIT = True
Pierre-Yves Chibon a324b4
DEBUG = True
Aurélien Bompard e78d79
PAGURE_CI_SERVICES = ['jenkins']
Aurélien Bompard e78d79
EMAIL_SEND = False
Aurélien Bompard e78d79
TESTING = True
Aurélien Bompard e78d79
GIT_FOLDER = '%(path)s/repos'
Aurélien Bompard e78d79
REQUESTS_FOLDER = '%(path)s/repos/requests'
Aurélien Bompard e78d79
TICKETS_FOLDER = %(tickets_folder)r
Aurélien Bompard e78d79
DOCS_FOLDER = %(docs_folder)r
Aurélien Bompard e78d79
ATTACHMENTS_FOLDER = '%(path)s/attachments'
Aurélien Bompard e78d79
BROKER_URL = 'redis+socket://%(global_path)s/broker'
Patrick Uiterwijk 55e7e0
"""
Patrick Uiterwijk 55e7e0
Pierre-Yves Chibon 413073
Pierre-Yves Chibon 59df6f
LOG.info('BUILD_ID: %s', os.environ.get('BUILD_ID'))
Pierre-Yves Chibon 413073
Patrick Uiterwijk 114ca2
Pierre-Yves Chibon f341aa
WAIT_REGEX = re.compile("""var _url = '(\/wait\/[a-z0-9-]+\??.*)'""")
Patrick Uiterwijk 114ca2
def get_wait_target(html):
Patrick Uiterwijk 114ca2
    """ This parses the window.location out of the HTML for the wait page. """
Patrick Uiterwijk 114ca2
    found = WAIT_REGEX.findall(html)
Pierre-Yves Chibon f341aa
    if len(found) == 0:
Patrick Uiterwijk 114ca2
        raise Exception("Not able to get wait target in %s" % html)
Pierre-Yves Chibon f341aa
    return found[-1]
Patrick Uiterwijk 114ca2
Patrick Uiterwijk 114ca2
Patrick Uiterwijk 114ca2
def create_maybe_waiter(method, getter):
Patrick Uiterwijk 114ca2
    def maybe_waiter(*args, **kwargs):
Patrick Uiterwijk 114ca2
        """ A wrapper for self.app.get()/.post() that will resolve wait's """
Patrick Uiterwijk 114ca2
        result = method(*args, **kwargs)
Patrick Uiterwijk 114ca2
        count = 0
Patrick Uiterwijk 114ca2
        while 'We are waiting for your task to finish.' in result.data:
Patrick Uiterwijk 114ca2
            # Resolve wait page
Patrick Uiterwijk 114ca2
            target_url = get_wait_target(result.data)
Patrick Uiterwijk 114ca2
            if count > 10:
Patrick Uiterwijk 114ca2
                time.sleep(0.5)
Patrick Uiterwijk 114ca2
            else:
Patrick Uiterwijk 114ca2
                time.sleep(0.1)
Patrick Uiterwijk 114ca2
            result = getter(target_url, follow_redirects=True)
Patrick Uiterwijk 114ca2
            if count > 50:
Patrick Uiterwijk 114ca2
                raise Exception('Had to wait too long')
Patrick Uiterwijk 114ca2
        else:
Patrick Uiterwijk 114ca2
            return result
Patrick Uiterwijk 114ca2
    return maybe_waiter
Patrick Uiterwijk 114ca2
Patrick Uiterwijk 114ca2
Pierre-Yves Chibon 413073
@contextmanager
Pierre-Yves Chibon 413073
def user_set(APP, user):
Pierre-Yves Chibon 413073
    """ Set the provided user as fas_user in the provided application."""
Pierre-Yves Chibon 413073
Pierre-Yves Chibon 413073
    # Hack used to remove the before_request function set by
Pierre-Yves Chibon 413073
    # flask.ext.fas_openid.FAS which otherwise kills our effort to set a
Pierre-Yves Chibon 413073
    # flask.g.fas_user.
Pierre-Yves Chibon 413073
    from flask import appcontext_pushed, g
Pierre-Yves Chibon 4ad0bb
    keep = []
Pierre-Yves Chibon 4ad0bb
    for meth in APP.before_request_funcs[None]:
Pierre-Yves Chibon 4ad0bb
        if 'flask_fas_openid.FAS' in str(meth):
Pierre-Yves Chibon 4ad0bb
            continue
Pierre-Yves Chibon 4ad0bb
        keep.append(meth)
Pierre-Yves Chibon 4ad0bb
    APP.before_request_funcs[None] = keep
Pierre-Yves Chibon 413073
Pierre-Yves Chibon 413073
    def handler(sender, **kwargs):
Pierre-Yves Chibon 413073
        g.fas_user = user
Pierre-Yves Chibon e120d5
        g.fas_session_id = b'123'
Pierre-Yves Chibon 392277
        g.authenticated = True
Pierre-Yves Chibon 413073
Pierre-Yves Chibon 413073
    with appcontext_pushed.connected_to(handler, APP):
Pierre-Yves Chibon 413073
        yield
Pierre-Yves Chibon 413073
Slavek Kabrda 7713cf
Aurélien Bompard e78d79
tests_state = {
Aurélien Bompard e78d79
    "path": tempfile.mkdtemp(prefix='pagure-tests-'),
Aurélien Bompard e78d79
    "broker": None,
Aurélien Bompard e78d79
}
Slavek Kabrda 7713cf
Slavek Kabrda 7713cf
Aurélien Bompard e78d79
def _populate_db(session):
Slavek Kabrda 7713cf
    # Create a couple of users
Slavek Kabrda 7713cf
    item = pagure.lib.model.User(
Slavek Kabrda 7713cf
        user='pingou',
Slavek Kabrda 7713cf
        fullname='PY C',
Slavek Kabrda 7713cf
        password='foo',
Slavek Kabrda 7713cf
        default_email='bar@pingou.com',
Slavek Kabrda 7713cf
    )
Slavek Kabrda 7713cf
    session.add(item)
Slavek Kabrda 7713cf
    item = pagure.lib.model.UserEmail(
Slavek Kabrda 7713cf
        user_id=1,
Slavek Kabrda 7713cf
        email='bar@pingou.com')
Slavek Kabrda 7713cf
    session.add(item)
Slavek Kabrda 7713cf
    item = pagure.lib.model.UserEmail(
Slavek Kabrda 7713cf
        user_id=1,
Slavek Kabrda 7713cf
        email='foo@pingou.com')
Slavek Kabrda 7713cf
    session.add(item)
Slavek Kabrda 7713cf
Slavek Kabrda 7713cf
    item = pagure.lib.model.User(
Slavek Kabrda 7713cf
        user='foo',
Slavek Kabrda 7713cf
        fullname='foo bar',
Slavek Kabrda 7713cf
        password='foo',
Slavek Kabrda 7713cf
        default_email='foo@bar.com',
Slavek Kabrda 7713cf
    )
Slavek Kabrda 7713cf
    session.add(item)
Slavek Kabrda 7713cf
    item = pagure.lib.model.UserEmail(
Slavek Kabrda 7713cf
        user_id=2,
Slavek Kabrda 7713cf
        email='foo@bar.com')
Slavek Kabrda 7713cf
    session.add(item)
Slavek Kabrda 7713cf
Slavek Kabrda 7713cf
    session.commit()
Slavek Kabrda 7713cf
Slavek Kabrda 7713cf
Slavek Kabrda 7713cf
Aurélien Bompard e78d79
Aurélien Bompard e78d79
def setUp():
Aurélien Bompard e78d79
    # In order to save time during local test execution, we create sqlite DB
Aurélien Bompard e78d79
    # file only once and then we populate it and empty it for every test case
Aurélien Bompard e78d79
    # (as opposed to creating DB file for every test case).
Aurélien Bompard e78d79
    session = pagure.lib.model.create_tables(
Aurélien Bompard e78d79
        'sqlite:///%s/db.sqlite' % tests_state["path"],
Aurélien Bompard e78d79
        acls=pagure_config.get('ACLS', {}),
Aurélien Bompard e78d79
    )
Aurélien Bompard e78d79
    tests_state["db_session"] = session
Slavek Kabrda 7713cf
Slavek Kabrda 3cb529
    # Create a broker
Aurélien Bompard e78d79
    broker_url = os.path.join(tests_state["path"], 'broker')
Aurélien Bompard e78d79
Aurélien Bompard e78d79
    tests_state["broker"] = broker = subprocess.Popen(
Slavek Kabrda 3cb529
        ['/usr/bin/redis-server', '--unixsocket', broker_url, '--port',
Slavek Kabrda 3cb529
         '0', '--loglevel', 'warning', '--logfile', '/dev/null'],
Slavek Kabrda 3cb529
        stdout=None, stderr=None)
Slavek Kabrda 3cb529
    broker.poll()
Slavek Kabrda 3cb529
    if broker.returncode is not None:
Slavek Kabrda 3cb529
        raise Exception('Broker failed to start')
Slavek Kabrda 7713cf
Pierre-Yves Chibon 2d5c52
Slavek Kabrda 3cb529
def tearDown():
Aurélien Bompard e78d79
    tests_state["db_session"].close()
Aurélien Bompard e78d79
    broker = tests_state["broker"]
Slavek Kabrda 3cb529
    broker.kill()
Slavek Kabrda 3cb529
    broker.wait()
Aurélien Bompard e78d79
    shutil.rmtree(tests_state["path"])
Pierre-Yves Chibon 59e3b9
Pierre-Yves Chibon 59e3b9
Clement Verna 109c4b
class SimplePagureTest(unittest.TestCase):
Clement Verna 109c4b
    """
Clement Verna 109c4b
    Simple Test class that does not set a broker/worker
Clement Verna 109c4b
    """
Pierre-Yves Chibon 413073
Aurélien Bompard e78d79
    populate_db = True
Aurélien Bompard e78d79
    config_values = {}
Aurélien Bompard e78d79
Pierre-Yves Chibon a324b4
    @mock.patch('pagure.lib.notify.fedmsg_publish', mock.MagicMock())
Pierre-Yves Chibon 413073
    def __init__(self, method_name='runTest'):
Pierre-Yves Chibon 413073
        """ Constructor. """
Pierre-Yves Chibon 413073
        unittest.TestCase.__init__(self, method_name)
Pierre-Yves Chibon 413073
        self.session = None
Jeremy Cline 20109f
        self.path = None
Pierre-Yves Chibon 3a4d42
        self.gitrepo = None
Pierre-Yves Chibon 619b9a
        self.gitrepos = None
Pierre-Yves Chibon 413073
Patrick Uiterwijk fcd520
    def perfMaxWalks(self, max_walks, max_steps):
Patrick Uiterwijk fcd520
        """ Check that we have not performed too many walks/steps. """
Patrick Uiterwijk fcd520
        num_walks = 0
Patrick Uiterwijk fcd520
        num_steps = 0
Patrick Uiterwijk fcd520
        for reqstat in perfrepo.REQUESTS:
Patrick Uiterwijk fcd520
            for walk in reqstat['walks'].values():
Patrick Uiterwijk fcd520
                num_walks += 1
Patrick Uiterwijk fcd520
                num_steps += walk['steps']
Patrick Uiterwijk fcd520
        self.assertLessEqual(num_walks, max_walks,
Patrick Uiterwijk fcd520
                             '%s git repo walks performed, at most %s allowed'
Patrick Uiterwijk fcd520
                             % (num_walks, max_walks))
Patrick Uiterwijk fcd520
        self.assertLessEqual(num_steps, max_steps,
Patrick Uiterwijk fcd520
                             '%s git repo steps performed, at most %s allowed'
Patrick Uiterwijk fcd520
                             % (num_steps, max_steps))
Patrick Uiterwijk fcd520
Patrick Uiterwijk fcd520
    def perfReset(self):
Patrick Uiterwijk fcd520
        """ Reset perfrepo stats. """
Patrick Uiterwijk fcd520
        perfrepo.reset_stats()
Patrick Uiterwijk fcd520
        perfrepo.REQUESTS = []
Patrick Uiterwijk fcd520
Clement Verna 109c4b
    def setUp(self):
Clement Verna 109c4b
        self.perfReset()
Patrick Uiterwijk fcd520
Pierre-Yves Chibon 8b2c5c
        if not self.path:
Pierre-Yves Chibon 8b2c5c
            self.path = tempfile.mkdtemp(prefix='pagure-tests-path-')
Pierre-Yves Chibon 8b2c5c
Pierre-Yves Chibon b130e5
        LOG.debug('Testdir: %s', self.path)
Slavek Kabrda adea20
        for folder in ['repos', 'forks', 'releases', 'remotes', 'attachments']:
Jeremy Cline 20109f
            os.mkdir(os.path.join(self.path, folder))
Pierre-Yves Chibon 58e731
Slavek Kabrda afb8f6
        if hasattr(pagure, 'REDIS') and pagure.REDIS:
Slavek Kabrda afb8f6
            pagure.REDIS.connection_pool.disconnect()
Slavek Kabrda afb8f6
            pagure.REDIS = None
Slavek Kabrda afb8f6
        if hasattr(pagure.lib, 'REDIS') and pagure.lib.REDIS:
Slavek Kabrda afb8f6
            pagure.lib.REDIS.connection_pool.disconnect()
Slavek Kabrda afb8f6
            pagure.lib.REDIS = None
Slavek Kabrda afb8f6
Aurélien Bompard e78d79
        # Database
Aurélien Bompard e78d79
        self._prepare_db()
Patrick Uiterwijk 55e7e0
Patrick Uiterwijk 55e7e0
        # Write a config file
Aurélien Bompard e78d79
        config_values = {
Aurélien Bompard e78d79
            'path': self.path, 'dburl': self.dbpath,
Aurélien Bompard e78d79
            'enable_docs': True,
Aurélien Bompard e78d79
            'docs_folder': '%s/repos/docs' % self.path,
Aurélien Bompard e78d79
            'enable_tickets': True,
Aurélien Bompard e78d79
            'tickets_folder': '%s/repos/tickets' % self.path,
Aurélien Bompard e78d79
            'global_path': tests_state["path"],
Aurélien Bompard e78d79
        }
Aurélien Bompard e78d79
        config_values.update(self.config_values)
Pierre-Yves Chibon 8b2c5c
        config_path = os.path.join(self.path, 'config')
Pierre-Yves Chibon 8b2c5c
        if not os.path.exists(config_path):
Pierre-Yves Chibon 8b2c5c
            with open(config_path, 'w') as f:
Pierre-Yves Chibon 8b2c5c
                f.write(CONFIG_TEMPLATE % config_values)
Aurélien Bompard e78d79
        os.environ["PAGURE_CONFIG"] = config_path
Aurélien Bompard e78d79
        pagure_config.update(reload_config())
Patrick Uiterwijk 55e7e0
Aurélien Bompard e78d79
        reload(pagure.lib.tasks)
Aurélien Bompard e78d79
        reload(pagure.lib.tasks_services)
Pierre-Yves Chibon b130e5
Slavek Kabrda 3675ce
        self._app = pagure.flask_app.create_app({'DB_URL': self.dbpath})
Pierre-Yves Chibon b130e5
        # Remove the log handlers for the tests
Slavek Kabrda 3675ce
        self._app.logger.handlers = []
Pierre-Yves Chibon b130e5
Slavek Kabrda 3675ce
        self.app = self._app.test_client()
Pierre-Yves Chibon 564e63
Clement Verna 109c4b
    def tearDown(self):
Aurélien Bompard e78d79
        self.session.rollback()
Aurélien Bompard e78d79
        self._clear_database()
Pierre-Yves Chibon 7cbc4e
Patrick Uiterwijk 55e7e0
        # Remove testdir
Pierre-Yves Chibon e49b79
        try:
Pierre-Yves Chibon e49b79
            shutil.rmtree(self.path)
Pierre-Yves Chibon e49b79
        except:
Pierre-Yves Chibon e49b79
            # Sometimes there is a race condition that makes deleting the folder
Pierre-Yves Chibon e49b79
            # fail during the first attempt. So just try a second time if that's
Pierre-Yves Chibon e49b79
            # the case.
Pierre-Yves Chibon e49b79
            shutil.rmtree(self.path)
Patrick Uiterwijk 55e7e0
        self.path = None
Patrick Uiterwijk 55e7e0
Slavek Kabrda 3675ce
        del self.app
Slavek Kabrda 3675ce
        del self._app
Slavek Kabrda 3675ce
Aurélien Bompard f61bb3
    def shortDescription(self):
Aurélien Bompard f61bb3
          doc = self.__str__() +": "+self._testMethodDoc
Aurélien Bompard f61bb3
          return doc or None
Aurélien Bompard f61bb3
Aurélien Bompard e78d79
    def _prepare_db(self):
Aurélien Bompard e78d79
        self.dbpath = 'sqlite:///%s' % os.path.join(
Aurélien Bompard e78d79
            tests_state["path"], 'db.sqlite')
Aurélien Bompard e78d79
        self.session = tests_state["db_session"]
Aurélien Bompard e78d79
        pagure.lib.model.create_default_status(
Aurélien Bompard e78d79
            self.session, acls=pagure_config.get('ACLS', {}))
Aurélien Bompard e78d79
        if self.populate_db:
Aurélien Bompard e78d79
            _populate_db(self.session)
Aurélien Bompard e78d79
Aurélien Bompard e78d79
    def _clear_database(self):
Aurélien Bompard e78d79
        tables = reversed(pagure.lib.model.BASE.metadata.sorted_tables)
Aurélien Bompard e78d79
        if self.dbpath.startswith('postgresql'):
Aurélien Bompard e78d79
            self.session.execute("TRUNCATE %s CASCADE" % ", ".join(
Aurélien Bompard e78d79
                [t.name for t in tables]))
Aurélien Bompard e78d79
        elif self.dbpath.startswith('sqlite'):
Aurélien Bompard e78d79
            for table in tables:
Aurélien Bompard e78d79
                self.session.execute("DELETE FROM %s" % table.name)
Aurélien Bompard e78d79
        elif self.dbpath.startswith('mysql'):
Aurélien Bompard e78d79
            self.session.execute("SET FOREIGN_KEY_CHECKS = 0")
Aurélien Bompard e78d79
            for table in tables:
Aurélien Bompard e78d79
                self.session.execute("TRUNCATE %s" % table.name)
Aurélien Bompard e78d79
            self.session.execute("SET FOREIGN_KEY_CHECKS = 1")
Aurélien Bompard e78d79
        self.session.commit()
Aurélien Bompard e78d79
Pierre-Yves Chibon a754ea
    def get_csrf(self, url='/new', output=None):
Pierre-Yves Chibon d596a9
        """Retrieve a CSRF token from given URL."""
Pierre-Yves Chibon a754ea
        if output is None:
Pierre-Yves Chibon a754ea
            output = self.app.get(url)
Pierre-Yves Chibon a754ea
            self.assertEqual(output.status_code, 200)
Pierre-Yves Chibon d596a9
Pierre-Yves Chibon d596a9
        return output.data.split(
Pierre-Yves Chibon d596a9
            'name="csrf_token" type="hidden" value="')[1].split('">')[0]
Pierre-Yves Chibon d596a9
Aurélien Bompard f61bb3
    def assertURLEqual(self, url_1, url_2):
Aurélien Bompard f61bb3
        url_parsed_1 = list(urlparse(url_1))
Aurélien Bompard f61bb3
        url_parsed_1[4] = parse_qs(url_parsed_1[4])
Aurélien Bompard f61bb3
        url_parsed_2 = list(urlparse(url_2))
Aurélien Bompard f61bb3
        url_parsed_2[4] = parse_qs(url_parsed_2[4])
Aurélien Bompard f61bb3
        return self.assertListEqual(url_parsed_1, url_parsed_2)
Aurélien Bompard f61bb3
Aurélien Bompard f61bb3
    def assertJSONEqual(self, json_1, json_2):
Aurélien Bompard f61bb3
        return self.assertEqual(json.loads(json_1), json.loads(json_2))
Aurélien Bompard f61bb3
Pierre-Yves Chibon b130e5
Clement Verna 109c4b
class Modeltests(SimplePagureTest):
Clement Verna 109c4b
    """ Model tests. """
Clement Verna 109c4b
Clement Verna 109c4b
    def setUp(self):    # pylint: disable=invalid-name
Clement Verna 109c4b
        """ Set up the environnment, ran before every tests. """
Clement Verna 109c4b
        # Clean up test performance info
Clement Verna 109c4b
        super(Modeltests, self).setUp()
Clement Verna 109c4b
Clement Verna 109c4b
        # Start a worker
Clement Verna 109c4b
        # Using cocurrency 2 to test with some concurrency, but not be heavy
Clement Verna 109c4b
        # Using eventlet so that worker.terminate kills everything
Pierre-Yves Chibon b130e5
        self.workerlog = open(os.path.join('.', 'worker.log'), 'w')
Lubomír Sedlář a3be3b
        celery_exec = 'celery'
Lubomír Sedlář a3be3b
        celery_env = os.environ.copy()
Lubomír Sedlář a3be3b
        celery_env.update({
Slavek Kabrda 3cb529
            'PAGURE_BROKER_URL': pagure_config['BROKER_URL'],
Slavek Kabrda 2641c4
            'PAGURE_CONFIG': os.path.join(self.path, 'config'),
Slavek Kabrda 2641c4
            'PYTHONPATH': '.'
Lubomír Sedlář a3be3b
        })
Slavek Kabrda 2641c4
        celery_cwd = os.path.normpath(
Aurélien Bompard e78d79
            os.path.join(os.path.dirname(__file__), '..')
Slavek Kabrda 2641c4
        )
Clement Verna 109c4b
        self.worker = subprocess.Popen(
Slavek Kabrda 2641c4
            [celery_exec, '-A', 'pagure.lib.tasks', 'worker',
Clement Verna 109c4b
             '--loglevel=info', '--concurrency=2', '--pool=eventlet',
Clement Verna 109c4b
             '--without-gossip', '--without-mingle', '--quiet'],
Slavek Kabrda 2641c4
            env=celery_env,
Slavek Kabrda 2641c4
            cwd=celery_cwd,
Clement Verna 109c4b
            stdout=self.workerlog,
Clement Verna 109c4b
            stderr=self.workerlog)
Clement Verna 109c4b
        self.worker.poll()
Clement Verna 109c4b
        if self.worker.returncode is not None:
Clement Verna 109c4b
            raise Exception('Worker failed to start')
Pierre-Yves Chibon 8b2c5c
Slavek Kabrda 2641c4
        # We could do the ping below in-process:
Slavek Kabrda 2641c4
        # pagure.lib.tasks.conn.control.ping(timeout=0.1)
Slavek Kabrda 2641c4
        # but if we try it, Python starts raising OSError
Slavek Kabrda 2641c4
        # with too many open files. This is probably related
Slavek Kabrda 2641c4
        # to https://github.com/celery/celery/issues/4465
Slavek Kabrda 2641c4
        wait_start = time.time()
Slavek Kabrda 2641c4
        while True:
Slavek Kabrda 2641c4
            time.sleep(0.1)
Slavek Kabrda 2641c4
            res = subprocess.call(
Slavek Kabrda 2641c4
                [celery_exec, '-A', 'pagure.lib.tasks',
Slavek Kabrda 2641c4
                 'inspect', '-t=0.1', 'ping'],
Slavek Kabrda 2641c4
                env=celery_env,
Slavek Kabrda 2641c4
                cwd=celery_cwd,
Slavek Kabrda 2641c4
                stdout=subprocess.PIPE,
Slavek Kabrda 2641c4
                stderr=subprocess.PIPE
Slavek Kabrda 2641c4
            )
Slavek Kabrda 2641c4
            if res == 0:
Slavek Kabrda 2641c4
                break
Slavek Kabrda 2641c4
            if time.time() - wait_start > 5:
Slavek Kabrda 2641c4
                raise Exception('Worker failed to initialize in 5 seconds')
Clement Verna 109c4b
Clement Verna 109c4b
        self.app.get = create_maybe_waiter(self.app.get, self.app.get)
Clement Verna 109c4b
        self.app.post = create_maybe_waiter(self.app.post, self.app.get)
Clement Verna 109c4b
Clement Verna 109c4b
    def tearDown(self):     # pylint: disable=invalid-name
Clement Verna 109c4b
        """ Remove the test.db database if there is one. """
Aurélien Bompard e78d79
        # Terminate worker
Clement Verna 109c4b
        # We just send a SIGKILL (kill -9), since when the test finishes, we
Clement Verna 109c4b
        #  don't really care about the output of either worker or broker
Clement Verna 109c4b
        #  anymore
Clement Verna 109c4b
        self.worker.kill()
Clement Verna 109c4b
        self.worker.wait()
Clement Verna 109c4b
        self.worker = None
Clement Verna 109c4b
        self.workerlog.close()
Clement Verna 109c4b
        self.workerlog = None
Slavek Kabrda 3cb529
        subprocess.check_call(
Slavek Kabrda 3cb529
            ['/usr/bin/redis-cli', '-s',
Slavek Kabrda 3cb529
             pagure_config['BROKER_URL'][len('redis+socket://'):], 'flushall'],
Slavek Kabrda 3cb529
            stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Aurélien Bompard e78d79
        super(Modeltests, self).tearDown()
Clement Verna 109c4b
Pierre-Yves Chibon 413073
Adam Williamson 8dc0a9
class FakeGroup(object):    # pylint: disable=too-few-public-methods
Pierre-Yves Chibon 413073
    """ Fake object used to make the FakeUser object closer to the
Pierre-Yves Chibon 413073
    expectations.
Pierre-Yves Chibon 413073
    """
Pierre-Yves Chibon 413073
Pierre-Yves Chibon 413073
    def __init__(self, name):
Pierre-Yves Chibon 413073
        """ Constructor.
Pierre-Yves Chibon 413073
        :arg name: the name given to the name attribute of this object.
Pierre-Yves Chibon 413073
        """
Pierre-Yves Chibon 413073
        self.name = name
Pierre-Yves Chibon 413073
        self.group_type = 'cla'
Pierre-Yves Chibon 413073
Pierre-Yves Chibon 413073
Adam Williamson 8dc0a9
class FakeUser(object):     # pylint: disable=too-few-public-methods
Pierre-Yves Chibon 413073
    """ Fake user used to test the fedocallib library. """
Pierre-Yves Chibon 413073
Pierre-Yves Chibon a71ef5
    def __init__(self, groups=None, username='username', cla_done=True, id=1):
Pierre-Yves Chibon 413073
        """ Constructor.
Pierre-Yves Chibon 413073
        :arg groups: list of the groups in which this fake user is
Pierre-Yves Chibon 413073
            supposed to be.
Pierre-Yves Chibon 413073
        """
Pierre-Yves Chibon 413073
        if isinstance(groups, basestring):
Pierre-Yves Chibon 413073
            groups = [groups]
Pierre-Yves Chibon ad2b94
        self.id = id
Pierre-Yves Chibon a71ef5
        self.groups = groups or []
Pierre-Yves Chibon ad2b94
        self.user = username
Pierre-Yves Chibon 413073
        self.username = username
Pierre-Yves Chibon 413073
        self.name = username
Pierre-Yves Chibon c52718
        self.email = 'foo@bar.com'
Pierre-Yves Chibon 413073
        self.approved_memberships = [
Pierre-Yves Chibon 413073
            FakeGroup('packager'),
Pierre-Yves Chibon 413073
            FakeGroup('design-team')
Pierre-Yves Chibon 413073
        ]
Pierre-Yves Chibon 413073
        self.dic = {}
Pierre-Yves Chibon 413073
        self.dic['timezone'] = 'Europe/Paris'
Pierre-Yves Chibon 9fe7c1
        self.login_time = datetime.utcnow()
Pierre-Yves Chibon 413073
        self.cla_done = cla_done
Pierre-Yves Chibon 413073
Pierre-Yves Chibon 413073
    def __getitem__(self, key):
Pierre-Yves Chibon 413073
        return self.dic[key]
Pierre-Yves Chibon 413073
Pierre-Yves Chibon 413073
Pierre-Yves Chibon 413073
def create_projects(session):
Pierre-Yves Chibon 413073
    """ Create some projects in the database. """
Pierre-Yves Chibon fe5017
    item = pagure.lib.model.Project(
Pierre-Yves Chibon 413073
        user_id=1,  # pingou
Pierre-Yves Chibon 413073
        name='test',
Pierre-Yves Chibon 413073
        description='test project #1',
Pierre-Yves Chibon e2259d
        hook_token='aaabbbccc',
Pierre-Yves Chibon 413073
    )
Pierre-Yves Chibon 2aa887
    item.close_status = ['Invalid', 'Insufficient data', 'Fixed', 'Duplicate']
Pierre-Yves Chibon 413073
    session.add(item)
Pierre-Yves Chibon 413073
Pierre-Yves Chibon fe5017
    item = pagure.lib.model.Project(
Pierre-Yves Chibon 413073
        user_id=1,  # pingou
Pierre-Yves Chibon 413073
        name='test2',
Pierre-Yves Chibon 413073
        description='test project #2',
Pierre-Yves Chibon e2259d
        hook_token='aaabbbddd',
Pierre-Yves Chibon 413073
    )
Pierre-Yves Chibon 2aa887
    item.close_status = ['Invalid', 'Insufficient data', 'Fixed', 'Duplicate']
Pierre-Yves Chibon 413073
    session.add(item)
Pierre-Yves Chibon 413073
clime afed57
    item = pagure.lib.model.Project(
clime afed57
        user_id=1,  # pingou
clime afed57
        name='test3',
clime afed57
        description='namespaced test project',
clime afed57
        hook_token='aaabbbeee',
clime afed57
        namespace='somenamespace',
clime afed57
    )
clime afed57
    item.close_status = ['Invalid', 'Insufficient data', 'Fixed', 'Duplicate']
clime afed57
    session.add(item)
clime afed57
Pierre-Yves Chibon 413073
    session.commit()
Pierre-Yves Chibon 413073
Pierre-Yves Chibon 413073
Pierre-Yves Chibon 05b648
def create_projects_git(folder, bare=False):
Pierre-Yves Chibon 4e9b76
    """ Create some projects in the database. """
Pierre-Yves Chibon 4e9b76
    repos = []
clime afed57
    for project in ['test.git', 'test2.git',
clime afed57
                    os.path.join('somenamespace', 'test3.git')]:
Pierre-Yves Chibon 4e9b76
        repo_path = os.path.join(folder, project)
Pierre-Yves Chibon 4e9b76
        repos.append(repo_path)
Pierre-Yves Chibon 63d161
        if not os.path.exists(repo_path):
Pierre-Yves Chibon 63d161
            os.makedirs(repo_path)
Pierre-Yves Chibon 05b648
        pygit2.init_repository(repo_path, bare=bare)
Pierre-Yves Chibon 4e9b76
Pierre-Yves Chibon 4e9b76
    return repos
Pierre-Yves Chibon 4e9b76
Pierre-Yves Chibon 4e9b76
Pierre-Yves Chibon a14636
def create_tokens(session, user_id=1, project_id=1):
Pierre-Yves Chibon c0b635
    """ Create some tokens for the project in the database. """
Pierre-Yves Chibon c0b635
    item = pagure.lib.model.Token(
Pierre-Yves Chibon c0b635
        id='aaabbbcccddd',
Pierre-Yves Chibon c0b635
        user_id=user_id,
Pierre-Yves Chibon a14636
        project_id=project_id,
Pierre-Yves Chibon c0b635
        expiration=datetime.utcnow() + timedelta(days=30)
Pierre-Yves Chibon c0b635
    )
Pierre-Yves Chibon c0b635
    session.add(item)
Pierre-Yves Chibon c0b635
Pierre-Yves Chibon c0b635
    item = pagure.lib.model.Token(
Pierre-Yves Chibon c0b635
        id='foo_token',
Pierre-Yves Chibon c0b635
        user_id=user_id,
Pierre-Yves Chibon a14636
        project_id=project_id,
Pierre-Yves Chibon c0b635
        expiration=datetime.utcnow() + timedelta(days=30)
Pierre-Yves Chibon c0b635
    )
Pierre-Yves Chibon c0b635
    session.add(item)
Pierre-Yves Chibon c0b635
Pierre-Yves Chibon c0b635
    item = pagure.lib.model.Token(
Pierre-Yves Chibon c0b635
        id='expired_token',
Pierre-Yves Chibon c0b635
        user_id=user_id,
Pierre-Yves Chibon a14636
        project_id=project_id,
Pierre-Yves Chibon c0b635
        expiration=datetime.utcnow() - timedelta(days=1)
Pierre-Yves Chibon c0b635
    )
Pierre-Yves Chibon c0b635
    session.add(item)
Pierre-Yves Chibon c0b635
Pierre-Yves Chibon c0b635
    session.commit()
Pierre-Yves Chibon c0b635
Pierre-Yves Chibon c0b635
Matt Prahl 30f8b1
def create_tokens_acl(session, token_id='aaabbbcccddd', acl_name=None):
Matt Prahl 30f8b1
    """ Create some ACLs for the token. If acl_name is not set, the token will
Matt Prahl 30f8b1
    have all the ACLs enabled.
Matt Prahl 30f8b1
    """
Matt Prahl 30f8b1
    if acl_name is None:
Pierre-Yves Chibon b130e5
        for aclid in range(len(pagure_config['ACLS'])):
Matt Prahl 30f8b1
            token_acl = pagure.lib.model.TokenAcl(
Matt Prahl 30f8b1
                token_id=token_id,
Matt Prahl 30f8b1
                acl_id=aclid + 1,
Matt Prahl 30f8b1
            )
Matt Prahl 30f8b1
            session.add(token_acl)
Matt Prahl 30f8b1
    else:
Matt Prahl 30f8b1
        acl = session.query(pagure.lib.model.ACL).filter_by(
Matt Prahl 30f8b1
            name=acl_name).one()
Matt Prahl 30f8b1
        token_acl = pagure.lib.model.TokenAcl(
Pierre-Yves Chibon 631c33
            token_id=token_id,
Matt Prahl 30f8b1
            acl_id=acl.id,
Pierre-Yves Chibon 955beb
        )
Matt Prahl 30f8b1
        session.add(token_acl)
Pierre-Yves Chibon 955beb
Pierre-Yves Chibon 955beb
    session.commit()
Pierre-Yves Chibon 955beb
Pierre-Yves Chibon 955beb
Pierre-Yves Chibon 62e16b
def add_content_git_repo(folder, branch='master'):
Pierre-Yves Chibon f0ad75
    """ Create some content for the specified git repo. """
Pierre-Yves Chibon f0ad75
    if not os.path.exists(folder):
Pierre-Yves Chibon f0ad75
        os.makedirs(folder)
Pierre-Yves Chibon 128dfb
    brepo = pygit2.init_repository(folder, bare=True)
Pierre-Yves Chibon 128dfb
Pierre-Yves Chibon 128dfb
    newfolder = tempfile.mkdtemp(prefix='pagure-tests')
Pierre-Yves Chibon 128dfb
    repo = pygit2.clone_repository(folder, newfolder)
Pierre-Yves Chibon f0ad75
Pierre-Yves Chibon f0ad75
    # Create a file in that git repo
Pierre-Yves Chibon 128dfb
    with open(os.path.join(newfolder, 'sources'), 'w') as stream:
Pierre-Yves Chibon f0ad75
        stream.write('foo\n bar')
Pierre-Yves Chibon f0ad75
    repo.index.add('sources')
Pierre-Yves Chibon f0ad75
    repo.index.write()
Pierre-Yves Chibon f0ad75
Pierre-Yves Chibon a71c8d
    parents = []
Pierre-Yves Chibon a71c8d
    commit = None
Pierre-Yves Chibon a71c8d
    try:
Pierre-Yves Chibon 62e16b
        commit = repo.revparse_single(
Pierre-Yves Chibon 62e16b
            'HEAD' if branch == 'master' else branch)
Pierre-Yves Chibon a71c8d
    except KeyError:
Pierre-Yves Chibon a71c8d
        pass
Pierre-Yves Chibon a71c8d
    if commit:
Pierre-Yves Chibon a71c8d
        parents = [commit.oid.hex]
Pierre-Yves Chibon a71c8d
Pierre-Yves Chibon f0ad75
    # Commits the files added
Pierre-Yves Chibon f0ad75
    tree = repo.index.write_tree()
Pierre-Yves Chibon f0ad75
    author = pygit2.Signature(
Pierre-Yves Chibon f0ad75
        'Alice Author', 'alice@authors.tld')
Pierre-Yves Chibon f0ad75
    committer = pygit2.Signature(
Pierre-Yves Chibon f0ad75
        'Cecil Committer', 'cecil@committers.tld')
Pierre-Yves Chibon f0ad75
    repo.create_commit(
Pierre-Yves Chibon 62e16b
        'refs/heads/%s' % branch,  # the name of the reference to update
Pierre-Yves Chibon f0ad75
        author,
Pierre-Yves Chibon f0ad75
        committer,
Pierre-Yves Chibon f0ad75
        'Add sources file for testing',
Pierre-Yves Chibon f0ad75
        # binary string representing the tree object ID
Pierre-Yves Chibon f0ad75
        tree,
Pierre-Yves Chibon f0ad75
        # list of binary strings representing parents of the new commit
Pierre-Yves Chibon a71c8d
        parents,
Pierre-Yves Chibon f0ad75
    )
Pierre-Yves Chibon a71c8d
Pierre-Yves Chibon a71c8d
    parents = []
Pierre-Yves Chibon a71c8d
    commit = None
Pierre-Yves Chibon a71c8d
    try:
Pierre-Yves Chibon 62e16b
        commit = repo.revparse_single(
Pierre-Yves Chibon 62e16b
            'HEAD' if branch == 'master' else branch)
Pierre-Yves Chibon a71c8d
    except KeyError:
Pierre-Yves Chibon a71c8d
        pass
Pierre-Yves Chibon a71c8d
    if commit:
Pierre-Yves Chibon a71c8d
        parents = [commit.oid.hex]
Pierre-Yves Chibon f0ad75
Pierre-Yves Chibon f0ad75
    subfolder = os.path.join('folder1', 'folder2')
Pierre-Yves Chibon 128dfb
    if not os.path.exists(os.path.join(newfolder, subfolder)):
Pierre-Yves Chibon 128dfb
        os.makedirs(os.path.join(newfolder, subfolder))
Pierre-Yves Chibon f0ad75
    # Create a file in that git repo
Pierre-Yves Chibon 128dfb
    with open(os.path.join(newfolder, subfolder, 'file'), 'w') as stream:
Pierre-Yves Chibon f0ad75
        stream.write('foo\n bar\nbaz')
Pierre-Yves Chibon f0ad75
    repo.index.add(os.path.join(subfolder, 'file'))
Ryan Lerch 9dad14
    with open(os.path.join(newfolder, subfolder, 'fileŠ'), 'w') as stream:
Ryan Lerch 9dad14
        stream.write('foo\n bar\nbaz')
Ryan Lerch 9dad14
    repo.index.add(os.path.join(subfolder, 'fileŠ'))
Pierre-Yves Chibon f0ad75
    repo.index.write()
Pierre-Yves Chibon f0ad75
Pierre-Yves Chibon f0ad75
    # Commits the files added
Pierre-Yves Chibon f0ad75
    tree = repo.index.write_tree()
Pierre-Yves Chibon f0ad75
    author = pygit2.Signature(
Pierre-Yves Chibon f0ad75
        'Alice Author', 'alice@authors.tld')
Pierre-Yves Chibon f0ad75
    committer = pygit2.Signature(
Pierre-Yves Chibon f0ad75
        'Cecil Committer', 'cecil@committers.tld')
Pierre-Yves Chibon f0ad75
    repo.create_commit(
Pierre-Yves Chibon 62e16b
        'refs/heads/%s' % branch,  # the name of the reference to update
Pierre-Yves Chibon f0ad75
        author,
Pierre-Yves Chibon f0ad75
        committer,
Pierre-Yves Chibon f0ad75
        'Add some directory and a file for more testing',
Pierre-Yves Chibon f0ad75
        # binary string representing the tree object ID
Pierre-Yves Chibon f0ad75
        tree,
Pierre-Yves Chibon f0ad75
        # list of binary strings representing parents of the new commit
Pierre-Yves Chibon a71c8d
        parents
Pierre-Yves Chibon f0ad75
    )
Pierre-Yves Chibon f0ad75
Pierre-Yves Chibon 128dfb
    # Push to origin
Pierre-Yves Chibon 128dfb
    ori_remote = repo.remotes[0]
Pierre-Yves Chibon 62e16b
    master_ref = repo.lookup_reference(
Pierre-Yves Chibon 62e16b
        'HEAD' if branch == 'master' else 'refs/heads/%s' % branch).resolve()
Pierre-Yves Chibon 128dfb
    refname = '%s:%s' % (master_ref.name, master_ref.name)
Pierre-Yves Chibon 128dfb
Pierre-Yves Chibon 27a73d
    PagureRepo.push(ori_remote, refname)
Pierre-Yves Chibon 128dfb
Pierre-Yves Chibon 128dfb
    shutil.rmtree(newfolder)
Pierre-Yves Chibon 128dfb
Pierre-Yves Chibon f0ad75
Pierre-Yves Chibon 87ffe2
def add_readme_git_repo(folder):
Pierre-Yves Chibon 87ffe2
    """ Create a README file for the specified git repo. """
Pierre-Yves Chibon 87ffe2
    if not os.path.exists(folder):
Pierre-Yves Chibon 87ffe2
        os.makedirs(folder)
Pierre-Yves Chibon 128dfb
    brepo = pygit2.init_repository(folder, bare=True)
Pierre-Yves Chibon 128dfb
Pierre-Yves Chibon 128dfb
    newfolder = tempfile.mkdtemp(prefix='pagure-tests')
Pierre-Yves Chibon 128dfb
    repo = pygit2.clone_repository(folder, newfolder)
Pierre-Yves Chibon 87ffe2
Pierre-Yves Chibon fe5017
    content = """Pagure
Pierre-Yves Chibon 87ffe2
======
Pierre-Yves Chibon 87ffe2
Pierre-Yves Chibon 87ffe2
:Author: Pierre-Yves Chibon <pingou@pingoured.fr></pingou@pingoured.fr>
Pierre-Yves Chibon 87ffe2
Pierre-Yves Chibon 87ffe2
Pierre-Yves Chibon fe5017
Pagure is a light-weight git-centered forge based on pygit2.
Pierre-Yves Chibon 87ffe2
Pierre-Yves Chibon fe5017
Currently, Pagure offers a web-interface for git repositories, a ticket
Pierre-Yves Chibon fe5017
system and possibilities to create new projects, fork existing ones and
Pierre-Yves Chibon fe5017
create/merge pull-requests across or within projects.
Pierre-Yves Chibon 87ffe2
Pierre-Yves Chibon 87ffe2
Pierre-Yves Chibon fe5017
Homepage: https://github.com/pypingou/pagure
Pierre-Yves Chibon 87ffe2
Pierre-Yves Chibon 87ffe2
Dev instance: http://209.132.184.222/ (/!\\ May change unexpectedly, it's a dev instance ;-))
Pierre-Yves Chibon 87ffe2
"""
Pierre-Yves Chibon 87ffe2
Pierre-Yves Chibon 87ffe2
    parents = []
Pierre-Yves Chibon a71c8d
    commit = None
Pierre-Yves Chibon a71c8d
    try:
Pierre-Yves Chibon a71c8d
        commit = repo.revparse_single('HEAD')
Pierre-Yves Chibon a71c8d
    except KeyError:
Pierre-Yves Chibon a71c8d
        pass
Pierre-Yves Chibon 87ffe2
    if commit:
Pierre-Yves Chibon 87ffe2
        parents = [commit.oid.hex]
Pierre-Yves Chibon 87ffe2
Pierre-Yves Chibon 87ffe2
    # Create a file in that git repo
Pierre-Yves Chibon 128dfb
    with open(os.path.join(newfolder, 'README.rst'), 'w') as stream:
Pierre-Yves Chibon 87ffe2
        stream.write(content)
Pierre-Yves Chibon 87ffe2
    repo.index.add('README.rst')
Pierre-Yves Chibon 87ffe2
    repo.index.write()
Pierre-Yves Chibon 87ffe2
Pierre-Yves Chibon 87ffe2
    # Commits the files added
Pierre-Yves Chibon 87ffe2
    tree = repo.index.write_tree()
Pierre-Yves Chibon 87ffe2
    author = pygit2.Signature(
Pierre-Yves Chibon 87ffe2
        'Alice Author', 'alice@authors.tld')
Pierre-Yves Chibon 87ffe2
    committer = pygit2.Signature(
Pierre-Yves Chibon 87ffe2
        'Cecil Committer', 'cecil@committers.tld')
Pierre-Yves Chibon 87ffe2
    repo.create_commit(
Pierre-Yves Chibon 87ffe2
        'refs/heads/master',  # the name of the reference to update
Pierre-Yves Chibon 87ffe2
        author,
Pierre-Yves Chibon 87ffe2
        committer,
Pierre-Yves Chibon 87ffe2
        'Add a README file',
Pierre-Yves Chibon 87ffe2
        # binary string representing the tree object ID
Pierre-Yves Chibon 87ffe2
        tree,
Pierre-Yves Chibon 87ffe2
        # list of binary strings representing parents of the new commit
Pierre-Yves Chibon 87ffe2
        parents
Pierre-Yves Chibon 87ffe2
    )
Pierre-Yves Chibon 87ffe2
Pierre-Yves Chibon 128dfb
    # Push to origin
Pierre-Yves Chibon 128dfb
    ori_remote = repo.remotes[0]
Pierre-Yves Chibon 128dfb
    master_ref = repo.lookup_reference('HEAD').resolve()
Pierre-Yves Chibon 128dfb
    refname = '%s:%s' % (master_ref.name, master_ref.name)
Pierre-Yves Chibon 128dfb
Pierre-Yves Chibon 27a73d
    PagureRepo.push(ori_remote, refname)
Pierre-Yves Chibon 128dfb
Pierre-Yves Chibon 128dfb
    shutil.rmtree(newfolder)
Pierre-Yves Chibon 128dfb
Pierre-Yves Chibon 87ffe2
Patrick Uiterwijk 02a7cc
def add_commit_git_repo(folder, ncommits=10, filename='sources',
Patrick Uiterwijk 02a7cc
                        branch='master'):
Pierre-Yves Chibon 595b4e
    """ Create some more commits for the specified git repo. """
Pierre-Yves Chibon 595b4e
    if not os.path.exists(folder):
Pierre-Yves Chibon 595b4e
        os.makedirs(folder)
Patrick Uiterwijk 02a7cc
        pygit2.init_repository(folder, bare=True)
Pierre-Yves Chibon 128dfb
Pierre-Yves Chibon 128dfb
    newfolder = tempfile.mkdtemp(prefix='pagure-tests')
Pierre-Yves Chibon 128dfb
    repo = pygit2.clone_repository(folder, newfolder)
Pierre-Yves Chibon 595b4e
Pierre-Yves Chibon 595b4e
    for index in range(ncommits):
Pierre-Yves Chibon 595b4e
        # Create a file in that git repo
Pierre-Yves Chibon a48463
        with open(os.path.join(newfolder, filename), 'a') as stream:
Pierre-Yves Chibon 595b4e
            stream.write('Row %s\n' % index)
Pierre-Yves Chibon a48463
        repo.index.add(filename)
Pierre-Yves Chibon 595b4e
        repo.index.write()
Pierre-Yves Chibon 595b4e
Pierre-Yves Chibon 595b4e
        parents = []
Pierre-Yves Chibon 595b4e
        commit = None
Pierre-Yves Chibon 595b4e
        try:
Pierre-Yves Chibon 595b4e
            commit = repo.revparse_single('HEAD')
Pierre-Yves Chibon 595b4e
        except KeyError:
Pierre-Yves Chibon 595b4e
            pass
Pierre-Yves Chibon 595b4e
        if commit:
Pierre-Yves Chibon 595b4e
            parents = [commit.oid.hex]
Pierre-Yves Chibon 595b4e
Pierre-Yves Chibon 595b4e
        # Commits the files added
Pierre-Yves Chibon 595b4e
        tree = repo.index.write_tree()
Pierre-Yves Chibon 595b4e
        author = pygit2.Signature(
Pierre-Yves Chibon 595b4e
            'Alice Author', 'alice@authors.tld')
Pierre-Yves Chibon 595b4e
        committer = pygit2.Signature(
Pierre-Yves Chibon 595b4e
            'Cecil Committer', 'cecil@committers.tld')
Pierre-Yves Chibon 595b4e
        repo.create_commit(
Patrick Uiterwijk 02a7cc
            'refs/heads/master',
Pierre-Yves Chibon 595b4e
            author,
Pierre-Yves Chibon 595b4e
            committer,
Pierre-Yves Chibon a48463
            'Add row %s to %s file' % (index, filename),
Pierre-Yves Chibon 595b4e
            # binary string representing the tree object ID
Pierre-Yves Chibon 595b4e
            tree,
Pierre-Yves Chibon 595b4e
            # list of binary strings representing parents of the new commit
Pierre-Yves Chibon 595b4e
            parents,
Pierre-Yves Chibon 595b4e
        )
Pierre-Yves Chibon 595b4e
Pierre-Yves Chibon 128dfb
    # Push to origin
Pierre-Yves Chibon 128dfb
    ori_remote = repo.remotes[0]
Patrick Uiterwijk 02a7cc
    PagureRepo.push(ori_remote, 'HEAD:refs/heads/%s' % branch)
Pierre-Yves Chibon 1cd41d
Pierre-Yves Chibon 1cd41d
    shutil.rmtree(newfolder)
Pierre-Yves Chibon 1cd41d
Pierre-Yves Chibon 1cd41d
Pierre-Yves Chibon 1cd41d
def add_content_to_git(folder, filename='sources', content='foo'):
Pierre-Yves Chibon 1cd41d
    """ Create some more commits for the specified git repo. """
Pierre-Yves Chibon 1cd41d
    if not os.path.exists(folder):
Pierre-Yves Chibon 1cd41d
        os.makedirs(folder)
Pierre-Yves Chibon 1cd41d
    brepo = pygit2.init_repository(folder, bare=True)
Pierre-Yves Chibon 1cd41d
Pierre-Yves Chibon 1cd41d
    newfolder = tempfile.mkdtemp(prefix='pagure-tests')
Pierre-Yves Chibon 1cd41d
    repo = pygit2.clone_repository(folder, newfolder)
Pierre-Yves Chibon 1cd41d
Pierre-Yves Chibon 1cd41d
    # Create a file in that git repo
Pierre-Yves Chibon 1cd41d
    with open(os.path.join(newfolder, filename), 'a') as stream:
Pierre-Yves Chibon 1cd41d
        stream.write('%s\n' % content)
Pierre-Yves Chibon 1cd41d
    repo.index.add(filename)
Pierre-Yves Chibon 1cd41d
    repo.index.write()
Pierre-Yves Chibon 1cd41d
Pierre-Yves Chibon 1cd41d
    parents = []
Pierre-Yves Chibon 1cd41d
    commit = None
Pierre-Yves Chibon 1cd41d
    try:
Pierre-Yves Chibon 1cd41d
        commit = repo.revparse_single('HEAD')
Pierre-Yves Chibon 1cd41d
    except KeyError:
Pierre-Yves Chibon 1cd41d
        pass
Pierre-Yves Chibon 1cd41d
    if commit:
Pierre-Yves Chibon 1cd41d
        parents = [commit.oid.hex]
Pierre-Yves Chibon 1cd41d
Pierre-Yves Chibon 1cd41d
    # Commits the files added
Pierre-Yves Chibon 1cd41d
    tree = repo.index.write_tree()
Pierre-Yves Chibon 1cd41d
    author = pygit2.Signature(
Pierre-Yves Chibon 1cd41d
        'Alice Author', 'alice@authors.tld')
Pierre-Yves Chibon 1cd41d
    committer = pygit2.Signature(
Pierre-Yves Chibon 1cd41d
        'Cecil Committer', 'cecil@committers.tld')
Pierre-Yves Chibon 1cd41d
    repo.create_commit(
Pierre-Yves Chibon 1cd41d
        'refs/heads/master',  # the name of the reference to update
Pierre-Yves Chibon 1cd41d
        author,
Pierre-Yves Chibon 1cd41d
        committer,
Pierre-Yves Chibon 1cd41d
        'Add content to file %s' % (filename),
Pierre-Yves Chibon 1cd41d
        # binary string representing the tree object ID
Pierre-Yves Chibon 1cd41d
        tree,
Pierre-Yves Chibon 1cd41d
        # list of binary strings representing parents of the new commit
Pierre-Yves Chibon 1cd41d
        parents,
Pierre-Yves Chibon 1cd41d
    )
Pierre-Yves Chibon 1cd41d
Pierre-Yves Chibon 1cd41d
    # Push to origin
Pierre-Yves Chibon 1cd41d
    ori_remote = repo.remotes[0]
Pierre-Yves Chibon 1cd41d
    master_ref = repo.lookup_reference('HEAD').resolve()
Pierre-Yves Chibon 1cd41d
    refname = '%s:%s' % (master_ref.name, master_ref.name)
Pierre-Yves Chibon 1cd41d
Pierre-Yves Chibon 1cd41d
    PagureRepo.push(ori_remote, refname)
Pierre-Yves Chibon 128dfb
Pierre-Yves Chibon 128dfb
    shutil.rmtree(newfolder)
Pierre-Yves Chibon 128dfb
Pierre-Yves Chibon 595b4e
Pierre-Yves Chibon 6e857b
def add_binary_git_repo(folder, filename):
Pierre-Yves Chibon 6e857b
    """ Create a fake image file for the specified git repo. """
Pierre-Yves Chibon 6e857b
    if not os.path.exists(folder):
Pierre-Yves Chibon 6e857b
        os.makedirs(folder)
Pierre-Yves Chibon 128dfb
    brepo = pygit2.init_repository(folder, bare=True)
Pierre-Yves Chibon 128dfb
Pierre-Yves Chibon 128dfb
    newfolder = tempfile.mkdtemp(prefix='pagure-tests')
Pierre-Yves Chibon 128dfb
    repo = pygit2.clone_repository(folder, newfolder)
Pierre-Yves Chibon 6e857b
Pierre-Yves Chibon 945241
    content = b"""\x00\x00\x01\x00\x01\x00\x18\x18\x00\x00\x01\x00 \x00\x88
Pierre-Yves Chibon 945241
\t\x00\x00\x16\x00\x00\x00(\x00\x00\x00\x18\x00x00\x00\x01\x00 \x00\x00\x00
Pierre-Yves Chibon 945241
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
Pierre-Yves Chibon 945241
00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7lM\x01\xa6kM\t\xa6kM\x01
Pierre-Yves Chibon 945241
\xa4fF\x04\xa2dE\x95\xa2cD8\xa1a
Pierre-Yves Chibon 6e857b
"""
Pierre-Yves Chibon 6e857b
Pierre-Yves Chibon 6e857b
    parents = []
Pierre-Yves Chibon 6e857b
    commit = None
Pierre-Yves Chibon 6e857b
    try:
Pierre-Yves Chibon 6e857b
        commit = repo.revparse_single('HEAD')
Pierre-Yves Chibon 6e857b
    except KeyError:
Pierre-Yves Chibon 6e857b
        pass
Pierre-Yves Chibon 6e857b
    if commit:
Pierre-Yves Chibon 6e857b
        parents = [commit.oid.hex]
Pierre-Yves Chibon 6e857b
Pierre-Yves Chibon 6e857b
    # Create a file in that git repo
Pierre-Yves Chibon 945241
    with open(os.path.join(newfolder, filename), 'wb') as stream:
Pierre-Yves Chibon 6e857b
        stream.write(content)
Pierre-Yves Chibon 6e857b
    repo.index.add(filename)
Pierre-Yves Chibon 6e857b
    repo.index.write()
Pierre-Yves Chibon 6e857b
Pierre-Yves Chibon 6e857b
    # Commits the files added
Pierre-Yves Chibon 6e857b
    tree = repo.index.write_tree()
Pierre-Yves Chibon 6e857b
    author = pygit2.Signature(
Pierre-Yves Chibon 6e857b
        'Alice Author', 'alice@authors.tld')
Pierre-Yves Chibon 6e857b
    committer = pygit2.Signature(
Pierre-Yves Chibon 6e857b
        'Cecil Committer', 'cecil@committers.tld')
Pierre-Yves Chibon 6e857b
    repo.create_commit(
Pierre-Yves Chibon 6e857b
        'refs/heads/master',  # the name of the reference to update
Pierre-Yves Chibon 6e857b
        author,
Pierre-Yves Chibon 6e857b
        committer,
Pierre-Yves Chibon 6e857b
        'Add a fake image file',
Pierre-Yves Chibon 6e857b
        # binary string representing the tree object ID
Pierre-Yves Chibon 6e857b
        tree,
Pierre-Yves Chibon 6e857b
        # list of binary strings representing parents of the new commit
Pierre-Yves Chibon 6e857b
        parents
Pierre-Yves Chibon 6e857b
    )
Pierre-Yves Chibon 6e857b
Pierre-Yves Chibon 128dfb
    # Push to origin
Pierre-Yves Chibon 128dfb
    ori_remote = repo.remotes[0]
Pierre-Yves Chibon 128dfb
    master_ref = repo.lookup_reference('HEAD').resolve()
Pierre-Yves Chibon 128dfb
    refname = '%s:%s' % (master_ref.name, master_ref.name)
Pierre-Yves Chibon 128dfb
Pierre-Yves Chibon 27a73d
    PagureRepo.push(ori_remote, refname)
Pierre-Yves Chibon 128dfb
Pierre-Yves Chibon 128dfb
    shutil.rmtree(newfolder)
Pierre-Yves Chibon 128dfb
Pierre-Yves Chibon 652aff
Pierre-Yves Chibon 413073
if __name__ == '__main__':
Pierre-Yves Chibon 413073
    SUITE = unittest.TestLoader().loadTestsFromTestCase(Modeltests)
Pierre-Yves Chibon 413073
    unittest.TextTestRunner(verbosity=2).run(SUITE)