Blame tests/test_pagure_repospanner.py

Patrick Uiterwijk 3f97f6
# -*- coding: utf-8 -*-
Patrick Uiterwijk 3f97f6
Patrick Uiterwijk 3f97f6
"""
Patrick Uiterwijk 3f97f6
 (c) 2015-2018 - Copyright Red Hat Inc
Patrick Uiterwijk 3f97f6
Patrick Uiterwijk 3f97f6
 Authors:
Patrick Uiterwijk 3f97f6
   Patrick Uiterwijk <puiterwijk@redhat.com></puiterwijk@redhat.com>
Patrick Uiterwijk 3f97f6
Patrick Uiterwijk 3f97f6
"""
Patrick Uiterwijk 3f97f6
Pierre-Yves Chibon 67d1cc
from __future__ import unicode_literals, absolute_import
Patrick Uiterwijk 3f97f6
Patrick Uiterwijk 3f97f6
import datetime
Patrick Uiterwijk 69ea3d
import functools
Patrick Uiterwijk d29158
import munch
Patrick Uiterwijk 3f97f6
import unittest
Patrick Uiterwijk 3f97f6
import shutil
Patrick Uiterwijk 3f97f6
import subprocess
Patrick Uiterwijk 3f97f6
import sys
Patrick Uiterwijk 3f97f6
import tempfile
Patrick Uiterwijk 3f97f6
import time
Patrick Uiterwijk 3f97f6
import os
Patrick Uiterwijk 3f97f6
Patrick Uiterwijk 3f97f6
import six
Patrick Uiterwijk 3f97f6
import json
Patrick Uiterwijk 3f97f6
import pygit2
Patrick Uiterwijk 3f97f6
import requests
Patrick Uiterwijk 3f97f6
from requests.adapters import HTTPAdapter
Patrick Uiterwijk 3f97f6
from requests.packages.urllib3.util.retry import Retry
Patrick Uiterwijk 3f97f6
from mock import patch, MagicMock
Patrick Uiterwijk 3f97f6
Patrick Uiterwijk 3f97f6
sys.path.insert(0, os.path.join(os.path.dirname(
Patrick Uiterwijk 3f97f6
    os.path.abspath(__file__)), '..'))
Patrick Uiterwijk 3f97f6
Pierre-Yves Chibon 930073
import pagure.lib.query
Patrick Uiterwijk d29158
import pagure.cli.admin
Patrick Uiterwijk 3f97f6
import tests
Patrick Uiterwijk 3f97f6
Patrick Uiterwijk 3f97f6
Patrick Uiterwijk 3f97f6
REPOSPANNER_CONFIG_TEMPLATE = """
Patrick Uiterwijk 3f97f6
---
Patrick Uiterwijk 3f97f6
ca:
Patrick Uiterwijk 3f97f6
  path: %(path)s/repospanner/pki
Patrick Uiterwijk 3f97f6
admin:
Patrick Uiterwijk 9b2de7
  url:  https://localhost.localdomain:%(gitport)s/
Patrick Uiterwijk 3f97f6
  ca:   %(path)s/repospanner/pki/ca.crt
Patrick Uiterwijk 3f97f6
  cert: %(path)s/repospanner/pki/admin.crt
Patrick Uiterwijk 3f97f6
  key:  %(path)s/repospanner/pki/admin.key
Patrick Uiterwijk 3f97f6
storage:
Patrick Uiterwijk 3f97f6
  state: %(path)s/repospanner/state
Patrick Uiterwijk 3f97f6
  git:
Patrick Uiterwijk 3f97f6
    type: tree
Patrick Uiterwijk 3f97f6
    clustered: true
Patrick Uiterwijk 3f97f6
    directory: %(path)s/repospanner/git
Patrick Uiterwijk 3f97f6
listen:
Patrick Uiterwijk 3f97f6
  rpc:  127.0.0.1:%(rpcport)s
Patrick Uiterwijk 3f97f6
  http: 127.0.0.1:%(gitport)s
Patrick Uiterwijk 3f97f6
certificates:
Patrick Uiterwijk 3f97f6
  ca: %(path)s/repospanner/pki/ca.crt
Patrick Uiterwijk 3f97f6
  client:
Patrick Uiterwijk 9b2de7
    cert: %(path)s/repospanner/pki/repospanner.localhost.crt
Patrick Uiterwijk 9b2de7
    key:  %(path)s/repospanner/pki/repospanner.localhost.key
Patrick Uiterwijk 3f97f6
  server:
Patrick Uiterwijk 3f97f6
    default:
Patrick Uiterwijk 9b2de7
      cert: %(path)s/repospanner/pki/repospanner.localhost.crt
Patrick Uiterwijk 9b2de7
      key:  %(path)s/repospanner/pki/repospanner.localhost.key
Patrick Uiterwijk 3f97f6
hooks:
Patrick Uiterwijk 21f935
  debug: true
Patrick Uiterwijk 3f97f6
  bubblewrap:
Patrick Uiterwijk cf1396
    enabled: false
Patrick Uiterwijk 3f97f6
    unshare:
Patrick Uiterwijk 3f97f6
    - net
Patrick Uiterwijk 3f97f6
    - ipc
Patrick Uiterwijk 3f97f6
    - pid
Patrick Uiterwijk 3f97f6
    - uts
Patrick Uiterwijk 3f97f6
    share_net: false
Patrick Uiterwijk 3f97f6
    mount_proc: true
Patrick Uiterwijk 3f97f6
    mount_dev: true
Patrick Uiterwijk 3f97f6
    uid:
Patrick Uiterwijk 3f97f6
    gid:
Patrick Uiterwijk 3f97f6
    hostname: myhostname
Patrick Uiterwijk 3f97f6
    bind:
Patrick Uiterwijk 3f97f6
    ro_bind:
Patrick Uiterwijk d29158
    - - /usr
Patrick Uiterwijk d29158
      - /usr
Patrick Uiterwijk d29158
    - - %(codepath)s
Patrick Uiterwijk d29158
      - %(codepath)s
Patrick Uiterwijk d29158
    - - %(path)s
Patrick Uiterwijk d29158
      - %(path)s
Patrick Uiterwijk d29158
    - - %(crosspath)s
Patrick Uiterwijk d29158
      - %(crosspath)s
Patrick Uiterwijk 3f97f6
    symlink:
Patrick Uiterwijk d29158
    - - usr/lib64
Patrick Uiterwijk d29158
      - /lib64
Patrick Uiterwijk d29158
    - - usr/bin
Patrick Uiterwijk d29158
      - /bin
Patrick Uiterwijk d29158
  runner: %(hookrunner_bin)s
Patrick Uiterwijk 3f97f6
  user: 0
Patrick Uiterwijk 3f97f6
"""
Patrick Uiterwijk 3f97f6
Patrick Uiterwijk 3f97f6
Patrick Uiterwijk 3f97f6
class PagureRepoSpannerTests(tests.Modeltests):
Patrick Uiterwijk 3f97f6
    """ Tests for repoSpanner integration of pagure """
