Skip to content
Draft
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
6 changes: 4 additions & 2 deletions docs/developer/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,10 +225,12 @@ def test_dynflow_service_instances(server, instance):

## Where to add new tests

The directory `tests/feature` is special. Any subdirectory automatically applies the feature marker. `tests/feature/foreman/api_test.py` is equivalent to `tests/foreman_api_test.py` with `pytestmark = pytest.mark.feature("foreman")`.

| What you're testing | File |
| --- | --- |
| A new service (container or systemd unit) | `tests/<service>_test.py` |
| Foreman API behavior | `tests/foreman_api_test.py` (or a new file for larger areas) |
| A new service (container or systemd unit) | `tests/feature/<feature>/<service>_test.py` |
| Foreman API behavior | `tests/feature/foreman/api_test.py` (or a new file for larger areas) |
| Client registration or content workflows | `tests/client_test.py` |
| CLI flags, playbooks, or feature management | `tests/features_test.py` or `tests/playbooks_test.py` |
| A standalone script (no deployment needed) | `tests/unit/<name>_test.py` |
Expand Down
10 changes: 10 additions & 0 deletions src/features.yaml
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
---
foreman:
description: Base Foreman Server
dependencies:
- httpd
- redis
foreman-proxy:
description: Base Foreman Proxy
hammer:
description: Foreman CLI
httpd:
internal: true
redis:
internal: true
katello:
description: Content and Subscription Management plugin for Foreman
foreman:
plugin_name: katello
hammer: katello
dependencies:
- httpd
- redis
google:
description: Google Compute Engine plugin for Foreman
hammer: foreman_google
Expand Down
63 changes: 50 additions & 13 deletions src/playbooks/deploy/deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,44 @@
- "../../vars/foreman.yml"
- "../../vars/base.yaml"
pre_tasks:
- name: Add iop databases
- name: Determine databases
when:
- "'iop' in enabled_features"
- database_mode == 'internal'
block:
- name: Include iop databases
ansible.builtin.include_vars:
file: "../../vars/database_iop.yml"
- name: Configure Candlepin database
ansible.builtin.set_fact:
postgresql_databases: "{{ postgresql_databases + postgresql_databases_candlepin }}"
postgresql_users: "{{ postgresql_users + postgresql_users_candlepin }}"
when:
- "'foreman' in enabled_features"
- "'katello' in enabled_features"

- name: Configure Foreman database
ansible.builtin.set_fact:
postgresql_databases: "{{ postgresql_databases + postgresql_databases_foreman }}"
postgresql_users: "{{ postgresql_users + postgresql_users_foreman }}"
when:
- "'foreman' in enabled_features"

- name: Combine lists
- name: Configure Pulp database
ansible.builtin.set_fact:
postgresql_databases: "{{ postgresql_databases + iop_postgresql_databases }}"
postgresql_users: "{{ postgresql_users + iop_postgresql_users }}"
postgresql_databases: "{{ postgresql_databases + postgresql_databases_pulp }}"
postgresql_users: "{{ postgresql_users + postgresql_users_pulp }}"
when:
- "'katello' in enabled_features"

- name: Add iop databases
when:
- "'iop' in enabled_features"
block:
- name: Include iop databases
ansible.builtin.include_vars:
file: "../../vars/database_iop.yml"

