ci: fix tests
Some checks failed
pull-requests-open / Check commit compliance (pull_request) Successful in 5s
pull-requests-open / Run tests (pull_request) Failing after 32s

This commit is contained in:
Bertrand Lanson 2024-09-14 20:47:50 +02:00
parent 84989cfbee
commit 194d5ed1f0
Signed by: lanson
SSH Key Fingerprint: SHA256:/nqc6HGqld/PS208F6FUOvZlUzTS0rGpNNwR5O2bQBw
2 changed files with 172 additions and 182 deletions

View File

@ -46,6 +46,13 @@ jobs:
shell: bash shell: bash
working-directory: ${{ gitea.workspace }} working-directory: ${{ gitea.workspace }}
- name: Setup testing environment
run: |
mkdir -p /tmp/ansible_collections/ednz_cloud
ln -s ${{ gitea.workspace }} /tmp/ansible_collections/ednz_cloud/infomaniak
shell: bash
working-directory: ${{ gitea.workspace }}
- name: Run ansible unit tests - name: Run ansible unit tests
run: ansible-test units --coverage run: ansible-test units --coverage
shell: bash shell: bash

View File

@ -1,11 +1,40 @@
import unittest import unittest
import json
import pytest
from unittest.mock import patch, MagicMock from unittest.mock import patch, MagicMock
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils import basic
from ansible.module_utils.common.text.converters import to_bytes
from ansible_collections.ednz_cloud.infomaniak.plugins.modules import ( from ansible_collections.ednz_cloud.infomaniak.plugins.modules import (
public_cloud_config_info, public_cloud_config_info,
) )
def set_module_args(args):
if "_ansible_remote_tmp" not in args:
args["_ansible_remote_tmp"] = "/tmp"
if "_ansible_keep_remote_files" not in args:
args["_ansible_keep_remote_files"] = False
args = json.dumps({"ANSIBLE_MODULE_ARGS": args})
basic._ANSIBLE_ARGS = to_bytes(args)
class AnsibleExitJson(Exception):
def __init__(self, kwargs):
self.kwargs = kwargs
def exit_json(*args, **kwargs):
if "changed" not in kwargs:
kwargs["changed"] = False
raise AnsibleExitJson(kwargs)
def fail_json(*args, **kwargs):
raise SystemExit(json.dumps(kwargs))
class TestPublicCloudConfigInfoModule(unittest.TestCase): class TestPublicCloudConfigInfoModule(unittest.TestCase):
""" """
Unit tests for the public_cloud_config_info Ansible module. Unit tests for the public_cloud_config_info Ansible module.
@ -21,7 +50,6 @@ class TestPublicCloudConfigInfoModule(unittest.TestCase):
""" """
Test a successful retrieval of public cloud configuration. Test a successful retrieval of public cloud configuration.
""" """
# Mock API response data
api_response_data = { api_response_data = {
"result": "success", "result": "success",
"data": { "data": {
@ -34,209 +62,139 @@ class TestPublicCloudConfigInfoModule(unittest.TestCase):
}, },
} }
# Mock the InfomaniakAPIClient instance
mock_client_instance = MagicMock() mock_client_instance = MagicMock()
mock_client_instance.get.return_value = api_response_data mock_client_instance.get.return_value = api_response_data
mock_client_class.return_value = mock_client_instance mock_client_class.return_value = mock_client_instance
# Mock AnsibleModule parameters
mock_module_instance = MagicMock() mock_module_instance = MagicMock()
mock_module_instance.params = { mock_module_instance.params = {
"api_token": "mock_api_token", "api_token": "mock_api_token",
"account_id": "mock_account_id", "account_id": "mock_account_id",
} }
mock_module_instance.check_mode = False # Simulate non-check mode mock_module_instance.check_mode = False
mock_ansible_module.return_value = mock_module_instance mock_ansible_module.return_value = mock_module_instance
# Mock exit_json to prevent actual exit
mock_module_instance.exit_json = MagicMock() mock_module_instance.exit_json = MagicMock()
# Execute the run_module function
public_cloud_config_info.run_module() public_cloud_config_info.run_module()
# Assert that the InfomaniakAPIClient was initialized with the correct token
mock_client_class.assert_called_with( mock_client_class.assert_called_with(
api_version="1", api_token="mock_api_token" api_version="1", api_token="mock_api_token"
) )
# Assert that the correct API call was made
mock_client_instance.get.assert_called_once_with( mock_client_instance.get.assert_called_once_with(
"/public_clouds/config", params={"account_id": "mock_account_id"} "/public_clouds/config", params={"account_id": "mock_account_id"}
) )
# Assert exit_json is called once with the expected data
mock_module_instance.exit_json.assert_called_once_with( mock_module_instance.exit_json.assert_called_once_with(
changed=False, config=api_response_data["data"] changed=False, config=api_response_data["data"]
) )
@patch( # def test_successful_retrieval(self):
"ansible_collections.ednz_cloud.infomaniak.plugins.modules.public_cloud_config_info.AnsibleModule" # """
) # Test a successful retrieval of public cloud configuration.
@patch( # """
"ansible_collections.ednz_cloud.infomaniak.plugins.modules.public_cloud_config_info.InfomaniakAPIClient" # set_module_args(
) # {
def test_api_failure(self, mock_client_class, mock_ansible_module): # "api_token": "mock_api_token",
""" # "account_id": "mock_account_id",
Test failure scenario where API returns an error result. # }
""" # )
#
# api_response_data = {
# "result": "success",
# "data": {
# "free_tier": 300,
# "free_tier_used": 24.34,
# "account_resource_level": 2,
# "valid_from": 1707584356,
# "valid_to": 1717192799,
# "project_count": 2,
# },
# }
#
# self.mock_client_instance.get.return_value = api_response_data
#
# with patch.object(
# AnsibleModule, "exit_json", side_effect=exit_json
# ) as mock_exit_json:
# with patch.object(
# AnsibleModule, "fail_json", side_effect=fail_json
# ) as mock_fail_json:
# with pytest.raises(AnsibleExitJson) as e:
# public_cloud_config_info.main()
# mock_fail_json.assert_not_called()
# result = e.value.kwargs
# assert result["changed"] is False
# assert "config" in result
# assert result["config"] == api_response_data["data"]
# mock_exit_json.assert_called_once()
# self.mock_client_class.assert_called_with(
# api_version="1", api_token="mock_api_token"
# )
# self.mock_client_instance.get.assert_called_once_with(
# "/public_clouds/config",
# params={"account_id": "mock_account_id"},
# )
# Mock API failure response def test_missing_required_params(self):
mock_client_instance = MagicMock()
mock_client_instance.get.side_effect = Exception(
"API request failed with result: error"
)
mock_client_class.return_value = mock_client_instance
# Mock AnsibleModule parameters
mock_module_instance = MagicMock()
mock_module_instance.params = {
"api_token": "mock_api_token",
"account_id": "invalid_account_id",
}
mock_module_instance.check_mode = False # Simulate non-check mode
mock_ansible_module.return_value = mock_module_instance
# Mock fail_json to prevent actual exit
mock_module_instance.fail_json = MagicMock()
# Execute the run_module function
public_cloud_config_info.run_module()
# Assert fail_json was called with the expected error message
mock_module_instance.fail_json.assert_called_once_with(
msg="API request failed with result: error"
)
@patch(
"ansible_collections.ednz_cloud.infomaniak.plugins.modules.public_cloud_config_info.AnsibleModule"
)
def test_missing_required_params(self, mock_ansible_module):
""" """
Test behavior when required parameters are missing. Test behavior when required parameters are missing.
""" """
# Mock the AnsibleModule instance set_module_args(
mock_module_instance = MagicMock() {
"api_token": "mock_api_token",
# Simulate missing 'api_token' in the parameters # 'account_id' is missing
mock_module_instance.params = {
"account_id": "mock_account_id", # Missing api_token
} }
# Simulate Ansible behavior: fail_json should be called when 'api_token' is missing
mock_ansible_module.return_value = mock_module_instance
# Execute the run_module function and expect KeyError
with self.assertRaises(KeyError):
public_cloud_config_info.run_module()
@patch(
"ansible_collections.ednz_cloud.infomaniak.plugins.modules.public_cloud_config_info.AnsibleModule"
) )
@patch(
"ansible_collections.ednz_cloud.infomaniak.plugins.modules.public_cloud_config_info.InfomaniakAPIClient"
)
def test_empty_api_response(self, mock_client_class, mock_ansible_module):
"""
Test behavior when the API returns an empty response.
"""
# Mock API response data
api_response_data = {"result": "success", "data": {}} # Empty data
# Mock the InfomaniakAPIClient instance with patch.object(AnsibleModule, "fail_json", side_effect=fail_json):
mock_client_instance = MagicMock() with pytest.raises(SystemExit) as e:
mock_client_instance.get.return_value = api_response_data public_cloud_config_info.main()
mock_client_class.return_value = mock_client_instance
# Mock AnsibleModule parameters captured_output = json.loads(e.value.args[0])
mock_module_instance = MagicMock()
mock_module_instance.params = { assert "msg" in captured_output
assert "missing required arguments: account_id" in captured_output["msg"]
def test_check_mode(self):
"""
Test the behavior in check mode, where no changes should be made.
"""
set_module_args(
{
"api_token": "mock_api_token", "api_token": "mock_api_token",
"account_id": "mock_account_id", "account_id": "mock_account_id",
"_ansible_check_mode": True,
} }
mock_module_instance.check_mode = False # Simulate non-check mode
mock_ansible_module.return_value = mock_module_instance
# Execute the run_module function
public_cloud_config_info.run_module()
# Assert exit_json is called once with empty config data
mock_module_instance.exit_json.assert_called_once_with(changed=False, config={})
@patch(
"ansible_collections.ednz_cloud.infomaniak.plugins.modules.public_cloud_config_info.AnsibleModule"
)
@patch(
"ansible_collections.ednz_cloud.infomaniak.plugins.modules.public_cloud_config_info.InfomaniakAPIClient"
)
def test_unexpected_api_response_format(
self, mock_client_class, mock_ansible_module
):
"""
Test behavior when the API response format is unexpected.
"""
# Mock an unexpected API response (missing 'result')
api_response_data = {
"data": {
"free_tier": 300,
}
}
# Mock the InfomaniakAPIClient instance
mock_client_instance = MagicMock()
mock_client_instance.get.return_value = api_response_data
mock_client_class.return_value = mock_client_instance
# Mock AnsibleModule parameters
mock_module_instance = MagicMock()
mock_module_instance.params = {
"api_token": "mock_api_token",
"account_id": "mock_account_id",
}
mock_ansible_module.return_value = mock_module_instance
# Execute the run_module function
public_cloud_config_info.run_module()
# Assert fail_json is called with an appropriate error
mock_module_instance.fail_json.assert_called_once_with(
msg="API request failed with result: None"
) )
@patch( with patch.object(
"ansible_collections.ednz_cloud.infomaniak.plugins.modules.public_cloud_config_info.AnsibleModule" AnsibleModule, "exit_json", side_effect=exit_json
) ) as mock_exit_json:
def test_check_mode(self, mock_ansible_module): with pytest.raises(AnsibleExitJson) as e:
""" public_cloud_config_info.main()
Test behavior when check_mode is enabled.
"""
# Mock AnsibleModule parameters
mock_module_instance = MagicMock()
mock_module_instance.params = {
"api_token": "mock_api_token",
"account_id": "mock_account_id",
}
mock_module_instance.check_mode = True # Simulate check mode
mock_ansible_module.return_value = mock_module_instance
# Execute the run_module function mock_exit_json.assert_called_once_with(
public_cloud_config_info.run_module()
# Assert exit_json is called with the check_mode message
mock_module_instance.exit_json.assert_called_once_with(
changed=False, changed=False,
msg="Check mode: No changes made, would retrieve public cloud config.", msg="Check mode: No changes made, would retrieve public cloud config.",
) )
@patch( def test_network_timeout(self):
"ansible_collections.ednz_cloud.infomaniak.plugins.modules.public_cloud_config_info.AnsibleModule"
)
@patch(
"ansible_collections.ednz_cloud.infomaniak.plugins.modules.public_cloud_config_info.InfomaniakAPIClient"
)
def test_network_timeout(self, mock_client_class, mock_ansible_module):
""" """
Test behavior when a network timeout occurs. Test behavior when a network timeout occurs.
""" """
set_module_args(
{
"api_token": "mock_api_token",
"account_id": "mock_account_id",
}
)
with patch.object(AnsibleModule, "fail_json", side_effect=fail_json):
with pytest.raises(SystemExit) as e:
public_cloud_config_info.main()
# Simulate a network timeout error # Simulate a network timeout error
mock_client_instance = MagicMock() mock_client_instance = MagicMock()
mock_client_instance.get.side_effect = Exception("Request timeout") mock_client_instance.get.side_effect = Exception("Request timeout")
@ -257,36 +215,61 @@ class TestPublicCloudConfigInfoModule(unittest.TestCase):
mock_module_instance.fail_json.assert_called_once_with(msg="Request timeout") mock_module_instance.fail_json.assert_called_once_with(msg="Request timeout")
@patch( @patch(
"ansible_collections.ednz_cloud.infomaniak.plugins.modules.public_cloud_config_info.AnsibleModule" "ansible_collections.ednz_cloud.infomaniak.plugins.modules.public_cloud_config_info.InfomaniakAPIClient"
) )
def test_network_timeout(self, mock_client_class):
"""
Test behavior when a network timeout occurs.
"""
# Simulate a network timeout error
mock_client_instance = MagicMock()
mock_client_instance.get.side_effect = Exception("Request timeout")
mock_client_class.return_value = mock_client_instance
set_module_args(
{
"api_token": "mock_api_token",
"account_id": "mock_account_id",
}
)
with patch.object(
AnsibleModule, "fail_json", side_effect=fail_json
) as mock_fail_json:
with pytest.raises(SystemExit) as e:
public_cloud_config_info.main()
captured_output = json.loads(e.value.args[0])
assert "msg" in captured_output
assert captured_output["msg"] == "Request timeout"
mock_fail_json.assert_called_once()
@patch( @patch(
"ansible_collections.ednz_cloud.infomaniak.plugins.modules.public_cloud_config_info.InfomaniakAPIClient" "ansible_collections.ednz_cloud.infomaniak.plugins.modules.public_cloud_config_info.InfomaniakAPIClient"
) )
def test_invalid_json_response(self, mock_client_class, mock_ansible_module): def test_invalid_json_response(self, mock_client_class):
""" """
Test behavior when the API returns an invalid JSON response. Test behavior when the API returns an invalid JSON response.
""" """
# Mock the InfomaniakAPIClient instance to raise a JSONDecodeError
mock_client_instance = MagicMock() mock_client_instance = MagicMock()
mock_client_instance.get.side_effect = Exception("Invalid JSON response") mock_client_instance.get.side_effect = Exception("Invalid JSON response")
mock_client_class.return_value = mock_client_instance mock_client_class.return_value = mock_client_instance
# Mock AnsibleModule parameters # Set module args with the required parameters
mock_module_instance = MagicMock() set_module_args(
mock_module_instance.params = { {
"api_token": "mock_api_token", "api_token": "mock_api_token",
"account_id": "mock_account_id", "account_id": "mock_account_id",
} }
mock_ansible_module.return_value = mock_module_instance
# Execute the run_module function
public_cloud_config_info.run_module()
# Assert fail_json is called with the appropriate error message
mock_module_instance.fail_json.assert_called_once_with(
msg="Invalid JSON response"
) )
with patch.object(
AnsibleModule, "fail_json", side_effect=fail_json
) as mock_fail_json:
with pytest.raises(SystemExit) as e:
public_cloud_config_info.main()
if __name__ == "__main__": captured_output = json.loads(e.value.args[0])
unittest.main() assert "msg" in captured_output
assert captured_output["msg"] == "Invalid JSON response"
mock_fail_json.assert_called_once()