Patrick Uiterwijk 3f97f6
    repospanner_binary = None
Patrick Uiterwijk 3f97f6
    repospanner_runlog = None
Patrick Uiterwijk 3f97f6
    repospanner_proc = None
Patrick Uiterwijk 3f97f6
Patrick Uiterwijk 3f97f6
    def run_cacmd(self, logfile, *args):
Patrick Uiterwijk 3f97f6
        """ Run a repoSpanner CA command. """
Patrick Uiterwijk 3f97f6
        subprocess.check_call(
Patrick Uiterwijk 3f97f6
            [self.repospanner_binary,
Patrick Uiterwijk 3f97f6
             '--config',
Patrick Uiterwijk 3f97f6
             os.path.join(self.path, 'repospanner', 'config.yml'),
Patrick Uiterwijk 3f97f6
             # NEVER use this in a production system! It makes repeatable keys
Patrick Uiterwijk 3f97f6
             'ca'] + list(args) + ['--very-insecure-weak-keys'],
Patrick Uiterwijk 3f97f6
            stdout=logfile,
Patrick Uiterwijk 3f97f6
            stderr=subprocess.STDOUT,
Patrick Uiterwijk 3f97f6
        )
Patrick Uiterwijk 3f97f6
Patrick Uiterwijk 3f97f6
    def setUp(self):
Patrick Uiterwijk 3f97f6
        """ set up the environment. """
Patrick Uiterwijk 3f97f6
        possible_paths = [
Patrick Uiterwijk 3f97f6
            './repospanner',
Patrick Uiterwijk 3f97f6
            '/usr/bin/repospanner',
Patrick Uiterwijk 3f97f6
        ]
Patrick Uiterwijk 3f97f6
Patrick Uiterwijk 3f97f6
        for option in possible_paths:
Patrick Uiterwijk 3f97f6
            option = os.path.abspath(option)
Patrick Uiterwijk 3f97f6
            if os.path.exists(option):
Patrick Uiterwijk 3f97f6
                self.repospanner_binary = option
Patrick Uiterwijk 3f97f6
                break
Patrick Uiterwijk 3f97f6
Patrick Uiterwijk 3f97f6
        if not self.repospanner_binary:
Patrick Uiterwijk 3f97f6
            raise unittest.SkipTest('repoSpanner not found')
Patrick Uiterwijk 3f97f6
Pierre-Yves Chibon 37fdbb
        hookrunbins = [
Pierre-Yves Chibon 37fdbb
            os.path.join(
Pierre-Yves Chibon 37fdbb
                os.path.dirname(self.repospanner_binary), 'repohookrunner'),
Pierre-Yves Chibon 37fdbb
            os.path.join('/usr', 'libexec','repohookrunner'),
Pierre-Yves Chibon 37fdbb
        ]
Pierre-Yves Chibon 37fdbb
        found = False
Pierre-Yves Chibon 37fdbb
        for hookrunbin in hookrunbins:
Pierre-Yves Chibon 37fdbb
            if os.path.exists(hookrunbin):
Pierre-Yves Chibon 37fdbb
                found = True
Pierre-Yves Chibon 37fdbb
                break
Pierre-Yves Chibon 37fdbb
        if not found:
Patrick Uiterwijk d29158
            raise Exception('repoSpanner found, but repohookrunner not')
Pierre-Yves Chibon 37fdbb
Pierre-Yves Chibon 37fdbb
        repobridgebins = [
Pierre-Yves Chibon 37fdbb
            os.path.join(
Pierre-Yves Chibon 37fdbb
                os.path.dirname(self.repospanner_binary), 'repobridge'),
Pierre-Yves Chibon 37fdbb
            os.path.join('/usr', 'libexec','repobridge'),
Pierre-Yves Chibon 37fdbb
        ]
Pierre-Yves Chibon 37fdbb
        found = False
Pierre-Yves Chibon 37fdbb
        for repobridgebin in repobridgebins:
Pierre-Yves Chibon 37fdbb
            if os.path.exists(repobridgebin):
Pierre-Yves Chibon 37fdbb
                found = True
Pierre-Yves Chibon 37fdbb
                break
Pierre-Yves Chibon 37fdbb
        if not found:
Patrick Uiterwijk 8174a4
            raise Exception('repoSpanner found, but repobridge not')