- name: Combine lists
ansible.builtin.set_fact:
postgresql_databases: "{{ postgresql_databases + iop_postgresql_databases }}"
postgresql_users: "{{ postgresql_users + iop_postgresql_users }}"
roles:
- role: pre_install
- role: checks
Expand All @@ -39,11 +64,23 @@
- role: postgresql
when:
- database_mode == 'internal'
- redis
- candlepin
- httpd
- pulp
- foreman
- postgresql_databases | length > 0
- role: redis
when:
- "'redis' in enabled_features"
- role: candlepin
when:
- "'foreman' in enabled_features"
- "'katello' in enabled_features"
- role: httpd
when:
- "'httpd' in enabled_features"
- role: pulp
when:
- "'katello' in enabled_features"
- role: foreman
when:
- "'foreman' in enabled_features"
- role: systemd_target
- role: iop_core
when:
Expand Down
2 changes: 2 additions & 0 deletions src/roles/foreman/tasks/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -313,3 +313,5 @@
oauth1_consumer_key: "{{ foreman_oauth_consumer_key }}"
oauth1_consumer_secret: "{{ foreman_oauth_consumer_secret }}"
ca_path: "{{ foreman_ca_certificate }}"
when:
- "'katello' in enabled_features"
2 changes: 2 additions & 0 deletions src/roles/foreman_proxy/tasks/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@
oauth1_consumer_key: "{{ foreman_proxy_oauth_consumer_key }}"
oauth1_consumer_secret: "{{ foreman_proxy_oauth_consumer_secret }}"
ca_path: "{{ foreman_proxy_foreman_ca_certificate | default(omit) }}"
when:
- False

- name: Flush handlers to restart services
ansible.builtin.meta: flush_handlers
2 changes: 2 additions & 0 deletions src/roles/post_install/tasks/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
vars:
_post_install_url_msg: "Foreman is running at {{ foreman_url }}"
_post_install_cred_msg: "Admin credentials: {{ foreman_initial_admin_username }}:{{ foreman_initial_admin_password }}"
when:
- "'foreman' in enabled_features"
- name: Mark installation as complete
ansible.builtin.copy:
dest: "{{ post_install_done_flag }}"
Expand Down
16 changes: 14 additions & 2 deletions src/vars/database.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,29 @@ foreman_database_port: "{{ database_port }}"
foreman_database_ssl_mode: "{{ database_ssl_mode }}"
foreman_database_ssl_ca: "{{ database_ssl_ca }}"

postgresql_databases:
postgresql_databases_candlepin:
- name: "{{ candlepin_database_name }}"
owner: "{{ candlepin_database_user }}"

postgresql_databases_foreman:
- name: "{{ foreman_database_name }}"
owner: "{{ foreman_database_user }}"

postgresql_databases_pulp:
- name: "{{ pulp_database_name }}"
owner: "{{ pulp_database_user }}"
postgresql_users:

postgresql_users_candlepin:
- name: "{{ candlepin_database_user }}"
password: "{{ candlepin_database_password }}"

postgresql_users_foreman:
- name: "{{ foreman_database_user }}"
password: "{{ foreman_database_password }}"

postgresql_users_pulp:
- name: "{{ pulp_database_user }}"
password: "{{ pulp_database_password }}"

postgresql_databases: []
postgresql_users: []
3 changes: 3 additions & 0 deletions src/vars/flavors/foreman-proxy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
flavor_features:
- foreman-proxy
3 changes: 3 additions & 0 deletions src/vars/flavors/foreman.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
flavor_features:
- foreman
18 changes: 18 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import subprocess
import uuid
from functools import cached_property
from pathlib import Path

import apypie
import paramiko
Expand Down Expand Up @@ -144,6 +145,10 @@
api._session.headers['Host'] = server_fqdn
return api

@pytest.fixture

Check failure on line 148 in tests/conftest.py

View workflow job for this annotation

GitHub Actions / Python Lint

ruff (E302)

tests/conftest.py:148:1: E302 Expected 2 blank lines, found 1 help: Add missing blank line(s)
def features(pytestconfig):
return pytestconfig.user_parameters.features


@pytest.fixture
def organization(foremanapi):
Expand Down Expand Up @@ -242,6 +247,19 @@
config.user_parameters = UserParameters(config)


def pytest_collection_modifyitems(config, items):
feature_dir = config.rootdir / 'tests' / 'feature'
for item in items:
try:
rel_path = Path(item.fspath).relative_to(feature_dir)
except ValueError:
# Not in the features directory
pass
else:
feature = rel_path.parts[0]
item.add_marker(pytest.mark.feature(feature))


