diff --git a/robottelo/cli/factory.py b/robottelo/cli/factory.py index c1ac9cb4268..007fa7dadfd 100644 --- a/robottelo/cli/factory.py +++ b/robottelo/cli/factory.py @@ -942,6 +942,7 @@ def make_job_invocation_with_credentials(options=None, credentials=None): 'dynamic': None, 'effective-user': None, 'end-time': None, + 'feature': None, 'input-files': None, 'inputs': None, 'job-template': None, diff --git a/robottelo/cli/rex_feature.py b/robottelo/cli/rex_feature.py new file mode 100644 index 00000000000..e4981f91d2d --- /dev/null +++ b/robottelo/cli/rex_feature.py @@ -0,0 +1,26 @@ +""" +Usage:: + + hammer remote-execution-feature [OPTIONS] SUBCOMMAND [ARG] ... + +Parameters:: + + SUBCOMMAND Subcommand + [ARG] ... Subcommand arguments + +Subcommands:: + + info Show remote execution feature + list List remote execution features + update Update a job template + +""" +from robottelo.cli.base import Base + + +class RemoteExecutionFeature(Base): + """ + Handles Remote Execution Feature commands + """ + + command_base = 'remote-execution-feature' diff --git a/tests/foreman/api/test_repositories.py b/tests/foreman/api/test_repositories.py index a7c4b1a5340..58cbd9792b2 100644 --- a/tests/foreman/api/test_repositories.py +++ b/tests/foreman/api/test_repositories.py @@ -25,9 +25,7 @@ from robottelo import constants from robottelo.cli.base import CLIReturnCodeError from robottelo.config import settings -from robottelo.constants import DEFAULT_ARCHITECTURE -from robottelo.constants import MIRRORING_POLICIES -from robottelo.constants import REPOS +from robottelo.constants import DEFAULT_ARCHITECTURE, MIRRORING_POLICIES, REPOS from robottelo.utils.datafactory import parametrized diff --git a/tests/foreman/cli/test_remoteexecution.py b/tests/foreman/cli/test_remoteexecution.py index 09e1eda28af..aac15191dcc 100644 --- a/tests/foreman/cli/test_remoteexecution.py +++ b/tests/foreman/cli/test_remoteexecution.py @@ -18,6 +18,7 @@ """ from calendar import monthrange from datetime import datetime, timedelta +import random from time import sleep from broker import Broker @@ -25,6 +26,7 @@ from fauxfactory import gen_string import pytest +from robottelo import constants from robottelo.cli.factory import ( make_filter, make_job_invocation, @@ -46,6 +48,21 @@ from robottelo.constants import PRDS, REPOS, REPOSET from robottelo.hosts import ContentHost from robottelo.utils import ohsnap +from robottelo.utils.datafactory import filtered_datapoint, parametrized + + +@filtered_datapoint +def valid_feature_names(): + """Returns a list of valid features and their descriptions""" + return [ + {'label': 'katello_package_install', 'jt_name': 'Install Package - Katello Script Default'}, + {'label': 'katello_package_update', 'jt_name': 'Update Package - Katello Script Default'}, + {'label': 'katello_package_remove', 'jt_name': 'Remove Package - Katello Script Default'}, + {'label': 'katello_group_install', 'jt_name': 'Install Group - Katello Script Default'}, + {'label': 'katello_group_update', 'jt_name': 'Update Group - Katello Script Default'}, + {'label': 'katello_group_remove', 'jt_name': 'Remove Group - Katello Script Default'}, + {'label': 'katello_errata_install', 'jt_name': 'Install Errata - Katello Script Default'}, + ] @pytest.fixture() @@ -269,15 +286,15 @@ def test_positive_run_default_job_template_multiple_hosts_by_ip( @pytest.mark.skipif( (not settings.robottelo.repos_hosting_url), reason='Missing repos_hosting_url' ) - def test_positive_install_multiple_packages_with_a_job_by_ip( + def test_positive_install_remove_multiple_packages_with_a_job( self, rhel_contenthost, module_org, module_ak_with_cv, target_sat ): - """Run job to install several packages on host by ip + """Run job to install and remove several packages on host by ip :id: 8b73033f-83c9-4024-83c3-5e442a79d320 :expectedresults: Verify the packages were successfully installed - on host + and removed on a host :parametrized: yes """ @@ -290,16 +307,145 @@ def test_positive_install_multiple_packages_with_a_job_by_ip( target_sat, repo=settings.repos.yum_3.url, ) + # Install packages invocation_command = make_job_invocation( { 'job-template': 'Install Package - Katello Script Default', - 'inputs': 'package={} {} {}'.format(*packages), + 'inputs': f'package={" ".join(packages)}', 'search-query': f'name ~ {client.hostname}', } ) assert_job_invocation_result(invocation_command['id'], client.hostname) result = client.run(f'rpm -q {" ".join(packages)}') assert result.status == 0 + # Update packages + pre_versions = result.stdout.splitlines() + result = client.run(f'dnf -y downgrade {" ".join(packages)}') + assert result.status == 0 + invocation_command = make_job_invocation( + { + 'job-template': 'Update Package - Katello Script Default', + 'inputs': f'package={" ".join(packages)}', + 'search-query': f'name ~ {client.hostname}', + } + ) + assert_job_invocation_result(invocation_command['id'], client.hostname) + post_versions = client.run(f'rpm -q {" ".join(packages)}').stdout.splitlines() + assert set(pre_versions) == set(post_versions) + # Remove packages + invocation_command = make_job_invocation( + { + 'job-template': 'Remove Package - Katello Script Default', + 'inputs': f'package={" ".join(packages)}', + 'search-query': f'name ~ {client.hostname}', + } + ) + assert_job_invocation_result(invocation_command['id'], client.hostname) + result = client.run(f'rpm -q {" ".join(packages)}') + assert result.status == len(packages) + + @pytest.mark.tier3 + @pytest.mark.no_containers + @pytest.mark.rhel_ver_list([8]) + @pytest.mark.skipif( + (not settings.robottelo.repos_hosting_url), reason='Missing repos_hosting_url' + ) + def test_positive_install_remove_packagegroup_with_a_job( + self, rhel_contenthost, module_org, module_ak_with_cv, target_sat + ): + """Run job to install and remove several package groups on host by ip + + :id: 5be2a5c0-199a-4655-9784-e95c7ef151f5 + + :expectedresults: Verify the package groups were successfully installed + and removed on a host + + :parametrized: yes + """ + client = rhel_contenthost + groups = ['birds', 'mammals'] + client.register( + module_org, + None, + module_ak_with_cv.name, + target_sat, + repo=settings.repos.yum_1.url, + ) + # Install the package groups + invocation_command = make_job_invocation( + { + 'job-template': 'Install Group - Katello Script Default', + 'inputs': f'package={" ".join(groups)}', + 'search-query': f'name ~ {client.hostname}', + } + ) + assert_job_invocation_result(invocation_command['id'], client.hostname) + result = client.run('dnf grouplist --installed') + assert all(item in result.stdout for item in groups) + # Remove one of the installed package groups + remove = random.choice(groups) + invocation_command = make_job_invocation( + { + 'job-template': 'Remove Group - Katello Script Default', + 'inputs': f'package={remove}', + 'search-query': f'name ~ {client.hostname}', + } + ) + assert_job_invocation_result(invocation_command['id'], client.hostname) + result = client.run('dnf grouplist --installed') + assert remove not in result.stdout + + @pytest.mark.tier3 + @pytest.mark.no_containers + @pytest.mark.rhel_ver_list([8]) + @pytest.mark.skipif( + (not settings.robottelo.repos_hosting_url), reason='Missing repos_hosting_url' + ) + def test_positive_install_errata_with_a_job( + self, rhel_contenthost, module_org, module_ak_with_cv, target_sat + ): + """Run job to install errata on host by ip + + :id: d906a884-9fd7-48dc-a91b-fa6e8c3311c1 + + :expectedresults: Verify the errata was successfully installed on a host + + :parametrized: yes + """ + client = rhel_contenthost + client.register( + module_org, + None, + module_ak_with_cv.name, + target_sat, + repo=settings.repos.yum_1.url, + ) + client.run(f'dnf install -y {constants.FAKE_1_CUSTOM_PACKAGE}') + # Install errata + invocation_command = make_job_invocation( + { + 'job-template': 'Install Errata - Katello Script Default', + 'inputs': f'errata={settings.repos.yum_0.errata[1]}', + 'search-query': f'name ~ {client.hostname}', + } + ) + assert_job_invocation_result(invocation_command['id'], client.hostname) + result = client.run(f'rpm -q {constants.FAKE_2_CUSTOM_PACKAGE}') + assert result.status == 0 + + @pytest.mark.tier3 + @pytest.mark.parametrize('feature', **parametrized(valid_feature_names())) + def test_positive_match_feature_templates(self, target_sat, feature): + """Verify the `feature` names match the correct templates + + :id: a7cf23fe-4d3b-4bd2-b921-d31ad3e4d7e9 + + :expectedresults: All features exist and match the expected templates + + :parametrized: yes + """ + result = target_sat.cli.RemoteExecutionFeature.info({'id': feature['label']}) + assert result['job-template-name'] == feature['jt_name'] @pytest.mark.tier3 @pytest.mark.rhel_ver_list([8]) diff --git a/tests/foreman/destructive/test_katello_agent.py b/tests/foreman/destructive/test_katello_agent.py deleted file mode 100644 index 97b92c495c8..00000000000 --- a/tests/foreman/destructive/test_katello_agent.py +++ /dev/null @@ -1,149 +0,0 @@ -"""CLI tests for ``katello-agent``. - -:Requirement: Host - -:CaseAutomation: Automated - -:CaseLevel: Component - -:CaseComponent: katello-agent - -:team: Phoenix-subscriptions - -:TestType: Functional - -:CaseImportance: High - -:Upstream: No -""" -import pytest - -from robottelo import constants -from robottelo.config import settings - -pytestmark = [ - pytest.mark.run_in_one_thread, - pytest.mark.destructive, - pytest.mark.no_containers, - pytest.mark.tier5, - pytest.mark.upgrade, -] - - -@pytest.mark.rhel_ver_match(r'[\d]+') -def test_positive_apply_errata(katello_agent_client): - """Apply errata on a host - - :id: 8d0e5c93-f9fd-4ec0-9a61-aa93082a30c5 - - :expectedresults: Errata is scheduled for installation - - :parametrized: yes - - :CaseLevel: System - """ - sat = katello_agent_client['sat'] - client = katello_agent_client['client'] - host_info = katello_agent_client['host_info'] - client.run(f'yum install -y {constants.FAKE_1_CUSTOM_PACKAGE}') - result = sat.cli.Host.errata_info( - {'host-id': host_info['id'], 'id': settings.repos.yum_0.errata[1]} - ) - assert result[0]['errata-id'] == settings.repos.yum_0.errata[1] - assert constants.FAKE_2_CUSTOM_PACKAGE in result[0]['packages'] - - sat.cli.Host.errata_apply( - {'errata-ids': settings.repos.yum_0.errata[1], 'host-id': host_info['id']} - ) - assert client.run(f'rpm -q {constants.FAKE_2_CUSTOM_PACKAGE}').status == 0 - - -@pytest.mark.rhel_ver_match(r'[\d]+') -def test_positive_install_and_remove_package(katello_agent_client): - """Install and remove a package on a host remotely - - :id: b1009bba-0c7e-4b00-8ac4-256e5cfe4a78 - - :expectedresults: Package successfully installed and removed - - :parametrized: yes - - :CaseLevel: System - """ - sat = katello_agent_client['sat'] - client = katello_agent_client['client'] - host_info = katello_agent_client['host_info'] - sat.cli.Host.package_install( - {'host-id': host_info['id'], 'packages': constants.FAKE_0_CUSTOM_PACKAGE_NAME} - ) - assert client.run(f'rpm -q {constants.FAKE_0_CUSTOM_PACKAGE_NAME}').status == 0 - sat.cli.Host.package_remove( - {'host-id': host_info['id'], 'packages': constants.FAKE_0_CUSTOM_PACKAGE_NAME} - ) - assert client.run(f'rpm -q {constants.FAKE_0_CUSTOM_PACKAGE_NAME}').status != 0 - - -@pytest.mark.rhel_ver_match(r'[\d]+') -def test_positive_upgrade_package(katello_agent_client): - """Upgrade a package on a host remotely - - :id: ad751c63-7175-40ae-8bc4-800462cd9c29 - - :expectedresults: Package successfully upgraded - - :parametrized: yes - - :CaseLevel: System - """ - sat = katello_agent_client['sat'] - client = katello_agent_client['client'] - host_info = katello_agent_client['host_info'] - client.run(f'yum install -y {constants.FAKE_1_CUSTOM_PACKAGE}') - sat.cli.Host.package_upgrade( - {'host-id': host_info['id'], 'packages': constants.FAKE_1_CUSTOM_PACKAGE_NAME} - ) - assert client.run(f'rpm -q {constants.FAKE_2_CUSTOM_PACKAGE}').status == 0 - - -@pytest.mark.rhel_ver_match(r'[\d]+') -def test_positive_upgrade_packages_all(katello_agent_client): - """Upgrade all packages on a host remotely - - :id: 003101c7-bb95-4e51-a598-57977b2858a9 - - :expectedresults: Packages successfully upgraded (at least 1 with newer version available) - - :parametrized: yes - - :CaseLevel: System - """ - sat = katello_agent_client['sat'] - client = katello_agent_client['client'] - host_info = katello_agent_client['host_info'] - client.run(f'yum install -y {constants.FAKE_1_CUSTOM_PACKAGE}') - sat.cli.Host.package_upgrade_all({'host-id': host_info['id']}) - assert client.run(f'rpm -q {constants.FAKE_2_CUSTOM_PACKAGE}').status == 0 - - -@pytest.mark.rhel_ver_match(r'[\d]+') -def test_positive_install_and_remove_package_group(katello_agent_client): - """Install and remove a package group on a host remotely - - :id: ded20a89-cfd9-48d5-8829-739b1a4d4042 - - :expectedresults: Package group successfully installed and removed - - :parametrized: yes - - :CaseLevel: System - """ - sat = katello_agent_client['sat'] - client = katello_agent_client['client'] - host_info = katello_agent_client['host_info'] - hammer_args = {'groups': constants.FAKE_0_CUSTOM_PACKAGE_GROUP_NAME, 'host-id': host_info['id']} - sat.cli.Host.package_group_install(hammer_args) - for package in constants.FAKE_0_CUSTOM_PACKAGE_GROUP: - assert client.run(f'rpm -q {package}').status == 0 - sat.cli.Host.package_group_remove(hammer_args) - for package in constants.FAKE_0_CUSTOM_PACKAGE_GROUP: - assert client.run(f'rpm -q {package}').status != 0