Patrick Uiterwijk 8174a4
Patrick Uiterwijk 8174a4
        self.config_values['repobridge_binary'] = repobridgebin
Patrick Uiterwijk d29158
Patrick Uiterwijk d29158
        codepath = os.path.normpath(
Patrick Uiterwijk d29158
            os.path.join(
Patrick Uiterwijk d29158
                os.path.dirname(os.path.abspath(__file__)),
Patrick Uiterwijk d29158
                "../"))
Patrick Uiterwijk d29158
Patrick Uiterwijk 3f97f6
        # Only run the setUp() function if we are actually going ahead and run
Patrick Uiterwijk 3f97f6
        # this test. The reason being that otherwise, setUp will set up a
Patrick Uiterwijk 3f97f6
        # database, but because we "error out" from setUp, the tearDown()
Patrick Uiterwijk 3f97f6
        # function never gets called, leaving it behind.
Patrick Uiterwijk 3f97f6
        super(PagureRepoSpannerTests, self).setUp()
Patrick Uiterwijk 3f97f6
Patrick Uiterwijk 3f97f6
        # TODO: Find free ports
Patrick Uiterwijk 3f97f6
        configvals = {
Patrick Uiterwijk 3f97f6
            'path': self.path,
Patrick Uiterwijk d29158
            'crosspath': tests.tests_state["path"],
Patrick Uiterwijk 7b18a6
            'gitport': 8443 + sys.version_info.major,
Patrick Uiterwijk 7b18a6
            'rpcport': 8445 + sys.version_info.major,
Patrick Uiterwijk d29158
            'codepath': codepath,
Patrick Uiterwijk d29158
            'hookrunner_bin': hookrunbin,
Patrick Uiterwijk 3f97f6
        }
Patrick Uiterwijk 3f97f6
Patrick Uiterwijk 3f97f6
        os.mkdir(os.path.join(self.path, 'repospanner'))
Patrick Uiterwijk 3f97f6
        cfgpath = os.path.join(self.path, 'repospanner', 'config.yml')
Patrick Uiterwijk 3f97f6
        with open(cfgpath, 'w') as cfg:
Patrick Uiterwijk 3f97f6
            cfg.write(REPOSPANNER_CONFIG_TEMPLATE % configvals)
Patrick Uiterwijk 3f97f6
Patrick Uiterwijk 3f97f6
        with open(os.path.join(self.path, 'repospanner', 'keylog'),
Patrick Uiterwijk 3f97f6
                  'w') as keylog:
Patrick Uiterwijk 3f97f6
            # Create the CA
Patrick Uiterwijk 9b2de7
            self.run_cacmd(keylog, 'init', 'localdomain',
Patrick Uiterwijk 3df2fc
                           '--no-name-constraint', '--random-cn')
Patrick Uiterwijk 3f97f6
            # Create the node cert
Patrick Uiterwijk 9b2de7
            self.run_cacmd(keylog, 'node', 'localhost', 'repospanner')
Patrick Uiterwijk 3f97f6
            # Create the admin cert
Patrick Uiterwijk 3f97f6
            self.run_cacmd(keylog, 'leaf', 'admin',
Patrick Uiterwijk 3f97f6
                           '--admin', '--region', '*', '--repo', '*')
Patrick Uiterwijk 3f97f6
            # Create the Pagure cert
Patrick Uiterwijk 3f97f6
            self.run_cacmd(keylog, 'leaf', 'pagure',
Patrick Uiterwijk 3f97f6
                           '--read', '--write',
Patrick Uiterwijk 3f97f6
                           '--region', '*', '--repo', '*')
Patrick Uiterwijk 3f97f6
Patrick Uiterwijk 3f97f6
        with open(os.path.join(self.path, 'repospanner', 'spawnlog'),
Patrick Uiterwijk 3f97f6
                  'w') as spawnlog:
Patrick Uiterwijk 3f97f6
            # Initialize state
Patrick Uiterwijk 3f97f6
            subprocess.check_call(
Patrick Uiterwijk 3f97f6
                [self.repospanner_binary,
Patrick Uiterwijk 3f97f6
                 '--config', cfgpath,
Patrick Uiterwijk 3f97f6
                 'serve', '--spawn'],
Patrick Uiterwijk 3f97f6
                stdout=spawnlog,
Patrick Uiterwijk 3f97f6
                stderr=subprocess.STDOUT,
Patrick Uiterwijk 3f97f6
            )
Patrick Uiterwijk 3f97f6
Patrick Uiterwijk 3f97f6
        self.repospanner_runlog = open(
Patrick Uiterwijk 69ea3d
            os.path.join(self.path, 'repospanner', 'runlog'), 'w+')
Patrick Uiterwijk 3f97f6
Patrick Uiterwijk 3f97f6
        try:
Patrick Uiterwijk 3f97f6
            self.repospanner_proc = subprocess.Popen(
Patrick Uiterwijk 3f97f6
                [self.repospanner_binary,
Patrick Uiterwijk 3f97f6
                 '--config', cfgpath,
Patrick Uiterwijk 3f97f6
                 'serve', '--debug'],
Patrick Uiterwijk 3f97f6
                stdout=self.repospanner_runlog,
Patrick Uiterwijk 3f97f6
                stderr=subprocess.STDOUT,
Patrick Uiterwijk 3f97f6
            )
Patrick Uiterwijk 3f97f6
        except:
Patrick Uiterwijk 3f97f6
            # Make sure to clean up repoSpanner, since we did start it
Patrick Uiterwijk 3f97f6
            self.tearDown()
Patrick Uiterwijk 3f97f6
            raise
Patrick Uiterwijk 3f97f6
Patrick Uiterwijk 3bda5f
        attempts = 0
