Skip to content

Commit

Permalink
Merge branch '6.14.z' into cherry-pick-6.14.z-31b25db8dcbc76373f3829a…
Browse files Browse the repository at this point in the history
…0e653c3a896365cb5
  • Loading branch information
pnovotny authored May 23, 2024
2 parents 609963e + 1e08392 commit eccf501
Show file tree
Hide file tree
Showing 23 changed files with 213 additions and 85 deletions.
2 changes: 1 addition & 1 deletion conf/supportability.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
supportability:
content_hosts:
rhel:
versions: [6, 7,'7_fips', 8, '8_fips', 9, '9_fips']
versions: [7,'7_fips', 8, '8_fips', 9, '9_fips']
1 change: 1 addition & 0 deletions pytest_fixtures/component/http_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,4 @@ def setup_http_proxy(request, module_manifest_org, target_sat):
yield http_proxy, request.param
target_sat.update_setting('content_default_http_proxy', content_proxy_value)
target_sat.update_setting('http_proxy', general_proxy_value)
http_proxy.delete()
2 changes: 1 addition & 1 deletion pytest_fixtures/component/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ class constructor arguments. It can create multiple repos with distro.
]
Then the fixtures loop over it to create multiple repositories.
:returns: The tuple of distro of repositories(if given) and simplified repos
:return: The tuple of distro of repositories(if given) and simplified repos
"""
_repos = []
repo_distro = None
Expand Down
4 changes: 2 additions & 2 deletions requirements-optional.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ redis==5.0.4
pre-commit==3.7.1

# For generating documentation.
sphinx==7.3.6
sphinx-autoapi==3.0.0
sphinx==7.3.7
sphinx-autoapi==3.1.0

# For 'manage' interactive shell
manage==0.1.15
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ navmazing==1.2.2
productmd==1.38
pyotp==2.9.0
python-box==7.1.1
pytest==8.2.0
pytest==8.2.1
pytest-order==1.2.1
pytest-services==2.2.1
pytest-mock==3.14.0
Expand All @@ -21,7 +21,7 @@ pytest-xdist==3.5.0
pytest-fixturecollection==0.1.2
pytest-ibutsu==2.2.4
PyYAML==6.0.1
requests==2.31.0
requests==2.32.2
tenacity==8.3.0
testimony==2.4.0
wait-for==1.2.0
Expand Down
2 changes: 1 addition & 1 deletion robottelo/cli/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def _handle_response(cls, response, ignore_stderr=None):
:param response: a result object, returned by :mod:`robottelo.utils.ssh.command`.
:param ignore_stderr: indicates whether to throw a warning in logs if
``stderr`` is not empty.
:returns: contents of ``stdout``.
:return: contents of ``stdout``.
:raises robottelo.exceptions.CLIReturnCodeError: If return code is
different from zero.
"""
Expand Down
2 changes: 1 addition & 1 deletion robottelo/constants/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@
'Norway East',
]
AZURERM_RHEL7_FT_IMG_URN = 'marketplace://RedHat:RHEL:7-RAW:latest'
AZURERM_RHEL7_UD_IMG_URN = 'marketplace://RedHat:RHEL:7-RAW-CI:7.6.2019072418'
AZURERM_RHEL7_UD_IMG_URN = 'marketplace://RedHat:rhel-byos:rhel-raw-ci76:7.6.20190814'
AZURERM_RHEL7_FT_BYOS_IMG_URN = 'marketplace://RedHat:rhel-byos:rhel-lvm78:7.8.20200410'
AZURERM_RHEL7_FT_CUSTOM_IMG_URN = 'custom://imageVM1-RHEL7-image-20220617150105'
AZURERM_RHEL7_FT_GALLERY_IMG_URN = 'gallery://RHEL77img'
Expand Down
2 changes: 1 addition & 1 deletion robottelo/host_helpers/api_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ def one_to_one_names(self, name):
True
:param name: A field name.
:returns: A set including both ``name`` and variations on ``name``.
:return: A set including both ``name`` and variations on ``name``.
"""
return {f'{name}_name', f'{name}_id'}
Expand Down
4 changes: 2 additions & 2 deletions robottelo/host_helpers/repository_mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -588,7 +588,7 @@ def add_item(self, item) -> None:
Add repository to collection
:param BaseRepository item: Item to add
:returns: None
:return: None
"""
if self._repos_info:
raise RepositoryAlreadyCreated('Repositories already created can not add more')
Expand All @@ -605,7 +605,7 @@ def add_items(self, items):
Add multiple repositories to collection
:param List[BaseRepository] items: Items to add
:returns: None
:return: None
"""
for item in items:
self.add_item(item)
Expand Down
6 changes: 3 additions & 3 deletions robottelo/host_helpers/satellite_mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ def upload_manifest(self, org_id, manifest=None, interface='API', timeout=None):
:type interface: str
:type timeout: int
:returns: the manifest upload result
:return: the manifest upload result
"""
if not isinstance(manifest, bytes | io.BytesIO) and (
Expand Down Expand Up @@ -176,7 +176,7 @@ def is_sca_mode_enabled(self, org_id):
given organization.
:param str org_id: The unique identifier of the organization to check for SCA mode.
:returns: A boolean value indicating whether SCA mode is enabled or not.
:return: A boolean value indicating whether SCA mode is enabled or not.
:rtype: bool
"""
return self.api.Organization(id=org_id).read().simple_content_access
Expand All @@ -187,7 +187,7 @@ def publish_content_view(self, org, repo_list):
:param str org: The name of the organization to which the content view belongs
:param list or str repo_list: A list of repositories or a single repository
:returns: A dictionary containing the details of the published content view.
:return: A dictionary containing the details of the published content view.
"""
repo = repo_list if isinstance(repo_list, list) else [repo_list]
content_view = self.api.ContentView(organization=org, repository=repo).create()
Expand Down
6 changes: 3 additions & 3 deletions robottelo/hosts.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ def os_distro(self):
def os_version(self):
"""Get host's OS version information
:returns: A ``packaging.version.Version`` instance
:return: A ``packaging.version.Version`` instance
"""
return Version(self._os_release['VERSION_ID'])

Expand Down Expand Up @@ -472,7 +472,7 @@ def download_file(self, file_url, local_path=None, file_name=None):
provided file will be saved in /tmp/ directory.
:param str file_name: New name of the Downloaded file else its given from file_url
:returns: Returns list containing complete file path and name of downloaded file.
:return: Returns list containing complete file path and name of downloaded file.
"""
file_name = PurePath(file_name or file_url).name
local_path = PurePath(local_path or '/tmp') / file_name
Expand Down Expand Up @@ -1497,7 +1497,7 @@ def ping_host(self, host):
"""Check the provisioned host status by pinging the ip of host
:param host: IP address or hostname of the provisioned host
:returns: None
:return: None
:raises: : `HostPingFailed` if the host is not pingable
"""
result = self.execute(
Expand Down
2 changes: 1 addition & 1 deletion robottelo/utils/datafactory.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def generate_strings_list(length=None, exclude_types=None, min_length=3, max_len
generated list. example: exclude_types=['html', 'cjk']
:param int min_length: Minimum length to be used in integer generator
:param int max_length: Maximum length to be used in integer generator
:returns: A list of various string types.
:return: A list of various string types.
"""
if length is None:
Expand Down
8 changes: 2 additions & 6 deletions robottelo/utils/report_portal/portal.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,12 @@ def __init__(self, rp_url=None, rp_api_key=None, rp_project=None):

@property
def api_url(self):
"""Super url of report portal
:returns: Base url for API request
"""
"""Super url of report portal API."""
return f'{self.rp_url}/api/v1/{self.rp_project}'

@property
def headers(self):
"""The headers for Report Portal Requests.
:returns: header for API request
"""
"""The headers for Report Portal Requests."""
return {'Authorization': f'Bearer {self.rp_api_key}'}

def get_launches(
Expand Down
131 changes: 131 additions & 0 deletions tests/foreman/api/test_ansible.py
Original file line number Diff line number Diff line change
Expand Up @@ -470,3 +470,134 @@ def test_positive_ansible_job_on_multiple_host(
assert result.succeeded == 2 # SELECTED_ROLE working on rhel8/rhel9 clients
assert result.failed == 1 # SELECTED_ROLE failing on rhel7 client
assert result.status_label == 'failed'

@pytest.mark.no_containers
@pytest.mark.rhel_ver_match('[^6]')
def test_positive_ansible_localhost_job_on_host(
self, target_sat, module_org, module_location, module_ak_with_synced_repo, rhel_contenthost
):
"""Test successful execution of Ansible Job with "hosts: localhost" on host.
:id: c8dcdc54-cb98-4b24-bff9-049a6cc36acd
:steps:
1. Register a content host with satellite
2. Run the Ansible playbook with "hosts: localhost" on registered host
3. Check if the job is executed and verify job output
:expectedresults:
1. Ansible playbook with "hosts: localhost" job execution must be successful.
:BZ: 1982698
:customerscenario: true
"""
playbook = '''
---
- name: Simple Ansible Playbook for Localhost
hosts: localhost
gather_facts: no
tasks:
- name: Print a message
debug:
msg: "Hello, localhost!"
'''
result = rhel_contenthost.register(
module_org, module_location, module_ak_with_synced_repo.name, target_sat
)
assert result.status == 0, f'Failed to register host: {result.stderr}'

template_id = (
target_sat.api.JobTemplate()
.search(query={'search': 'name="Ansible - Run playbook"'})[0]
.id
)
job = target_sat.api.JobInvocation().run(
synchronous=False,
data={
'job_template_id': template_id,
'targeting_type': 'static_query',
'search_query': f'name = {rhel_contenthost.hostname}',
'inputs': {'playbook': playbook},
},
)
target_sat.wait_for_tasks(
f'resource_type = JobInvocation and resource_id = {job["id"]}', poll_timeout=1000
)
result = target_sat.api.JobInvocation(id=job['id']).read()
assert result.pending == 0
assert result.succeeded == 1
assert result.status_label == 'succeeded'

result = target_sat.api.JobInvocation(id=job['id']).outputs()['outputs'][0]['output']
assert [i['output'] for i in result if '"msg": "Hello, localhost!"' in i['output']]
assert [i['output'] for i in result if i['output'] == 'Exit status: 0']

@pytest.mark.no_containers
@pytest.mark.rhel_ver_list('8')
def test_negative_ansible_job_timeout_to_kill(
self, target_sat, module_org, module_location, module_ak_with_synced_repo, rhel_contenthost
):
"""when running ansible-playbook, timeout to kill/execution_timeout_interval setting
is honored for registered host
:id: a082f599-fbf7-4779-aa18-5139e2bce777
:steps:
1. Register a content host with satellite
2. Run Ansible playbook to pause execution for a while, along with
timeout to kill/execution_timeout_interval setting on the registered host
3. Verify job is terminated honoring timeout to kill setting and verify job output.
:expectedresults: Timeout to kill terminates the job if playbook doesn't finish in time
:BZ: 1931489
:customerscenario: true
"""
playbook = '''
---
- name: Sample Ansible Playbook to pause
hosts: all
gather_facts: no
tasks:
- name: Pause for 5 minutes
pause:
minutes: 5
'''
result = rhel_contenthost.register(
module_org, module_location, module_ak_with_synced_repo.name, target_sat
)
assert result.status == 0, f'Failed to register host: {result.stderr}'

template_id = (
target_sat.api.JobTemplate()
.search(query={'search': 'name="Ansible - Run playbook"'})[0]
.id
)
# run ansible-playbook with execution_timeout_interval/timeout_to_kill
job = target_sat.api.JobInvocation().run(
synchronous=False,
data={
'job_template_id': template_id,
'targeting_type': 'static_query',
'search_query': f'name = {rhel_contenthost.hostname}',
'inputs': {'playbook': playbook},
'execution_timeout_interval': '30',
},
)
target_sat.wait_for_tasks(
f'resource_type = JobInvocation and resource_id = {job["id"]}',
poll_timeout=1000,
must_succeed=False,
)
result = target_sat.api.JobInvocation(id=job['id']).read()
assert result.pending == 0
assert result.failed == 1
assert result.status_label == 'failed'

result = target_sat.api.JobInvocation(id=job['id']).outputs()['outputs'][0]['output']
termination_msg = 'Timeout for execution passed, stopping the job'
assert [i['output'] for i in result if i['output'] == termination_msg]
assert [i['output'] for i in result if i['output'] == 'StandardError: Job execution failed']
assert [i['output'] for i in result if i['output'] == 'Exit status: 120']
2 changes: 1 addition & 1 deletion tests/foreman/api/test_notifications.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ def wait_for_no_long_running_task_mail(target_sat, clean_root_mailbox, long_runn
def root_mailbox_copy(target_sat, clean_root_mailbox):
"""Parsed local system copy of the Satellite's root user mailbox.
:returns: :class:`mailbox.mbox` instance
:return: :class:`mailbox.mbox` instance
"""
result = target_sat.execute(f'cat {clean_root_mailbox}')
assert result.status == 0, f'Could not read mailbox {clean_root_mailbox} on Satellite host.'
Expand Down
2 changes: 1 addition & 1 deletion tests/foreman/api/test_permission.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ def give_user_permission(self, perm_name, target_sat):
searching for the permission with name ``perm_name``.
:raises: ``requests.exceptions.HTTPError`` if an error occurs when
updating ``self.user``'s roles.
:returns: Nothing.
:return: Nothing.
"""
role = target_sat.api.Role().create()
permissions = target_sat.api.Permission().search(query={'search': f'name="{perm_name}"'})
Expand Down
Loading

0 comments on commit eccf501

Please sign in to comment.