Skip to content

Commit

Permalink
added unit tests and updated version_utils.py
Browse files Browse the repository at this point in the history
  • Loading branch information
Kilian Soltermann committed Nov 9, 2023
1 parent a2a62f4 commit 24f0362
Show file tree
Hide file tree
Showing 4 changed files with 190 additions and 3 deletions.
3 changes: 1 addition & 2 deletions plugins/module_utils/version_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ def get_opnsense_version() -> str:
Returns output of command opensense-version
"""
try:
output = subprocess.check_output(["opnsense-version"]).decode("utf-8").strip()
return output
return subprocess.check_output(args=["opnsense-version"], encoding="utf-8").strip()

except subprocess.CalledProcessError as exc:
return str(exc)
83 changes: 82 additions & 1 deletion tests/unit/plugins/module_utils/test_config_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import os
from tempfile import NamedTemporaryFile
from xml.etree import ElementTree
from unittest.mock import patch, MagicMock
from unittest.mock import patch, MagicMock, call

import pytest
from ansible_collections.puzzle.opnsense.plugins.module_utils import xml_utils
Expand Down Expand Up @@ -395,6 +395,87 @@ def test_del_module_setting(mock_object: MagicMock, opnsense_config, sample_conf
assert new_config["system"]["domain"] is None


@patch("ansible_collections.puzzle.opnsense.plugins.module_utils.opnsense_utils.run_function")
@patch("ansible_collections.puzzle.opnsense.plugins.module_utils.config_utils.OPNsenseConfig._get_configure_functions")
@patch("ansible_collections.puzzle.opnsense.plugins.module_utils.config_utils.OPNsenseConfig._get_php_requirements")
@patch("ansible_collections.puzzle.opnsense.plugins.module_utils.version_utils.get_opnsense_version", return_value="OPNsense 23.1")
def test_apply_module_setting(
version_mock_object: MagicMock,
php_mock_object: MagicMock,
configure_mock_object: MagicMock,
run_function_mock_object: MagicMock,
opnsense_config
):
"""
Test the application of module settings within the OPNsense configuration.
This test ensures that given a set of PHP requirements and configure functions,
the `apply_module_setting` method applies the settings correctly by invoking
the appropriate functions with the expected parameters.
The method under test should retrieve the PHP requirements and configuration
functions for the specified module and execute them, collecting the output.
We mock the dependencies involved in this process to assert that the functions
are called as expected, and the resultant output is correctly aggregated.
The expected behavior is that for each configure function provided, a corresponding
call to `opnsense_utils.run_function` is made with the appropriate PHP requirements
and parameters, and the result of these function calls is returned as a list of outputs.
"""

test_php_requirements = [
"/usr/local/etc/inc/config.inc",
"/usr/local/etc/inc/util.inc",
"/usr/local/etc/inc/system.inc",
"/usr/local/etc/inc/interfaces.lib.inc",
"/usr/local/etc/inc/interfaces.inc",
"/usr/local/etc/inc/filter.inc",
]

test_configure_functions = {
"system_timezone_configure": {
"name": "system_timezone_configure",
"configure_params": ["true"]
},
"system_resolver_configure": {
"name": "system_resolver_configure",
"configure_params": ["true"]
},
"plugins_configure": {
"name": "plugins_configure",
"configure_params": ["'dns'", "true"]
},
}

php_mock_object.return_value = test_php_requirements
configure_mock_object.return_value = test_configure_functions

# Act: Call the apply_module_setting method
result = opnsense_config.apply_module_setting(module="system_settings")

# Assert: Check that run_function was called correctly
expected_calls = [
call(
php_requirements=test_php_requirements,
configure_function='system_timezone_configure',
configure_params=["true"]
),
call(
php_requirements=test_php_requirements,
configure_function='system_resolver_configure',
configure_params=["true"]
),
call(
php_requirements=test_php_requirements,
configure_function='plugins_configure',
configure_params=["'dns'", "true"]
),
]
run_function_mock_object.assert_has_calls(expected_calls, any_order=True)
assert len(result) == len(test_configure_functions)


@patch("ansible_collections.puzzle.opnsense.plugins.module_utils.version_utils.get_opnsense_version", return_value="OPNsense X.X.X")
def test_version_not_found_in_version_map(mock_object: MagicMock, opnsense_config, sample_config_path):
"""
Expand Down
67 changes: 67 additions & 0 deletions tests/unit/plugins/module_utils/test_opnsense_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Copyright: (c) 2023, Puzzle ITC
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
"""Tests for the plugins.module_utils.opnsense_utils module."""