Patrick Uiterwijk 3bda5f
        while True:
Patrick Uiterwijk 3bda5f
            try:
Patrick Uiterwijk 3bda5f
                # Wait for the instance to become available
Patrick Uiterwijk 3bda5f
                resp = requests.get(
Patrick Uiterwijk 9b2de7
                    'https://repospanner.localhost.localdomain:%d/'
Patrick Uiterwijk 3bda5f
                    % configvals['gitport'],
Patrick Uiterwijk 3bda5f
                    verify=os.path.join(self.path, 'repospanner', 'pki', 'ca.crt'),
Patrick Uiterwijk 3bda5f
                    cert=(
Patrick Uiterwijk 3bda5f
                        os.path.join(self.path, 'repospanner', 'pki', 'pagure.crt'),
Patrick Uiterwijk 3bda5f
                        os.path.join(self.path, 'repospanner', 'pki', 'pagure.key'),
Patrick Uiterwijk 3bda5f
                    )
Patrick Uiterwijk 3bda5f
                )
Patrick Uiterwijk 3bda5f
                resp.raise_for_status()
Patrick Uiterwijk 3bda5f
Patrick Uiterwijk 3bda5f
                print('repoSpanner identification: %s' % resp.text)
Patrick Uiterwijk 3bda5f
                break
Patrick Uiterwijk 3bda5f
            except:
Patrick Uiterwijk 3bda5f
                if attempts < 5:
Patrick Uiterwijk 3bda5f
                    attempts += 1
Patrick Uiterwijk 3bda5f
                    time.sleep(1)
Patrick Uiterwijk 3bda5f
                    continue
Patrick Uiterwijk 3bda5f
                # Make sure to clean up repoSpanner, since we did start it
Patrick Uiterwijk 3bda5f
                self.tearDown()
Patrick Uiterwijk 3bda5f
                raise
Patrick Uiterwijk 3bda5f
Patrick Uiterwijk 880f5e
        # Upload the hook script to repoSpanner
Patrick Uiterwijk 880f5e
        args = munch.Munch({'region': 'default'})
Patrick Uiterwijk 880f5e
        hookid = pagure.cli.admin.do_upload_repospanner_hooks(args)
Patrick Uiterwijk 880f5e
        pagure.config.config['REPOSPANNER_REGIONS']['default']['hook'] = hookid
Patrick Uiterwijk 880f5e
Patrick Uiterwijk 3f97f6
    def tearDown(self):
Patrick Uiterwijk 3f97f6
        """ Tear down the repoSpanner instance. """
Patrick Uiterwijk 3f97f6
        if self.repospanner_proc:
Patrick Uiterwijk 3f97f6
            # Tear down
Patrick Uiterwijk 3f97f6
            self.repospanner_proc.terminate()
Patrick Uiterwijk 3f97f6
            exitcode = self.repospanner_proc.wait()
Patrick Uiterwijk 3f97f6
            if exitcode != 0:
Patrick Uiterwijk 3f97f6
                print('repoSpanner exit code: %d' % exitcode)
Patrick Uiterwijk 3f97f6
Patrick Uiterwijk 3f97f6
        if self.repospanner_runlog:
Patrick Uiterwijk 3f97f6
            self.repospanner_runlog.close()
Patrick Uiterwijk 3f97f6
Patrick Uiterwijk 3f97f6
        super(PagureRepoSpannerTests, self).tearDown()
Patrick Uiterwijk 3f97f6
Patrick Uiterwijk 3f97f6
Patrick Uiterwijk 69ea3d
def print_repospanner_log(fn):
Patrick Uiterwijk 69ea3d
    @functools.wraps(fn)
Patrick Uiterwijk 69ea3d
    def wrapper(self, *args, **kwargs):
Patrick Uiterwijk 69ea3d
        try:
Patrick Uiterwijk 69ea3d
            return fn(self, *args, **kwargs)
Patrick Uiterwijk 69ea3d
        finally:
Patrick Uiterwijk 69ea3d
            if self.repospanner_runlog:
Patrick Uiterwijk 69ea3d
                self.repospanner_runlog.seek(0, 0,)
Patrick Uiterwijk 69ea3d
                print("repoSpanner log follows:")
Patrick Uiterwijk 69ea3d
                print(self.repospanner_runlog.read())
Patrick Uiterwijk 69ea3d
Patrick Uiterwijk 69ea3d
    return wrapper
Patrick Uiterwijk 69ea3d
Patrick Uiterwijk 69ea3d
Patrick Uiterwijk 3f97f6
class PagureRepoSpannerTestsNewRepoDefault(PagureRepoSpannerTests):
Patrick Uiterwijk 3f97f6
    config_values = {
Patrick Uiterwijk d29158
        'repospanner_new_repo': "'default'",
Patrick Uiterwijk d29158
        'authbackend': 'test_auth',
Patrick Uiterwijk 3f97f6
    }
Patrick Uiterwijk 3f97f6
Patrick Uiterwijk 69ea3d
    @print_repospanner_log
Patrick Uiterwijk 3f97f6
    @patch('pagure.ui.app.admin_session_timedout')
Patrick Uiterwijk 3f97f6
    def test_new_project(self, ast):
Patrick Uiterwijk 3f97f6
        """ Test creating a new repo by default on repoSpanner works. """
Patrick Uiterwijk 3f97f6
        ast.return_value = False
Patrick Uiterwijk 3f97f6
Patrick Uiterwijk 3f97f6
        user = tests.FakeUser(username='foo')
Patrick Uiterwijk 3f97f6
        with tests.user_set(self.app.application, user):
Patrick Uiterwijk 3f97f6
            output = self.app.get('/new/')
