Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

time-to-pickup tests for pull rex #10591

Merged
merged 1 commit into from
Feb 8, 2023
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
7 changes: 5 additions & 2 deletions robottelo/api/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,9 @@ def create_role_permissions(role, permissions_types_names, search=None): # prag
entities.Filter(permission=permissions_entities, role=role, search=search).create()


def wait_for_tasks(search_query, search_rate=1, max_tries=10, poll_rate=None, poll_timeout=None):
def wait_for_tasks(
search_query, search_rate=1, max_tries=10, poll_rate=None, poll_timeout=None, must_succeed=True
):
"""Search for tasks by specified search query and poll them to ensure that
task has finished.
Expand All @@ -467,14 +469,15 @@ def wait_for_tasks(search_query, search_rate=1, max_tries=10, poll_rate=None, po
``nailgun.entities.ForemanTask.poll()`` method.
:param poll_timeout: Maximum number of seconds to wait until timing out.
Parameter for ``nailgun.entities.ForemanTask.poll()`` method.
:param must_succeed: Assert success result on finished task.
:return: List of ``nailgun.entities.ForemanTasks`` entities.
:raises: ``AssertionError``. If not tasks were found until timeout.
"""
for _ in range(max_tries):
tasks = entities.ForemanTask().search(query={'search': search_query})
if len(tasks) > 0:
for task in tasks:
task.poll(poll_rate=poll_rate, timeout=poll_timeout)
task.poll(poll_rate=poll_rate, timeout=poll_timeout, must_succeed=must_succeed)
break
else:
time.sleep(search_rate)
Expand Down
144 changes: 144 additions & 0 deletions tests/foreman/api/test_remoteexecution.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
import pytest

from robottelo.api.utils import wait_for_tasks
from robottelo.config import settings
from robottelo.hosts import get_sat_version
from robottelo.utils import ohsnap
from robottelo.utils.issue_handlers import is_open

CAPSULE_TARGET_VERSION = f'6.{get_sat_version().minor}.z'
Expand Down Expand Up @@ -72,3 +74,145 @@ def test_positive_run_capsule_upgrade_playbook(module_capsule_configured, target
).refresh()
feature_set = {feat['name'] for feat in result['features']}
assert {'Ansible', 'Dynflow', 'Script', 'Pulpcore', 'Logs'}.issubset(feature_set)


@pytest.mark.tier3
@pytest.mark.no_containers
@pytest.mark.rhel_ver_match('[^6].*')
def test_negative_time_to_pickup(
module_org,
module_target_sat,
smart_proxy_location,
module_ak_with_cv,
module_capsule_configured_mqtt,
rhel_contenthost,
):
"""Time to pickup setting is honored for host registered to mqtt

:id: a082f599-fbf7-4779-aa18-5139e2bce774

:expectedresults: Time to pickup aborts the job if mqtt client doesn't
respond in time

:CaseImportance: High

:bz: 2158738, 2118651

:parametrized: yes
"""
client_repo = ohsnap.dogfood_repository(
settings.repos.ohsnap_repo_host,
product='client',
repo='client',
release='Client',
os_release=rhel_contenthost.os_version.major,
)
# Update module_capsule_configured_mqtt to include module_org/smart_proxy_location
module_target_sat.cli.Capsule.update(
{
'name': module_capsule_configured_mqtt.hostname,
'organization-ids': module_org.id,
'location-ids': smart_proxy_location.id,
}
)
# register host with pull provider rex
result = rhel_contenthost.register(
module_org,
smart_proxy_location,
module_ak_with_cv.name,
target=module_capsule_configured_mqtt,
satellite=module_target_sat,
setup_remote_execution_pull=True,
repo=client_repo.baseurl,
)
template_id = (
module_target_sat.api.JobTemplate()
.search(query={'search': 'name="Run Command - Script Default"'})[0]
.id
)
assert result.status == 0, f'Failed to register host: {result.stderr}'
# check mqtt client is running
result = rhel_contenthost.execute('systemctl status yggdrasild')
assert result.status == 0, f'Failed to start yggdrasil on client: {result.stderr}'
# check that longrunning command is not affected by time_to_pickup BZ#2158738
job = module_target_sat.api.JobInvocation().run(
synchronous=False,
data={
'job_template_id': template_id,
'organization': module_org.name,
'location': smart_proxy_location.name,
'inputs': {
'command': 'echo start; sleep 10; echo done',
},
'targeting_type': 'static_query',
'search_query': f'name = {rhel_contenthost.hostname}',
'time_to_pickup': '5',
},
)
wait_for_tasks(f'resource_type = JobInvocation and resource_id = {job["id"]}')
result = module_target_sat.api.JobInvocation(id=job['id']).read()
assert result.succeeded == 1
shubhamsg199 marked this conversation as resolved.
Show resolved Hide resolved
# stop yggdrasil client on host
result = rhel_contenthost.execute('systemctl stop yggdrasild')
assert result.status == 0, f'Failed to stop yggdrasil on client: {result.stderr}'

# Make sure the job is executed by the registered-trough capsule
global_ttp = module_target_sat.api.Setting().search(
query={'search': 'name="remote_execution_global_proxy"'}
)[0]
global_ttp.value = False
global_ttp.update(['value'])

# run script provider rex command with time_to_pickup
job = module_target_sat.api.JobInvocation().run(
synchronous=False,
data={
'job_template_id': template_id,
'organization': module_org.name,
'location': smart_proxy_location.name,
'inputs': {
'command': 'ls -la',
},
'targeting_type': 'static_query',
'search_query': f'name = {rhel_contenthost.hostname}',
'time_to_pickup': '10',
},
)
wait_for_tasks(
f'resource_type = JobInvocation and resource_id = {job["id"]}', must_succeed=False
)
result = module_target_sat.api.JobInvocation(id=job['id']).read()
assert result.status_label == "failed"
shubhamsg199 marked this conversation as resolved.
Show resolved Hide resolved
result = module_target_sat.api.ForemanTask().search(
query={'search': f'resource_type = JobInvocation and resource_id = {job["id"]}'}
)
assert 'The job was not picked up in time' in result[0].humanized['output']

# Check that global setting is applied
global_ttp = module_target_sat.api.Setting().search(
query={'search': 'name="remote_execution_time_to_pickup"'}
)[0]
global_ttp.value = '10'
global_ttp.update(['value'])
job = module_target_sat.api.JobInvocation().run(
synchronous=False,
data={
'job_template_id': template_id,
'organization': module_org.name,
'location': smart_proxy_location.name,
'inputs': {
'command': 'ls -la',
},
'targeting_type': 'static_query',
'search_query': f'name = {rhel_contenthost.hostname}',
},
)
wait_for_tasks(
f'resource_type = JobInvocation and resource_id = {job["id"]}', must_succeed=False
)
result = module_target_sat.api.JobInvocation(id=job['id']).read()
assert result.status_label == "failed"
result = module_target_sat.api.ForemanTask().search(
query={'search': f'resource_type = JobInvocation and resource_id = {job["id"]}'}
)
assert 'The job was not picked up in time' in result[0].humanized['output']