Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import pytest

from robottelo.config import settings

pytest_plugins = [
# Plugins
'pytest_plugins.auto_vault',
Expand Down Expand Up @@ -94,3 +96,14 @@ def pytest_runtest_makereport(item, call):
# be "setup", "call", "teardown"

setattr(item, "report_" + report.when, report)


@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_protocol(item, nextitem):
"""Set version source to upstream for tests marked with foremanctl."""
if item.get_closest_marker('foremanctl'):
settings.set('server.version.source', 'upstream')
yield
settings.set('server.version.source', 'internal')
else:
yield
1 change: 1 addition & 0 deletions pytest_plugins/markers.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ def pytest_configure(config):
"ldap: Tests related to ldap authentication",
"no_compose : Skip the marked sanity test for nightly compose",
"network: Restrict test to specific network environments",
"foremanctl: Tests that require foremanctl",
]
markers.extend(module_markers())
for marker in markers:
Expand Down
6 changes: 5 additions & 1 deletion robottelo/config/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@
Validator('server.hostname', is_type_of=str),
Validator('server.hostnames', must_exist=True, is_type_of=list),
Validator('server.version.release', must_exist=True),
Validator('server.version.source', default='internal', is_in=['internal', 'ga', 'nightly']),
Validator(
'server.version.source',
default='internal',
is_in=['internal', 'ga', 'nightly', 'upstream'],
),
Validator('server.version.rhel_version', must_exist=True, cast=str),
Validator(
'server.xdist_behavior', must_exist=True, is_in=['run-on-one', 'balance', 'on-demand']
Expand Down
55 changes: 55 additions & 0 deletions robottelo/hosts.py
Original file line number Diff line number Diff line change
Expand Up @@ -1577,6 +1577,12 @@ def setup_satellite_repos(self):
satellite_repo=settings.repos.satellite_repo,
satmaintenance_repo=settings.repos.satmaintenance_repo,
)
elif settings.server.version.source == 'upstream':
self.create_custom_repos(
foreman='https://yum.theforeman.org/nightly/el9/x86_64/',
foreman_plugins='https://yum.theforeman.org/plugins/nightly/el9/x86_64/',
katello='https://yum.theforeman.org/katello/nightly/katello/el9/x86_64/',
)
else:
# get ohsnap repofile
self.download_repofile(
Expand Down Expand Up @@ -1955,6 +1961,55 @@ def install_satellite_or_capsule_package(self):
self.enable_satellite_or_capsule_module_for_rhel8()
assert self.execute(f'dnf -y install {self.product_rpm_name}').status == 0

def install_satellite_foremanctl(self, enable_fapolicyd=False, enable_fips=False):
# Enable RHEL and Satellite repos
self.register_to_cdn()
self.setup_rhel_repos()
self.setup_satellite_repos()
assert self.execute('dnf copr enable -y @theforeman/foremanctl rhel-9-x86_64').status == 0
assert self.execute('dnf install -y foremanctl').status == 0

if enable_fapolicyd:
assert self.execute('dnf -y install fapolicyd').status == 0
assert self.execute('systemctl enable --now fapolicyd').status == 0
assert self.execute('systemctl is-active fapolicyd').status == 0
if enable_fips:
Broker().execute(
workflow='enable-fips',
target_vm=self.name,
)
self.connect()
assert self.is_fips_enabled()

# Configure Satellite firewall to open communication
assert (
self.execute(
'(which firewall-cmd || dnf -y install firewalld) && systemctl enable --now firewalld'
).status
== 0
), 'firewalld is not present and can\'t be installed'
assert (
self.execute(
'firewall-cmd --permanent --add-service RH-Satellite-6 && firewall-cmd --reload'
).status
== 0
)
# Install Satellite and return result
assert (
self.execute(
f'foremanctl deploy --foreman-initial-admin-username {settings.server.admin_username} --foreman-initial-admin-password {settings.server.admin_password}',
timeout='30m',
).status
== 0
)
assert (
self.execute(
'foremanctl deploy --add-feature foreman-proxy --add-feature hammer'
).status
== 0
)
return

def query_db(self, query, db='foreman', output_format='json'):
"""Execute a PostgreSQL query and return the result.
Expand Down
124 changes: 124 additions & 0 deletions tests/foreman/installer/test_install_foremanctl.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
"""Smoke tests to check installation health
:Requirement: Installation
:CaseAutomation: Automated
:CaseComponent: Installation
:Team: Rocket
:CaseImportance: Critical
"""

from broker import Broker
import pytest

from robottelo.config import settings
from robottelo.hosts import Satellite
from robottelo.utils.issue_handlers import is_open

pytestmark = [pytest.mark.foremanctl, pytest.mark.build_sanity, pytest.mark.upgrade]

SATELLITE_SERVICES = [
'candlepin',
'dynflow-sidekiq@orchestrator',
'dynflow-sidekiq@worker',
'dynflow-sidekiq@worker-hosts-queue',
'foreman-proxy',
'foreman',
'httpd',
'postgresql',
'pulp-api',
'pulp-content',
'pulp-worker@*',
'redis',
]


def common_sat_install_assertions(satellite):
# no errors/failures in journald
result = satellite.execute(
r'journalctl --quiet --no-pager --boot --grep ERROR -u "dynflow-sidekiq*" -u "foreman-proxy" -u "foreman" -u "httpd" -u "postgresql" -u "pulp-api" -u "pulp-content" -u "pulp-worker*" -u "redis" -u "candlepin"'
)
Comment on lines +42 to +44
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the list here is the same as SATELLITE_SERVICES, you could do

Suggested change
result = satellite.execute(
r'journalctl --quiet --no-pager --boot --grep ERROR -u "dynflow-sidekiq*" -u "foreman-proxy" -u "foreman" -u "httpd" -u "postgresql" -u "pulp-api" -u "pulp-content" -u "pulp-worker*" -u "redis" -u "candlepin"'
)
units_string = ' -u '.join([f'"{service}"' for service in SATELLITE_SERVICES])
result = satellite.execute(f'journalctl --quiet --no-pager --boot --grep ERROR -u {units_string}')

It makes the test re-use the list, but is not really well readable :/

(Why is this a raw string btw?)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does not exactly follow a SATELLITE_SERVICES as dynflow-sidekiq* and pulp-worker* is not a service, and defining a separate list for this systemd units would not make any sense as it wouldn't be reusable, and I see no problem with it being in raw string

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SATELLITE_SERVICES contains pulp-worker@*, the list here has pulp-worker*, and I would expect both match "all pulp worker units"
Same-ish for dynflow-sidekiq* here which should match the three instances listed in SATELLITE_SERVICES

So yes, the lists are not identical, but I'd expect the result to be.

That said, this all is not blocking and I am totally OK with the current code.

if is_open('SAT-21086'):
assert not list(filter(lambda x: 'PG::' not in x, result.stdout.splitlines()))
else:
assert not result.stdout
# no errors/failures in /var/log/httpd/*
result = satellite.execute(r'grep -iR "error" /var/log/httpd/*')
assert not result.stdout
httpd_log = satellite.execute('journalctl --unit=httpd')
assert 'WARNING' not in httpd_log.stdout


@pytest.fixture(scope='module')
def module_sat_ready_rhel(request):
with Broker(
workflow=settings.server.deploy_workflows.os,
deploy_rhel_version=settings.server.version.rhel_version,
deploy_flavor=settings.flavors.default,
deploy_network_type=settings.server.network_type,
host_class=Satellite,
) as sat:
sat.install_satellite_foremanctl(
enable_fapolicyd=(request.param == 'fapolicyd'), enable_fips=(request.param == 'fips')
)
yield sat


@pytest.mark.first_sanity
@pytest.mark.parametrize('module_sat_ready_rhel', ['default'], indirect=True)
def test_satellite_installation_with_foremanctl(module_sat_ready_rhel):
"""Run a basic Satellite installation
:id: 661206f3-2eec-403c-af26-3c5cadcd5769
:steps:
1. Get RHEL Host
2. Configure satellite repos
3. Install satellite using foremanctl
4. Run foremanctl deploy
:expectedresults:
1. foremanctl deploy runs successfully
2. no unexpected errors in logs
"""
common_sat_install_assertions(module_sat_ready_rhel)


@pytest.mark.parametrize('module_sat_ready_rhel', ['default'], indirect=True)
@pytest.mark.parametrize('service', SATELLITE_SERVICES)
def test_positive_check_installer_service_running(service, module_sat_ready_rhel):
"""Check if all Satellite services is running
:id: 5389c174-7ab1-4e9d-b2aa-66d80fd6dc5h
:steps:
1. Verify a service is active with systemctl is-active
:expectedresults: All Satellite services are active
"""
is_active = module_sat_ready_rhel.execute(f'systemctl is-active {service}')
status = module_sat_ready_rhel.execute(f'systemctl status {service}')
assert is_active.status == 0, status.stdout


@pytest.mark.parametrize('module_sat_ready_rhel', ['default'], indirect=True)
def test_positive_check_installer_hammer_ping(module_sat_ready_rhel):
"""Check if hammer ping reports all services as ok
:id: 85fd4388-6d94-42f5-bed2-24be38e9f111
:steps:
1. Run the 'hammer ping' command on satellite.
:expectedresults: All services are active (running)
"""
# check status reported by hammer ping command
result = module_sat_ready_rhel.execute('hammer ping')
assert result.status == 0
for line in result.stdout.split('\n'):
if 'Status' in line:
assert 'ok' in line
Loading