Patrick Uiterwijk 3f97f6
            self.assertEqual(output.status_code, 200)
Patrick Uiterwijk 3f97f6
            output_text = output.get_data(as_text=True)
Patrick Uiterwijk 3f97f6
            self.assertIn(
Patrick Uiterwijk 3f97f6
                'Create new Project', output_text)
Patrick Uiterwijk 3f97f6
Patrick Uiterwijk 3f97f6
            data = {
Patrick Uiterwijk 3f97f6
                'name': 'project-1',
Patrick Uiterwijk 3f97f6
                'description': 'Project #1',
Patrick Uiterwijk 3f97f6
                'create_readme': 'y',
Patrick Uiterwijk d29158
                'csrf_token': self.get_csrf(),
Patrick Uiterwijk 3f97f6
            }
Patrick Uiterwijk 3f97f6
Patrick Uiterwijk 3f97f6
            output = self.app.post('/new/', data=data, follow_redirects=True)
Patrick Uiterwijk 3f97f6
            self.assertEqual(output.status_code, 200)
Patrick Uiterwijk 3f97f6
            output_text = output.get_data(as_text=True)
Patrick Uiterwijk 3f97f6
            self.assertIn(
Patrick Uiterwijk 3f97f6
                '
\nProject #1',
Patrick Uiterwijk 3f97f6
                output_text)
Patrick Uiterwijk 3f97f6
            self.assertIn(
Patrick Uiterwijk 3f97f6
                '<title>Overview - project-1 - Pagure</title>', output_text)
Patrick Uiterwijk 3f97f6
            self.assertIn('Added the README', output_text)
Patrick Uiterwijk 3f97f6
Patrick Uiterwijk 3f97f6
            output = self.app.get('/project-1/settings')
Patrick Uiterwijk 3f97f6
            self.assertIn(
Patrick Uiterwijk 3f97f6
                'This repository is on repoSpanner region default',
Patrick Uiterwijk 3f97f6
                output.get_data(as_text=True))
Patrick Uiterwijk 3f97f6
Patrick Uiterwijk 3f97f6
        with tests.user_set(self.app.application, tests.FakeUser(username='pingou')):
Patrick Uiterwijk 3c1099
            # Verify that for forking, Git auth status is ignored (hooks should not be run)
Patrick Uiterwijk 3c1099
            self.set_auth_status(False)
Patrick Uiterwijk 3c1099
Patrick Uiterwijk 3f97f6
            data = {
Patrick Uiterwijk d29158
                'csrf_token': self.get_csrf(),
Patrick Uiterwijk 3f97f6
            }
Patrick Uiterwijk 3f97f6
Patrick Uiterwijk 3f97f6
            output = self.app.post(
Patrick Uiterwijk 3f97f6
                '/do_fork/project-1', data=data,
Patrick Uiterwijk 3f97f6
                follow_redirects=True)
Patrick Uiterwijk 3f97f6
            self.assertEqual(output.status_code, 200)
Patrick Uiterwijk 3f97f6
            output_text = output.get_data(as_text=True)
Patrick Uiterwijk 3f97f6
            self.assertIn(
Patrick Uiterwijk 3f97f6
                '
\nProject #1',
Patrick Uiterwijk 3f97f6
                output_text)
Patrick Uiterwijk 3f97f6
            self.assertIn(
Patrick Uiterwijk 3f97f6
                '<title>Overview - project-1 - Pagure</title>', output_text)
Patrick Uiterwijk 3f97f6
            self.assertIn('Added the README', output_text)
Patrick Uiterwijk 3c1099
            self.assertIn('/?next=http://localhost/fork/pingou/project-1', output_text)
Patrick Uiterwijk 3f97f6
Patrick Uiterwijk 3f97f6
            output = self.app.get('/fork/pingou/project-1/settings')
Patrick Uiterwijk 3f97f6
            self.assertIn(
Patrick Uiterwijk 3f97f6
                'This repository is on repoSpanner region default',
Patrick Uiterwijk 3f97f6
                output.get_data(as_text=True))
Patrick Uiterwijk 3f97f6
Patrick Uiterwijk 3f97f6
        # Verify that only pseudo repos exist, and no on-disk repos got created
Patrick Uiterwijk 3f97f6
        repodirlist = os.listdir(os.path.join(self.path, 'repos'))
Patrick Uiterwijk 3f97f6
        self.assertEqual(repodirlist, ['pseudo'])
Patrick Uiterwijk 3f97f6
Patrick Uiterwijk 69ea3d
    @print_repospanner_log
Patrick Uiterwijk a50651
    @patch.dict('pagure.config.config', {
Patrick Uiterwijk a50651
        'ALLOW_HTTP_PULL_PUSH': True,
Patrick Uiterwijk a50651
        'ALLOW_HTTP_PUSH': True,
Patrick Uiterwijk a50651
        'HTTP_REPO_ACCESS_GITOLITE': False,
Patrick Uiterwijk a50651
    })
Patrick Uiterwijk a50651
    def test_http_pull(self):
Patrick Uiterwijk a50651
        """ Test that the HTTP pull endpoint works for repoSpanner. """
Patrick Uiterwijk a50651
        tests.create_projects(self.session)
Patrick Uiterwijk a50651
        tests.create_tokens(self.session)
Patrick Uiterwijk a50651
        tests.create_tokens_acl(self.session)
Patrick Uiterwijk a50651
        self.create_project_full('clonetest', {"create_readme": "y"})
Patrick Uiterwijk a50651
Patrick Uiterwijk a50651
        # Verify the new project is indeed on repoSpanner
Pierre-Yves Chibon 930073
        project = pagure.lib.query._get_project(self.session, 'clonetest')
