|
Pierre-Yves Chibon |
33b534 |
# -*- coding: utf-8 -*-
|
|
Pierre-Yves Chibon |
413073 |
|
|
Pierre-Yves Chibon |
413073 |
"""
|
|
Pierre-Yves Chibon |
517d69 |
(c) 2015-2018 - 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 |
67d1cc |
from __future__ import unicode_literals, absolute_import
|
|
Aurélien Bompard |
626417 |
|
|
Aurélien Bompard |
626417 |
import imp
|
|
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
|
|
Aurélien Bompard |
619e2a |
from io import open, StringIO
|
|
Pierre-Yves Chibon |
73d120 |
|
|
Pierre-Yves Chibon |
59df6f |
logging.basicConfig(stream=sys.stderr)
|
|
Pierre-Yves Chibon |
413073 |
|
|
Aurélien Bompard |
626417 |
from bs4 import BeautifulSoup
|
|
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 |
626417 |
from six.moves.urllib.parse import urlparse, parse_qs
|
|
Pierre-Yves Chibon |
413073 |
|
|
Pierre-Yves Chibon |
a324b4 |
import mock
|
|
Pierre-Yves Chibon |
4e9b76 |
import pygit2
|
|
Aurélien Bompard |
00115d |
import redis
|
|
Aurélien Bompard |
626417 |
import six
|
|
Pierre-Yves Chibon |
4e9b76 |
|
|
Pierre-Yves Chibon |
675b89 |
from bs4 import BeautifulSoup
|
|
Aurélien Bompard |
00115d |
from celery.app.task import EagerResult
|
|
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 |
|
|
Aurélien Bompard |
626417 |
if six.PY2:
|
|
Aurélien Bompard |
626417 |
# Always enable performance counting for tests
|
|
Pierre-Yves Chibon |
73d120 |
os.environ["PAGURE_PERFREPO"] = "true"
|
|
Aurélien Bompard |
626417 |
|
|
Pierre-Yves Chibon |
73d120 |
sys.path.insert(
|
|
Pierre-Yves Chibon |
73d120 |
0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..")
|
|
Pierre-Yves Chibon |
73d120 |
)
|
|
Pierre-Yves Chibon |
413073 |
|
|
Pierre-Yves Chibon |
fe5017 |
import pagure
|
|
Pierre-Yves Chibon |
b130e5 |
import pagure.api
|
|
Patrick Uiterwijk |
3f97f6 |
from pagure.api.ci import jenkins
|
|
Pierre-Yves Chibon |
b130e5 |
import pagure.flask_app
|
|
Pierre-Yves Chibon |
6fdafd |
import pagure.lib.git
|
|
Pierre-Yves Chibon |
fe5017 |
import pagure.lib.model
|
|
Pierre-Yves Chibon |
930073 |
import pagure.lib.query
|
|
Patrick Uiterwijk |
4012dc |
import pagure.lib.tasks_mirror
|
|
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 |
73d120 |
PAGLOG = logging.getLogger("pagure")
|
|
Pierre-Yves Chibon |
b73de8 |
PAGLOG.setLevel(logging.CRITICAL)
|
|
Pierre-Yves Chibon |
b73de8 |
PAGLOG.handlers = []
|
|
Pierre-Yves Chibon |
b73de8 |
|
|
Pierre-Yves Chibon |
73d120 |
if "PYTHONPATH" not in os.environ:
|
|
Pierre-Yves Chibon |
73d120 |
os.environ["PYTHONPATH"] = os.path.normpath(os.path.join(HERE, "../"))
|
|
Patrick Uiterwijk |
b2cb9c |
|
|
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
|
|
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
|
|
Patrick Uiterwijk |
3f97f6 |
REPOSPANNER_PSEUDO_FOLDER = '%(path)s/repos/pseudo'
|
|
Aurélien Bompard |
e78d79 |
ATTACHMENTS_FOLDER = '%(path)s/attachments'
|
|
Aurélien Bompard |
e78d79 |
BROKER_URL = 'redis+socket://%(global_path)s/broker'
|
|
Aurélien Bompard |
00115d |
CELERY_CONFIG = {
|
|
Aurélien Bompard |
00115d |
"task_always_eager": True,
|
|
Aurélien Bompard |
626417 |
#"task_eager_propagates": True,
|
|
Aurélien Bompard |
00115d |
}
|
|
Patrick Uiterwijk |
b2cb9c |
GIT_AUTH_BACKEND = '%(authbackend)s'
|
|
Patrick Uiterwijk |
b2cb9c |
TEST_AUTH_STATUS = '%(path)s/testauth_status.json'
|
|
Patrick Uiterwijk |
8174a4 |
REPOBRIDGE_BINARY = '%(repobridge_binary)s'
|
|
Patrick Uiterwijk |
3f97f6 |
REPOSPANNER_NEW_REPO = %(repospanner_new_repo)s
|
|
Patrick Uiterwijk |
3f97f6 |
REPOSPANNER_NEW_REPO_ADMIN_OVERRIDE = %(repospanner_admin_override)s
|
|
Patrick Uiterwijk |
3f97f6 |
REPOSPANNER_NEW_FORK = %(repospanner_new_fork)s
|
|
Patrick Uiterwijk |
3f97f6 |
REPOSPANNER_ADMIN_MIGRATION = %(repospanner_admin_migration)s
|
|
Patrick Uiterwijk |
3f97f6 |
REPOSPANNER_REGIONS = {
|
|
Patrick Uiterwijk |
9b2de7 |
'default': {'url': 'https://repospanner.localhost.localdomain:%(repospanner_gitport)s',
|
|
Patrick Uiterwijk |
3f97f6 |
'repo_prefix': 'pagure/',
|
|
Patrick Uiterwijk |
d29158 |
'hook': None,
|
|
Patrick Uiterwijk |
3f97f6 |
'ca': '%(path)s/repospanner/pki/ca.crt',
|
|
Patrick Uiterwijk |
3f97f6 |
'admin_cert': {'cert': '%(path)s/repospanner/pki/admin.crt',
|
|
Patrick Uiterwijk |
3f97f6 |
'key': '%(path)s/repospanner/pki/admin.key'},
|
|
Patrick Uiterwijk |
3f97f6 |
'push_cert': {'cert': '%(path)s/repospanner/pki/pagure.crt',
|
|
Patrick Uiterwijk |
3f97f6 |
'key': '%(path)s/repospanner/pki/pagure.key'}}
|
|
Patrick Uiterwijk |
3f97f6 |
}
|
|
Patrick Uiterwijk |
55e7e0 |
"""
|
|
Aurélien Bompard |
00115d |
# The Celery docs warn against using task_always_eager:
|
|
Aurélien Bompard |
00115d |
# http://docs.celeryproject.org/en/latest/userguide/testing.html
|
|
Aurélien Bompard |
00115d |
# but that warning is only valid when testing the async nature of the task, not
|
|
Aurélien Bompard |
00115d |
# what the task actually does.
|
|
Patrick Uiterwijk |
55e7e0 |
|
|
Pierre-Yves Chibon |
413073 |
|
|
Pierre-Yves Chibon |
73d120 |
LOG.info("BUILD_ID: %s", os.environ.get("BUILD_ID"))
|
|
Pierre-Yves Chibon |
413073 |
|
|
Patrick Uiterwijk |
114ca2 |
|
|
Karsten Hopp |
b310af |
WAIT_REGEX = re.compile(r"""var _url = '(\/wait\/[a-z0-9-]+\??.*)'""")
|
|
Pierre-Yves Chibon |
73d120 |
|
|
Pierre-Yves Chibon |
73d120 |
|
|
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 |
|
|
Pierre-Yves Chibon |
517d69 |
def get_post_target(html):
|
|
Pierre-Yves Chibon |
675b89 |
""" This parses the wait page form to get the POST url. """
|
|
Pierre-Yves Chibon |
73d120 |
soup = BeautifulSoup(html, "html.parser")
|
|
Pierre-Yves Chibon |
73d120 |
form = soup.find(id="waitform")
|
|
Pierre-Yves Chibon |
675b89 |
if not form:
|
|
Pierre-Yves Chibon |
517d69 |
raise Exception("Not able to get the POST url in %s" % html)
|
|
Pierre-Yves Chibon |
73d120 |
return form.get("action")
|
|
Pierre-Yves Chibon |
517d69 |
|
|
Pierre-Yves Chibon |
517d69 |
|
|
Pierre-Yves Chibon |
517d69 |
def get_post_args(html):
|
|
Pierre-Yves Chibon |
675b89 |
""" This parses the wait page for the hidden arguments of the form. """
|
|
Pierre-Yves Chibon |
73d120 |
soup = BeautifulSoup(html, "html.parser")
|
|
Pierre-Yves Chibon |
517d69 |
output = {}
|
|
Pierre-Yves Chibon |
73d120 |
inputs = soup.find_all("input")
|
|
Pierre-Yves Chibon |
675b89 |
if not inputs:
|
|
Pierre-Yves Chibon |
675b89 |
raise Exception("Not able to get the POST arguments in %s" % html)
|
|
Pierre-Yves Chibon |
675b89 |
for inp in inputs:
|
|
Pierre-Yves Chibon |
73d120 |
if inp.get("type") == "hidden":
|
|
Pierre-Yves Chibon |
73d120 |
output[inp.get("name")] = inp.get("value")
|
|
Pierre-Yves Chibon |
517d69 |
return output
|
|
Pierre-Yves Chibon |
517d69 |
|
|
Pierre-Yves Chibon |
517d69 |
|
|
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)
|
|
Pierre-Yves Chibon |
517d69 |
|
|
Pierre-Yves Chibon |
517d69 |
# Handle the POST wait case
|
|
Pierre-Yves Chibon |
517d69 |
form_url = None
|
|
Pierre-Yves Chibon |
517d69 |
form_args = None
|
|
Aurélien Bompard |
626417 |
try:
|
|
Aurélien Bompard |
626417 |
result_text = result.get_data(as_text=True)
|
|
Aurélien Bompard |
626417 |
except UnicodeDecodeError:
|
|
Aurélien Bompard |
626417 |
return result
|
|
Aurélien Bompard |
626417 |
if 'id="waitform"' in result_text:
|
|
Aurélien Bompard |
626417 |
form_url = get_post_target(result_text)
|
|
Aurélien Bompard |
626417 |
form_args = get_post_args(result_text)
|
|
Pierre-Yves Chibon |
73d120 |
form_args["csrf_token"] = result_text.split(
|
|
Pierre-Yves Chibon |
73d120 |
'name="csrf_token" type="hidden" value="'
|
|
Pierre-Yves Chibon |
73d120 |
)[1].split('">')[0]
|
|
Pierre-Yves Chibon |
517d69 |
|
|
Patrick Uiterwijk |
114ca2 |
count = 0
|
|
Pierre-Yves Chibon |
73d120 |
while "We are waiting for your task to finish." in result_text:
|
|
Patrick Uiterwijk |
114ca2 |
# Resolve wait page
|
|
Aurélien Bompard |
626417 |
target_url = get_wait_target(result_text)
|
|
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)
|
|
Aurélien Bompard |
626417 |
try:
|
|
Aurélien Bompard |
626417 |
result_text = result.get_data(as_text=True)
|
|
Aurélien Bompard |
626417 |
except UnicodeDecodeError:
|
|
Aurélien Bompard |
626417 |
return result
|
|
Patrick Uiterwijk |
114ca2 |
if count > 50:
|
|
Pierre-Yves Chibon |
73d120 |
raise Exception("Had to wait too long")
|
|
Patrick Uiterwijk |
114ca2 |
else:
|
|
Pierre-Yves Chibon |
517d69 |
if form_url and form_args:
|
|
Pierre-Yves Chibon |
517d69 |
return method(form_url, data=form_args, follow_redirects=True)
|
|
Patrick Uiterwijk |
114ca2 |
return result
|
|
Pierre-Yves Chibon |
73d120 |
|
|
Patrick Uiterwijk |
114ca2 |
return maybe_waiter
|
|
Patrick Uiterwijk |
114ca2 |
|
|
Patrick Uiterwijk |
114ca2 |
|
|
Pierre-Yves Chibon |
413073 |
@contextmanager
|
|
Patrick Uiterwijk |
3d2cb5 |
def user_set(APP, user, keep_get_user=False):
|
|
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 |
73d120 |
|
|
Pierre-Yves Chibon |
4ad0bb |
keep = []
|
|
Pierre-Yves Chibon |
4ad0bb |
for meth in APP.before_request_funcs[None]:
|
|
Pierre-Yves Chibon |
73d120 |
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 |
73d120 |
g.fas_session_id = b"123"
|
|
Pierre-Yves Chibon |
392277 |
g.authenticated = True
|
|
Pierre-Yves Chibon |
73d120 |
|
|
Patrick Uiterwijk |
3d2cb5 |
old_get_user = pagure.flask_app._get_user
|
|
Patrick Uiterwijk |
3d2cb5 |
if not keep_get_user:
|
|
Patrick Uiterwijk |
3d2cb5 |
pagure.flask_app._get_user = mock.MagicMock(
|
|
Pierre-Yves Chibon |
73d120 |
return_value=pagure.lib.model.User()
|
|
Pierre-Yves Chibon |
73d120 |
)
|
|
Pierre-Yves Chibon |
413073 |
|
|
Pierre-Yves Chibon |
413073 |
with appcontext_pushed.connected_to(handler, APP):
|
|
Pierre-Yves Chibon |
413073 |
yield
|
|
Pierre-Yves Chibon |
413073 |
|
|
Patrick Uiterwijk |
3d2cb5 |
pagure.flask_app._get_user = old_get_user
|
|
Patrick Uiterwijk |
3d2cb5 |
|
|
Slavek Kabrda |
7713cf |
|
|
Aurélien Bompard |
e78d79 |
tests_state = {
|
|
Pierre-Yves Chibon |
73d120 |
"path": tempfile.mkdtemp(prefix="pagure-tests-"),
|
|
Aurélien Bompard |
e78d79 |
"broker": None,
|
|
Aurélien Bompard |
00115d |
"broker_client": None,
|
|
Aurélien Bompard |
00115d |
"results": {},
|
|
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(
|
|
Pierre-Yves Chibon |
73d120 |
user="pingou",
|
|
Pierre-Yves Chibon |
73d120 |
fullname="PY C",
|
|
Pierre-Yves Chibon |
73d120 |
password=b"foo",
|
|
Pierre-Yves Chibon |
73d120 |
default_email="bar@pingou.com",
|
|
Slavek Kabrda |
7713cf |
)
|
|
Slavek Kabrda |
7713cf |
session.add(item)
|
|
Pierre-Yves Chibon |
73d120 |
item = pagure.lib.model.UserEmail(user_id=1, email="bar@pingou.com")
|
|
Slavek Kabrda |
7713cf |
session.add(item)
|
|
Pierre-Yves Chibon |
73d120 |
item = pagure.lib.model.UserEmail(user_id=1, email="foo@pingou.com")
|
|
Slavek Kabrda |
7713cf |
session.add(item)
|
|
Slavek Kabrda |
7713cf |
|
|
Slavek Kabrda |
7713cf |
item = pagure.lib.model.User(
|
|
Pierre-Yves Chibon |
73d120 |
user="foo",
|
|
Pierre-Yves Chibon |
73d120 |
fullname="foo bar",
|
|
Pierre-Yves Chibon |
73d120 |
password=b"foo",
|
|
Pierre-Yves Chibon |
73d120 |
default_email="foo@bar.com",
|
|
Slavek Kabrda |
7713cf |
)
|
|
Slavek Kabrda |
7713cf |
session.add(item)
|
|
Pierre-Yves Chibon |
73d120 |
item = pagure.lib.model.UserEmail(user_id=2, email="foo@bar.com")
|
|
Slavek Kabrda |
7713cf |
session.add(item)
|
|
Slavek Kabrda |
7713cf |
|
|
Slavek Kabrda |
7713cf |
session.commit()
|
|
Slavek Kabrda |
7713cf |
|
|
Slavek Kabrda |
7713cf |
|
|
Aurélien Bompard |
00115d |
def store_eager_results(*args, **kwargs):
|
|
Aurélien Bompard |
00115d |
"""A wrapper for EagerResult that stores the instance."""
|
|
Aurélien Bompard |
00115d |
result = EagerResult(*args, **kwargs)
|
|
Aurélien Bompard |
00115d |
tests_state["results"][result.id] = result
|
|
Aurélien Bompard |
00115d |
return result
|
|
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(
|
|
Pierre-Yves Chibon |
73d120 |
"sqlite:///%s/db.sqlite" % tests_state["path"],
|
|
Pierre-Yves Chibon |
73d120 |
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
|
|
Pierre-Yves Chibon |
73d120 |
broker_url = os.path.join(tests_state["path"], "broker")
|
|
Aurélien Bompard |
e78d79 |
|
|
Aurélien Bompard |
e78d79 |
tests_state["broker"] = broker = subprocess.Popen(
|
|
Pierre-Yves Chibon |
73d120 |
[
|
|
Pierre-Yves Chibon |
73d120 |
"/usr/bin/redis-server",
|
|
Pierre-Yves Chibon |
73d120 |
"--unixsocket",
|
|
Pierre-Yves Chibon |
73d120 |
broker_url,
|
|
Pierre-Yves Chibon |
73d120 |
"--port",
|
|
Pierre-Yves Chibon |
73d120 |
"0",
|
|
Pierre-Yves Chibon |
73d120 |
"--loglevel",
|
|
Pierre-Yves Chibon |
73d120 |
"warning",
|
|
Pierre-Yves Chibon |
73d120 |
"--logfile",
|
|
Pierre-Yves Chibon |
73d120 |
"/dev/null",
|
|
Pierre-Yves Chibon |
73d120 |
],
|
|
Pierre-Yves Chibon |
73d120 |
stdout=None,
|
|
Pierre-Yves Chibon |
73d120 |
stderr=None,
|
|
Pierre-Yves Chibon |
73d120 |
)
|
|
Slavek Kabrda |
3cb529 |
broker.poll()
|
|
Slavek Kabrda |
3cb529 |
if broker.returncode is not None:
|
|
Pierre-Yves Chibon |
73d120 |
raise Exception("Broker failed to start")
|
|
Aurélien Bompard |
00115d |
tests_state["broker_client"] = redis.Redis(unix_socket_path=broker_url)
|
|
Aurélien Bompard |
00115d |
|
|
Aurélien Bompard |
00115d |
# Store the EagerResults to be able to retrieve them later
|
|
Pierre-Yves Chibon |
73d120 |
tests_state["eg_patcher"] = mock.patch("celery.app.task.EagerResult")
|
|
Aurélien Bompard |
00115d |
eg_mock = tests_state["eg_patcher"].start()
|
|
Aurélien Bompard |
00115d |
eg_mock.side_effect = store_eager_results
|
|
Slavek Kabrda |
7713cf |
|
|
Pierre-Yves Chibon |
2d5c52 |
|
|
Slavek Kabrda |
3cb529 |
def tearDown():
|
|
Aurélien Bompard |
e78d79 |
tests_state["db_session"].close()
|
|
Aurélien Bompard |
00115d |
tests_state["eg_patcher"].stop()
|
|
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 |
73d120 |
@mock.patch("pagure.lib.notify.fedmsg_publish", mock.MagicMock())
|
|
Pierre-Yves Chibon |
73d120 |
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:
|
|
Pierre-Yves Chibon |
73d120 |
for walk in reqstat["walks"].values():
|
|
Patrick Uiterwijk |
fcd520 |
num_walks += 1
|
|
Pierre-Yves Chibon |
73d120 |
num_steps += walk["steps"]
|
|
Pierre-Yves Chibon |
73d120 |
self.assertLessEqual(
|
|
Pierre-Yves Chibon |
73d120 |
num_walks,
|
|
Pierre-Yves Chibon |
73d120 |
max_walks,
|
|
Pierre-Yves Chibon |
73d120 |
"%s git repo walks performed, at most %s allowed"
|
|
Pierre-Yves Chibon |
73d120 |
% (num_walks, max_walks),
|
|
Pierre-Yves Chibon |
73d120 |
)
|
|
Pierre-Yves Chibon |
73d120 |
self.assertLessEqual(
|
|
Pierre-Yves Chibon |
73d120 |
num_steps,
|
|
Pierre-Yves Chibon |
73d120 |
max_steps,
|
|
Pierre-Yves Chibon |
73d120 |
"%s git repo steps performed, at most %s allowed"
|
|
Pierre-Yves Chibon |
73d120 |
% (num_steps, max_steps),
|
|
Pierre-Yves Chibon |
73d120 |
)
|
|
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):
|
|
Patrick Uiterwijk |
8a2282 |
if self.path:
|
|
Patrick Uiterwijk |
8a2282 |
# This prevents test state leakage.
|
|
Patrick Uiterwijk |
8a2282 |
# This should be None if the previous runs' tearDown didn't finish,
|
|
Patrick Uiterwijk |
8a2282 |
# leaving behind a self.path.
|
|
Patrick Uiterwijk |
8a2282 |
# If we continue in this case, not only did the previous worker and
|
|
Patrick Uiterwijk |
8a2282 |
# redis instances not exit, we also might accidentally use the
|
|
Patrick Uiterwijk |
8a2282 |
# old database connection.
|
|
Patrick Uiterwijk |
8a2282 |
# @pingou, don't delete this again... :)
|
|
Pierre-Yves Chibon |
73d120 |
raise Exception("Previous test failed!")
|
|
Patrick Uiterwijk |
8a2282 |
|
|
Clement Verna |
109c4b |
self.perfReset()
|
|
Patrick Uiterwijk |
fcd520 |
|
|
Pierre-Yves Chibon |
73d120 |
self.path = tempfile.mkdtemp(prefix="pagure-tests-path-")
|
|
Pierre-Yves Chibon |
8b2c5c |
|
|
Pierre-Yves Chibon |
73d120 |
LOG.debug("Testdir: %s", self.path)
|
|
Pierre-Yves Chibon |
73d120 |
for folder in ["repos", "forks", "releases", "remotes", "attachments"]:
|
|
Jeremy Cline |
20109f |
os.mkdir(os.path.join(self.path, folder))
|
|
Pierre-Yves Chibon |
58e731 |
|
|
Pierre-Yves Chibon |
73d120 |
if hasattr(pagure.lib.query, "REDIS") and pagure.lib.query.REDIS:
|
|
Pierre-Yves Chibon |
930073 |
pagure.lib.query.REDIS.connection_pool.disconnect()
|
|
Pierre-Yves Chibon |
930073 |
pagure.lib.query.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 = {
|
|
Pierre-Yves Chibon |
73d120 |
"path": self.path,
|
|
Pierre-Yves Chibon |
73d120 |
"dburl": self.dbpath,
|
|
Pierre-Yves Chibon |
73d120 |
"enable_docs": True,
|
|
Pierre-Yves Chibon |
73d120 |
"docs_folder": "%s/repos/docs" % self.path,
|
|
Pierre-Yves Chibon |
73d120 |
"enable_tickets": True,
|
|
Pierre-Yves Chibon |
73d120 |
"tickets_folder": "%s/repos/tickets" % self.path,
|
|
Pierre-Yves Chibon |
73d120 |
"global_path": tests_state["path"],
|
|
Pierre-Yves Chibon |
73d120 |
"authbackend": "gitolite3",
|
|
Pierre-Yves Chibon |
73d120 |
"repobridge_binary": "/usr/libexec/repobridge",
|
|
Pierre-Yves Chibon |
73d120 |
"repospanner_gitport": str(8443 + sys.version_info.major),
|
|
Pierre-Yves Chibon |
73d120 |
"repospanner_new_repo": "None",
|
|
Pierre-Yves Chibon |
73d120 |
"repospanner_admin_override": "False",
|
|
Pierre-Yves Chibon |
73d120 |
"repospanner_new_fork": "True",
|
|
Pierre-Yves Chibon |
73d120 |
"repospanner_admin_migration": "False",
|
|
Aurélien Bompard |
e78d79 |
}
|
|
Aurélien Bompard |
e78d79 |
config_values.update(self.config_values)
|
|
Pierre-Yves Chibon |
30c623 |
self.config_values = config_values
|
|
Pierre-Yves Chibon |
73d120 |
config_path = os.path.join(self.path, "config")
|
|
Pierre-Yves Chibon |
8b2c5c |
if not os.path.exists(config_path):
|
|
Pierre-Yves Chibon |
73d120 |
with open(config_path, "w") as f:
|
|
Pierre-Yves Chibon |
30c623 |
f.write(CONFIG_TEMPLATE % self.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 |
626417 |
imp.reload(pagure.lib.tasks)
|
|
Pierre-Yves Chibon |
893d4f |
imp.reload(pagure.lib.tasks_mirror)
|
|
Aurélien Bompard |
626417 |
imp.reload(pagure.lib.tasks_services)
|
|
Pierre-Yves Chibon |
b130e5 |
|
|
Pierre-Yves Chibon |
73d120 |
self._app = pagure.flask_app.create_app({"DB_URL": self.dbpath})
|
|
Pierre-Yves Chibon |
b130e5 |
|
|
Slavek Kabrda |
3675ce |
self.app = self._app.test_client()
|
|
Pierre-Yves Chibon |
73d120 |
self.gr_patcher = mock.patch("pagure.lib.tasks.get_result")
|
|
Aurélien Bompard |
00115d |
gr_mock = self.gr_patcher.start()
|
|
Aurélien Bompard |
00115d |
gr_mock.side_effect = lambda tid: tests_state["results"][tid]
|
|
Pierre-Yves Chibon |
564e63 |
|
|
Pierre-Yves Chibon |
b3d8b5 |
# Refresh the DB session
|
|
Pierre-Yves Chibon |
b3d8b5 |
self.session = pagure.lib.query.create_session(self.dbpath)
|
|
Pierre-Yves Chibon |
b3d8b5 |
|
|
Clement Verna |
109c4b |
def tearDown(self):
|
|
Aurélien Bompard |
00115d |
self.gr_patcher.stop()
|
|
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 |
00115d |
doc = self.__str__() + ": " + self._testMethodDoc
|
|
Aurélien Bompard |
00115d |
return doc or None
|
|
Aurélien Bompard |
f61bb3 |
|
|
Aurélien Bompard |
e78d79 |
def _prepare_db(self):
|
|
Pierre-Yves Chibon |
73d120 |
self.dbpath = "sqlite:///%s" % os.path.join(
|
|
Pierre-Yves Chibon |
73d120 |
tests_state["path"], "db.sqlite"
|
|
Pierre-Yves Chibon |
73d120 |
)
|
|
Aurélien Bompard |
e78d79 |
self.session = tests_state["db_session"]
|
|
Aurélien Bompard |
e78d79 |
pagure.lib.model.create_default_status(
|
|
Pierre-Yves Chibon |
73d120 |
self.session, acls=pagure_config.get("ACLS", {})
|
|
Pierre-Yves Chibon |
73d120 |
)
|
|
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):
|
|
Pierre-Yves Chibon |
930073 |
tables = reversed(pagure.lib.model_base.BASE.metadata.sorted_tables)
|
|
Pierre-Yves Chibon |
73d120 |
if self.dbpath.startswith("postgresql"):
|
|
Pierre-Yves Chibon |
73d120 |
self.session.execute(
|
|
Pierre-Yves Chibon |
73d120 |
"TRUNCATE %s CASCADE" % ", ".join([t.name for t in tables])
|
|
Pierre-Yves Chibon |
73d120 |
)
|
|
Pierre-Yves Chibon |
73d120 |
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)
|
|
Pierre-Yves Chibon |
73d120 |
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 |
|
|
Patrick Uiterwijk |
b2cb9c |
def set_auth_status(self, value):
|
|
Patrick Uiterwijk |
b2cb9c |
""" Set the return value for the test auth """
|
|
Pierre-Yves Chibon |
73d120 |
with open(
|
|
Pierre-Yves Chibon |
73d120 |
os.path.join(self.path, "testauth_status.json"), "w"
|
|
Pierre-Yves Chibon |
73d120 |
) as statusfile:
|
|
Patrick Uiterwijk |
b2cb9c |
statusfile.write(six.u(json.dumps(value)))
|
|
Patrick Uiterwijk |
b2cb9c |
|
|
Pierre-Yves Chibon |
73d120 |
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 |
73d120 |
return (
|
|
Pierre-Yves Chibon |
73d120 |
output.get_data(as_text=True)
|
|
Pierre-Yves Chibon |
73d120 |
.split('name="csrf_token" type="hidden" value="')[1]
|
|
Pierre-Yves Chibon |
73d120 |
.split('">')[0]
|
|
Pierre-Yves Chibon |
73d120 |
)
|
|
Pierre-Yves Chibon |
d596a9 |
|
|
Pierre-Yves Chibon |
3e9b1d |
def get_wtforms_version(self):
|
|
Pierre-Yves Chibon |
3e9b1d |
"""Returns the wtforms version as a tuple."""
|
|
Pierre-Yves Chibon |
3e9b1d |
import wtforms
|
|
Pierre-Yves Chibon |
73d120 |
|
|
Pierre-Yves Chibon |
73d120 |
wtforms_v = wtforms.__version__.split(".")
|
|
Pierre-Yves Chibon |
3e9b1d |
for idx, val in enumerate(wtforms_v):
|
|
Pierre-Yves Chibon |
3e9b1d |
try:
|
|
Pierre-Yves Chibon |
3e9b1d |
val = int(val)
|
|
Pierre-Yves Chibon |
3e9b1d |
except ValueError:
|
|
Pierre-Yves Chibon |
3e9b1d |
pass
|
|
Pierre-Yves Chibon |
3e9b1d |
wtforms_v[idx] = val
|
|
Pierre-Yves Chibon |
3e9b1d |
return tuple(wtforms_v)
|
|
Pierre-Yves Chibon |
3e9b1d |
|
|
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 |
|
|
Pierre-Yves Chibon |
73d120 |
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 |
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 |
|
|
Pierre-Yves Chibon |
19ab90 |
# Refresh the DB session
|
|
Pierre-Yves Chibon |
19ab90 |
self.session = pagure.lib.query.create_session(self.dbpath)
|
|
Pierre-Yves Chibon |
19ab90 |
|
|
Pierre-Yves Chibon |
73d120 |
def tearDown(self): # pylint: disable=invalid-name
|
|
Clement Verna |
109c4b |
""" Remove the test.db database if there is one. """
|
|
Aurélien Bompard |
00115d |
tests_state["broker_client"].flushall()
|
|
Aurélien Bompard |
e78d79 |
super(Modeltests, self).tearDown()
|
|
Clement Verna |
109c4b |
|
|
Patrick Uiterwijk |
390193 |
def create_project_full(self, projectname, extra=None):
|
|
Patrick Uiterwijk |
b2cb9c |
""" Create a project via the API.
|
|
Patrick Uiterwijk |
b2cb9c |
|
|
Patrick Uiterwijk |
b2cb9c |
This makes sure that the repo is fully setup the way a normal new
|
|
Patrick Uiterwijk |
b2cb9c |
project would be, with hooks and all setup.
|
|
Patrick Uiterwijk |
b2cb9c |
"""
|
|
Patrick Uiterwijk |
b2cb9c |
|
|
Pierre-Yves Chibon |
73d120 |
headers = {"Authorization": "token aaabbbcccddd"}
|
|
Pierre-Yves Chibon |
73d120 |
data = {"name": projectname, "description": "A test repo"}
|
|
Patrick Uiterwijk |
390193 |
if extra:
|
|
Patrick Uiterwijk |
390193 |
data.update(extra)
|
|
Patrick Uiterwijk |
b2cb9c |
|
|
Patrick Uiterwijk |
b2cb9c |
# Valid request
|
|
Pierre-Yves Chibon |
73d120 |
output = self.app.post("/api/0/new/", data=data, headers=headers)
|
|
Patrick Uiterwijk |
b2cb9c |
self.assertEqual(output.status_code, 200)
|
|
Patrick Uiterwijk |
b2cb9c |
data = json.loads(output.get_data(as_text=True))
|
|
Patrick Uiterwijk |
b2cb9c |
self.assertDictEqual(
|
|
Pierre-Yves Chibon |
73d120 |
data, {"message": 'Project "%s" created' % projectname}
|
|
Patrick Uiterwijk |
b2cb9c |
)
|
|
Patrick Uiterwijk |
b2cb9c |
|
|
Pierre-Yves Chibon |
413073 |
|
|
Pierre-Yves Chibon |
73d120 |
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 |
73d120 |
self.group_type = "cla"
|
|
Pierre-Yves Chibon |
413073 |
|
|
Pierre-Yves Chibon |
413073 |
|
|
Pierre-Yves Chibon |
73d120 |
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 |
73d120 |
def __init__(
|
|
Pierre-Yves Chibon |
73d120 |
self, groups=None, username="username", cla_done=True, id=None
|
|
Pierre-Yves Chibon |
73d120 |
):
|
|
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 |
"""
|
|
Aurélien Bompard |
626417 |
if isinstance(groups, six.string_types):
|
|
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 |
73d120 |
self.email = "foo@bar.com"
|
|
Pierre-Yves Chibon |
73d120 |
self.default_email = "foo@bar.com"
|
|
Ryan Lerch |
5682fd |
|
|
Pierre-Yves Chibon |
413073 |
self.approved_memberships = [
|
|
Pierre-Yves Chibon |
73d120 |
FakeGroup("packager"),
|
|
Pierre-Yves Chibon |
73d120 |
FakeGroup("design-team"),
|
|
Pierre-Yves Chibon |
413073 |
]
|
|
Pierre-Yves Chibon |
413073 |
self.dic = {}
|
|
Pierre-Yves Chibon |
73d120 |
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 |
|
|
Patrick Uiterwijk |
3f97f6 |
def create_locks(session, project):
|
|
Pierre-Yves Chibon |
73d120 |
for ltype in ("WORKER", "WORKER_TICKET", "WORKER_REQUEST"):
|
|
Patrick Uiterwijk |
3f97f6 |
lock = pagure.lib.model.ProjectLock(
|
|
Pierre-Yves Chibon |
73d120 |
project_id=project.id, lock_type=ltype
|
|
Pierre-Yves Chibon |
73d120 |
)
|
|
Patrick Uiterwijk |
3f97f6 |
session.add(lock)
|
|
Patrick Uiterwijk |
3f97f6 |
|
|
Patrick Uiterwijk |
3f97f6 |
|
|
Pierre-Yves Chibon |
73d120 |
def create_projects(session, is_fork=False, user_id=1, hook_token_suffix=""):
|
|
Pierre-Yves Chibon |
413073 |
""" Create some projects in the database. """
|
|
Pierre-Yves Chibon |
fe5017 |
item = pagure.lib.model.Project(
|
|
Pierre-Yves Chibon |
11d019 |
user_id=user_id, # pingou
|
|
Pierre-Yves Chibon |
73d120 |
name="test",
|
|
Pierre-Yves Chibon |
11d019 |
is_fork=is_fork,
|
|
Pierre-Yves Chibon |
11d019 |
parent_id=1 if is_fork else None,
|
|
Pierre-Yves Chibon |
73d120 |
description="test project #1",
|
|
Pierre-Yves Chibon |
73d120 |
hook_token="aaabbbccc" + hook_token_suffix,
|
|
Pierre-Yves Chibon |
413073 |
)
|
|
Pierre-Yves Chibon |
73d120 |
item.close_status = ["Invalid", "Insufficient data", "Fixed", "Duplicate"]
|
|
Pierre-Yves Chibon |
413073 |
session.add(item)
|
|
Patrick Uiterwijk |
3f97f6 |
session.flush()
|
|
Patrick Uiterwijk |
3f97f6 |
create_locks(session, item)
|
|
Pierre-Yves Chibon |
413073 |
|
|
Pierre-Yves Chibon |
fe5017 |
item = pagure.lib.model.Project(
|
|
Pierre-Yves Chibon |
11d019 |
user_id=user_id, # pingou
|
|
Pierre-Yves Chibon |
73d120 |
name="test2",
|
|
Pierre-Yves Chibon |
11d019 |
is_fork=is_fork,
|
|
Pierre-Yves Chibon |
11d019 |
parent_id=2 if is_fork else None,
|
|
Pierre-Yves Chibon |
73d120 |
description="test project #2",
|
|
Pierre-Yves Chibon |
73d120 |
hook_token="aaabbbddd" + hook_token_suffix,
|
|
Pierre-Yves Chibon |
413073 |
)
|
|
Pierre-Yves Chibon |
73d120 |
item.close_status = ["Invalid", "Insufficient data", "Fixed", "Duplicate"]
|
|
Pierre-Yves Chibon |
413073 |
session.add(item)
|
|
Pierre-Yves Chibon |
930073 |
session.flush()
|
|
Pierre-Yves Chibon |
930073 |
create_locks(session, item)
|
|
Pierre-Yves Chibon |
413073 |
|
|
clime |
afed57 |
item = pagure.lib.model.Project(
|
|
Pierre-Yves Chibon |
11d019 |
user_id=user_id, # pingou
|
|
Pierre-Yves Chibon |
73d120 |
name="test3",
|
|
Pierre-Yves Chibon |
11d019 |
is_fork=is_fork,
|
|
Pierre-Yves Chibon |
11d019 |
parent_id=3 if is_fork else None,
|
|
Pierre-Yves Chibon |
73d120 |
description="namespaced test project",
|
|
Pierre-Yves Chibon |
73d120 |
hook_token="aaabbbeee" + hook_token_suffix,
|
|
Pierre-Yves Chibon |
73d120 |
namespace="somenamespace",
|
|
clime |
afed57 |
)
|
|
Pierre-Yves Chibon |
73d120 |
item.close_status = ["Invalid", "Insufficient data", "Fixed", "Duplicate"]
|
|
clime |
afed57 |
session.add(item)
|
|
Pierre-Yves Chibon |
930073 |
session.flush()
|
|
Pierre-Yves Chibon |
930073 |
create_locks(session, item)
|
|
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 = []
|
|
Pierre-Yves Chibon |
73d120 |
for project in [
|
|
Pierre-Yves Chibon |
73d120 |
"test.git",
|
|
Pierre-Yves Chibon |
73d120 |
"test2.git",
|
|
Pierre-Yves Chibon |
73d120 |
os.path.join("somenamespace", "test3.git"),
|
|
Pierre-Yves Chibon |
73d120 |
]:
|
|
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 |
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 |
73d120 |
id="aaabbbcccddd",
|
|
Pierre-Yves Chibon |
c0b635 |
user_id=user_id,
|
|
Pierre-Yves Chibon |
a14636 |
project_id=project_id,
|
|
Pierre-Yves Chibon |
73d120 |
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 |
73d120 |
id="foo_token",
|
|
Pierre-Yves Chibon |
c0b635 |
user_id=user_id,
|
|
Pierre-Yves Chibon |
a14636 |
project_id=project_id,
|
|
Pierre-Yves Chibon |
73d120 |
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 |
73d120 |
id="expired_token",
|
|
Pierre-Yves Chibon |
c0b635 |
user_id=user_id,
|
|
Pierre-Yves Chibon |
a14636 |
project_id=project_id,
|
|
Pierre-Yves Chibon |
73d120 |
expiration=datetime.utcnow() - timedelta(days=1),
|
|
Pierre-Yves Chibon |
c0b635 |
)
|
|
Pierre-Yves Chibon |
c0b635 |
session.add(item)
|
|
Pierre-Yves Chibon |
c0b635 |
session.commit()
|
|
Pierre-Yves Chibon |
c0b635 |
|
|
Pierre-Yves Chibon |
c0b635 |
|
|
Pierre-Yves Chibon |
73d120 |
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 |
73d120 |
for aclid in range(len(pagure_config["ACLS"])):
|
|
Matt Prahl |
30f8b1 |
token_acl = pagure.lib.model.TokenAcl(
|
|
Pierre-Yves Chibon |
73d120 |
token_id=token_id, acl_id=aclid + 1
|
|
Matt Prahl |
30f8b1 |
)
|
|
Matt Prahl |
30f8b1 |
session.add(token_acl)
|
|
Matt Prahl |
30f8b1 |
else:
|
|
Pierre-Yves Chibon |
73d120 |
acl = (
|
|
Pierre-Yves Chibon |
73d120 |
session.query(pagure.lib.model.ACL).filter_by(name=acl_name).one()
|
|
Pierre-Yves Chibon |
955beb |
)
|
|
Pierre-Yves Chibon |
73d120 |
token_acl = pagure.lib.model.TokenAcl(token_id=token_id, acl_id=acl.id)
|
|
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 |
8a76fa |
def _clone_and_top_commits(folder, branch, branch_ref=False):
|
|
Pierre-Yves Chibon |
8a76fa |
""" Clone the repository, checkout the specified branch and return
|
|
Pierre-Yves Chibon |
8a76fa |
the top commit of that branch if there is one.
|
|
Pierre-Yves Chibon |
8a76fa |
Returns the repo, the path to the clone and the top commit(s) in a tuple
|
|
Pierre-Yves Chibon |
8a76fa |
or the repo, the path to the clone and the reference to the branch
|
|
Pierre-Yves Chibon |
8a76fa |
object if branch_ref is True.
|
|
Pierre-Yves Chibon |
8a76fa |
"""
|
|
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 |
73d120 |
newfolder = tempfile.mkdtemp(prefix="pagure-tests")
|
|
Pierre-Yves Chibon |
128dfb |
repo = pygit2.clone_repository(folder, newfolder)
|
|
Pierre-Yves Chibon |
f0ad75 |
|
|
Pierre-Yves Chibon |
6fdafd |
branch_ref_obj = None
|
|
Pierre-Yves Chibon |
6fdafd |
if "origin/%s" % branch in repo.listall_branches(pygit2.GIT_BRANCH_ALL):
|
|
Pierre-Yves Chibon |
6fdafd |
branch_ref_obj = pagure.lib.git.get_branch_ref(repo, branch)
|
|
Pierre-Yves Chibon |
6fdafd |
repo.checkout(branch_ref_obj)
|
|
Pierre-Yves Chibon |
f0ad75 |
|
|
Pierre-Yves Chibon |
8a76fa |
if branch_ref:
|
|
Pierre-Yves Chibon |
8a76fa |
return (repo, newfolder, branch_ref_obj)
|
|
Pierre-Yves Chibon |
8a76fa |
|
|
Pierre-Yves Chibon |
a71c8d |
parents = []
|
|
Pierre-Yves Chibon |
a71c8d |
commit = None
|
|
Pierre-Yves Chibon |
a71c8d |
try:
|
|
Pierre-Yves Chibon |
6fdafd |
if branch_ref_obj:
|
|
Pierre-Yves Chibon |
29ff0a |
commit = repo[branch_ref_obj.peel().hex]
|
|
Pierre-Yves Chibon |
6fdafd |
else:
|
|
Pierre-Yves Chibon |
73d120 |
commit = repo.revparse_single("HEAD")
|
|
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 |
8a76fa |
return (repo, newfolder, parents)
|
|
Pierre-Yves Chibon |
8a76fa |
|
|
Pierre-Yves Chibon |
8a76fa |
|
|
Pierre-Yves Chibon |
73d120 |
def add_content_git_repo(folder, branch="master", append=None):
|
|
Pierre-Yves Chibon |
8a76fa |
""" Create some content for the specified git repo. """
|
|
Pierre-Yves Chibon |
8a76fa |
repo, newfolder, parents = _clone_and_top_commits(folder, branch)
|
|
Pierre-Yves Chibon |
8a76fa |
|
|
Pierre-Yves Chibon |
6fdafd |
# Create a file in that git repo
|
|
Pierre-Yves Chibon |
73d120 |
filename = os.path.join(newfolder, "sources")
|
|
Pierre-Yves Chibon |
73d120 |
content = "foo\n bar"
|
|
Pierre-Yves Chibon |
6fdafd |
if os.path.exists(filename):
|
|
Pierre-Yves Chibon |
73d120 |
content = "foo\n bar\nbaz"
|
|
Pierre-Yves Chibon |
6fdafd |
if append:
|
|
Pierre-Yves Chibon |
6fdafd |
content += append
|
|
Pierre-Yves Chibon |
73d120 |
with open(filename, "w") as stream:
|
|
Pierre-Yves Chibon |
6fdafd |
stream.write(content)
|
|
Pierre-Yves Chibon |
73d120 |
repo.index.add("sources")
|
|
Pierre-Yves Chibon |
6fdafd |
repo.index.write()
|
|
Pierre-Yves Chibon |
6fdafd |
|
|
Pierre-Yves Chibon |
f0ad75 |
# Commits the files added
|
|
Pierre-Yves Chibon |
f0ad75 |
tree = repo.index.write_tree()
|
|
Pierre-Yves Chibon |
73d120 |
author = pygit2.Signature("Alice Author", "alice@authors.tld")
|
|
Pierre-Yves Chibon |
73d120 |
committer = pygit2.Signature("Cecil Committer", "cecil@committers.tld")
|
|
Pierre-Yves Chibon |
6fdafd |
commit = repo.create_commit(
|
|
Pierre-Yves Chibon |
73d120 |
"refs/heads/%s" % branch, # the name of the reference to update
|
|
Pierre-Yves Chibon |
f0ad75 |
author,
|
|
Pierre-Yves Chibon |
f0ad75 |
committer,
|
|
Pierre-Yves Chibon |
73d120 |
"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 |
if commit:
|
|
Pierre-Yves Chibon |
6fdafd |
parents = [commit.hex]
|
|
Pierre-Yves Chibon |
f0ad75 |
|
|
Pierre-Yves Chibon |
73d120 |
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 |
73d120 |
with open(os.path.join(newfolder, subfolder, "file"), "w") as stream:
|
|
Pierre-Yves Chibon |
73d120 |
stream.write("foo\n bar\nbaz")
|
|
Pierre-Yves Chibon |
73d120 |
repo.index.add(os.path.join(subfolder, "file"))
|
|
Pierre-Yves Chibon |
73d120 |
with open(os.path.join(newfolder, subfolder, "fileŠ"), "w") as stream:
|
|
Pierre-Yves Chibon |
73d120 |
stream.write("foo\n bar\nbaz")
|
|
Pierre-Yves Chibon |
73d120 |
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 |
73d120 |
author = pygit2.Signature("Alice Author", "alice@authors.tld")
|
|
Pierre-Yves Chibon |
73d120 |
committer = pygit2.Signature("Cecil Committer", "cecil@committers.tld")
|
|
Pierre-Yves Chibon |
73d120 |
commit = repo.create_commit(
|
|
Pierre-Yves Chibon |
73d120 |
"refs/heads/%s" % branch, # the name of the reference to update
|
|
Pierre-Yves Chibon |
f0ad75 |
author,
|
|
Pierre-Yves Chibon |
f0ad75 |
committer,
|
|
Pierre-Yves Chibon |
73d120 |
"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 |
73d120 |
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 |
73d120 |
"HEAD" if branch == "master" else "refs/heads/%s" % branch
|
|
Pierre-Yves Chibon |
73d120 |
).resolve()
|
|
Pierre-Yves Chibon |
73d120 |
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 |
73d120 |
def add_readme_git_repo(folder, readme_name="README.rst", branch="master"):
|
|
Pierre-Yves Chibon |
87ffe2 |
""" Create a README file for the specified git repo. """
|
|
Pierre-Yves Chibon |
8a76fa |
repo, newfolder, parents = _clone_and_top_commits(folder, branch)
|
|
Pierre-Yves Chibon |
6fdafd |
|
|
Pierre-Yves Chibon |
73d120 |
if readme_name == "README.rst":
|
|
Karsten Hopp |
5192eb |
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 |
"""
|
|
Karsten Hopp |
5192eb |
else:
|
|
Pierre-Yves Chibon |
73d120 |
content = (
|
|
Pierre-Yves Chibon |
73d120 |
"""Pagure
|
|
Karsten Hopp |
5192eb |
======
|
|
Karsten Hopp |
5192eb |
|
|
Pierre-Yves Chibon |
73d120 |
This is a placeholder """
|
|
Pierre-Yves Chibon |
73d120 |
+ readme_name
|
|
Pierre-Yves Chibon |
73d120 |
+ """
|
|
Karsten Hopp |
5192eb |
that should never get displayed on the website if there is a README.rst in the repo.
|
|
Karsten Hopp |
5192eb |
"""
|
|
Pierre-Yves Chibon |
73d120 |
)
|
|
Pierre-Yves Chibon |
87ffe2 |
|
|
Pierre-Yves Chibon |
87ffe2 |
# Create a file in that git repo
|
|
Pierre-Yves Chibon |
73d120 |
with open(os.path.join(newfolder, readme_name), "w") as stream:
|
|
Pierre-Yves Chibon |
87ffe2 |
stream.write(content)
|
|
Karsten Hopp |
5192eb |
repo.index.add(readme_name)
|
|
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 |
73d120 |
author = pygit2.Signature("Alice Author", "alice@authors.tld")
|
|
Pierre-Yves Chibon |
73d120 |
committer = pygit2.Signature("Cecil Committer", "cecil@committers.tld")
|
|
Pierre-Yves Chibon |
6fdafd |
branch_ref = "refs/heads/%s" % branch
|
|
Pierre-Yves Chibon |
87ffe2 |
repo.create_commit(
|
|
Pierre-Yves Chibon |
6fdafd |
branch_ref, # the name of the reference to update
|
|
Pierre-Yves Chibon |
87ffe2 |
author,
|
|
Pierre-Yves Chibon |
87ffe2 |
committer,
|
|
Pierre-Yves Chibon |
73d120 |
"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 |
73d120 |
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 |
|
|
Pierre-Yves Chibon |
73d120 |
PagureRepo.push(ori_remote, "%s:%s" % (branch_ref, branch_ref))
|
|
Pierre-Yves Chibon |
128dfb |
|
|
Pierre-Yves Chibon |
128dfb |
shutil.rmtree(newfolder)
|
|
Pierre-Yves Chibon |
128dfb |
|
|
Pierre-Yves Chibon |
87ffe2 |
|
|
Pierre-Yves Chibon |
73d120 |
def add_commit_git_repo(
|
|
Pierre-Yves Chibon |
73d120 |
folder, ncommits=10, filename="sources", branch="master", symlink_to=None
|
|
Pierre-Yves Chibon |
73d120 |
):
|
|
Pierre-Yves Chibon |
595b4e |
""" Create some more commits for the specified git repo. """
|
|
Pierre-Yves Chibon |
8a76fa |
repo, newfolder, branch_ref_obj = _clone_and_top_commits(
|
|
Pierre-Yves Chibon |
73d120 |
folder, branch, branch_ref=True
|
|
Pierre-Yves Chibon |
73d120 |
)
|
|
Pierre-Yves Chibon |
6fdafd |
|
|
Pierre-Yves Chibon |
595b4e |
for index in range(ncommits):
|
|
Pierre-Yves Chibon |
595b4e |
# Create a file in that git repo
|
|
Slavek Kabrda |
dade63 |
if symlink_to:
|
|
Pierre-Yves Chibon |
73d120 |
os.symlink(symlink_to, os.path.join(newfolder, filename))
|
|
Slavek Kabrda |
dade63 |
else:
|
|
Pierre-Yves Chibon |
73d120 |
with open(os.path.join(newfolder, filename), "a") as stream:
|
|
Pierre-Yves Chibon |
73d120 |
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 |
6fdafd |
if branch_ref_obj:
|
|
Pierre-Yves Chibon |
29ff0a |
commit = repo[branch_ref_obj.peel().hex]
|
|
Pierre-Yves Chibon |
6fdafd |
else:
|
|
Pierre-Yves Chibon |
73d120 |
commit = repo.revparse_single("HEAD")
|
|
Pierre-Yves Chibon |
6fdafd |
except (KeyError, AttributeError):
|
|
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 |
73d120 |
author = pygit2.Signature("Alice Author", "alice@authors.tld")
|
|
Pierre-Yves Chibon |
73d120 |
committer = pygit2.Signature("Cecil Committer", "cecil@committers.tld")
|
|
Pierre-Yves Chibon |
6fdafd |
branch_ref = "refs/heads/%s" % branch
|
|
Pierre-Yves Chibon |
595b4e |
repo.create_commit(
|
|
Pierre-Yves Chibon |
6fdafd |
branch_ref,
|
|
Pierre-Yves Chibon |
595b4e |
author,
|
|
Pierre-Yves Chibon |
595b4e |
committer,
|
|
Pierre-Yves Chibon |
73d120 |
"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 |
6fdafd |
branch_ref_obj = pagure.lib.git.get_branch_ref(repo, branch)
|
|
Pierre-Yves Chibon |
595b4e |
|
|
Pierre-Yves Chibon |
128dfb |
# Push to origin
|
|
Pierre-Yves Chibon |
128dfb |
ori_remote = repo.remotes[0]
|
|
Pierre-Yves Chibon |
73d120 |
PagureRepo.push(ori_remote, "%s:%s" % (branch_ref, branch_ref))
|
|
Pierre-Yves Chibon |
1cd41d |
|
|
Pierre-Yves Chibon |
1cd41d |
shutil.rmtree(newfolder)
|
|
Pierre-Yves Chibon |
1cd41d |
|
|
Pierre-Yves Chibon |
1cd41d |
|
|
Slavek Kabrda |
be430b |
def add_tag_git_repo(folder, tagname, obj_hash, message):
|
|
Slavek Kabrda |
be430b |
""" Add a tag to the given object of the given repo annotated by given message. """
|
|
Slavek Kabrda |
be430b |
repo, newfolder, branch_ref_obj = _clone_and_top_commits(
|
|
Pierre-Yves Chibon |
73d120 |
folder, "master", branch_ref=True
|
|
Pierre-Yves Chibon |
73d120 |
)
|
|
Slavek Kabrda |
be430b |
|
|
Slavek Kabrda |
be430b |
tag_sha = repo.create_tag(
|
|
Slavek Kabrda |
be430b |
tagname,
|
|
Slavek Kabrda |
be430b |
obj_hash,
|
|
Slavek Kabrda |
be430b |
repo.get(obj_hash).type,
|
|
Pierre-Yves Chibon |
73d120 |
pygit2.Signature("Alice Author", "alice@authors.tld"),
|
|
Slavek Kabrda |
be430b |
message,
|
|
Slavek Kabrda |
be430b |
)
|
|
Slavek Kabrda |
be430b |
|
|
Slavek Kabrda |
be430b |
# Push to origin
|
|
Slavek Kabrda |
be430b |
ori_remote = repo.remotes[0]
|
|
Pierre-Yves Chibon |
73d120 |
PagureRepo.push(
|
|
Pierre-Yves Chibon |
73d120 |
ori_remote, "refs/tags/%s:refs/tags/%s" % (tagname, tagname)
|
|
Pierre-Yves Chibon |
73d120 |
)
|
|
Slavek Kabrda |
be430b |
|
|
Slavek Kabrda |
be430b |
shutil.rmtree(newfolder)
|
|
Slavek Kabrda |
be430b |
return tag_sha
|
|
Slavek Kabrda |
be430b |
|
|
Slavek Kabrda |
be430b |
|
|
Pierre-Yves Chibon |
ec5e38 |
def add_content_to_git(
|
|
Julen Landa Alustiza |
c95aa4 |
folder,
|
|
Julen Landa Alustiza |
c95aa4 |
branch="master",
|
|
Julen Landa Alustiza |
c95aa4 |
filename="sources",
|
|
Julen Landa Alustiza |
c95aa4 |
content="foo",
|
|
Julen Landa Alustiza |
c95aa4 |
message=None,
|
|
Julen Landa Alustiza |
c95aa4 |
author=("Alice Author", "alice@authors.tld"),
|
|
Julen Landa Alustiza |
c95aa4 |
commiter=("Cecil Committer", "cecil@committers.tld"),
|
|
Pierre-Yves Chibon |
73d120 |
):
|
|
Pierre-Yves Chibon |
1cd41d |
""" Create some more commits for the specified git repo. """
|
|
Pierre-Yves Chibon |
ec5e38 |
repo, newfolder, branch_ref_obj = _clone_and_top_commits(
|
|
Pierre-Yves Chibon |
73d120 |
folder, branch, branch_ref=True
|
|
Pierre-Yves Chibon |
73d120 |
)
|
|
Pierre-Yves Chibon |
1cd41d |
|
|
Pierre-Yves Chibon |
1cd41d |
# Create a file in that git repo
|
|
Pierre-Yves Chibon |
73d120 |
with open(
|
|
Pierre-Yves Chibon |
73d120 |
os.path.join(newfolder, filename), "a", encoding="utf-8"
|
|
Pierre-Yves Chibon |
73d120 |
) as stream:
|
|
Pierre-Yves Chibon |
73d120 |
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 |
ec5e38 |
parents = []
|
|
Pierre-Yves Chibon |
ec5e38 |
commit = None
|
|
Pierre-Yves Chibon |
ec5e38 |
try:
|
|
Pierre-Yves Chibon |
ec5e38 |
if branch_ref_obj:
|
|
Pierre-Yves Chibon |
29ff0a |
commit = repo[branch_ref_obj.peel().hex]
|
|
Pierre-Yves Chibon |
ec5e38 |
else:
|
|
Pierre-Yves Chibon |
73d120 |
commit = repo.revparse_single("HEAD")
|
|
Pierre-Yves Chibon |
ec5e38 |
except (KeyError, AttributeError):
|
|
Pierre-Yves Chibon |
ec5e38 |
pass
|
|
Pierre-Yves Chibon |
ec5e38 |
if commit:
|
|
Pierre-Yves Chibon |
ec5e38 |
parents = [commit.oid.hex]
|
|
Pierre-Yves Chibon |
ec5e38 |
|
|
Pierre-Yves Chibon |
1cd41d |
# Commits the files added
|
|
Pierre-Yves Chibon |
1cd41d |
tree = repo.index.write_tree()
|
|
Julen Landa Alustiza |
c95aa4 |
author = pygit2.Signature(*author)
|
|
Julen Landa Alustiza |
c95aa4 |
committer = pygit2.Signature(*commiter)
|
|
Pierre-Yves Chibon |
ec5e38 |
branch_ref = "refs/heads/%s" % branch
|
|
Pierre-Yves Chibon |
73d120 |
message = message or "Add content to file %s" % (filename)
|
|
Pierre-Yves Chibon |
1cd41d |
repo.create_commit(
|
|
Pierre-Yves Chibon |
ec5e38 |
branch_ref, # the name of the reference to update
|
|
Pierre-Yves Chibon |
1cd41d |
author,
|
|
Pierre-Yves Chibon |
1cd41d |
committer,
|
|
Pierre-Yves Chibon |
722f04 |
message,
|
|
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 |
73d120 |
PagureRepo.push(ori_remote, "%s:%s" % (branch_ref, branch_ref))
|
|
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 |
73d120 |
repo, newfolder, parents = _clone_and_top_commits(folder, "master")
|
|
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 |
# Create a file in that git repo
|
|
Pierre-Yves Chibon |
73d120 |
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 |
73d120 |
author = pygit2.Signature("Alice Author", "alice@authors.tld")
|
|
Pierre-Yves Chibon |
73d120 |
committer = pygit2.Signature("Cecil Committer", "cecil@committers.tld")
|
|
Pierre-Yves Chibon |
6e857b |
repo.create_commit(
|
|
Pierre-Yves Chibon |
73d120 |
"refs/heads/master", # the name of the reference to update
|
|
Pierre-Yves Chibon |
6e857b |
author,
|
|
Pierre-Yves Chibon |
6e857b |
committer,
|
|
Pierre-Yves Chibon |
73d120 |
"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 |
73d120 |
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 |
73d120 |
master_ref = repo.lookup_reference("HEAD").resolve()
|
|
Pierre-Yves Chibon |
73d120 |
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 |
73d120 |
def remove_file_git_repo(folder, filename, branch="master"):
|
|
Pierre-Yves Chibon |
3470e1 |
""" Delete the specified file on the give git repo and branch. """
|
|
Pierre-Yves Chibon |
8a76fa |
repo, newfolder, parents = _clone_and_top_commits(folder, branch)
|
|
Pierre-Yves Chibon |
3470e1 |
|
|
Pierre-Yves Chibon |
3470e1 |
# Remove file
|
|
Pierre-Yves Chibon |
3470e1 |
repo.index.remove(filename)
|
|
Pierre-Yves Chibon |
3470e1 |
|
|
Pierre-Yves Chibon |
3470e1 |
# Write the change and commit it
|
|
Pierre-Yves Chibon |
3470e1 |
tree = repo.index.write_tree()
|
|
Pierre-Yves Chibon |
3470e1 |
|
|
Pierre-Yves Chibon |
73d120 |
author = pygit2.Signature("Alice Author", "alice@authors.tld")
|
|
Pierre-Yves Chibon |
73d120 |
committer = pygit2.Signature("Cecil Committer", "cecil@committers.tld")
|
|
Pierre-Yves Chibon |
3470e1 |
branch_ref = "refs/heads/%s" % branch
|
|
Pierre-Yves Chibon |
3470e1 |
repo.create_commit(
|
|
Pierre-Yves Chibon |
3470e1 |
branch_ref, # the name of the reference to update
|
|
Pierre-Yves Chibon |
3470e1 |
author,
|
|
Pierre-Yves Chibon |
3470e1 |
committer,
|
|
Pierre-Yves Chibon |
73d120 |
"Remove file %s" % filename,
|
|
Pierre-Yves Chibon |
3470e1 |
# binary string representing the tree object ID
|
|
Pierre-Yves Chibon |
3470e1 |
tree,
|
|
Pierre-Yves Chibon |
3470e1 |
# list of binary strings representing parents of the new commit
|
|
Pierre-Yves Chibon |
73d120 |
parents,
|
|
Pierre-Yves Chibon |
3470e1 |
)
|
|
Pierre-Yves Chibon |
3470e1 |
|
|
Pierre-Yves Chibon |
3470e1 |
# Push to origin
|
|
Pierre-Yves Chibon |
3470e1 |
ori_remote = repo.remotes[0]
|
|
Pierre-Yves Chibon |
3470e1 |
|
|
Pierre-Yves Chibon |
73d120 |
PagureRepo.push(ori_remote, "%s:%s" % (branch_ref, branch_ref))
|
|
Pierre-Yves Chibon |
3470e1 |
|
|
Pierre-Yves Chibon |
3470e1 |
shutil.rmtree(newfolder)
|
|
Pierre-Yves Chibon |
3470e1 |
|
|
Pierre-Yves Chibon |
3470e1 |
|
|
Aurélien Bompard |
a29742 |
@contextmanager
|
|
Aurélien Bompard |
a29742 |
def capture_output(merge_stderr=True):
|
|
Aurélien Bompard |
a29742 |
oldout, olderr = sys.stdout, sys.stderr
|
|
Aurélien Bompard |
a29742 |
try:
|
|
Aurélien Bompard |
a29742 |
out = StringIO()
|
|
Aurélien Bompard |
a29742 |
err = StringIO()
|
|
Aurélien Bompard |
a29742 |
if merge_stderr:
|
|
Aurélien Bompard |
a29742 |
sys.stdout = sys.stderr = out
|
|
Aurélien Bompard |
a29742 |
yield out
|
|
Aurélien Bompard |
a29742 |
else:
|
|
Aurélien Bompard |
a29742 |
sys.stdout, sys.stderr = out, err
|
|
Aurélien Bompard |
a29742 |
yield out, err
|
|
Aurélien Bompard |
a29742 |
finally:
|
|
Aurélien Bompard |
a29742 |
sys.stdout, sys.stderr = oldout, olderr
|
|
Aurélien Bompard |
a29742 |
|
|
Aurélien Bompard |
a29742 |
|
|
Aurélien Bompard |
626417 |
def get_alerts(html):
|
|
Aurélien Bompard |
626417 |
soup = BeautifulSoup(html, "html.parser")
|
|
Aurélien Bompard |
626417 |
alerts = []
|
|
Aurélien Bompard |
626417 |
for element in soup.find_all("div", class_="alert"):
|
|
Aurélien Bompard |
626417 |
severity = None
|
|
Aurélien Bompard |
626417 |
for class_ in element["class"]:
|
|
Aurélien Bompard |
626417 |
if not class_.startswith("alert-"):
|
|
Aurélien Bompard |
626417 |
continue
|
|
Aurélien Bompard |
626417 |
if class_ == "alert-dismissible":
|
|
Aurélien Bompard |
626417 |
continue
|
|
Pierre-Yves Chibon |
73d120 |
severity = class_[len("alert-") :]
|
|
Aurélien Bompard |
626417 |
break
|
|
Aurélien Bompard |
626417 |
element.find("button").decompose() # close button
|
|
Pierre-Yves Chibon |
73d120 |
alerts.append(
|
|
Pierre-Yves Chibon |
73d120 |
dict(severity=severity, text="".join(element.stripped_strings))
|
|
Pierre-Yves Chibon |
73d120 |
)
|
|
Aurélien Bompard |
626417 |
return alerts
|
|
Aurélien Bompard |
626417 |
|
|
Aurélien Bompard |
626417 |
|
|
Patrick Uiterwijk |
3f97f6 |
def definitely_wait(result):
|
|
Patrick Uiterwijk |
3f97f6 |
""" Helper function for definitely waiting in _maybe_wait. """
|
|
Patrick Uiterwijk |
3f97f6 |
result.wait()
|
|
Patrick Uiterwijk |
3f97f6 |
|
|
Patrick Uiterwijk |
3f97f6 |
|
|
Pierre-Yves Chibon |
73d120 |
if __name__ == "__main__":
|
|
Pierre-Yves Chibon |
413073 |
SUITE = unittest.TestLoader().loadTestsFromTestCase(Modeltests)
|
|
Pierre-Yves Chibon |
413073 |
unittest.TextTestRunner(verbosity=2).run(SUITE)
|