def pytest_runtest_setup(item):
feature_markers = set(mark.args[0] for mark in item.iter_markers(name="feature"))
if feature_markers:
Expand Down
Empty file added tests/feature/__init__.py
Empty file.
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,17 @@ def test_foreman_proxy_features(server, certificates, server_fqdn, enabled_featu
assert cmd.succeeded
features = json.loads(cmd.stdout)
assert "logs" in features
assert "script" in features
assert "dynflow" in features

if "remote-execution" in enabled_features:
assert "script" in features
else:
assert "script" not in features

if "dynflow" in enabled_features:
assert "dynflow" in features
else:
assert "dynflow" not in features

if 'bmc' in enabled_features:
assert "bmc" in features
else:
Expand Down
Empty file.
10 changes: 10 additions & 0 deletions tests/feature/foreman/api_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
def test_foreman_organization(organization):
assert organization


def test_foreman_initial_organization(foremanapi):
assert foremanapi.list('organizations', search='name="Foreman CI"')


def test_foreman_initial_location(foremanapi):
assert foremanapi.list('locations', search='name="Internet"')
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ def test_foreman_status_cache(foreman_status):
assert foreman_status['results']['foreman']['cache']['servers'][0]['status'] == 'ok'


@pytest.mark.feature('katello')
@pytest.mark.parametrize("katello_service", ['candlepin', 'candlepin_auth', 'foreman_tasks', 'katello_events', 'pulp3', 'pulp3_content'])
def test_katello_services_status(foreman_status, katello_service):
assert foreman_status['results']['katello']['services'][katello_service]['status'] == 'ok'
Expand Down
25 changes: 25 additions & 0 deletions tests/feature/foreman/compute_resources_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import pytest


# TODO: Foreman really should have a dedicated API endpoint to expose this info
@pytest.fixture
def provider_description(foremanapi):
create = foremanapi.resource('compute_resources').action('create')
compute_resource_param = [param for param in create.params if param.name == 'compute_resource'][0]
provider = [param for param in compute_resource_param.params if param.name == 'provider'][0]
return provider.description


@pytest.mark.parametrize("compute_resource", ['EC2', 'Libvirt', 'Openstack', 'Vmware'])
def test_foreman_compute_resources_built_in(provider_description, compute_resource):
assert compute_resource in provider_description


@pytest.mark.feature('azure-rm')
def test_foreman_compute_resources_azure_rm(provider_description):
assert 'AzureRm' in provider_description


@pytest.mark.feature('google')
def test_foreman_compute_resources_google(provider_description):
assert 'GCE' in provider_description
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
def test_foreman_organization(organization):
assert organization
import pytest

pytestmark = pytest.mark.feature('katello')


def test_foreman_product(product):
Expand Down Expand Up @@ -49,11 +50,3 @@ def test_foreman_manifest(organization, foremanapi, fixture_dir):
files = {'content': (str(manifest_path), manifest_file, 'application/zip')}
params = {'organization_id': organization['id']}
foremanapi.resource_action('subscriptions', 'upload', params, files=files)


def test_foreman_initial_organization(foremanapi):
assert foremanapi.list('organizations', search='name="Foreman CI"')


def test_foreman_initial_location(foremanapi):
assert foremanapi.list('locations', search='name="Internet"')
16 changes: 16 additions & 0 deletions tests/feature/foreman/plugins_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import pytest


@pytest.fixture
def foreman_plugins(foremanapi):
return [plugin['name'] for plugin in foremanapi.list('plugins')]


@pytest.mark.feature('azure-rm')
def test_foreman_compute_resources_azure_rm(foreman_plugins):
assert 'foreman_azure_rm' in foreman_plugins


@pytest.mark.feature('google')
def test_foreman_compute_resources_google(foreman_plugins):
assert 'foreman_google' in foreman_plugins
Empty file.
File renamed without changes.
Empty file added tests/feature/httpd/__init__.py
Empty file.
Loading
Loading