Patrick Uiterwijk a50651
        self.assertTrue(project.is_on_repospanner)
Patrick Uiterwijk a50651
Patrick Uiterwijk a50651
        # Unfortunately, actually testing a git clone would need the app to
Patrick Uiterwijk a50651
        # run on a TCP port, which the test environment doesn't do.
Patrick Uiterwijk a50651
        output = self.app.get('/clonetest.git/info/refs?service=git-upload-pack')
Patrick Uiterwijk a50651
        self.assertEqual(output.status_code, 200)
Patrick Uiterwijk 05f1d9
        self.assertEqual(output.content_type,
Patrick Uiterwijk 05f1d9
                         "application/x-git-upload-pack-advertisement")
Patrick Uiterwijk a50651
        output_text = output.get_data(as_text=True)
Patrick Uiterwijk a50651
        self.assertIn("# service=git-upload-pack", output_text)
Patrick Uiterwijk 05f1d9
        self.assertIn("agent=repoSpanner", output_text)
Patrick Uiterwijk a50651
        self.assertIn("symref=HEAD:refs/heads/master", output_text)
Patrick Uiterwijk a50651
        self.assertIn(" refs/heads/master\x00", output_text)
Patrick Uiterwijk a50651
Patrick Uiterwijk 802c7e
        output = self.app.post(
Patrick Uiterwijk 802c7e
            '/clonetest.git/git-upload-pack',
Patrick Uiterwijk 802c7e
            headers={'Content-Type': 'application/x-git-upload-pack-request'},
Patrick Uiterwijk 802c7e
        )
Patrick Uiterwijk 4e180b
        self.assertEqual(output.status_code, 400)
Patrick Uiterwijk 802c7e
        output_text = output.get_data(as_text=True)
Patrick Uiterwijk 802c7e
        self.assertIn("Error processing your request", output_text)
Patrick Uiterwijk 802c7e
Patrick Uiterwijk 69ea3d
    @print_repospanner_log
Patrick Uiterwijk a50651
    @patch.dict('pagure.config.config', {
Patrick Uiterwijk a50651
        'ALLOW_HTTP_PULL_PUSH': True,
Patrick Uiterwijk a50651
        'ALLOW_HTTP_PUSH': True,
Patrick Uiterwijk a50651
        'HTTP_REPO_ACCESS_GITOLITE': False,
Patrick Uiterwijk a50651
    })
Patrick Uiterwijk a50651
    def test_http_push(self):
Patrick Uiterwijk a50651
        """ Test that the HTTP push endpoint works for repoSpanner. """
Patrick Uiterwijk a50651
        tests.create_projects(self.session)
Patrick Uiterwijk a50651
        tests.create_tokens(self.session)
Patrick Uiterwijk a50651
        tests.create_tokens_acl(self.session)
Patrick Uiterwijk a50651
        self.create_project_full('clonetest', {"create_readme": "y"})
Patrick Uiterwijk a50651
Patrick Uiterwijk a50651
        # Verify the new project is indeed on repoSpanner
Pierre-Yves Chibon 930073
        project = pagure.lib.query._get_project(self.session, 'clonetest')
Patrick Uiterwijk a50651
        self.assertTrue(project.is_on_repospanner)
Patrick Uiterwijk a50651
Patrick Uiterwijk a50651
        # Unfortunately, actually testing a git clone would need the app to
Patrick Uiterwijk a50651
        # run on a TCP port, which the test environment doesn't do.
Patrick Uiterwijk a50651
        output = self.app.get(
Patrick Uiterwijk 05f1d9
            '/clonetest.git/info/refs?service=git-receive-pack',
Patrick Uiterwijk a50651
            environ_overrides={'REMOTE_USER': 'pingou'},
Patrick Uiterwijk a50651
        )
Patrick Uiterwijk a50651
        self.assertEqual(output.status_code, 200)
Patrick Uiterwijk 05f1d9
        self.assertEqual(output.content_type,
Patrick Uiterwijk 05f1d9
                         "application/x-git-receive-pack-advertisement")
Patrick Uiterwijk a50651
        output_text = output.get_data(as_text=True)
Patrick Uiterwijk 05f1d9
        self.assertIn("# service=git-receive-pack", output_text)
Patrick Uiterwijk 05f1d9
        self.assertIn("agent=repoSpanner", output_text)
Patrick Uiterwijk a50651
        self.assertIn("symref=HEAD:refs/heads/master", output_text)
Patrick Uiterwijk a50651
        self.assertIn(" refs/heads/master\x00", output_text)
Patrick Uiterwijk a50651
Patrick Uiterwijk 69ea3d
    @print_repospanner_log
Patrick Uiterwijk d29158
    @patch('pagure.ui.app.admin_session_timedout')
Patrick Uiterwijk d29158
    def test_hooks(self, ast):
Patrick Uiterwijk d29158
        """ Test hook setting and running works. """
Patrick Uiterwijk d29158
        ast.return_value = False
Patrick Uiterwijk d29158
        pagure.cli.admin.session = self.session
Patrick Uiterwijk d29158
Patrick Uiterwijk d29158
        user = tests.FakeUser(username='foo')
Patrick Uiterwijk d29158
        with tests.user_set(self.app.application, user):
Patrick Uiterwijk d29158
            data = {
Patrick Uiterwijk d29158
                'name': 'project-1',
Patrick Uiterwijk d29158
                'description': 'Project #1',
Patrick Uiterwijk d29158
                'create_readme': 'y',
Patrick Uiterwijk d29158
                'csrf_token': self.get_csrf(),
Patrick Uiterwijk d29158
            }
