Skip to content

Commit

Permalink
[6.12.z] Capsule N-Minus testing (#12939) (#14372)
Browse files Browse the repository at this point in the history
Capsule N-Minus testing (#12939)
  • Loading branch information
jyejare authored Mar 12, 2024
1 parent 803b450 commit 88b2795
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 12 deletions.
2 changes: 2 additions & 0 deletions conf/capsule.yaml.template
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
CAPSULE:
# Capsule hostname for N-minus testing
HOSTNAME:
VERSION:
# The full release version (6.9.2)
RELEASE: # populate with capsule version
Expand Down
6 changes: 3 additions & 3 deletions conf/dynaconf_hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,9 @@ def get_ohsnap_repos(settings):
settings,
repo='capsule',
product='capsule',
release=settings.server.version.release,
os_release=settings.server.version.rhel_version,
snap=settings.server.version.snap,
release=settings.capsule.version.release,
os_release=settings.capsule.version.rhel_version,
snap=settings.capsule.version.snap,
)

data['SATELLITE_REPO'] = get_ohsnap_repo_url(
Expand Down
1 change: 1 addition & 0 deletions conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
'pytest_plugins.requirements.update_requirements',
'pytest_plugins.sanity_plugin',
'pytest_plugins.video_cleanup',
'pytest_plugins.capsule_n-minus',
# Fixtures
'pytest_fixtures.core.broker',
'pytest_fixtures.core.sat_cap_factory',
Expand Down
40 changes: 31 additions & 9 deletions pytest_fixtures/core/sat_cap_factory.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from contextlib import contextmanager
from functools import lru_cache

from broker import Broker
from packaging.version import Version
Expand Down Expand Up @@ -37,13 +38,29 @@ def _target_satellite_host(request, satellite_factory):
yield


@lru_cache
def cached_capsule_cdn_register(hostname=None):
cap = Capsule.get_host_by_hostname(hostname=hostname)
cap.enable_capsule_downstream_repos()


@contextmanager
def _target_capsule_host(request, capsule_factory):
if 'sanity' not in request.config.option.markexpr:
if 'sanity' not in request.config.option.markexpr and not request.config.option.n_minus:
new_cap = capsule_factory()
yield new_cap
new_cap.teardown()
Broker(hosts=[new_cap]).checkin()
elif request.config.option.n_minus:
if not settings.capsule.hostname:
hosts = Capsule.get_hosts_from_inventory(filter="'cap' in @inv.name")
settings.capsule.hostname = hosts[0].hostname
cap = hosts[0]
else:
cap = Capsule.get_host_by_hostname(settings.capsule.hostname)
# Capsule needs RHEL contents for some tests
cached_capsule_cdn_register(hostname=settings.capsule.hostname)
yield cap
else:
yield

Expand Down Expand Up @@ -148,9 +165,10 @@ def session_capsule_host(request, capsule_factory):


@pytest.fixture
def capsule_configured(capsule_host, target_sat):
def capsule_configured(request, capsule_host, target_sat):
"""Configure the capsule instance with the satellite from settings.server.hostname"""
capsule_host.capsule_setup(sat_host=target_sat)
if not request.config.option.n_minus:
capsule_host.capsule_setup(sat_host=target_sat)
return capsule_host


Expand All @@ -162,21 +180,23 @@ def large_capsule_configured(large_capsule_host, target_sat):


@pytest.fixture(scope='module')
def module_capsule_configured(module_capsule_host, module_target_sat):
def module_capsule_configured(request, module_capsule_host, module_target_sat):
"""Configure the capsule instance with the satellite from settings.server.hostname"""
module_capsule_host.capsule_setup(sat_host=module_target_sat)
if not request.config.option.n_minus:
module_capsule_host.capsule_setup(sat_host=module_target_sat)
return module_capsule_host


@pytest.fixture(scope='session')
def session_capsule_configured(session_capsule_host, session_target_sat):
def session_capsule_configured(request, session_capsule_host, session_target_sat):
"""Configure the capsule instance with the satellite from settings.server.hostname"""
session_capsule_host.capsule_setup(sat_host=session_target_sat)
if not request.config.option.n_minus:
session_capsule_host.capsule_setup(sat_host=session_target_sat)
return session_capsule_host


@pytest.fixture(scope='module')
def module_capsule_configured_mqtt(module_capsule_configured):
def module_capsule_configured_mqtt(request, module_capsule_configured):
"""Configure the capsule instance with the satellite from settings.server.hostname,
enable MQTT broker"""
module_capsule_configured.set_rex_script_mode_provider('pull-mqtt')
Expand All @@ -192,7 +212,9 @@ def module_capsule_configured_mqtt(module_capsule_configured):
)
result = module_capsule_configured.cli.Service.restart(options={'only': 'foreman-proxy'})
assert result.status == 0, 'foreman-proxy restart unsuccessful'
return module_capsule_configured
yield module_capsule_configured
if request.config.option.n_minus:
raise TypeError('The teardown is missed for MQTT configuration undo for nminus testing')


@pytest.fixture(scope='module')
Expand Down
55 changes: 55 additions & 0 deletions pytest_plugins/capsule_n-minus.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Collection of Capsule Factory fixture tests
# No destructive tests
# Adjust capsule host and capsule_configured host behavior for n_minus testing
# Calculate capsule hostname from inventory just as we do in xDist.py
from robottelo.config import settings
from robottelo.hosts import Capsule


def pytest_addoption(parser):
"""Add options for pytest to collect tests based on fixtures its using"""
help_text = '''
Collects tests based on capsule fixtures used by tests and uncollect destructive tests
Usage: --n-minus
example: pytest --n-minus tests/foreman
'''
parser.addoption("--n-minus", action='store_true', default=False, help=help_text)


def pytest_collection_modifyitems(items, config):

if not config.getoption('n_minus', False):
return

selected = []
deselected = []

for item in items:
is_destructive = item.get_closest_marker('destructive')
# Deselect Destructive tests and tests without capsule_factory fixture
if 'capsule_factory' not in item.fixturenames or is_destructive:
deselected.append(item)
continue
# Ignoring all puppet tests as they are destructive in nature
# and needs its own satellite for verification
if 'session_puppet_enabled_sat' in item.fixturenames:
deselected.append(item)
continue
# Ignoring all satellite maintain tests as they are destructive in nature
# Also dont need them in nminus testing as its not integration testing
if 'sat_maintain' in item.fixturenames and 'satellite' in item.callspec.params.values():
deselected.append(item)
continue
selected.append(item)

config.hook.pytest_deselected(items=deselected)
items[:] = selected


def pytest_sessionfinish(session, exitstatus):
# Unregister the capsule from CDN after all tests
if session.config.option.n_minus and not session.config.option.collectonly:
caps = Capsule.get_host_by_hostname(hostname=settings.capsule.hostname)
caps.unregister()
6 changes: 6 additions & 0 deletions robottelo/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ class CLIError(Exception):
"""Indicates that a CLI command could not be run."""


class CapsuleHostError(Exception):
"""Indicates error in capsule configuration etc"""

pass


class CLIBaseError(Exception):
"""Indicates that a CLI command has finished with return code different
from zero.
Expand Down
15 changes: 15 additions & 0 deletions robottelo/hosts.py
Original file line number Diff line number Diff line change
Expand Up @@ -1555,6 +1555,21 @@ def get_features(self):
"""Get capsule features"""
return requests.get(f'https://{self.hostname}:9090/features', verify=False).text

def enable_capsule_downstream_repos(self):
"""Enable CDN repos and capsule downstream repos on Capsule Host"""
# CDN Repos
self.register_to_cdn()
for repo in getattr(constants, f"OHSNAP_RHEL{self.os_version.major}_REPOS"):
result = self.enable_repo(repo, force=True)
if result.status:
raise CapsuleHostError(f'Repo enable at capsule host failed\n{result.stdout}')
# Downstream Capsule specific Repos
self.download_repofile(
product='capsule',
release=settings.capsule.version.release,
snap=settings.capsule.version.snap,
)

def capsule_setup(self, sat_host=None, **installer_kwargs):
"""Prepare the host and run the capsule installer"""
self._satellite = sat_host or Satellite()
Expand Down

0 comments on commit 88b2795

Please sign in to comment.