Commit 6926754a authored by Georges Racinet's avatar Georges Racinet 🦑
Browse files

heptapod#612: making Heptapod 0.28 the stable series

--HG--
branch : stable
Pipeline #31547 passed with stage
in 44 minutes and 52 seconds
variables:
TARGET_HEPTAPOD_IMAGE: "0-27-testing"
TARGET_HEPTAPOD_IMAGE: "0-28-testing"
HEPTAPOD_BASE_IMAGE: registry.heptapod.net/heptapod/omnibus-heptapod
GITLAB_ROOT_PASSWORD: "5l!fe-as-initial-root-password-on-ci"
CI_CLEVER_CLOUD_FLAVOR: XL
......@@ -78,6 +78,10 @@ docker-inside:
variables:
HEPTAPOD_HG_NATIVE: full
.hg-without-git:
variables:
HEPTAPOD_HG_NATIVE: without-git
docker-remote-0:
variables:
PYTEST_SHARD_ID: 0
......@@ -188,3 +192,42 @@ docker-fully-native-remote-1:
- .hg-fully-native
docker-without-git-inside:
extends:
- docker-inside
- .hg-without-git
# unfortunately variables are not expanded in service aliases
# so we need to duplicate
services:
- name: $SELENIUM_SERVER_IMAGE
alias: selenium-for-native-inside-without-git
docker-without-git-remote-0:
variables:
PYTEST_SHARD_ID: 0
services:
# unfortunately variables are not expanded in service aliases
# so we need to duplicate
- name: $HEPTAPOD_BASE_IMAGE:$TARGET_HEPTAPOD_IMAGE
alias: heptapod-native-without-git-0
- name: $SELENIUM_SERVER_IMAGE
alias: selenium-native-without-git-0
extends:
- .docker-remote
- .rules:test-heptapod
- .hg-without-git
docker-without-git-remote-1:
variables:
PYTEST_SHARD_ID: 1
services:
# unfortunately variables are not expanded in service aliases
# so we need to duplicate
- name: $HEPTAPOD_BASE_IMAGE:$TARGET_HEPTAPOD_IMAGE
alias: heptapod-native-without-git-1
- name: $SELENIUM_SERVER_IMAGE
alias: selenium-native-without-git-1
extends:
- .docker-remote
- .rules:test-heptapod
- .hg-without-git
......@@ -79,7 +79,8 @@ def pytest_addoption(parser):
"direct command nor file system access is possible "
"leading to skipping some tests and some teardown "
"reliability actions.")
parser.addoption('--heptapod-hg-native', choices=('full', 'hgitaly1'),
parser.addoption('--heptapod-hg-native',
choices=('without-git', 'full', 'hgitaly1'),
help="Have all Mercurial projects created as 'native' "
"(HGitaly backed)")
parser.addoption('--heptapod-repositories-root',
......@@ -154,6 +155,10 @@ def pytest_configure(config):
"hg_native: mark test as running only if "
"session is in hg-native mode"
)
config.addinivalue_line("markers",
"git_aux_repo: mark test as running only if "
"Mercurial repos have an auxiliary Git repo."
)
config.addinivalue_line("markers",
"prod_server: mark test as suitable "
"on production servers."
......@@ -175,6 +180,8 @@ def pytest_collection_modifyitems(config, items):
skip_hg_native = pytest.mark.skip(reason="needs hg-native mode")
skip_prod_server = pytest.mark.skip(
reason="not meant for production servers ")
skip_git_aux_repo = pytest.mark.skip(
reason="not meant for --heptapod-hg-native=without-git")
no_reverse_call = not(config.getoption('heptapod_reverse_call_host'))
prod_server = config.getoption('heptapod_prod_server')
......@@ -202,6 +209,8 @@ def pytest_collection_modifyitems(config, items):
item.add_marker(skip_hg_native)
if prod_server and "prod_server" not in item.keywords:
item.add_marker(skip_prod_server)
if "git_aux_repo" in item.keywords and hg_native == 'without-git':
item.add_marker(skip_git_aux_repo)
heptapod_instance = None
......@@ -239,7 +248,7 @@ def heptapod(pytestconfig):
wait_after_first_response=pytestconfig.getoption(
'heptapod_wait_after_first_response'),
clever_cloud_sso=pytestconfig.getoption('heptapod_clever_cloud_sso'),
hg_native=pytestconfig.getoption('heptapod_hg_native')
hg_native=pytestconfig.getoption('heptapod_hg_native'),
)
# make tests fully independent of current user settings
......@@ -307,6 +316,8 @@ def project_fixture(heptapod, name_prefix, owner=None, group=None, **opts):
group=group, **opts) as proj:
yield proj
proj.assert_no_unwanted_git_repo()
@contextlib.contextmanager
def group_fixture(heptapod, path_prefix, creator_name='root', parent=None):
......
......@@ -13,9 +13,18 @@ from .test_push import prepare_simple_repo
parametrize = pytest.mark.parametrize
@needs.fs_access
def test_group_project(heptapod):
inner_test_group_project(heptapod, hashed_storage=True)
@needs.services
@parametrize('hashed_storage', [True, False])
def test_group_project(heptapod, hashed_storage):
@needs.docker
def test_group_project_legacy_storage(heptapod):
inner_test_group_project(heptapod, hashed_storage=False)
def inner_test_group_project(heptapod, hashed_storage):
group = group2 = None
group_name = unique_name('test_group')
group2_name = unique_name('transfer_target')
......@@ -108,9 +117,18 @@ def test_custom_attributes_perms(heptapod):
assert_forbidden(owner)
@needs.fs_access
def test_subgroups(heptapod):
inner_test_subgroups(heptapod, hashed_storage=True)
@needs.docker
@needs.services
@parametrize('hashed_storage', [True, False])
def test_subgroups(heptapod, hashed_storage):
def test_subgroups_legacy_storage(heptapod):
inner_test_subgroups(heptapod, hashed_storage=False)
def inner_test_subgroups(heptapod, hashed_storage):
user_name = 'test_basic'
group = subgroup = None
group_name = unique_name('test_group')
......
......@@ -26,15 +26,12 @@ parametrize = pytest.mark.parametrize
@needs.services
@parametrize('hashed_storage', [True, False])
def test_webdriver_destroy(test_project, hashed_storage):
def test_webdriver_destroy(test_project):
"""
When a project was destroyed in the GUI, the mercurial repositories
were not destroyed along with the git repositories.
This test makes sure that they are destroyed too.
"""
if not hashed_storage:
test_project.make_storage_legacy()
test_project.webdriver_destroy()
heptapod = test_project.heptapod
......@@ -91,6 +88,7 @@ def test_transfer(public_project, tmpdir):
@needs.services
@needs.docker
def test_transfer_not_hashed(public_project, tmpdir):
public_project.make_storage_legacy()
inner_test_transfer(public_project, tmpdir)
......@@ -266,6 +264,7 @@ def test_hgrc_get_put(test_project):
@needs.services
@needs.docker
def test_hashed_storage_migration(heptapod, tmpdir):
user_name = 'test_basic'
......
......@@ -293,6 +293,7 @@ def test_push_hook_env(test_project, tmpdir, push_proto):
@needs.fs_access
@needs.git_aux_repo
def test_push_corrupted(test_project, tmpdir):
"""If Git repo has more commits (issue hg-git#3)."""
url = test_project.owner_basic_auth_url
......@@ -497,6 +498,7 @@ def test_protected_branch_ultimate(test_project, tmpdir):
@needs.docker
@needs.git_aux_repo
def test_push_corrupted_2(test_project, tmpdir):
"""If Git repo has more commits in a topic (issue heptapod#119)."""
......
......@@ -99,6 +99,7 @@ class Heptapod:
self.ssh_port = ssh_port
self.ssh_user = ssh_user
self.hg_native = hg_native
self.hg_without_git = hg_native == 'without-git'
self.clever_cloud_sso = clever_cloud_sso
self.users = {}
if reverse_call_host is not None:
......@@ -309,7 +310,9 @@ class Heptapod:
api_caching_rate_limit_branches=False,
)
if native is not None:
feature_flags['hg_fully_native'] = native == 'full'
feature_flags['hg_fully_native'] = native in ('full',
'without-git')
feature_flags['hg_without_git'] = self.hg_without_git
self.set_feature_flags(feature_flags)
logger.info("Preparing basic user.")
......@@ -766,6 +769,9 @@ class OmnibusHeptapod(Heptapod):
fobj.writelines(lines)
os.chown(path, uid, gid)
def path_exists(self, path):
return os.path.exists(path)
def get_file_lines(self, path):
with open(path) as fobj:
return fobj.readlines()
......@@ -834,6 +840,10 @@ class DockerHeptapod(OmnibusHeptapod):
def get_archive(self, path, tarf):
return docker.heptapod_get_archive(self.docker_container, path, tarf)
def path_exists(self, path):
code, out = self.execute(['stat', path])
return code == 0
def put_file_lines(self, path, lines, uid=998, gid=998):
dirpath, filename = path.rsplit('/', 1)
tar_buf = BytesIO()
......@@ -926,6 +936,9 @@ class SourceHeptapod(Heptapod):
with open(path, 'w') as fobj:
fobj.writelines(lines)
def path_exists(self, path):
return os.path.exists(path)
class GdkHeptapod(SourceHeptapod):
"""An Heptapod server running with the GDK.
......
......@@ -6,4 +6,12 @@ reverse_call = pytest.mark.reverse_call
services = pytest.mark.services
sql = pytest.mark.sql
hg_git = pytest.mark.hg_git
"""The test session creates Mercurial projects with `vcs_type == hg_git`
"""
git_aux_repo = pytest.mark.git_aux_repo
"""The test session creates Mercurial projects having an inner Git repo.
As of this writing, the `hgitaly1` and `full` values for
`--heptapod-hg-native` still make use of an auxiliary Git repository.
"""
prod_server = pytest.mark.prod_server
......@@ -67,6 +67,17 @@ class Project(object):
# preferably for temporary workarounds.
vcs_type = attr.ib(default=None)
is_legacy = attr.ib(default=False)
hg_git_repo_expected = attr.ib(default=False)
"""For Mercurial, express whether an auxiliary Git repo is expected.
This can be ``True`` in two cases:
- because of general testing options. As of this writing, if
``--heptapod-hg-native`` is not set to ``without-git``.
- because the Git repository is a functionally desireable outcome
(see heptapod#125). In this case, the tests are expected to override
the value, because it is initialized from the general testing options.
"""
def owner_get(self, **kwargs):
"""A shortcut to perform a simple GET, with BasicAuth as the owner.
......@@ -1230,6 +1241,7 @@ class Project(object):
group=group, name=project_name,
id=proj_info['id'],
vcs_type=vcs_type,
hg_git_repo_expected=not heptapod.hg_without_git,
owner=user_name)
@classmethod
......@@ -1446,6 +1458,17 @@ class Project(object):
assert resp.status_code < 300
return resp.json()
def assert_no_unwanted_git_repo(self):
if self.vcs_type != 'hg' or self.hg_git_repo_expected:
return
heptapod = self.heptapod
if not heptapod.fs_access:
# we can't assert
return
assert not heptapod.path_exists(self.fs_path_git)
def __enter__(self):
return self
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment