# 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 annotations import json import pytest from ansible.module_utils import basic from ansible_collections.community.general.plugins.modules import redhat_subscription 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 """ 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) """ 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: list[str] = [item[1]["id"] for item in TEST_CASES] # type: ignore @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"]] 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: list[str] = [item[1]["id"] for item in SYSPURPOSE_TEST_CASES] # type: ignore @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"]] 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