Patrick Uiterwijk d29158
Patrick Uiterwijk d29158
            output = self.app.post('/new/', data=data, follow_redirects=True)
Patrick Uiterwijk d29158
            self.assertEqual(output.status_code, 200)
Patrick Uiterwijk d29158
            output_text = output.get_data(as_text=True)
Patrick Uiterwijk d29158
            self.assertIn(
Patrick Uiterwijk d29158
                '
\nProject #1',
Patrick Uiterwijk d29158
                output_text)
Patrick Uiterwijk d29158
            self.assertIn(
Patrick Uiterwijk d29158
                '<title>Overview - project-1 - Pagure</title>', output_text)
Patrick Uiterwijk d29158
            self.assertIn('Added the README', output_text)
Patrick Uiterwijk d29158
Patrick Uiterwijk d29158
            output = self.app.get('/project-1/settings')
Patrick Uiterwijk d29158
            self.assertIn(
Patrick Uiterwijk d29158
                'This repository is on repoSpanner region default',
Patrick Uiterwijk d29158
                output.get_data(as_text=True))
Patrick Uiterwijk d29158
Patrick Uiterwijk d29158
            # Check file before the commit:
Patrick Uiterwijk d29158
            output = self.app.get('/project-1/raw/master/f/README.md')
Patrick Uiterwijk d29158
            self.assertEqual(output.status_code, 200)
Patrick Uiterwijk d29158
            output_text = output.get_data(as_text=True)
Patrick Uiterwijk d29158
            self.assertEqual(output_text, '# project-1\n\nProject #1')
Patrick Uiterwijk d29158
Patrick Uiterwijk d29158
        with tests.user_set(self.app.application, user):
Patrick Uiterwijk d29158
            # Set editing Denied
Patrick Uiterwijk d29158
            self.set_auth_status(False)
Patrick Uiterwijk d29158
Patrick Uiterwijk d29158
            # Try to make an edit in the repo
Patrick Uiterwijk d29158
            data = {
Patrick Uiterwijk d29158
                'content': 'foo\n bar\n  baz',
Patrick Uiterwijk d29158
                'commit_title': 'test commit',
Patrick Uiterwijk d29158
                'commit_message': 'Online commit',
Patrick Uiterwijk d29158
                'email': 'foo@bar.com',
Patrick Uiterwijk d29158
                'branch': 'master',
Patrick Uiterwijk d29158
                'csrf_token': self.get_csrf(),
Patrick Uiterwijk d29158
            }
Patrick Uiterwijk d29158
Patrick Uiterwijk d29158
            output = self.app.post(
Patrick Uiterwijk d29158
                '/project-1/edit/master/f/README.md', data=data,
Patrick Uiterwijk d29158
                follow_redirects=True)
Patrick Uiterwijk d29158
            self.assertEqual(output.status_code, 200)
Patrick Uiterwijk d29158
            output_text = output.get_data(as_text=True)
Patrick Uiterwijk d29158
            self.assertIn(
Patrick Uiterwijk d29158
                "Remote hook declined the push: ",
Patrick Uiterwijk d29158
                output_text
Patrick Uiterwijk d29158
            )
Patrick Uiterwijk d29158
            self.assertIn(
Patrick Uiterwijk 7262c5
                "Denied push for ref 'refs/heads/master' for user 'foo'",
Patrick Uiterwijk d29158
                output_text
Patrick Uiterwijk d29158
            )
Patrick Uiterwijk d29158
Patrick Uiterwijk d29158
            # Check file after the commit:
Patrick Uiterwijk d29158
            output = self.app.get('/project-1/raw/master/f/README.md')
Patrick Uiterwijk d29158
            self.assertEqual(output.status_code, 200)
Patrick Uiterwijk d29158
            output_text = output.get_data(as_text=True)
Patrick Uiterwijk d29158
            self.assertEqual(output_text, '# project-1\n\nProject #1')
Patrick Uiterwijk d29158
Patrick Uiterwijk d29158
            # Set editing Allowed
Patrick Uiterwijk d29158
            self.set_auth_status(True)
Patrick Uiterwijk d29158
Patrick Uiterwijk d29158
            # Try to make an edit in the repo
Patrick Uiterwijk d29158
            data = {
Patrick Uiterwijk d29158
                'content': 'foo\n bar\n  baz',
Patrick Uiterwijk d29158
                'commit_title': 'test commit',
Patrick Uiterwijk d29158
                'commit_message': 'Online commit',
Patrick Uiterwijk d29158
                'email': 'foo@bar.com',
Patrick Uiterwijk d29158
                'branch': 'master',
Patrick Uiterwijk d29158
                'csrf_token': self.get_csrf(),
Patrick Uiterwijk d29158
            }
Patrick Uiterwijk d29158
Patrick Uiterwijk d29158
            output = self.app.post(
Patrick Uiterwijk d29158
                '/project-1/edit/master/f/README.md', data=data,
Patrick Uiterwijk d29158
                follow_redirects=True)
Patrick Uiterwijk d29158
            self.assertEqual(output.status_code, 200)
Patrick Uiterwijk d29158
            output_text = output.get_data(as_text=True)
Patrick Uiterwijk d29158
            self.assertIn(
Patrick Uiterwijk d29158
                '<title>Commits - project-1 - Pagure</title>', output_text)
Patrick Uiterwijk d29158
Patrick Uiterwijk d29158
            # Check file after the commit:
Patrick Uiterwijk d29158
            output = self.app.get('/project-1/raw/master/f/README.md')
Patrick Uiterwijk d29158
            self.assertEqual(output.status_code, 200)
Patrick Uiterwijk d29158
            output_text = output.get_data(as_text=True)
