community.general/tests/unit/plugins/modules/test_redhat_subscription.py
Pino Toscano bcc92e8aac
redhat_subscription: stop manual unsubscribing on unregistration (#9578)
Unregistering a system also drops all the resources for it
automatically, so there is no need to manually unsubscribing (which
actually means removing all the subscriptions).

In addition to that, newer versions of subscription-manager drop all the
support for entitlements, so the "remove" subcommand (used by
unsubscribe()) does not exist anymore, and thus the unregistration fails
with those versions.

This fixes the registration on EL 10 systems, and Fedora 41 and greater.
2025-01-20 19:37:51 +01:00

1267 lines
43 KiB
Python

# -*- coding: utf-8 -*-
# Copyright (c) Jiri Hnidek (jhnidek@redhat.com)
#
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import json
from ansible.module_utils import basic
from ansible_collections.community.general.plugins.modules import redhat_subscription
import pytest
TESTED_MODULE = redhat_subscription.__name__
@pytest.fixture
def patch_redhat_subscription(mocker):
"""
Function used for mocking some parts of redhat_subscription module
"""
mocker.patch('ansible_collections.community.general.plugins.modules.redhat_subscription.Rhsm.REDHAT_REPO')
mocker.patch('ansible_collections.community.general.plugins.modules.redhat_subscription.isfile', return_value=False)
mocker.patch('ansible_collections.community.general.plugins.modules.redhat_subscription.unlink', return_value=True)
mocker.patch('ansible_collections.community.general.plugins.modules.redhat_subscription.AnsibleModule.get_bin_path',
return_value='/testbin/subscription-manager')
mocker.patch('ansible_collections.community.general.plugins.modules.redhat_subscription.Rhsm._can_connect_to_dbus',
return_value=False)
mocker.patch('ansible_collections.community.general.plugins.modules.redhat_subscription.Rhsm._has_dbus_interface',
return_value=False)
mocker.patch('ansible_collections.community.general.plugins.modules.redhat_subscription.getuid',
return_value=0)
@pytest.mark.parametrize('patch_ansible_module', [{}], indirect=['patch_ansible_module'])
@pytest.mark.usefixtures('patch_ansible_module')
def test_without_required_parameters_unregistered(mocker, capfd, patch_redhat_subscription):
"""
Failure must occurs when all parameters are missing
"""
mock_run_command = mocker.patch.object(
basic.AnsibleModule,
'run_command',
return_value=(1, 'This system is not yet registered.', ''))
with pytest.raises(SystemExit):
redhat_subscription.main()
out, err = capfd.readouterr()
results = json.loads(out)
assert results['failed']
assert 'state is present but any of the following are missing' in results['msg']
@pytest.mark.parametrize('patch_ansible_module', [{}], indirect=['patch_ansible_module'])
@pytest.mark.usefixtures('patch_ansible_module')
def test_without_required_parameters_registered(mocker, capfd, patch_redhat_subscription):
"""
System already registered, no parameters required (state=present is the
default)
"""
mock_run_command = mocker.patch.object(
basic.AnsibleModule,
'run_command',
return_value=(0, 'system identity: b26df632-25ed-4452-8f89-0308bfd167cb', ''))
with pytest.raises(SystemExit):
redhat_subscription.main()
out, err = capfd.readouterr()
results = json.loads(out)
assert 'changed' in results
if 'msg' in results:
assert results['msg'] == 'System already registered.'
TEST_CASES = [
# Test the case, when the system is already registered
[
{
'state': 'present',
'server_hostname': 'subscription.rhsm.redhat.com',
'username': 'admin',
'password': 'admin',
'org_id': 'admin'
},
{
'id': 'test_already_registered_system',
'run_command.calls': [
(
# Calling of following command will be asserted
['/testbin/subscription-manager', 'identity'],
# Was return code checked?
{'check_rc': False},
# Mock of returned code, stdout and stderr
(0, 'system identity: b26df632-25ed-4452-8f89-0308bfd167cb', '')
)
],
'changed': False,
'msg': 'System already registered.'
}
],
# Already registered system without credentials specified
[
{
'state': 'present',
},
{
'id': 'test_already_registered_system',
'run_command.calls': [
(
['/testbin/subscription-manager', 'identity'],
{'check_rc': False},
(0, 'system identity: b26df632-25ed-4452-8f89-0308bfd167cb', '')
)
],
'changed': False,
'msg': 'System already registered.'
}
],
# Test simple registration using username and password
[
{
'state': 'present',
'server_hostname': 'satellite.company.com',
'username': 'admin',
'password': 'admin',
},
{
'id': 'test_registeration_username_password',
'run_command.calls': [
(
['/testbin/subscription-manager', 'identity'],
{'check_rc': False},
(1, '', '')
),
(
['/testbin/subscription-manager', 'config', '--server.hostname=satellite.company.com'],
{'check_rc': True},
(0, '', '')
),
(
['/testbin/subscription-manager', 'register',
'--username', 'admin',
'--password', 'admin'],
{'check_rc': True, 'expand_user_and_vars': False},
(0, '', '')
)
],
'changed': True,
'msg': "System successfully registered to 'satellite.company.com'."
}
],
# Test simple registration using token
[
{
'state': 'present',
'server_hostname': 'satellite.company.com',
'token': 'fake_token',
},
{
'id': 'test_registeration_token',
'run_command.calls': [
(
['/testbin/subscription-manager', 'identity'],
{'check_rc': False},
(1, '', '')
),
(
['/testbin/subscription-manager', 'config', '--server.hostname=satellite.company.com'],
{'check_rc': True},
(0, '', '')
),
(
['/testbin/subscription-manager', 'register',
'--token', 'fake_token'],
{'check_rc': True, 'expand_user_and_vars': False},
(0, '', '')
)
],
'changed': True,
'msg': "System successfully registered to 'satellite.company.com'."
}
],
# Test unregistration, when system is unregistered
[
{
'state': 'absent',
'server_hostname': 'subscription.rhsm.redhat.com',
'username': 'admin',
'password': 'admin',
},
{
'id': 'test_unregisteration',
'run_command.calls': [
(
['/testbin/subscription-manager', 'identity'],
{'check_rc': False},
(0, 'system identity: b26df632-25ed-4452-8f89-0308bfd167cb', '')
),
(
['/testbin/subscription-manager', 'unregister'],
{'check_rc': True},
(0, '', '')
)
],
'changed': True,
'msg': "System successfully unregistered from subscription.rhsm.redhat.com."
}
],
# Test unregistration of already unregistered system
[
{
'state': 'absent',
'server_hostname': 'subscription.rhsm.redhat.com',
'username': 'admin',
'password': 'admin',
},
{
'id': 'test_unregisteration_of_unregistered_system',
'run_command.calls': [
(
['/testbin/subscription-manager', 'identity'],
{'check_rc': False},
(1, 'This system is not yet registered.', '')
)
],
'changed': False,
'msg': "System already unregistered."
}
],
# Test registration using activation key
[
{
'state': 'present',
'server_hostname': 'satellite.company.com',
'activationkey': 'some-activation-key',
'org_id': 'admin'
},
{
'id': 'test_registeration_activation_key',
'run_command.calls': [
(
['/testbin/subscription-manager', 'identity'],
{'check_rc': False},
(1, 'This system is not yet registered.', '')
),
(
['/testbin/subscription-manager', 'config', '--server.hostname=satellite.company.com'],
{'check_rc': True},
(0, '', '')
),
(
[
'/testbin/subscription-manager',
'register',
'--org', 'admin',
'--activationkey', 'some-activation-key'
],
{'check_rc': True, 'expand_user_and_vars': False},
(0, '', '')
)
],
'changed': True,
'msg': "System successfully registered to 'satellite.company.com'."
}
],
# Test of registration using username and password with auto-attach option
[
{
'state': 'present',
'username': 'admin',
'password': 'admin',
'org_id': 'admin',
'auto_attach': 'true'
},
{
'id': 'test_registeration_username_password_auto_attach',
'run_command.calls': [
(
['/testbin/subscription-manager', 'identity'],
{'check_rc': False},
(1, 'This system is not yet registered.', '')
),
(
[
'/testbin/subscription-manager',
'register',
'--org', 'admin',
'--auto-attach',
'--username', 'admin',
'--password', 'admin'
],
{'check_rc': True, 'expand_user_and_vars': False},
(0, '', '')
)
],
'changed': True,
'msg': "System successfully registered to 'None'."
}
],
# Test of force registration despite the system is already registered
[
{
'state': 'present',
'username': 'admin',
'password': 'admin',
'org_id': 'admin',
'force_register': 'true'
},
{
'id': 'test_force_registeration_username_password',
'run_command.calls': [
(
['/testbin/subscription-manager', 'identity'],
{'check_rc': False},
(0, 'This system already registered.', '')
),
(
[
'/testbin/subscription-manager',
'register',
'--force',
'--org', 'admin',
'--username', 'admin',
'--password', 'admin'
],
{'check_rc': True, 'expand_user_and_vars': False},
(0, '', '')
)
],
'changed': True,
'msg': "System successfully registered to 'None'."
}
],
# Test of registration with arguments that are not part of register options but needs to be configured
[
{
'state': 'present',
'username': 'admin',
'password': 'admin',
'org_id': 'admin',
'force_register': 'true',
'server_prefix': '/rhsm',
'server_port': '443'
},
{
'id': 'test_arguments_not_in_register_options',
'run_command.calls': [
(
['/testbin/subscription-manager', 'identity'],
{'check_rc': False},
(0, 'This system already registered.', '')
),
(
['/testbin/subscription-manager', 'config',
'--server.port=443',
'--server.prefix=/rhsm'
],
{'check_rc': True},
(0, '', '')
),
(
['/testbin/subscription-manager', 'register',
'--force',
'--org', 'admin',
'--username', 'admin',
'--password', 'admin'],
{'check_rc': True, 'expand_user_and_vars': False},
(0, '', '')
)
],
'changed': True,
'msg': "System successfully registered to 'None'."
}
],
# Test of registration using username, password and proxy options
[
{
'state': 'present',
'username': 'admin',
'password': 'admin',
'org_id': 'admin',
'force_register': 'true',
'server_proxy_hostname': 'proxy.company.com',
'server_proxy_scheme': 'https',
'server_proxy_port': '12345',
'server_proxy_user': 'proxy_user',
'server_proxy_password': 'secret_proxy_password'
},
{
'id': 'test_registeration_username_password_proxy_options',
'run_command.calls': [
(
['/testbin/subscription-manager', 'identity'],
{'check_rc': False},
(0, 'This system already registered.', '')
),
(
[
'/testbin/subscription-manager',
'config',
'--server.proxy_hostname=proxy.company.com',
'--server.proxy_password=secret_proxy_password',
'--server.proxy_port=12345',
'--server.proxy_scheme=https',
'--server.proxy_user=proxy_user'
],
{'check_rc': True},
(0, '', '')
),
(
[
'/testbin/subscription-manager',
'register',
'--force',
'--org', 'admin',
'--username', 'admin',
'--password', 'admin'
],
{'check_rc': True, 'expand_user_and_vars': False},
(0, '', '')
)
],
'changed': True,
'msg': "System successfully registered to 'None'."
}
],
# Test of registration using username and password and attach to pool ID and quantities
[
{
'state': 'present',
'username': 'admin',
'password': 'admin',
'org_id': 'admin',
'pool_ids': [{'ff8080816b8e967f016b8e99632804a6': 2}, {'ff8080816b8e967f016b8e99747107e9': 4}]
},
{
'id': 'test_registeration_username_password_pool_ids_quantities',
'run_command.calls': [
(
['/testbin/subscription-manager', 'identity'],
{'check_rc': False},
(1, 'This system is not yet registered.', '')
),
(
[
'/testbin/subscription-manager',
'register',
'--org', 'admin',
'--username', 'admin',
'--password', 'admin'
],
{'check_rc': True, 'expand_user_and_vars': False},
(0, '', '')
),
(
[
'subscription-manager list --available',
{'check_rc': True, 'environ_update': {'LANG': 'C', 'LC_ALL': 'C', 'LC_MESSAGES': 'C'}},
(0,
'''
+-------------------------------------------+
Available Subscriptions
+-------------------------------------------+
Subscription Name: SP Smart Management (A: ADDON1)
Provides: SP Addon 1 bits
SKU: sp-with-addon-1
Contract: 1
Pool ID: ff8080816b8e967f016b8e99747107e9
Provides Management: Yes
Available: 10
Suggested: 1
Service Type:
Roles:
Service Level:
Usage:
Add-ons: ADDON1
Subscription Type: Standard
Starts: 25.6.2019
Ends: 24.6.2020
Entitlement Type: Physical
Subscription Name: SP Server Premium (S: Premium, U: Production, R: SP Server)
Provides: SP Server Bits
SKU: sp-server-prem-prod
Contract: 0
Pool ID: ff8080816b8e967f016b8e99632804a6
Provides Management: Yes
Available: 5
Suggested: 1
Service Type: L1-L3
Roles: SP Server
Service Level: Premium
Usage: Production
Add-ons:
Subscription Type: Standard
Starts: 06/25/19
Ends: 06/24/20
Entitlement Type: Physical
''', '')
]
),
(
[
'/testbin/subscription-manager',
'attach',
'--pool', 'ff8080816b8e967f016b8e99632804a6',
'--quantity', '2'
],
{'check_rc': True},
(0, '', '')
),
(
[
'/testbin/subscription-manager',
'attach',
'--pool', 'ff8080816b8e967f016b8e99747107e9',
'--quantity', '4'
],
{'check_rc': True},
(0, '', '')
)
],
'changed': True,
'msg': "System successfully registered to 'None'."
}
],
# Test of registration using username and password and attach to pool ID without quantities
[
{
'state': 'present',
'username': 'admin',
'password': 'admin',
'org_id': 'admin',
'pool_ids': ['ff8080816b8e967f016b8e99632804a6', 'ff8080816b8e967f016b8e99747107e9']
},
{
'id': 'test_registeration_username_password_pool_ids',
'run_command.calls': [
(
['/testbin/subscription-manager', 'identity'],
{'check_rc': False},
(1, 'This system is not yet registered.', '')
),
(
[
'/testbin/subscription-manager',
'register',
'--org', 'admin',
'--username', 'admin',
'--password', 'admin'
],
{'check_rc': True, 'expand_user_and_vars': False},
(0, '', '')
),
(
[
'subscription-manager list --available',
{'check_rc': True, 'environ_update': {'LANG': 'C', 'LC_ALL': 'C', 'LC_MESSAGES': 'C'}},
(0,
'''
+-------------------------------------------+
Available Subscriptions
+-------------------------------------------+
Subscription Name: SP Smart Management (A: ADDON1)
Provides: SP Addon 1 bits
SKU: sp-with-addon-1
Contract: 1
Pool ID: ff8080816b8e967f016b8e99747107e9
Provides Management: Yes
Available: 10
Suggested: 1
Service Type:
Roles:
Service Level:
Usage:
Add-ons: ADDON1
Subscription Type: Standard
Starts: 25.6.2019
Ends: 24.6.2020
Entitlement Type: Physical
Subscription Name: SP Server Premium (S: Premium, U: Production, R: SP Server)
Provides: SP Server Bits
SKU: sp-server-prem-prod
Contract: 0
Pool ID: ff8080816b8e967f016b8e99632804a6
Provides Management: Yes
Available: 5
Suggested: 1
Service Type: L1-L3
Roles: SP Server
Service Level: Premium
Usage: Production
Add-ons:
Subscription Type: Standard
Starts: 06/25/19
Ends: 06/24/20
Entitlement Type: Physical
''', '')
]
),
(
[
'/testbin/subscription-manager',
'attach',
'--pool', 'ff8080816b8e967f016b8e99632804a6'
],
{'check_rc': True},
(0, '', '')
),
(
[
'/testbin/subscription-manager',
'attach',
'--pool', 'ff8080816b8e967f016b8e99747107e9'
],
{'check_rc': True},
(0, '', '')
)
],
'changed': True,
'msg': "System successfully registered to 'None'."
}
],
# Test of registration using username and password and attach to pool ID (one pool)
[
{
'state': 'present',
'username': 'admin',
'password': 'admin',
'org_id': 'admin',
'pool_ids': ['ff8080816b8e967f016b8e99632804a6']
},
{
'id': 'test_registeration_username_password_one_pool_id',
'run_command.calls': [
(
['/testbin/subscription-manager', 'identity'],
{'check_rc': False},
(1, 'This system is not yet registered.', '')
),
(
[
'/testbin/subscription-manager',
'register',
'--org', 'admin',
'--username', 'admin',
'--password', 'admin'
],
{'check_rc': True, 'expand_user_and_vars': False},
(0, '', '')
),
(
[
'subscription-manager list --available',
{'check_rc': True, 'environ_update': {'LANG': 'C', 'LC_ALL': 'C', 'LC_MESSAGES': 'C'}},
(0,
'''
+-------------------------------------------+
Available Subscriptions
+-------------------------------------------+
Subscription Name: SP Smart Management (A: ADDON1)
Provides: SP Addon 1 bits
SKU: sp-with-addon-1
Contract: 1
Pool ID: ff8080816b8e967f016b8e99747107e9
Provides Management: Yes
Available: 10
Suggested: 1
Service Type:
Roles:
Service Level:
Usage:
Add-ons: ADDON1
Subscription Type: Standard
Starts: 25.6.2019
Ends: 24.6.2020
Entitlement Type: Physical
Subscription Name: SP Server Premium (S: Premium, U: Production, R: SP Server)
Provides: SP Server Bits
SKU: sp-server-prem-prod
Contract: 0
Pool ID: ff8080816b8e967f016b8e99632804a6
Provides Management: Yes
Available: 5
Suggested: 1
Service Type: L1-L3
Roles: SP Server
Service Level: Premium
Usage: Production
Add-ons:
Subscription Type: Standard
Starts: 06/25/19
Ends: 06/24/20
Entitlement Type: Physical
''', '')
]
),
(
[
'/testbin/subscription-manager',
'attach',
'--pool', 'ff8080816b8e967f016b8e99632804a6',
],
{'check_rc': True},
(0, '', '')
)
],
'changed': True,
'msg': "System successfully registered to 'None'."
}
],
# Test attaching different set of pool IDs
[
{
'state': 'present',
'pool_ids': [{'ff8080816b8e967f016b8e99632804a6': 2}, {'ff8080816b8e967f016b8e99747107e9': 4}]
},
{
'id': 'test_attaching_different_pool_ids',
'run_command.calls': [
(
['/testbin/subscription-manager', 'identity'],
{'check_rc': False},
(0, 'system identity: b26df632-25ed-4452-8f89-0308bfd167cb', ''),
),
(
'subscription-manager list --consumed',
{'check_rc': True, 'environ_update': {'LANG': 'C', 'LC_ALL': 'C', 'LC_MESSAGES': 'C'}},
(0, '''
+-------------------------------------------+
Consumed Subscriptions
+-------------------------------------------+
Subscription Name: Multi-Attribute Stackable (4 cores, no content)
Provides: Multi-Attribute Limited Product (no content)
SKU: cores4-multiattr
Contract: 1
Account: 12331131231
Serial: 7807912223970164816
Pool ID: ff8080816b8e967f016b8e995f5103b5
Provides Management: No
Active: True
Quantity Used: 1
Service Type: Level 3
Roles:
Service Level: Premium
Usage:
Add-ons:
Status Details: Subscription is current
Subscription Type: Stackable
Starts: 06/25/19
Ends: 06/24/20
Entitlement Type: Physical
''', '')
),
(
[
'/testbin/subscription-manager',
'remove',
'--serial=7807912223970164816',
],
{'check_rc': True},
(0, '', '')
),
(
[
'subscription-manager list --available',
{'check_rc': True, 'environ_update': {'LANG': 'C', 'LC_ALL': 'C', 'LC_MESSAGES': 'C'}},
(0,
'''
+-------------------------------------------+
Available Subscriptions
+-------------------------------------------+
Subscription Name: SP Smart Management (A: ADDON1)
Provides: SP Addon 1 bits
SKU: sp-with-addon-1
Contract: 1
Pool ID: ff8080816b8e967f016b8e99747107e9
Provides Management: Yes
Available: 10
Suggested: 1
Service Type:
Roles:
Service Level:
Usage:
Add-ons: ADDON1
Subscription Type: Standard
Starts: 25.6.2019
Ends: 24.6.2020
Entitlement Type: Physical
Subscription Name: SP Server Premium (S: Premium, U: Production, R: SP Server)
Provides: SP Server Bits
SKU: sp-server-prem-prod
Contract: 0
Pool ID: ff8080816b8e967f016b8e99632804a6
Provides Management: Yes
Available: 5
Suggested: 1
Service Type: L1-L3
Roles: SP Server
Service Level: Premium
Usage: Production
Add-ons:
Subscription Type: Standard
Starts: 06/25/19
Ends: 06/24/20
Entitlement Type: Physical
Subscription Name: Multi-Attribute Stackable (4 cores, no content)
Provides: Multi-Attribute Limited Product (no content)
SKU: cores4-multiattr
Contract: 1
Pool ID: ff8080816b8e967f016b8e995f5103b5
Provides Management: No
Available: 10
Suggested: 1
Service Type: Level 3
Roles:
Service Level: Premium
Usage:
Add-ons:
Subscription Type: Stackable
Starts: 11.7.2019
Ends: 10.7.2020
Entitlement Type: Physical
''', '')
]
),
(
[
'/testbin/subscription-manager',
'attach',
'--pool', 'ff8080816b8e967f016b8e99632804a6',
'--quantity', '2'
],
{'check_rc': True},
(0, '', '')
),
(
[
'/testbin/subscription-manager',
'attach',
'--pool', 'ff8080816b8e967f016b8e99747107e9',
'--quantity', '4'
],
{'check_rc': True},
(0, '', '')
)
],
'changed': True,
}
]
]
TEST_CASES_IDS = [item[1]['id'] for item in TEST_CASES]
@pytest.mark.parametrize('patch_ansible_module, testcase', TEST_CASES, ids=TEST_CASES_IDS, indirect=['patch_ansible_module'])
@pytest.mark.usefixtures('patch_ansible_module')
def test_redhat_subscription(mocker, capfd, patch_redhat_subscription, testcase):
"""
Run unit tests for test cases listen in TEST_CASES
"""
# Mock function used for running commands first
call_results = [item[2] for item in testcase['run_command.calls']]
mock_run_command = mocker.patch.object(
basic.AnsibleModule,
'run_command',
side_effect=call_results)
# Try to run test case
with pytest.raises(SystemExit):
redhat_subscription.main()
out, err = capfd.readouterr()
results = json.loads(out)
assert 'changed' in results
assert results['changed'] == testcase['changed']
if 'msg' in results:
assert results['msg'] == testcase['msg']
assert basic.AnsibleModule.run_command.call_count == len(testcase['run_command.calls'])
if basic.AnsibleModule.run_command.call_count:
call_args_list = [(item[0][0], item[1]) for item in basic.AnsibleModule.run_command.call_args_list]
expected_call_args_list = [(item[0], item[1]) for item in testcase['run_command.calls']]
assert call_args_list == expected_call_args_list
SYSPURPOSE_TEST_CASES = [
# Test setting syspurpose attributes (system is already registered)
# and synchronization with candlepin server
[
{
'state': 'present',
'server_hostname': 'subscription.rhsm.redhat.com',
'username': 'admin',
'password': 'admin',
'org_id': 'admin',
'syspurpose': {
'role': 'AwesomeOS',
'usage': 'Production',
'service_level_agreement': 'Premium',
'addons': ['ADDON1', 'ADDON2'],
'sync': True
}
},
{
'id': 'test_setting_syspurpose_attributes',
'existing_syspurpose': {},
'expected_syspurpose': {
'role': 'AwesomeOS',
'usage': 'Production',
'service_level_agreement': 'Premium',
'addons': ['ADDON1', 'ADDON2'],
},
'run_command.calls': [
(
['/testbin/subscription-manager', 'identity'],
{'check_rc': False},
(0, 'system identity: b26df632-25ed-4452-8f89-0308bfd167cb', '')
),
(
['/testbin/subscription-manager', 'status'],
{'check_rc': False},
(0, '''
+-------------------------------------------+
System Status Details
+-------------------------------------------+
Overall Status: Current
System Purpose Status: Matched
''', '')
)
],
'changed': True,
'msg': 'Syspurpose attributes changed.'
}
],
# Test setting unspupported attributes
[
{
'state': 'present',
'server_hostname': 'subscription.rhsm.redhat.com',
'username': 'admin',
'password': 'admin',
'org_id': 'admin',
'syspurpose': {
'foo': 'Bar',
'role': 'AwesomeOS',
'usage': 'Production',
'service_level_agreement': 'Premium',
'addons': ['ADDON1', 'ADDON2'],
'sync': True
}
},
{
'id': 'test_setting_syspurpose_wrong_attributes',
'existing_syspurpose': {},
'expected_syspurpose': {},
'run_command.calls': [],
'failed': True
}
],
# Test setting addons not a list
[
{
'state': 'present',
'server_hostname': 'subscription.rhsm.redhat.com',
'username': 'admin',
'password': 'admin',
'org_id': 'admin',
'syspurpose': {
'role': 'AwesomeOS',
'usage': 'Production',
'service_level_agreement': 'Premium',
'addons': 'ADDON1',
'sync': True
}
},
{
'id': 'test_setting_syspurpose_addons_not_list',
'existing_syspurpose': {},
'expected_syspurpose': {
'role': 'AwesomeOS',
'usage': 'Production',
'service_level_agreement': 'Premium',
'addons': ['ADDON1']
},
'run_command.calls': [
(
['/testbin/subscription-manager', 'identity'],
{'check_rc': False},
(0, 'system identity: b26df632-25ed-4452-8f89-0308bfd167cb', '')
),
(
['/testbin/subscription-manager', 'status'],
{'check_rc': False},
(0, '''
+-------------------------------------------+
System Status Details
+-------------------------------------------+
Overall Status: Current
System Purpose Status: Matched
''', '')
)
],
'changed': True,
'msg': 'Syspurpose attributes changed.'
}
],
# Test setting syspurpose attributes (system is already registered)
# without synchronization with candlepin server. Some syspurpose attributes were set
# in the past
[
{
'state': 'present',
'server_hostname': 'subscription.rhsm.redhat.com',
'username': 'admin',
'password': 'admin',
'org_id': 'admin',
'syspurpose': {
'role': 'AwesomeOS',
'service_level_agreement': 'Premium',
'addons': ['ADDON1', 'ADDON2'],
'sync': False
}
},
{
'id': 'test_changing_syspurpose_attributes',
'existing_syspurpose': {
'role': 'CoolOS',
'usage': 'Production',
'service_level_agreement': 'Super',
'addons': [],
'foo': 'bar'
},
'expected_syspurpose': {
'role': 'AwesomeOS',
'service_level_agreement': 'Premium',
'addons': ['ADDON1', 'ADDON2'],
'foo': 'bar'
},
'run_command.calls': [
(
['/testbin/subscription-manager', 'identity'],
{'check_rc': False},
(0, 'system identity: b26df632-25ed-4452-8f89-0308bfd167cb', '')
),
],
'changed': True,
'msg': 'Syspurpose attributes changed.'
}
],
# Test trying to set syspurpose attributes (system is already registered)
# without synchronization with candlepin server. Some syspurpose attributes were set
# in the past. Syspurpose attributes are same as before
[
{
'state': 'present',
'server_hostname': 'subscription.rhsm.redhat.com',
'username': 'admin',
'password': 'admin',
'org_id': 'admin',
'syspurpose': {
'role': 'AwesomeOS',
'service_level_agreement': 'Premium',
'addons': ['ADDON1', 'ADDON2'],
'sync': False
}
},
{
'id': 'test_not_changing_syspurpose_attributes',
'existing_syspurpose': {
'role': 'AwesomeOS',
'service_level_agreement': 'Premium',
'addons': ['ADDON1', 'ADDON2'],
},
'expected_syspurpose': {
'role': 'AwesomeOS',
'service_level_agreement': 'Premium',
'addons': ['ADDON1', 'ADDON2'],
},
'run_command.calls': [
(
['/testbin/subscription-manager', 'identity'],
{'check_rc': False},
(0, 'system identity: b26df632-25ed-4452-8f89-0308bfd167cb', '')
),
],
'changed': False,
'msg': 'System already registered.'
}
],
# Test of registration using username and password with auto-attach option, when
# syspurpose attributes are set
[
{
'state': 'present',
'username': 'admin',
'password': 'admin',
'org_id': 'admin',
'auto_attach': 'true',
'syspurpose': {
'role': 'AwesomeOS',
'usage': 'Testing',
'service_level_agreement': 'Super',
'addons': ['ADDON1'],
'sync': False
},
},
{
'id': 'test_registeration_username_password_auto_attach_syspurpose',
'existing_syspurpose': None,
'expected_syspurpose': {
'role': 'AwesomeOS',
'usage': 'Testing',
'service_level_agreement': 'Super',
'addons': ['ADDON1'],
},
'run_command.calls': [
(
['/testbin/subscription-manager', 'identity'],
{'check_rc': False},
(1, 'This system is not yet registered.', '')
),
(
[
'/testbin/subscription-manager',
'register',
'--org', 'admin',
'--auto-attach',
'--username', 'admin',
'--password', 'admin'
],
{'check_rc': True, 'expand_user_and_vars': False},
(0, '', '')
)
],
'changed': True,
'msg': "System successfully registered to 'None'."
}
],
# Test of registration using username and password with auto-attach option, when
# syspurpose attributes are set. Syspurpose attributes are also synchronized
# in this case
[
{
'state': 'present',
'username': 'admin',
'password': 'admin',
'org_id': 'admin',
'auto_attach': 'true',
'syspurpose': {
'role': 'AwesomeOS',
'usage': 'Testing',
'service_level_agreement': 'Super',
'addons': ['ADDON1'],
'sync': True
},
},
{
'id': 'test_registeration_username_password_auto_attach_syspurpose_sync',
'existing_syspurpose': None,
'expected_syspurpose': {
'role': 'AwesomeOS',
'usage': 'Testing',
'service_level_agreement': 'Super',
'addons': ['ADDON1'],
},
'run_command.calls': [
(
['/testbin/subscription-manager', 'identity'],
{'check_rc': False},
(1, 'This system is not yet registered.', '')
),
(
[
'/testbin/subscription-manager',
'register',
'--org', 'admin',
'--auto-attach',
'--username', 'admin',
'--password', 'admin'
],
{'check_rc': True, 'expand_user_and_vars': False},
(0, '', '')
),
(
['/testbin/subscription-manager', 'status'],
{'check_rc': False},
(0, '''
+-------------------------------------------+
System Status Details
+-------------------------------------------+
Overall Status: Current
System Purpose Status: Matched
''', '')
)
],
'changed': True,
'msg': "System successfully registered to 'None'."
}
],
]
SYSPURPOSE_TEST_CASES_IDS = [item[1]['id'] for item in SYSPURPOSE_TEST_CASES]
@pytest.mark.parametrize('patch_ansible_module, testcase', SYSPURPOSE_TEST_CASES, ids=SYSPURPOSE_TEST_CASES_IDS, indirect=['patch_ansible_module'])
@pytest.mark.usefixtures('patch_ansible_module')
def test_redhat_subscription_syspurpose(mocker, capfd, patch_redhat_subscription, patch_ansible_module, testcase, tmpdir):
"""
Run unit tests for test cases listen in SYSPURPOSE_TEST_CASES (syspurpose specific cases)
"""
# Mock function used for running commands first
call_results = [item[2] for item in testcase['run_command.calls']]
mock_run_command = mocker.patch.object(
basic.AnsibleModule,
'run_command',
side_effect=call_results)
mock_syspurpose_file = tmpdir.mkdir("syspurpose").join("syspurpose.json")
# When there there are some existing syspurpose attributes specified, then
# write them to the file first
if testcase['existing_syspurpose'] is not None:
mock_syspurpose_file.write(json.dumps(testcase['existing_syspurpose']))
else:
mock_syspurpose_file.write("{}")
redhat_subscription.SysPurpose.SYSPURPOSE_FILE_PATH = str(mock_syspurpose_file)
# Try to run test case
with pytest.raises(SystemExit):
redhat_subscription.main()
out, err = capfd.readouterr()
results = json.loads(out)
if 'failed' in testcase:
assert results['failed'] == testcase['failed']
else:
assert 'changed' in results
assert results['changed'] == testcase['changed']
if 'msg' in results:
assert results['msg'] == testcase['msg']
mock_file_content = mock_syspurpose_file.read_text("utf-8")
current_syspurpose = json.loads(mock_file_content)
assert current_syspurpose == testcase['expected_syspurpose']
assert basic.AnsibleModule.run_command.call_count == len(testcase['run_command.calls'])
if basic.AnsibleModule.run_command.call_count:
call_args_list = [(item[0][0], item[1]) for item in basic.AnsibleModule.run_command.call_args_list]
expected_call_args_list = [(item[0], item[1]) for item in testcase['run_command.calls']]
assert call_args_list == expected_call_args_list