|
|
# Copyright (C) 2010-2024 RhodeCode GmbH
|
|
|
#
|
|
|
# This program is free software: you can redistribute it and/or modify
|
|
|
# it under the terms of the GNU Affero General Public License, version 3
|
|
|
# (only), as published by the Free Software Foundation.
|
|
|
#
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
# GNU General Public License for more details.
|
|
|
#
|
|
|
# You should have received a copy of the GNU Affero General Public License
|
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
#
|
|
|
# This program is dual-licensed. If you wish to learn more about the
|
|
|
# RhodeCode Enterprise Edition, including its added features, Support services,
|
|
|
# and proprietary license terms, please see https://rhodecode.com/licenses/
|
|
|
|
|
|
import pytest
|
|
|
|
|
|
from rhodecode.lib.config_utils import get_app_config
|
|
|
from rhodecode.tests.fixtures.rc_fixture import TestINI
|
|
|
from rhodecode.tests import TESTS_TMP_PATH
|
|
|
from rhodecode.tests.server_utils import RcVCSServer
|
|
|
from rhodecode.tests.server_utils import RcWebServer
|
|
|
from rhodecode.tests.server_utils import CeleryServer
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
|
def vcsserver_factory():
|
|
|
"""
|
|
|
Use this if you need a running vcsserver with a special configuration.
|
|
|
"""
|
|
|
|
|
|
def factory(request, store_dir, overrides=(), config_file=None, port=None, log_file=None, workers="3", env=None, info_prefix=""):
|
|
|
env = env or {"RC_NO_TEST_ENV": "1"}
|
|
|
vcsserver_port = port
|
|
|
if port is None:
|
|
|
vcsserver_port = get_available_port()
|
|
|
|
|
|
overrides = list(overrides)
|
|
|
overrides.append({"server:main": {"port": vcsserver_port}})
|
|
|
|
|
|
if getattr(request, 'param', None):
|
|
|
config_overrides = [request.param]
|
|
|
overrides.extend(config_overrides)
|
|
|
|
|
|
option_name = "vcsserver_config"
|
|
|
override_option_name = None
|
|
|
if not config_file:
|
|
|
config_file = get_config(
|
|
|
request.config,
|
|
|
option_name=option_name,
|
|
|
override_option_name=override_option_name,
|
|
|
overrides=overrides,
|
|
|
basetemp=store_dir,
|
|
|
prefix=f"{info_prefix}test_vcsserver_ini_",
|
|
|
)
|
|
|
server = RcVCSServer(config_file, log_file, workers, env=env, info_prefix=info_prefix)
|
|
|
server.start()
|
|
|
|
|
|
@request.addfinalizer
|
|
|
def cleanup():
|
|
|
server.shutdown()
|
|
|
|
|
|
server.wait_until_ready()
|
|
|
return server
|
|
|
|
|
|
return factory
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
|
def rhodecode_factory():
|
|
|
def factory(request, store_dir, overrides=(), config_file=None, port=None, log_file=None, workers="3", env=None, info_prefix=""):
|
|
|
env = env or {"RC_NO_TEST_ENV": "1"}
|
|
|
rhodecode_port = port
|
|
|
if port is None:
|
|
|
rhodecode_port = get_available_port()
|
|
|
|
|
|
overrides = list(overrides)
|
|
|
overrides.append({"server:main": {"port": rhodecode_port}})
|
|
|
overrides.append({"app:main": {"use_celery": "true"}})
|
|
|
overrides.append({"app:main": {"celery.task_always_eager": "false"}})
|
|
|
|
|
|
if getattr(request, 'param', None):
|
|
|
config_overrides = [request.param]
|
|
|
overrides.extend(config_overrides)
|
|
|
|
|
|
|
|
|
option_name = "rhodecode_config"
|
|
|
override_option_name = None
|
|
|
if not config_file:
|
|
|
config_file = get_config(
|
|
|
request.config,
|
|
|
option_name=option_name,
|
|
|
override_option_name=override_option_name,
|
|
|
overrides=overrides,
|
|
|
basetemp=store_dir,
|
|
|
prefix=f"{info_prefix}test_rhodecode_ini",
|
|
|
)
|
|
|
|
|
|
server = RcWebServer(config_file, log_file, workers, env, info_prefix=info_prefix)
|
|
|
server.start()
|
|
|
|
|
|
@request.addfinalizer
|
|
|
def cleanup():
|
|
|
server.shutdown()
|
|
|
|
|
|
server.wait_until_ready()
|
|
|
return server
|
|
|
|
|
|
return factory
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
|
def celery_factory():
|
|
|
def factory(request, store_dir, overrides=(), config_file=None, port=None, log_file=None, workers="3", env=None, info_prefix=""):
|
|
|
env = env or {"RC_NO_TEST_ENV": "1"}
|
|
|
rhodecode_port = port
|
|
|
|
|
|
overrides = list(overrides)
|
|
|
overrides.append({"app:main": {"use_celery": "true"}})
|
|
|
overrides.append({"app:main": {"celery.task_always_eager": "false"}})
|
|
|
config_overrides = None
|
|
|
|
|
|
if getattr(request, 'param', None):
|
|
|
config_overrides = [request.param]
|
|
|
overrides.extend(config_overrides)
|
|
|
|
|
|
option_name = "celery_config"
|
|
|
override_option_name = None
|
|
|
|
|
|
if not config_file:
|
|
|
config_file = get_config(
|
|
|
request.config,
|
|
|
option_name=option_name,
|
|
|
override_option_name=override_option_name,
|
|
|
overrides=overrides,
|
|
|
basetemp=store_dir,
|
|
|
prefix=f"{info_prefix}test_celery_ini_",
|
|
|
)
|
|
|
|
|
|
server = CeleryServer(config_file, log_file, workers, env, info_prefix=info_prefix)
|
|
|
server.start()
|
|
|
|
|
|
@request.addfinalizer
|
|
|
def cleanup():
|
|
|
server.shutdown()
|
|
|
|
|
|
server.wait_until_ready()
|
|
|
return server
|
|
|
|
|
|
return factory
|
|
|
|
|
|
|
|
|
def _use_log_level(config):
|
|
|
level = config.getoption("test_loglevel") or "critical"
|
|
|
return level.upper()
|
|
|
|
|
|
|
|
|
def _ini_config_factory(request, base_dir, rcserver_port, vcsserver_port):
|
|
|
option_name = "pyramid_config"
|
|
|
log_level = _use_log_level(request.config)
|
|
|
|
|
|
overrides = [
|
|
|
{"server:main": {"port": rcserver_port}},
|
|
|
{
|
|
|
"app:main": {
|
|
|
#'cache_dir': '%(here)s/rc-tests/rc_data',
|
|
|
"vcs.server": f"localhost:{vcsserver_port}",
|
|
|
# johbo: We will always start the VCSServer on our own based on the
|
|
|
# fixtures of the test cases. For the test run it must always be
|
|
|
# off in the INI file.
|
|
|
"vcs.start_server": "false",
|
|
|
"vcs.server.protocol": "http",
|
|
|
"vcs.scm_app_implementation": "http",
|
|
|
"vcs.svn.proxy.enabled": "true",
|
|
|
"vcs.hooks.protocol.v2": "celery",
|
|
|
"vcs.hooks.host": "*",
|
|
|
"repo_store.path": TESTS_TMP_PATH,
|
|
|
"app.service_api.token": "service_secret_token",
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
"handler_console": {
|
|
|
"class": "StreamHandler",
|
|
|
"args": "(sys.stderr,)",
|
|
|
"level": log_level,
|
|
|
}
|
|
|
},
|
|
|
]
|
|
|
|
|
|
filename = get_config(
|
|
|
request.config,
|
|
|
option_name=option_name,
|
|
|
override_option_name=f"{option_name}_override",
|
|
|
overrides=overrides,
|
|
|
basetemp=base_dir,
|
|
|
prefix="test_rce_",
|
|
|
)
|
|
|
return filename
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
|
def ini_config(request, tmpdir_factory, rcserver_port, vcsserver_port):
|
|
|
base_dir = tmpdir_factory.getbasetemp().strpath
|
|
|
return _ini_config_factory(request, base_dir, rcserver_port, vcsserver_port)
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
|
def ini_config_factory(request, tmpdir_factory, rcserver_port, vcsserver_port):
|
|
|
def _factory(ini_config_basedir, overrides=()):
|
|
|
return _ini_config_factory(request, ini_config_basedir, rcserver_port, vcsserver_port)
|
|
|
|
|
|
return _factory
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
|
def ini_settings(ini_config):
|
|
|
ini_path = ini_config
|
|
|
return get_app_config(ini_path)
|
|
|
|
|
|
|
|
|
def get_available_port(min_port=40000, max_port=55555):
|
|
|
from rhodecode.lib.utils2 import get_available_port as _get_port
|
|
|
|
|
|
return _get_port(min_port, max_port)
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
|
def rcserver_port(request):
|
|
|
port = get_available_port()
|
|
|
return port
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
|
def vcsserver_port(request):
|
|
|
port = request.config.getoption("--vcsserver-port")
|
|
|
if port is None:
|
|
|
port = get_available_port()
|
|
|
return port
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
|
def available_port_factory() -> get_available_port:
|
|
|
"""
|
|
|
Returns a callable which returns free port numbers.
|
|
|
"""
|
|
|
return get_available_port
|
|
|
|
|
|
|
|
|
@pytest.fixture()
|
|
|
def available_port(available_port_factory):
|
|
|
"""
|
|
|
Gives you one free port for the current test.
|
|
|
|
|
|
Uses "available_port_factory" to retrieve the port.
|
|
|
"""
|
|
|
return available_port_factory()
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
|
def testini_factory(tmpdir_factory, ini_config):
|
|
|
"""
|
|
|
Factory to create an INI file based on TestINI.
|
|
|
|
|
|
It will make sure to place the INI file in the correct directory.
|
|
|
"""
|
|
|
basetemp = tmpdir_factory.getbasetemp().strpath
|
|
|
return TestIniFactory(basetemp, ini_config)
|
|
|
|
|
|
|
|
|
class TestIniFactory(object):
|
|
|
def __init__(self, ini_store_dir, template_ini):
|
|
|
self._ini_store_dir = ini_store_dir
|
|
|
self._template_ini = template_ini
|
|
|
|
|
|
def __call__(self, ini_params, new_file_prefix="test"):
|
|
|
ini_file = TestINI(
|
|
|
self._template_ini, ini_params=ini_params, new_file_prefix=new_file_prefix, dir=self._ini_store_dir
|
|
|
)
|
|
|
result = ini_file.create()
|
|
|
return result
|
|
|
|
|
|
|
|
|
def get_config(config, option_name, override_option_name, overrides=None, basetemp=None, prefix="test"):
|
|
|
"""
|
|
|
Find a configuration file and apply overrides for the given `prefix`.
|
|
|
"""
|
|
|
try:
|
|
|
config_file = config.getoption(option_name)
|
|
|
except ValueError:
|
|
|
config_file = None
|
|
|
|
|
|
if not config_file:
|
|
|
config_file = config.getini(option_name)
|
|
|
|
|
|
if not config_file:
|
|
|
pytest.exit(f"Configuration error, could not extract {option_name}.")
|
|
|
|
|
|
overrides = overrides or []
|
|
|
if override_option_name:
|
|
|
config_override = config.getoption(override_option_name)
|
|
|
if config_override:
|
|
|
overrides.append(config_override)
|
|
|
temp_ini_file = TestINI(config_file, ini_params=overrides, new_file_prefix=prefix, dir=basetemp)
|
|
|
|
|
|
return temp_ini_file.create()
|
|
|
|