Patrick Uiterwijk d29158
            self.assertEqual(output_text, 'foo\n bar\n  baz')
Patrick Uiterwijk d29158
Patrick Uiterwijk 69ea3d
    @print_repospanner_log
Patrick Uiterwijk 335383
    @patch.dict('pagure.config.config', {'PAGURE_ADMIN_USERS': ['pingou'],
Patrick Uiterwijk 335383
                                         'ALLOW_ADMIN_IGNORE_EXISTING_REPOS': True})
Patrick Uiterwijk 335383
    @patch('pagure.ui.app.admin_session_timedout')
Patrick Uiterwijk 335383
    def test_adopt_project(self, ast):
Patrick Uiterwijk 335383
        """ Test adopting a project in repoSpanner works. """
Patrick Uiterwijk 335383
        ast.return_value = False
Patrick Uiterwijk 335383
Patrick Uiterwijk 335383
        user = tests.FakeUser(username='foo')
Patrick Uiterwijk 335383
        with tests.user_set(self.app.application, user):
Patrick Uiterwijk 335383
            output = self.app.get('/new/')
Patrick Uiterwijk 335383
            self.assertEqual(output.status_code, 200)
Patrick Uiterwijk 335383
            output_text = output.get_data(as_text=True)
Patrick Uiterwijk 335383
            self.assertIn(
Patrick Uiterwijk 335383
                'Create new Project', output_text)
Patrick Uiterwijk 335383
Patrick Uiterwijk 335383
            data = {
Patrick Uiterwijk 335383
                'name': 'project-1',
Patrick Uiterwijk 335383
                'description': 'Project #1',
Patrick Uiterwijk 335383
                'create_readme': 'y',
Patrick Uiterwijk 335383
                'csrf_token': self.get_csrf(),
Patrick Uiterwijk 335383
            }
Patrick Uiterwijk 335383
Patrick Uiterwijk 335383
            output = self.app.post('/new/', data=data, follow_redirects=True)
Patrick Uiterwijk 335383
            self.assertEqual(output.status_code, 200)
Patrick Uiterwijk 335383
            output_text = output.get_data(as_text=True)
Patrick Uiterwijk 335383
            self.assertIn(
Patrick Uiterwijk 335383
                '
\nProject #1',
Patrick Uiterwijk 335383
                output_text)
Patrick Uiterwijk 335383
            self.assertIn(
Patrick Uiterwijk 335383
                '<title>Overview - project-1 - Pagure</title>', output_text)
Patrick Uiterwijk 335383
            self.assertIn('Added the README', output_text)
Patrick Uiterwijk 335383
Patrick Uiterwijk 335383
            output = self.app.get('/project-1/settings')
Patrick Uiterwijk 335383
            self.assertIn(
Patrick Uiterwijk 335383
                'This repository is on repoSpanner region default',
Patrick Uiterwijk 335383
                output.get_data(as_text=True))
Patrick Uiterwijk 335383
Patrick Uiterwijk 335383
        # Delete the project instance so that the actual repo remains
Pierre-Yves Chibon 930073
        project = pagure.lib.query._get_project(self.session, 'project-1')
Patrick Uiterwijk 335383
        self.session.delete(project)
Patrick Uiterwijk 335383
        self.session.commit()
Patrick Uiterwijk 335383
        shutil.rmtree(os.path.join(self.path, 'repos', 'pseudo'))
Patrick Uiterwijk 335383
Patrick Uiterwijk 335383
        user = tests.FakeUser(username='pingou')
Patrick Uiterwijk 335383
        with tests.user_set(self.app.application, user):
Patrick Uiterwijk 335383
            output = self.app.get('/project-1/')
Patrick Uiterwijk 335383
            self.assertEqual(output.status_code, 404)
Patrick Uiterwijk 335383
Patrick Uiterwijk 335383
            data = {
Patrick Uiterwijk 335383
                'name': 'project-1',
Patrick Uiterwijk 335383
                'description': 'Recreated project #1',
Patrick Uiterwijk 335383
                'create_readme': 'false',
Patrick Uiterwijk 335383
                'csrf_token': self.get_csrf(),
Patrick Uiterwijk 335383
            }
Patrick Uiterwijk 335383
            output = self.app.post('/new/', data=data, follow_redirects=True)
Patrick Uiterwijk 335383
            self.assertEqual(output.status_code, 200)
Patrick Uiterwijk 335383
            output_text = output.get_data(as_text=True)
Patrick Uiterwijk 335383
            self.assertIn(
Patrick Uiterwijk 335383
                'Repo pagure/main/project-1 already exists',
Patrick Uiterwijk 335383
                output_text)
Patrick Uiterwijk 335383
Patrick Uiterwijk 335383
            data['ignore_existing_repos'] = 'y'
Patrick Uiterwijk 335383
            output = self.app.post('/new/', data=data, follow_redirects=True)
Patrick Uiterwijk 335383
            self.assertEqual(output.status_code, 200)
Patrick Uiterwijk 335383
            output_text = output.get_data(as_text=True)
Patrick Uiterwijk 335383
            self.assertIn(
Patrick Uiterwijk 335383
                '
\nRecreated project #1',
Patrick Uiterwijk 335383
                output_text)
Patrick Uiterwijk 335383
            self.assertIn(
Patrick Uiterwijk 335383
                '<title>Overview - project-1 - Pagure</title>', output_text)
Patrick Uiterwijk 335383
            self.assertIn('Added the README', output_text)
Patrick Uiterwijk 335383
Patrick Uiterwijk 3f97f6
Patrick Uiterwijk 3f97f6
if __name__ == '__main__':
Patrick Uiterwijk 3f97f6
    unittest.main(verbosity=2)