from __future__ import (absolute_import, division, print_function)

__metaclass__ = type

import subprocess
from unittest.mock import patch, MagicMock
from ansible_collections.puzzle.opnsense.plugins.module_utils import opnsense_utils


@patch("subprocess.run")
def test_run_function(mock_subprocess_run: MagicMock):
"""
Test the `run_function` utility which executes a PHP function with optional parameters.
This unit test mocks the `subprocess.run` method to simulate the execution of a PHP script
that includes specific PHP files and calls a given function with parameters, if any.
The purpose is to ensure that the `run_function` utility correctly constructs the PHP command,
executes it, and returns the standard output.
The mock is set up to ensure that `subprocess.run` behaves as if the PHP script was executed
successfully, returning an output as expected.
Mocks:
- mock_subprocess_run (MagicMock): A mock for `subprocess.run` to prevent the actual execution
of the PHP command during testing. It is configured to simulate a successful execution with
a predetermined standard output.
Assertions:
- Asserts that `run_function` returns the standard output correctly processed as a string.
Raises:
- AssertionError: If the `run_function` does not return the expected standard output string.
"""

# Mock the subprocess.run to return a predefined output
mock_output = b"Function executed successfully"
mock_subprocess_run.return_value.stdout = mock_output

# Define the PHP requirements and the function with parameters to be tested
php_requirements = ["/usr/local/etc/inc/config.inc", "/usr/local/etc/inc/util.inc"]
configure_function = 'plugins_configure'
configure_params = ['dns', 'true']

# Call run_function with the test parameters
result = opnsense_utils.run_function(php_requirements, configure_function, configure_params)

# Assert the result matches the mocked standard output
assert result.decode() == mock_output.decode()

# Assert the subprocess.run was called with the expected command
expected_command = [
"php",
"-r",
"require '/usr/local/etc/inc/config.inc'; "
"require '/usr/local/etc/inc/util.inc'; "
"plugins_configure(dns,true);"
]

mock_subprocess_run.assert_called_with(
expected_command,
stdout=subprocess.PIPE,
check=True
)
40 changes: 40 additions & 0 deletions tests/unit/plugins/module_utils/test_version_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Copyright: (c) 2023, Puzzle ITC
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
"""Tests for the plugins.module_utils.version_utils module."""

from __future__ import (absolute_import, division, print_function)

__metaclass__ = type

from unittest.mock import patch, MagicMock

from ansible_collections.puzzle.opnsense.plugins.module_utils import version_utils


@patch("subprocess.check_output", return_value=" OPNsense 23.1 ")
def test_version_utils(mock_object: MagicMock):
"""
Test the retrieval of the OPNsense version using the version_utils module.
This unit test mocks the `subprocess.check_output` method to simulate the system's response
for the OPNsense version check. It ensures that the `get_opnsense_version` function
correctly processes the output from the subprocess call, trimming any extraneous whitespace,
and returns the exact version string.
The mock is configured to return a string with leading and trailing spaces around the version
number, which mimics the real subprocess output behavior. The test checks that the function
under test extracts the version number accurately, without any surrounding whitespace.
Mocks:
- mock_subprocess_check_output (MagicMock): A mock for `subprocess.check_output` to avoid
executing the actual command line call during testing.
Assertions:
- Asserts that the `get_opnsense_version` function returns "OPNsense 23.1" exactly, ensuring
that any preprocessing of the output is handled correctly.
Raises:
- AssertionError: If the `get_opnsense_version` does not return the expected version string.
"""

assert version_utils.get_opnsense_version() == "OPNsense 23.1"

0 comments on commit 24f0362

Please sign in to comment.