diff --git a/plugins/module_utils/common/maintenance_mode.py b/plugins/module_utils/common/maintenance_mode.py index 00f4dce5f..e999b8c5c 100644 --- a/plugins/module_utils/common/maintenance_mode.py +++ b/plugins/module_utils/common/maintenance_mode.py @@ -23,9 +23,7 @@ import inspect import logging -from .api.v1.lan_fabric.rest.control.fabrics.fabrics import ( - EpFabricConfigDeploy, EpMaintenanceModeDeploy, EpMaintenanceModeDisable, - EpMaintenanceModeEnable) +from .api.v1.lan_fabric.rest.control.fabrics.fabrics import EpFabricConfigDeploy, EpMaintenanceModeDeploy, EpMaintenanceModeDisable, EpMaintenanceModeEnable from .conversion import ConversionUtils from .exceptions import ControllerResponseError from .properties import Properties @@ -35,34 +33,34 @@ @Properties.add_results class MaintenanceMode: """ - ### Summary - - Modify the maintenance mode state of switches. - - Optionally deploy the changes. - - ### Raises - - ``ValueError`` in the following methods: - - __init__() if params is missing mandatory parameters - ``check_mode`` or ``state``. - - - ``ValueError`` in the following properties: - - ``config`` if config contains invalid content. - - ``commit`` if config, rest_send, or results are not set. - - ``commit`` if ``EpMaintenanceModeEnable`` or - ``EpMaintenanceModeDisable`` raise ``ValueError``. - - ``commit`` if either ``chance_system_mode()`` or - ``deploy_switches()`` raise ``ControllerResponseError``. - - - ``TypeError`` in the following properties: - - ``rest_send`` if value is not an instance of RestSend. - - ``results`` if value is not an instance of Results. - - ### Details - - Updates MaintenanceMode().results to reflect success/failure of - the operation on the controller. - - For switches that are to be deployed, initiates a per-fabric - bulk switch config-deploy. - - ### Example value for ``config`` in the ``Usage`` section below: + # Summary + + Modify the maintenance mode state of switches and optionally deploy the changes. + + ## Raises + + ### ValueError + + - `__init__()`: params is missing mandatory parameters `check_mode` or `state`. + - `config` property setter: config contains invalid content. + - `commit()`: config, rest_send, or results are not set. + - `commit()`: `EpMaintenanceModeEnable` or `EpMaintenanceModeDisable` raise `ValueError`. + - `commit()`: either `change_system_mode()` or `deploy_switches()` raise `ControllerResponseError`. + + ### TypeError + + - `rest_send` property setter: value is not an instance of RestSend. + - `results` property setter: value is not an instance of Results. + + ## Details + + - Updates MaintenanceMode().results to reflect success/failure of + the operation on the controller. + - For switches that are to be deployed, initiates a per-fabric + bulk switch config-deploy. + + ## Example value for `config` in the `Usage` section below + ```json [ { @@ -82,16 +80,17 @@ class MaintenanceMode: ] ``` - ### Usage - - Where ``params`` is ``AnsibleModule.params`` - - Where ``config`` is a list of dicts, each containing the following: - - ``deploy``: ``bool``. If True, the switch maintenance mode - will be deployed. - - ``fabric_name``: ``str``. The name of the switch's hosting fabric. - - ``ip_address``: ``str``. The ip address of the switch. - - ``mode``: ``str``. The intended maintenance mode. Must be one of - "maintenance" or "normal". - - ``serial_number``: ``str``. The serial number of the switch. + ## Usage + + Where `params` is `AnsibleModule.params` and `config` is a list of dicts, + each containing the following: + + - `deploy`: `bool`. If True, the switch maintenance mode will be deployed. + - `fabric_name`: `str`. The name of the switch's hosting fabric. + - `ip_address`: `str`. The ip address of the switch. + - `mode`: `str`. The intended maintenance mode. Must be one of + "maintenance" or "normal". + - `serial_number`: `str`. The serial number of the switch. ```python instance = MaintenanceMode(params) @@ -153,20 +152,29 @@ def __init__(self, params): def verify_config_parameters(self, value) -> None: """ - ### Summary + # Summary + Verify that required parameters are present in config. - ### Raises - - ``TypeError`` if ``config`` is not a list. - - ``ValueError`` if ``config`` contains invalid content. - - ### NOTES - 1. See the following validation methods for details: - - verify_deploy() - - verify_fabric_name() - - verify_ip_address() - - verify_mode() - - verify_serial_number() + ## Raises + + ### TypeError + + - `config` is not a list. + + ### ValueError + + - `config` contains invalid content. + + ## Notes + + See the following validation methods for details: + + - verify_deploy() + - verify_fabric_name() + - verify_ip_address() + - verify_mode() + - verify_serial_number() """ method_name = inspect.stack()[0][3] if not isinstance(value, list): @@ -188,14 +196,19 @@ def verify_config_parameters(self, value) -> None: def verify_deploy(self, item) -> None: """ - ### Summary - Verify the ``deploy`` parameter. - - ### Raises - - ``ValueError`` if: - - ``deploy`` is not present. - - ``TypeError`` if: - - `deploy`` is not a boolean. + # Summary + + Verify the `deploy` parameter. + + ## Raises + + ### ValueError + + - `deploy` is not present. + + ### TypeError + + - `deploy` is not a boolean. """ method_name = inspect.stack()[0][3] if item.get("deploy", None) is None: @@ -211,13 +224,16 @@ def verify_deploy(self, item) -> None: def verify_fabric_name(self, item) -> None: """ - ### Summary - Validate the ``fabric_name`` parameter. + # Summary + + Validate the `fabric_name` parameter. + + ## Raises - ### Raises - - ``ValueError`` if: - - ``fabric_name`` is not present. - - ``fabric_name`` is not a valid fabric name. + ### ValueError + + - `fabric_name` is not present. + - `fabric_name` is not a valid fabric name. """ method_name = inspect.stack()[0][3] if item.get("fabric_name", None) is None: @@ -231,12 +247,15 @@ def verify_fabric_name(self, item) -> None: def verify_ip_address(self, item) -> None: """ - ### Summary - Validate the ``ip_address`` parameter. + # Summary + + Validate the `ip_address` parameter. + + ## Raises - ### Raises - - ``ValueError`` if: - - ``ip_address`` is not present. + ### ValueError + + - `ip_address` is not present. """ method_name = inspect.stack()[0][3] if item.get("ip_address", None) is None: @@ -246,13 +265,16 @@ def verify_ip_address(self, item) -> None: def verify_mode(self, item) -> None: """ - ### Summary - Validate the ``mode`` parameter. + # Summary + + Validate the `mode` parameter. - ### Raises - - ``ValueError`` if: - - ``mode`` is not present. - - ``mode`` is not one of "maintenance" or "normal". + ## Raises + + ### ValueError + + - `mode` is not present. + - `mode` is not one of "maintenance" or "normal". """ method_name = inspect.stack()[0][3] if item.get("mode", None) is None: @@ -267,12 +289,15 @@ def verify_mode(self, item) -> None: def verify_serial_number(self, item) -> None: """ - ### Summary - Validate the ``serial_number`` parameter. + # Summary + + Validate the `serial_number` parameter. + + ## Raises + + ### ValueError - ### Raises - - ``ValueError`` if: - - ``serial_number`` is not present. + - `serial_number` is not present. """ method_name = inspect.stack()[0][3] if item.get("serial_number", None) is None: @@ -282,14 +307,19 @@ def verify_serial_number(self, item) -> None: def verify_wait_for_mode_change(self, item) -> None: """ - ### Summary - Verify the ``wait_for_mode_change`` parameter. - - ### Raises - - ``ValueError`` if: - - ``wait_for_mode_change`` is not present. - - ``TypeError`` if: - - `wait_for_mode_change`` is not a boolean. + # Summary + + Verify the `wait_for_mode_change` parameter. + + ## Raises + + ### ValueError + + - `wait_for_mode_change` is not present. + + ### TypeError + + - `wait_for_mode_change` is not a boolean. """ method_name = inspect.stack()[0][3] if item.get("wait_for_mode_change", None) is None: @@ -305,14 +335,17 @@ def verify_wait_for_mode_change(self, item) -> None: def verify_commit_parameters(self) -> None: """ - ### Summary + # Summary + Verify that required parameters are present before calling commit. - ### Raises - - ``ValueError`` if: - - ``config`` is not set. - - ``rest_send`` is not set. - - ``results`` is not set. + ## Raises + + ### ValueError + + - `config` is not set. + - `rest_send` is not set. + - `results` is not set. """ method_name = inspect.stack()[0][3] if self.config is None: @@ -333,18 +366,21 @@ def verify_commit_parameters(self) -> None: def commit(self) -> None: """ - ### Summary + # Summary + Initiates the maintenance mode change on the controller. - ### Raises - - ``ValueError`` if - - ``config`` is not set. - - ``rest_send`` is not set. - - ``results`` is not set. - - any exception is raised by: - - ``verify_commit_parameters()`` - - ``change_system_mode()`` - - ``deploy_switches()`` + ## Raises + + ### ValueError + + - `config` is not set. + - `rest_send` is not set. + - `results` is not set. + - any exception is raised by: + - `verify_commit_parameters()` + - `change_system_mode()` + - `deploy_switches()` """ try: self.verify_commit_parameters() @@ -359,18 +395,25 @@ def commit(self) -> None: def change_system_mode(self) -> None: """ - ### Summary + # Summary + Send the maintenance mode change request to the controller. - ### Raises - - ``ControllerResponseError`` if: - - controller response != 200. - - ``ValueError`` if: - - ``fabric_name`` is invalid. - - endpoint cannot be resolved. - - ``Results()`` raises an exception. - - ``TypeError`` if: - - ``serial_number`` is not a string. + ## Raises + + ### ControllerResponseError + + - controller response != 200. + + ### ValueError + + - `fabric_name` is invalid. + - endpoint cannot be resolved. + - `Results()` raises an exception. + + ### TypeError + + - `serial_number` is not a string. """ method_name = inspect.stack()[0][3] @@ -417,12 +460,8 @@ def change_system_mode(self) -> None: self.results.action = "change_sytem_mode" self.results.check_mode = self.check_mode self.results.state = self.state - self.results.response_current = copy.deepcopy( - self.rest_send.response_current - ) - self.results.result_current = copy.deepcopy( - self.rest_send.result_current - ) + self.results.response_current = copy.deepcopy(self.rest_send.response_current) + self.results.result_current = copy.deepcopy(self.rest_send.result_current) self.results.register_task_result() except (TypeError, ValueError) as error: raise ValueError(error) from error @@ -438,41 +477,46 @@ def change_system_mode(self) -> None: def build_deploy_dict(self) -> None: """ - ### Summary - - Build the deploy_dict + # Summary + + Build the deploy_dict + + ## Raises - ### Raises None - ### Structure - - key: fabric_name - - value: list of dict - - each dict contains ``serial_number`` and ``wait_for_mode_change keys`` + ## Structure + + - key: fabric_name + - value: list of dict + - each dict contains `serial_number` and `wait_for_mode_change` keys + + ## Example - ### Example ```json { "MyFabric": [ { "serial_number": "CDM4593459", - "wait_for_mode_change": True + "wait_for_mode_change": true }, { "serial_number": "CDM4593460", - "wait_for_mode_change": False + "wait_for_mode_change": false } ], "YourFabric": [ { "serial_number": "DDM0455882", - "wait_for_mode_change": True + "wait_for_mode_change": true }, { "serial_number": "DDM5598759", - "wait_for_mode_change": True + "wait_for_mode_change": true } ] } + ``` """ self.deploy_dict = {} for item in self.config: @@ -490,25 +534,27 @@ def build_deploy_dict(self) -> None: def build_serial_number_to_ip_address(self) -> None: """ - ### Summary + # Summary + Populate self.serial_number_to_ip_address dict. - ### Raises + ## Raises + None - ### Structure - - key: switch serial_number - - value: associated switch ip_address + ## Structure + + - key: switch serial_number + - value: associated switch ip_address ```json { "CDM4593459": "192.168.1.2" } ``` - ### Raises - None - ### Notes - - ip_address and serial_number are added to the diff in the - ``deploy_switches()`` method. + ## Notes + + ip_address and serial_number are added to the diff in the + `deploy_switches()` method. """ for item in self.config: serial_number = item.get("serial_number") @@ -517,11 +563,15 @@ def build_serial_number_to_ip_address(self) -> None: def build_endpoints(self) -> None: """ - ### Summary - Build ``endpoints`` dict used in ``self.deploy_switches``. + # Summary + + Build `endpoints` dict used in `self.deploy_switches`. + + ## Raises + + ### ValueError - ### Raises - ``ValueError`` if endpoint configuration fails. + - endpoint configuration fails. """ method_name = inspect.stack()[0][3] endpoints = [] @@ -546,14 +596,19 @@ def build_endpoints(self) -> None: def deploy_switches(self) -> None: """ - ### Summary - Initiate config-deploy for the switches in ``self.deploy_dict``. - - ### Raises - - ``ControllerResponseError`` if: - - controller response != 200. - - ``ValueError`` if: - - endpoint cannot be resolved. + # Summary + + Initiate config-deploy for the switches in `self.deploy_dict`. + + ## Raises + + ### ControllerResponseError + + - controller response != 200. + + ### ValueError + + - endpoint cannot be resolved. """ method_name = inspect.stack()[0][3] self.build_deploy_dict() @@ -588,9 +643,7 @@ def deploy_switches(self) -> None: self.results.action = action self.results.check_mode = self.check_mode self.results.state = self.state - self.results.response_current = copy.deepcopy( - self.rest_send.response_current - ) + self.results.response_current = copy.deepcopy(self.rest_send.response_current) self.results.result_current = copy.deepcopy(self.rest_send.result_current) self.results.register_task_result() @@ -606,31 +659,30 @@ def deploy_switches(self) -> None: @property def config(self) -> list: """ - ### Summary - The maintenance mode configurations to be sent to the controller. - - ### Raises - - setter: ``ValueError`` if: - - value is not a list. - - value contains invalid content. - - ### getter - Return ``config``. - - ### setter - Set ``config``. - - ### Value structure - value is a ``list`` of ``dict``. Each dict must contain the following: - - ``deploy``: ``bool``. If True, the switch maintenance mode - will be deployed. - - ``fabric_name``: ``str``. The name of the switch's hosting fabric. - - ``ip_address``: ``str``. The ip address of the switch. - - ``mode``: ``str``. The intended maintenance mode. Must be one of - "maintenance" or "normal". - - ``serial_number``: ``str``. The serial number of the switch. - - ### Example + # Summary + + Get/set the maintenance mode configurations to be sent to the controller. + + ## Raises + + ### ValueError + + - setter: value is not a list. + - setter: value contains invalid content. + + ## Value structure + + value is a `list` of `dict`. Each dict must contain the following: + + - `deploy`: `bool`. If True, the switch maintenance mode will be deployed. + - `fabric_name`: `str`. The name of the switch's hosting fabric. + - `ip_address`: `str`. The ip address of the switch. + - `mode`: `str`. The intended maintenance mode. Must be one of + "maintenance" or "normal". + - `serial_number`: `str`. The serial number of the switch. + + ## Example + ```json [ { diff --git a/plugins/module_utils/common/maintenance_mode_info.py b/plugins/module_utils/common/maintenance_mode_info.py index ded423897..b2c1397ec 100644 --- a/plugins/module_utils/common/maintenance_mode_info.py +++ b/plugins/module_utils/common/maintenance_mode_info.py @@ -23,71 +23,79 @@ import inspect import logging +from ..fabric.fabric_details_v2 import FabricDetailsByName from .conversion import ConversionUtils from .exceptions import ControllerResponseError from .properties import Properties from .switch_details import SwitchDetails -from ..fabric.fabric_details_v2 import FabricDetailsByName @Properties.add_rest_send @Properties.add_results class MaintenanceModeInfo: """ - ### Summary - - Retrieve the maintenance mode state of switches. - - ### Raises - - ``TypeError`` in the following public properties: - - ``config`` if value is not a list. - - ``rest_send`` if value is not an instance of RestSend. - - ``results`` if value is not an instance of Results. - - - ``ValueError`` in the following public methods: - - ``refresh()`` if: - - ``config`` has not been set. - - ``rest_send`` has not been set. - - ``results`` has not been set. - - ### Details - Updates ``MaintenanceModeInfo().results`` to reflect success/failure of + # Summary + + Retrieve the maintenance mode state of switches. + + ## Raises + + ### TypeError + + - `config` property setter: value is not a list. + - `rest_send` property setter: value is not an instance of RestSend. + - `results` property setter: value is not an instance of Results. + + ### ValueError + + - `refresh()`: `config` has not been set. + - `refresh()`: `rest_send` has not been set. + - `refresh()`: `results` has not been set. + + ## Details + + Updates `MaintenanceModeInfo().results` to reflect success/failure of the operation on the controller. - Example value for ``config`` in the ``Usage`` section below: + ## Example value for `config` in the `Usage` section below + ```json ["192.168.1.2", "192.168.1.3"] ``` - Example value for ``info`` in the ``Usage`` section below: - ```json - { - "192.169.1.2": { - deployment_disabled: true - fabric_freeze_mode: true, - fabric_name: "MyFabric", - fabric_read_only: true - mode: "maintenance", - role: "spine", - serial_number: "FCI1234567" - }, - "192.169.1.3": { - deployment_disabled: false, - fabric_freeze_mode: false, - fabric_name: "YourFabric", - fabric_read_only: false - mode: "normal", - role: "leaf", - serial_number: "FCH2345678" - } + ## Example value for `info` in the `Usage` section below + + ```json + { + "192.169.1.2": { + "deployment_disabled": true, + "fabric_freeze_mode": true, + "fabric_name": "MyFabric", + "fabric_read_only": true, + "mode": "maintenance", + "role": "spine", + "serial_number": "FCI1234567" + }, + "192.169.1.3": { + "deployment_disabled": false, + "fabric_freeze_mode": false, + "fabric_name": "YourFabric", + "fabric_read_only": false, + "mode": "normal", + "role": "leaf", + "serial_number": "FCH2345678" } - ``` + } + ``` - ### Usage - - Where: - - ``params`` is ``AnsibleModule.params`` - - ``config`` is per the above example. - - ``sender`` is an instance of a Sender() class. - See ``sender_dcnm.py`` for usage. + ## Usage + + Where: + + - `params` is `AnsibleModule.params` + - `config` is per the above example. + - `sender` is an instance of a Sender() class. + See `sender_dcnm.py` for usage. ```python ansible_module = AnsibleModule() @@ -139,15 +147,17 @@ def __init__(self, params): def verify_refresh_parameters(self) -> None: """ - ### Summary - Verify that required parameters are present before - calling ``refresh()``. - - ### Raises - - ``ValueError`` if: - - ``config`` is not set. - - ``rest_send`` is not set. - - ``results`` is not set. + # Summary + + Verify that required parameters are present before calling `refresh()`. + + ## Raises + + ### ValueError + + - `config` is not set. + - `rest_send` is not set. + - `results` is not set. """ method_name = inspect.stack()[0][3] if self.config is None: @@ -168,47 +178,52 @@ def verify_refresh_parameters(self) -> None: def refresh(self): """ - ### Summary - Build ``self.info``, a dict containing the current maintenance mode + # Summary + + Build `self.info`, a dict containing the current maintenance mode status of all switches in self.config. - ### Raises - - ``ValueError`` if: - - ``SwitchDetails()`` raises ``ControllerResponseError`` - - ``SwitchDetails()`` raises ``ValueError`` - - ``FabricDetails()`` raises ``ControllerResponseError`` - - switch with ``ip_address`` does not exist on the controller. + ## Raises + + ### ValueError + + - `SwitchDetails()` raises `ControllerResponseError` + - `SwitchDetails()` raises `ValueError` + - `FabricDetails()` raises `ControllerResponseError` + - switch with `ip_address` does not exist on the controller. + + ## self.info structure - ### self.info structure info is a dict, keyed on switch_ip, where each element is a dict with the following structure: - - ``fabric_name``: The name of the switch's hosting fabric. - - ``freeze_mode``: The current state of the switch's hosting fabric. - If freeze_mode is True, configuration changes cannot be made to the - fabric or the switches within the fabric. - - ``mode``: The current maintenance mode of the switch. - - ``role``: The role of the switch in the hosting fabric. - - ``serial_number``: The serial number of the switch. + + - `fabric_name`: The name of the switch's hosting fabric. + - `freeze_mode`: The current state of the switch's hosting fabric. + If freeze_mode is True, configuration changes cannot be made to the + fabric or the switches within the fabric. + - `mode`: The current maintenance mode of the switch. + - `role`: The role of the switch in the hosting fabric. + - `serial_number`: The serial number of the switch. ```json { "192.169.1.2": { - fabric_deployment_disabled: true - fabric_freeze_mode: true, - fabric_name: "MyFabric", - fabric_read_only: true - mode: "maintenance", - role: "spine", - serial_number: "FCI1234567" + "fabric_deployment_disabled": true, + "fabric_freeze_mode": true, + "fabric_name": "MyFabric", + "fabric_read_only": true, + "mode": "maintenance", + "role": "spine", + "serial_number": "FCI1234567" }, "192.169.1.3": { - fabric_deployment_disabled: false, - fabric_freeze_mode: false, - fabric_name: "YourFabric", - fabric_read_only: false - mode: "normal", - role: "leaf", - serial_number: "FCH2345678" + "fabric_deployment_disabled": false, + "fabric_freeze_mode": false, + "fabric_name": "YourFabric", + "fabric_read_only": false, + "mode": "normal", + "role": "leaf", + "serial_number": "FCH2345678" } } ``` @@ -303,15 +318,21 @@ def refresh(self): def _get(self, item): """ + # Summary + Return the value of the item from the filtered switch. - ### Raises - - ``ValueError`` if: - - ``filter`` is not set. - - ``filter`` is not in the controller response. - ### NOTES - - We do not need to check that ``item`` exists in the filtered - switch dict, since ``refresh()`` has already done so. + ## Raises + + ### ValueError + + - `filter` is not set. + - `filter` is not in the controller response. + + ## Notes + + We do not need to check that `item` exists in the filtered + switch dict, since `refresh()` has already done so. """ method_name = inspect.stack()[0][3] @@ -327,27 +348,30 @@ def _get(self, item): msg += "the controller." raise ValueError(msg) - return self.conversion.make_boolean( - self.conversion.make_none(self._info[self.filter].get(item)) - ) + return self.conversion.make_boolean(self.conversion.make_none(self._info[self.filter].get(item))) @property def filter(self): """ - ### Summary + # Summary + Set the query filter (switch IP address) - ### Raises - None. However, if ``filter`` is not set, or ``filter`` is set to + ## Raises + + None + + However, if `filter` is not set, or `filter` is set to an ip_address for a switch that does not exist on the controller, - ``ValueError`` will be raised when accessing the various getter + `ValueError` will be raised when accessing the various getter properties. - ### Details + ## Details + The filter should be the ip_address of the switch from which to retrieve details. - ``filter`` must be set before accessing this class's properties. + `filter` must be set before accessing this class's properties. """ return self._filter @@ -358,25 +382,34 @@ def filter(self, value): @property def config(self) -> list: """ - ### Summary + # Summary + A list of switch ip addresses for which maintenance mode state will be retrieved. - ### Raises - - setter: ``TypeError`` if: - - ``config`` is not a ``list``. - - Elements of ``config`` are not ``str``. + ## Raises - ### getter - Return ``config``. + ### TypeError - ### setter - Set ``config``. + setter: - ### Value structure - value is a ``list`` of ip addresses + - `config` is not a `list`. + - Elements of `config` are not `str`. + + ## getter + + Return `config`. + + ## setter + + Set `config`. + + ## Value structure + + value is a `list` of ip addresses + + ## Example - ### Example ```json ["172.22.150.2", "172.22.150.3"] ``` @@ -406,136 +439,159 @@ def config(self, value): @property def fabric_deployment_disabled(self): """ - ### Summary - The current ``fabric_deployment_disabled`` state of the + # Summary + + The current `fabric_deployment_disabled` state of the filtered switch's hosting fabric. - ### Raises - - ``ValueError`` if: - - ``filter`` is not set. - - ``filter`` is not in the controller response. - - ``deployment_disabled`` is not in the filtered switch dict. - - ### Valid values - - ``True``: The fabric is in a state where configuration changes - cannot be made. - - ``False``: The fabric is in a state where configuration changes - can be made. + ## Raises + + ### ValueError + + - `filter` is not set. + - `filter` is not in the controller response. + - `deployment_disabled` is not in the filtered switch dict. + + ## Valid values + + - `True`: The fabric is in a state where configuration changes + cannot be made. + - `False`: The fabric is in a state where configuration changes + can be made. """ return self._get("fabric_deployment_disabled") @property def fabric_freeze_mode(self): """ - ### Summary + # Summary + The freezeMode state of the fabric in which the filtered switch resides. - ### Raises - - ``ValueError`` if: - - ``filter`` is not set. - - ``filter`` is not in the controller response. - - ``fabric_name`` is not in the filtered switch dict. - - ### Valid values - - ``True``: The fabric is in a state where configuration changes - cannot be made. - - ``False``: The fabric is in a state where configuration changes - can be made. + ## Raises + + ### ValueError + + - `filter` is not set. + - `filter` is not in the controller response. + - `fabric_name` is not in the filtered switch dict. + + ## Valid values + + - `True`: The fabric is in a state where configuration changes + cannot be made. + - `False`: The fabric is in a state where configuration changes + can be made. """ return self._get("fabric_freeze_mode") @property def fabric_name(self): """ - ### Summary + # Summary + The name of the fabric in which the filtered switch resides. - ### Raises - - ``ValueError`` if: - - ``filter`` is not set. - - ``filter`` is not in the controller response. - - ``fabric_name`` is not in the filtered switch dict. + ## Raises + + ### ValueError + + - `filter` is not set. + - `filter` is not in the controller response. + - `fabric_name` is not in the filtered switch dict. """ return self._get("fabric_name") @property def fabric_read_only(self): """ - ### Summary + # Summary + The read-only state of the fabric in which the filtered switch resides. - ### Raises - - ``ValueError`` if: - - ``filter`` is not set. - - ``filter`` is not in the controller response. - - ``fabric_name`` is not in the filtered switch dict. - - ### Valid values - - ``True``: The fabric is in a state where configuration changes - cannot be made. - - ``False``: The fabric is in a state where configuration changes - can be made. + ## Raises + + ### ValueError + + - `filter` is not set. + - `filter` is not in the controller response. + - `fabric_name` is not in the filtered switch dict. + + ## Valid values + + - `True`: The fabric is in a state where configuration changes + cannot be made. + - `False`: The fabric is in a state where configuration changes + can be made. """ return self._get("fabric_read_only") @property def info(self) -> dict: """ - ### Summary + # Summary + Return or set the current maintenance mode state of the switches represented by the ip_addresses in self.config. - ### Raises - - ``ValueError`` if: - - ``refresh()`` has not been called before accessing ``info``. + ## Raises + + ### ValueError - ### getter - Return ``info``. + - `refresh()` has not been called before accessing `info`. - ### setter - Set ``info``. + ## getter - ### ``info`` structure - ``info`` is a dict, keyed on switch_ip, where each element is a dict + Return `info`. + + ## setter + + Set `info`. + + ## `info` structure + + `info` is a dict, keyed on switch_ip, where each element is a dict with the following structure: - - ``fabric_deployment_disabled``: The current state of the switch's - hosting fabric. If fabric_deployment_disabled is True, - configuration changes cannot be made to the fabric or the switches - within the fabric. - - ``fabric_name``: The name of the switch's hosting fabric. - - ``fabric_freeze_mode``: The current state of the switch's - hosting fabric. If freeze_mode is True, configuration changes - cannot be made to the fabric or the switches within the fabric. - - ``fabric_read_only``: The current state of the switch's - hosting fabric. If fabric_read_only is True, configuration changes - cannot be made to the fabric or the switches within the fabric. - - ``mode``: The current maintenance mode of the switch. - - ``role``: The role of the switch in the hosting fabric. - - ``serial_number``: The serial number of the switch. - - ### Example info dict + + - `fabric_deployment_disabled`: The current state of the switch's + hosting fabric. If fabric_deployment_disabled is True, + configuration changes cannot be made to the fabric or the switches + within the fabric. + - `fabric_name`: The name of the switch's hosting fabric. + - `fabric_freeze_mode`: The current state of the switch's + hosting fabric. If freeze_mode is True, configuration changes + cannot be made to the fabric or the switches within the fabric. + - `fabric_read_only`: The current state of the switch's + hosting fabric. If fabric_read_only is True, configuration changes + cannot be made to the fabric or the switches within the fabric. + - `mode`: The current maintenance mode of the switch. + - `role`: The role of the switch in the hosting fabric. + - `serial_number`: The serial number of the switch. + + ## Example info dict + ```json { "192.169.1.2": { - fabric_deployment_disabled: true - fabric_freeze_mode: true, - fabric_name: "MyFabric", - fabric_read_only: true - mode: "maintenance", - role: "spine", - serial_number: "FCI1234567" + "fabric_deployment_disabled": true, + "fabric_freeze_mode": true, + "fabric_name": "MyFabric", + "fabric_read_only": true, + "mode": "maintenance", + "role": "spine", + "serial_number": "FCI1234567" }, "192.169.1.3": { - fabric_deployment_disabled: false - fabric_freeze_mode: false, - fabric_name: "YourFabric", - fabric_read_only: false - mode: "normal", - role: "leaf", - serial_number: "FCH2345678" + "fabric_deployment_disabled": false, + "fabric_freeze_mode": false, + "fabric_name": "YourFabric", + "fabric_read_only": false, + "mode": "normal", + "role": "leaf", + "serial_number": "FCH2345678" } } ``` @@ -560,41 +616,50 @@ def info(self, value: dict): @property def mode(self): """ - ### Summary + # Summary + The current maintenance mode of the filtered switch. - ### Raises - - ``ValueError`` if: - - ``filter`` is not set. - - ``filter`` is not in the controller response. - - ``mode`` is not in the filtered switch dict. + ## Raises + + ### ValueError + + - `filter` is not set. + - `filter` is not in the controller response. + - `mode` is not in the filtered switch dict. """ return self._get("mode") @property def role(self): """ - ### Summary + # Summary + The role of the filtered switch in the hosting fabric. - ### Raises - - ``ValueError`` if: - - ``filter`` is not set. - - ``filter`` is not in the controller response. - - ``role`` is not in the filtered switch dict. + ## Raises + + ### ValueError + + - `filter` is not set. + - `filter` is not in the controller response. + - `role` is not in the filtered switch dict. """ return self._get("role") @property def serial_number(self): """ - ### Summary + # Summary + The serial number of the filtered switch. - ### Raises - - ``ValueError`` if: - - ``filter`` is not set. - - ``filter`` is not in the controller response. - - ``serial_number`` is not in the filtered switch dict. + ## Raises + + ### ValueError + + - `filter` is not set. + - `filter` is not in the controller response. + - `serial_number` is not in the filtered switch dict. """ return self._get("serial_number") diff --git a/plugins/modules/dcnm_maintenance_mode.py b/plugins/modules/dcnm_maintenance_mode.py index f281904e0..da04957cd 100644 --- a/plugins/modules/dcnm_maintenance_mode.py +++ b/plugins/modules/dcnm_maintenance_mode.py @@ -149,6 +149,7 @@ import logging from ansible.module_utils.basic import AnsibleModule + from ..module_utils.common.log_v2 import Log from ..module_utils.common.maintenance_mode import MaintenanceMode from ..module_utils.common.maintenance_mode_info import MaintenanceModeInfo @@ -171,9 +172,16 @@ def json_pretty(msg): class ParamsSpec: """ + # Summary + Build parameter specifications for the dcnm_maintenance_mode module. - ### Usage + ## Raises + + None + + ## Usage + ```python from ansible.module_utils.basic import AnsibleModule @@ -216,10 +224,15 @@ def __init__(self): def commit(self): """ + # Summary + Build the parameter specification based on the state ## Raises - - ``ValueError`` if params is not set + + ### ValueError + + - params is not set """ if self._params is None: msg = f"{self.class_name}.commit: " @@ -275,19 +288,26 @@ def params_spec(self) -> dict: @property def params(self) -> dict: """ - ### Summary + # Summary + Expects value to be a dictionary containing, at mimimum, the key "state" with value of either "merged" or "query". - ### Raises - - setter: raise ``ValueError`` if value is not a dict - - setter: raise ``ValueError`` if value["state"] is missing - - setter: raise ``ValueError`` if value["state"] is not a valid state + ## Raises - ### Details - - Valid params: {"state": "merged"} or {"state": "query"} - - getter: return the params - - setter: set the params + ### ValueError + + setter: + + - value is not a dict + - value["state"] is missing + - value["state"] is not a valid state + + ## Details + + - Valid params: {"state": "merged"} or {"state": "query"} + - getter: return the params + - setter: set the params """ return self._params @@ -320,23 +340,29 @@ def params(self, value: dict) -> None: class Want: """ - ### Summary + # Summary + Build self.want, a list of validated playbook configurations. - ### Raises - - ``ValueError`` in the following cases: - - ``commit()`` is issued before setting mandatory properties - - When passing invalid values to property setters - - ``TypeError`` in the following cases: - - When passing invalid types to property setters + ## Raises + + ### ValueError + - `commit()` is issued before setting mandatory properties + - When passing invalid values to property setters + + ### TypeError + + - When passing invalid types to property setters + + ## Details - ### Details 1. Merge the playbook global config into each switch config. 2. Validate the merged configs from step 1 against the param spec. 3. Populate self.want with the validated configs. - ### Usage + ## Usage + ```python try: instance = Want() @@ -350,20 +376,21 @@ class Want: except (TypeError, ValueError) as error: handle_error(error) ``` - ### self.want structure + + ## self.want structure ```json [ { "ip_address": "192.168.1.2", "mode": "maintenance", - "deploy": false + "deploy": false, "wait_for_mode_change": false }, { "ip_address": "192.168.1.3", "mode": "normal", - "deploy": true + "deploy": true, "wait_for_mode_change": true } ] @@ -389,12 +416,16 @@ def __init__(self): def generate_params_spec(self) -> None: """ - ### Summary + # Summary + Generate the params_spec used to validate the configs - ### Raises - - ``ValueError`` if self.params is not set - - ``ValueError`` if self.params_spec is not set + ## Raises + + ### ValueError + + - self.params is not set + - self.params_spec is not set """ # Generate the params_spec used to validate the configs if self.params is None: @@ -415,15 +446,18 @@ def generate_params_spec(self) -> None: def validate_configs(self) -> None: """ - ### Summary + # Summary + Validate the merged configs against the param spec and populate self.want with the validated configs. - ### Raises + ## Raises + None - ### Notes - - validator is already verified in commit()s + ## Notes + + validator is already verified in commit()s """ self.validator.params_spec = self.params_spec.params_spec for config in self.merged_configs: @@ -433,12 +467,14 @@ def validate_configs(self) -> None: def build_merged_configs(self) -> None: """ - ### Summary + # Summary + If a parameter is missing from the config, and the parameter has a default value, merge the default value for the parameter into the config. - ### Raises + ## Raises + None """ self.merged_configs = [] @@ -455,25 +491,34 @@ def build_merged_configs(self) -> None: def commit(self) -> None: """ - ### Summary + # Summary + Build self.want, a list of validated playbook configurations. - ### Raises - - ``ValueError`` if: - - self.config is not set - - self.item_key is not set - - self.params is not set - - self.params_spec is not set - - self.validator is not set - - self.params_spec raises ``ValueError`` - - _merge_global_and_switch_configs() raises ``ValueError`` - - merge_dicts() raises `TypeError``` or ``ValueError`` - - playbook is missing list of items - - ### Details + ## Raises + + ### ValueError + + - self.config is not set + - self.item_key is not set + - self.params is not set + - self.params_spec is not set + - self.validator is not set + - self.params_spec raises `ValueError` + - _merge_global_and_switch_configs() raises `ValueError` + - merge_dicts() raises `ValueError` + - playbook is missing list of items + + ### TypeError + + - merge_dicts() raises `TypeError` + + ## Details + See class docstring. - ### self.want structure + ## self.want structure + See class docstring. """ method_name = inspect.stack()[0][3] @@ -511,23 +556,32 @@ def commit(self) -> None: def _merge_global_and_item_configs(self) -> None: """ - ### Summary + # Summary + Builds self.item_configs from self.config Merge the global playbook config with each item config and populate a list of merged configs (``self.item_configs``). - ### Raises - - ``ValueError`` if self.config is not set - - ``ValueError`` if self.items_key is not set - - ``ValueError`` if playbook is missing list of items - - ``ValueError`` if merge_dicts raises ``TypeError`` or ``ValueError`` - - ### Merge rules - - item_config takes precedence over global_config. - - If item_config is missing a parameter, use parameter - from global_config. - - If item_config has a parameter, use it. + ## Raises + + ### ValueError + + - self.config is not set + - self.items_key is not set + - playbook is missing list of items + - merge_dicts raises `ValueError` + + ### TypeError + + - merge_dicts raises `TypeError` + + ## Merge rules + + - item_config takes precedence over global_config. + - If item_config is missing a parameter, use parameter + from global_config. + - If item_config has a parameter, use it. """ method_name = inspect.stack()[0][3] @@ -584,15 +638,25 @@ def _merge_global_and_item_configs(self) -> None: @property def config(self): """ - ### Summary + # Summary + The playbook configuration to be processed. - ``config`` is processed by ``_merge_global_and_switch_configs()`` - to build ``switch_configs``. + `config` is processed by `_merge_global_and_switch_configs()` + to build `switch_configs`. + + ## Raises + + ### TypeError + + setter: - - getter: return config - - setter: set config - - setter: raise ``ValueError`` if value is not a dict + - value is not a dict + + ## Details + + - getter: return config + - setter: set config """ return self._config @@ -608,12 +672,23 @@ def config(self, value) -> None: @property def items_key(self) -> str: """ + # Summary + Expects value to be the key for the list of items in the playbook config. - - getter: return the items_key - - setter: set the items_key - - setter: raise ``ValueError`` if value is not a string + ## Raises + + ### TypeError + + setter: + + - value is not a string + + ## Details + + - getter: return the items_key + - setter: set the items_key """ return self._items_key @@ -632,27 +707,37 @@ def items_key(self, value: str) -> None: @property def want(self) -> list: """ - ### Summary + # Summary + Return the want list. See class docstring for structure details. + + ## Raises + + None """ return self._want @property def params(self) -> dict: """ - ### Summary - The return value of ``AnsibleModule.params`` property - (or equivalent dict). This is passed to ``params_spec`` + # Summary + + The return value of `AnsibleModule.params` property + (or equivalent dict). This is passed to `params_spec` and used in playbook config validation. - ### Raises - - setter: raise ``ValueError`` if value is not a ``dict``. + ## Raises - ### getter - Return params + ### TypeError - ### setter - Set params + setter: + + - value is not a `dict` + + ## Details + + - getter: Return params + - setter: Set params """ return self._params @@ -671,22 +756,26 @@ def params(self, value: dict) -> None: @property def params_spec(self): """ - ### Summary + # Summary + The parameter specification used to validate the playbook config. - Expects value to be an instance of ``ParamsSpec()``. + Expects value to be an instance of `ParamsSpec()`. - ``params_spec`` is passed to ``validator`` to validate the + `params_spec` is passed to `validator` to validate the playbook config. - ### Raises - - setter: raise ``TypeError`` if value is not an instance - of ParamsSpec() + ## Raises + + ### TypeError + + setter: + + - value is not an instance of ParamsSpec() - ### getter - Return params_spec + ## Details - ### setter - Set params_spec + - getter: Return params_spec + - setter: Set params_spec """ return self._params_spec @@ -711,18 +800,23 @@ def params_spec(self, value) -> None: @property def validator(self): """ - ### Summary - ``validator`` is used to validate the playbook config. - Expects value to be an instance of ``ParamsValidate()``. + # Summary + + `validator` is used to validate the playbook config. + Expects value to be an instance of `ParamsValidate()`. + + ## Raises - ### Raises - - setter: ``TypeError`` if value is not an instance of ``ParamsValidate()`` + ### TypeError - ### getter - Return validator + setter: - ### setter - Set validator + - value is not an instance of ``ParamsValidate()`` + + ## Details + + - getter: Return validator + - setter: Set validator """ return self._validator @@ -753,13 +847,21 @@ class Common: def __init__(self, params): """ - ### Raises - - ``ValueError`` if: - - ``params`` does not contain ``check_mode`` - - ``params`` does not contain ``state`` - - ``params`` does not contain ``config`` - - ``TypeError`` if: - - ``config`` is not a dict + # Summary + + Initialize Common instance + + ## Raises + + ### ValueError + + - `params` does not contain `check_mode` + - `params` does not contain `state` + - `params` does not contain `config` + + ### TypeError + + - `config` is not a dict """ self.class_name = self.__class__.__name__ method_name = inspect.stack()[0][3] @@ -809,11 +911,19 @@ def __init__(self, params): def get_want(self) -> None: """ - ### Summary + # Summary + Build self.want, a list of validated playbook configurations. - ### Raises - - ``ValueError`` if Want() instance raises ``ValueError`` + ## Raises + + ### ValueError + + - Want() instance raises `ValueError` + + ### TypeError + + - Want() instance raises `TypeError` """ try: instance = Want() @@ -830,16 +940,36 @@ def get_want(self) -> None: class Merged(Common): """ + # Summary + Handle merged state - ### Raises - - ``ValueError`` if Common().__init__() raises ``ValueError`` + ## Raises + + ### ValueError + + - Common().__init__() raises ``ValueError`` + + ### TypeError + + - Common().__init__() raises `TypeError` """ def __init__(self, params): """ - ### Raises - - ``ValueError`` if Common().__init__() raises ``ValueError`` + # Summary + + Initialize Merged instance + + ## Raises + + ### ValueError + + - Common().__init__() raises `ValueError` + + ### TypeError + + - Common().__init__() raises `TypeError` """ self.class_name = self.__class__.__name__ method_name = inspect.stack()[0][3] @@ -864,49 +994,59 @@ def __init__(self, params): def get_have(self): """ - ### Summary + # Summary + Build self.have, a dict containing the current mode of all switches. - ### Raises - - ``ValueError`` if self.ansible_module is not set - - ``ValueError`` if MaintenanceModeInfo() raises ``ValueError`` + ## Raises + + ### ValueError + + - self.ansible_module is not set + - MaintenanceModeInfo() raises `ValueError` + + ### TypeError + + - MaintenanceModeInfo() raises `TypeError` + + ## self.have structure - ### self.have structure Have is a dict, keyed on switch_ip, where each element is a dict with the following structure: - - ``fabric_name``: The name of the switch's hosting fabric. - - ``fabric_freeze_mode``: The current ``freezeMode`` state of the switch's - hosting fabric. If ``freeze_mode`` is True, configuration changes cannot - be made to the fabric or the switches within the fabric. - - ``fabric_read_only``: The current ``IS_READ_ONLY`` state of the switch's - hosting fabric. If ``fabric_read_only`` is True, configuration changes cannot - be made to the fabric or the switches within the fabric. - - ``mode``: The current maintenance mode of the switch. - Possible values include: , ``inconsistent``, ``maintenance``, - ``migration``, ``normal``. - - ``role``: The role of the switch in the hosting fabric, e.g. - ``spine``, ``leaf``, ``border_gateway``, etc. - - ``serial_number``: The serial number of the switch. + + - `fabric_name`: The name of the switch's hosting fabric. + - `fabric_freeze_mode`: The current `freezeMode` state of the switch's + hosting fabric. If `freeze_mode` is True, configuration changes cannot + be made to the fabric or the switches within the fabric. + - `fabric_read_only`: The current `IS_READ_ONLY` state of the switch's + hosting fabric. If `fabric_read_only` is True, configuration changes cannot + be made to the fabric or the switches within the fabric. + - `mode`: The current maintenance mode of the switch. + Possible values include: , `inconsistent`, `maintenance`, + `migration`, `normal`. + - `role`: The role of the switch in the hosting fabric, e.g. + `spine`, `leaf`, `border_gateway`, etc. + - `serial_number`: The serial number of the switch. ```json { "192.169.1.2": { - fabric_deployment_disabled: true - fabric_freeze_mode: true, - fabric_name: "MyFabric", - fabric_read_only: true - mode: "maintenance", - role: "spine", - serial_number: "FCI1234567" + "fabric_deployment_disabled": true, + "fabric_freeze_mode": true, + "fabric_name": "MyFabric", + "fabric_read_only": true, + "mode": "maintenance", + "role": "spine", + "serial_number": "FCI1234567" }, "192.169.1.3": { - fabric_deployment_disabled: false - fabric_freeze_mode: false, - fabric_name: "YourFabric", - fabric_read_only: false - mode: "normal", - role: "leaf", - serial_number: "FCH2345678" + "fabric_deployment_disabled": false, + "fabric_freeze_mode": false, + "fabric_name": "YourFabric", + "fabric_read_only": false, + "mode": "normal", + "role": "leaf", + "serial_number": "FCH2345678" } } ``` @@ -917,9 +1057,7 @@ def get_have(self): instance = MaintenanceModeInfo(self.params) instance.rest_send = self.rest_send instance.results = self.results - instance.config = [ - item["ip_address"] for item in self.config.get("switches", {}) - ] + instance.config = [item["ip_address"] for item in self.config.get("switches", {})] instance.refresh() except (TypeError, ValueError) as error: msg = f"{self.class_name}.{method_name}: " @@ -930,14 +1068,19 @@ def get_have(self): def fabric_deployment_disabled(self) -> None: """ - ### Summary + # Summary + Handle the following cases: - - switch migration mode is ``migration`` - - fabric is in read-only mode (IS_READ_ONLY is True) - - fabric is in freeze mode (Deployment Disable) - ### Raises - - ``ValueError`` if any of the above cases are true + - switch migration mode is `migration` + - fabric is in read-only mode (IS_READ_ONLY is True) + - fabric is in freeze mode (Deployment Disable) + + ## Raises + + ### ValueError + + - any of the above cases are true """ method_name = inspect.stack()[0][3] for ip_address, value in self.have.items(): @@ -1001,13 +1144,18 @@ def fabric_deployment_disabled(self) -> None: def get_need(self): """ - ### Summary + # Summary + Build self.need for merged state. - ### Raises - - ``ValueError`` if the switch is not found on the controller. + ## Raises + + ### ValueError + + - the switch is not found on the controller + + ## self.need structure - ### self.need structure ```json [ { @@ -1015,7 +1163,7 @@ def get_need(self): "fabric_name": "MyFabric", "ip_address": "172.22.150.2", "mode": "maintenance", - "serial_number": "FCI1234567" + "serial_number": "FCI1234567", "wait_for_mode_change": true }, { @@ -1023,10 +1171,11 @@ def get_need(self): "fabric_name": "YourFabric", "ip_address": "172.22.150.3", "mode": "normal", - "serial_number": "HMD2345678" + "serial_number": "HMD2345678", "wait_for_mode_change": true } ] + ``` """ method_name = inspect.stack()[0][3] self.need = [] @@ -1051,15 +1200,18 @@ def get_need(self): def commit(self): """ - ### Summary + # Summary + Commit the merged state request - ### Raises - - ``ValueError`` if: - - ``rest_send`` is not set. - - ``get_want()`` raises ``ValueError`` - - ``get_have()`` raises ``ValueError`` - - ``send_need()`` raises ``ValueError`` + ## Raises + + ### ValueError + + - `rest_send` is not set + - `get_want()` raises `ValueError` + - `get_have()` raises `ValueError` + - `send_need()` raises `ValueError` """ method_name = inspect.stack()[0][3] msg = f"{self.class_name}.{method_name}: entered" @@ -1100,13 +1252,19 @@ def commit(self): def send_need(self) -> None: """ - ### Summary + # Summary + Build and send the payload to modify maintenance mode. - ### Raises - - ``ValueError`` if MaintenanceMode() raises either - ``TypeError`` or ``ValueError`` + ## Raises + + ### ValueError + + - MaintenanceMode() raises `ValueError` + ### TypeError + + - MaintenanceMode() raises `TypeError` """ method_name = inspect.stack()[0][3] # pylint: disable=unused-variable @@ -1127,18 +1285,38 @@ def send_need(self) -> None: class Query(Common): """ + # Summary + Handle query state - ### Raises - - ``ValueError`` if Common().__init__() raises ``ValueError`` - - ``ValueError`` if get_want() raises ``ValueError`` - - ``ValueError`` if get_have() raises ``ValueError`` + ## Raises + + ### ValueError + + - Common().__init__() raises `ValueError` + - get_want() raises `ValueError` + - get_have() raises `ValueError` + + ### TypeError + + - Common().__init__() raises `TypeError` """ def __init__(self, params): """ - ### Raises - - ``ValueError`` if Common().__init__() raises ``ValueError`` + # Summary + + Initialize Query instance + + ## Raises + + ### ValueError + + - Common().__init__() raises `ValueError` + + ### TypeError + + - Common().__init__() raises `TypeError` """ self.class_name = self.__class__.__name__ method_name = inspect.stack()[0][3] @@ -1161,48 +1339,58 @@ def __init__(self, params): def get_have(self): """ - ### Summary + # Summary + Build self.have, a dict containing the current mode of all switches. - ### Raises - - ``ValueError`` if MaintenanceModeInfo() raises ``ValueError`` + ## Raises + + ### ValueError + + - MaintenanceModeInfo() raises `ValueError` + + ### TypeError + + - MaintenanceModeInfo() raises `TypeError` + + ## self.have structure - ### self.have structure Have is a dict, keyed on switch_ip, where each element is a dict with the following structure: - - ``fabric_name``: The name of the switch's hosting fabric. - - ``fabric_freeze_mode``: The current ``freezeMode`` state of the switch's - hosting fabric. If ``freeze_mode`` is True, configuration changes cannot - be made to the fabric or the switches within the fabric. - - ``fabric_read_only``: The current ``IS_READ_ONLY`` state of the switch's - hosting fabric. If ``fabric_read_only`` is True, configuration changes cannot - be made to the fabric or the switches within the fabric. - - ``mode``: The current maintenance mode of the switch. - Possible values include: , ``inconsistent``, ``maintenance``, - ``migration``, ``normal``. - - ``role``: The role of the switch in the hosting fabric, e.g. - ``spine``, ``leaf``, ``border_gateway``, etc. - - ``serial_number``: The serial number of the switch. + + - `fabric_name`: The name of the switch's hosting fabric. + - `fabric_freeze_mode`: The current `freezeMode` state of the switch's + hosting fabric. If `freeze_mode` is True, configuration changes cannot + be made to the fabric or the switches within the fabric. + - `fabric_read_only`: The current `IS_READ_ONLY` state of the switch's + hosting fabric. If `fabric_read_only` is True, configuration changes cannot + be made to the fabric or the switches within the fabric. + - `mode`: The current maintenance mode of the switch. + Possible values include: , `inconsistent`, `maintenance`, + `migration`, `normal`. + - `role`: The role of the switch in the hosting fabric, e.g. + `spine`, `leaf`, `border_gateway`, etc. + - `serial_number`: The serial number of the switch. ```json { "192.169.1.2": { - fabric_deployment_disabled: true - fabric_freeze_mode: true, - fabric_name: "MyFabric", - fabric_read_only: true - mode: "maintenance", - role: "spine", - serial_number: "FCI1234567" + "fabric_deployment_disabled": true, + "fabric_freeze_mode": true, + "fabric_name": "MyFabric", + "fabric_read_only": true, + "mode": "maintenance", + "role": "spine", + "serial_number": "FCI1234567" }, "192.169.1.3": { - fabric_deployment_disabled: false - fabric_freeze_mode: false, - fabric_name: "YourFabric", - fabric_read_only: false - mode: "normal", - role: "leaf", - serial_number: "FCH2345678" + "fabric_deployment_disabled": false, + "fabric_freeze_mode": false, + "fabric_name": "YourFabric", + "fabric_read_only": false, + "mode": "normal", + "role": "leaf", + "serial_number": "FCH2345678" } } ``` @@ -1212,9 +1400,7 @@ def get_have(self): try: self.maintenance_mode_info.rest_send = self.rest_send self.maintenance_mode_info.results = self.results - self.maintenance_mode_info.config = [ - item["ip_address"] for item in self.config.get("switches", {}) - ] + self.maintenance_mode_info.config = [item["ip_address"] for item in self.config.get("switches", {})] self.maintenance_mode_info.refresh() except (TypeError, ValueError) as error: msg = f"{self.class_name}.{method_name}: " @@ -1225,15 +1411,18 @@ def get_have(self): def commit(self) -> None: """ - ### Summary + # Summary + Query the switches in self.want that exist on the controller and update ``self.results`` with the query results. - ### Raises - - ``ValueError`` if: - - ``rest_send`` is not set. - - ``get_want()`` raises ``ValueError`` - - ``get_have()`` raises ``ValueError`` + ## Raises + + ### ValueError + + - `rest_send` is not set + - `get_want()` raises `ValueError` + - `get_have()` raises `ValueError` """ method_name = inspect.stack()[0][3] msg = f"{self.class_name}.{method_name}: entered" @@ -1292,9 +1481,7 @@ def main(): "type": "str", } - ansible_module = AnsibleModule( - argument_spec=argument_spec, supports_check_mode=True - ) + ansible_module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) params = copy.deepcopy(ansible_module.params) params["check_mode"] = ansible_module.check_mode diff --git a/tests/unit/module_utils/common/test_maintenance_mode.py b/tests/unit/module_utils/common/test_maintenance_mode.py index c18cd0793..55ebcfdb8 100644 --- a/tests/unit/module_utils/common/test_maintenance_mode.py +++ b/tests/unit/module_utils/common/test_maintenance_mode.py @@ -34,24 +34,24 @@ import pytest from ansible_collections.cisco.dcnm.plugins.module_utils.common.api.v1.lan_fabric.rest.control.fabrics.fabrics import ( - EpMaintenanceModeDisable, EpMaintenanceModeEnable) -from ansible_collections.cisco.dcnm.plugins.module_utils.common.conversion import \ - ConversionUtils -from ansible_collections.cisco.dcnm.plugins.module_utils.common.exceptions import \ - ControllerResponseError -from ansible_collections.cisco.dcnm.plugins.module_utils.common.maintenance_mode import \ - MaintenanceMode -from ansible_collections.cisco.dcnm.plugins.module_utils.common.response_handler import \ - ResponseHandler -from ansible_collections.cisco.dcnm.plugins.module_utils.common.rest_send_v2 import \ - RestSend -from ansible_collections.cisco.dcnm.plugins.module_utils.common.results import \ - Results -from ansible_collections.cisco.dcnm.plugins.module_utils.common.sender_file import \ - Sender + EpMaintenanceModeDisable, + EpMaintenanceModeEnable, +) +from ansible_collections.cisco.dcnm.plugins.module_utils.common.conversion import ConversionUtils +from ansible_collections.cisco.dcnm.plugins.module_utils.common.exceptions import ControllerResponseError +from ansible_collections.cisco.dcnm.plugins.module_utils.common.maintenance_mode import MaintenanceMode +from ansible_collections.cisco.dcnm.plugins.module_utils.common.response_handler import ResponseHandler +from ansible_collections.cisco.dcnm.plugins.module_utils.common.rest_send_v2 import RestSend +from ansible_collections.cisco.dcnm.plugins.module_utils.common.results import Results +from ansible_collections.cisco.dcnm.plugins.module_utils.common.sender_file import Sender from ansible_collections.cisco.dcnm.tests.unit.module_utils.common.common_utils import ( - ResponseGenerator, does_not_raise, maintenance_mode_fixture, params, - responses_deploy_maintenance_mode, responses_maintenance_mode) + ResponseGenerator, + does_not_raise, + maintenance_mode_fixture, + params, + responses_deploy_maintenance_mode, + responses_maintenance_mode, +) FABRIC_NAME = "VXLAN_Fabric" CONFIG = [ @@ -68,11 +68,16 @@ def test_maintenance_mode_00000(maintenance_mode) -> None: """ - Classes and Methods - - MaintenanceMode - - __init__() + # Summary + + Verify MaintenanceMode class attributes are initialized to expected values. + + ## Classes and Methods + + - MaintenanceMode.__init__() + + ## Test - Test - Class attributes are initialized to expected values - Exception is not raised """ @@ -101,12 +106,17 @@ def test_maintenance_mode_00000(maintenance_mode) -> None: def test_maintenance_mode_00010() -> None: """ - Classes and Methods - - MaintenanceMode - - __init__() + # Summary + + Verify `ValueError` is raised when params is missing check_mode key. - Test - - ``ValueError`` is raised when params is missing check_mode key. + ## Classes and Methods + + - MaintenanceMode.__init__() + + ## Test + + - `ValueError` is raised when params is missing check_mode key """ params = {"state": "merged"} match = r"MaintenanceMode\.__init__:\s+" @@ -117,12 +127,17 @@ def test_maintenance_mode_00010() -> None: def test_maintenance_mode_00020() -> None: """ - Classes and Methods - - MaintenanceMode - - __init__() + # Summary + + Verify `ValueError` is raised when params is missing state key. + + ## Classes and Methods + + - MaintenanceMode.__init__() - Test - - ``ValueError`` is raised when params is missing state key. + ## Test + + - `ValueError` is raised when params is missing state key """ params = {"check_mode": False} match = r"MaintenanceMode\.__init__:\s+" @@ -133,27 +148,29 @@ def test_maintenance_mode_00020() -> None: def test_maintenance_mode_00030(maintenance_mode) -> None: """ - Classes and Methods - - MaintenanceMode() - - __init__() - - verify_commit_parameters() - - commit() - - Summary - - Verify MaintenanceMode().commit() raises ``ValueError`` when - ``config`` is not set. - - Code Flow - Setup - - MaintenanceMode() is instantiated - - Other required attributes are set - - Code Flow - Test - - ``MaintenanceMode().commit()`` is called without having first set - ``MaintenanceMode().config`` - - Expected Result - - ``ValueError`` is raised - - Exception message matches expected + # Summary + + Verify MaintenanceMode().commit() raises `ValueError` when `config` is not set. + + ## Classes and Methods + + - MaintenanceMode.__init__() + - MaintenanceMode.verify_commit_parameters() + - MaintenanceMode.commit() + + ## Code Flow - Setup + + - MaintenanceMode() is instantiated + - Other required attributes are set + + ## Code Flow - Test + + - MaintenanceMode().commit() is called without having first set MaintenanceMode().config + + ## Expected Result + + - `ValueError` is raised + - Exception message matches expected """ with does_not_raise(): instance = maintenance_mode @@ -169,27 +186,29 @@ def test_maintenance_mode_00030(maintenance_mode) -> None: def test_maintenance_mode_00040(maintenance_mode) -> None: """ - Classes and Methods - - MaintenanceMode() - - __init__() - - verify_commit_parameters() - - commit() - - Summary - - Verify MaintenanceMode().commit() raises ``ValueError`` - when ``rest_send`` is not set. - - Code Flow - Setup - - MaintenanceMode() is instantiated - - Other required attributes are set - - Code Flow - Test - - MaintenanceMode().commit() is called without having - first set MaintenanceMode().rest_send - - Expected Result - - ``ValueError`` is raised - - Exception message matches expected + # Summary + + Verify MaintenanceMode().commit() raises `ValueError` when `rest_send` is not set. + + ## Classes and Methods + + - MaintenanceMode.__init__() + - MaintenanceMode.verify_commit_parameters() + - MaintenanceMode.commit() + + ## Code Flow - Setup + + - MaintenanceMode() is instantiated + - Other required attributes are set + + ## Code Flow - Test + + - MaintenanceMode().commit() is called without having first set MaintenanceMode().rest_send + + ## Expected Result + + - `ValueError` is raised + - Exception message matches expected """ with does_not_raise(): instance = maintenance_mode @@ -205,27 +224,29 @@ def test_maintenance_mode_00040(maintenance_mode) -> None: def test_maintenance_mode_00050(maintenance_mode) -> None: """ - Classes and Methods - - MaintenanceMode() - - __init__() - - verify_commit_parameters() - - commit() - - Summary - - Verify MaintenanceMode().commit() raises ``ValueError`` - when ``MaintenanceMode().results`` is not set. - - Code Flow - Setup - - MaintenanceMode() is instantiated - - Other required attributes are set - - Code Flow - Test - - MaintenanceMode().commit() is called without having - first set MaintenanceMode().results - - Expected Result - - ``ValueError`` is raised - - Exception message matches expected + # Summary + + Verify MaintenanceMode().commit() raises `ValueError` when `results` is not set. + + ## Classes and Methods + + - MaintenanceMode.__init__() + - MaintenanceMode.verify_commit_parameters() + - MaintenanceMode.commit() + + ## Code Flow - Setup + + - MaintenanceMode() is instantiated + - Other required attributes are set + + ## Code Flow - Test + + - MaintenanceMode().commit() is called without having first set MaintenanceMode().results + + ## Expected Result + + - `ValueError` is raised + - Exception message matches expected """ with does_not_raise(): instance = maintenance_mode @@ -247,34 +268,39 @@ def test_maintenance_mode_00050(maintenance_mode) -> None: (ValueError, ValueError, "Bad value"), ], ) -def test_maintenance_mode_00200( - monkeypatch, maintenance_mode, mock_exception, expected_exception, mock_message -) -> None: +def test_maintenance_mode_00200(monkeypatch, maintenance_mode, mock_exception, expected_exception, mock_message) -> None: """ - Classes and Methods - - MaintenanceMode() - - __init__() - - commit() - - Summary - - Verify MaintenanceMode().commit() raises ``ValueError`` when - ``MaintenanceMode().change_system_mode`` raises any of: - - ``ControllerResponseError`` - - ``TypeError`` - - ``ValueError`` - - - Code Flow - Setup - - MaintenanceMode() is instantiated - - Required attributes are set - - change_system_mode() is mocked to raise each of the above exceptions - - Code Flow - Test - - MaintenanceMode().commit() is called for each exception - - Expected Result - - ``ValueError`` is raised - - Exception message matches expected + # Summary + + Verify MaintenanceMode().commit() raises `ValueError` when change_system_mode raises exceptions. + + ## Classes and Methods + + - MaintenanceMode.__init__() + - MaintenanceMode.commit() + + ## Test + + Verify MaintenanceMode().commit() raises `ValueError` when MaintenanceMode().change_system_mode raises any of: + + - `ControllerResponseError` + - `TypeError` + - `ValueError` + + ## Code Flow - Setup + + - MaintenanceMode() is instantiated + - Required attributes are set + - change_system_mode() is mocked to raise each of the above exceptions + + ## Code Flow - Test + + - MaintenanceMode().commit() is called for each exception + + ## Expected Result + + - `ValueError` is raised + - Exception message matches expected """ def mock_change_system_mode(*args, **kwargs): @@ -298,34 +324,39 @@ def mock_change_system_mode(*args, **kwargs): (ValueError, ValueError, "Bad value"), ], ) -def test_maintenance_mode_00210( - monkeypatch, maintenance_mode, mock_exception, expected_exception, mock_message -) -> None: +def test_maintenance_mode_00210(monkeypatch, maintenance_mode, mock_exception, expected_exception, mock_message) -> None: """ - Classes and Methods - - MaintenanceMode() - - __init__() - - commit() - - Summary - - Verify MaintenanceMode().commit() raises ``ValueError`` when - ``MaintenanceMode().deploy_switches`` raises any of: - - ``ControllerResponseError`` - - ``ValueError`` - - - Code Flow - Setup - - MaintenanceMode() is instantiated - - Required attributes are set - - change_system_mode() is mocked to do nothing - - deploy_switches() is mocked to raise each of the above exceptions - - Code Flow - Test - - MaintenanceMode().commit() is called for each exception - - Expected Result - - ``ValueError`` is raised - - Exception message matches expected + # Summary + + Verify MaintenanceMode().commit() raises `ValueError` when deploy_switches raises exceptions. + + ## Classes and Methods + + - MaintenanceMode.__init__() + - MaintenanceMode.commit() + + ## Test + + Verify MaintenanceMode().commit() raises `ValueError` when MaintenanceMode().deploy_switches raises any of: + + - `ControllerResponseError` + - `ValueError` + + ## Code Flow - Setup + + - MaintenanceMode() is instantiated + - Required attributes are set + - change_system_mode() is mocked to do nothing + - deploy_switches() is mocked to raise each of the above exceptions + + ## Code Flow - Test + + - MaintenanceMode().commit() is called for each exception + + ## Expected Result + + - `ValueError` is raised + - Exception message matches expected """ def mock_change_system_mode(*args, **kwargs): @@ -357,34 +388,41 @@ def mock_deploy_switches(*args, **kwargs): ) def test_maintenance_mode_00220(maintenance_mode, mode, deploy) -> None: """ - Classes and Methods - - MaintenanceMode() - - __init__() - - commit() - - change_system_mode() - - deploy_switches() - - Summary - - Verify commit() success case: - - RETURN_CODE is 200. - - Controller response contains expected structure and values. - - Code Flow - Setup - - MaintenanceMode() is instantiated - - Sender() is mocked to return expected responses - - Required attributes are set - - MaintenanceMode().commit() is called - - responses_MaintenanceMode contains a dict with: - - RETURN_CODE == 200 - - DATA == {"status": "Success"} - - Code Flow - Test - - MaintenanceMode().commit() is called - - Expected Result - - Exception is not raised - - instance.response_data returns expected data - - MaintenanceMode()._properties are updated + # Summary + + Verify commit() success case with RETURN_CODE 200. + + ## Classes and Methods + + - MaintenanceMode.__init__() + - MaintenanceMode.commit() + - MaintenanceMode.change_system_mode() + - MaintenanceMode.deploy_switches() + + ## Test + + - RETURN_CODE is 200 + - Controller response contains expected structure and values + + ## Code Flow - Setup + + - MaintenanceMode() is instantiated + - Sender() is mocked to return expected responses + - Required attributes are set + - MaintenanceMode().commit() is called + - responses_MaintenanceMode contains a dict with: + - RETURN_CODE == 200 + - DATA == {"status": "Success"} + + ## Code Flow - Test + + - MaintenanceMode().commit() is called + + ## Expected Result + + - Exception is not raised + - instance.response_data returns expected data + - MaintenanceMode()._properties are updated """ method_name = inspect.stack()[0][3] key = f"{method_name}a" @@ -438,10 +476,7 @@ def responses(): assert instance.results.diff[1].get("deploy_maintenance_mode", None) is True assert instance.results.diff[1].get("sequence_number", None) == 2 - assert ( - instance.results.metadata[1].get("action", None) - == "deploy_maintenance_mode" - ) + assert instance.results.metadata[1].get("action", None) == "deploy_maintenance_mode" assert instance.results.metadata[1].get("sequence_number", None) == 2 assert instance.results.metadata[1].get("state", None) == "merged" @@ -464,38 +499,44 @@ def responses(): ) def test_maintenance_mode_00230(maintenance_mode, mode) -> None: """ - Classes and Methods - - MaintenanceMode() - - __init__() - - commit() - - change_system_mode() - - deploy_switches() - - Summary - - Verify commit() unsuccessful case: - - RETURN_CODE == 500. - - commit raises ``ValueError`` when change_system_mode() raises - ``ControllerResponseError``. - - Controller response contains expected structure and values. - - Code Flow - Setup - - MaintenanceMode() is instantiated - - Sender() is mocked to return expected responses - - Required attributes are set - - MaintenanceMode().commit() is called - - responses_MaintenanceMode contains a dict with: - - RETURN_CODE == 500 - - DATA == {"status": "Failure"} - - Code Flow - Test - - ``MaintenanceMode().commit()`` is called - - ``change_system_mode()`` raises ``ControllerResponseError`` - - ``commit()`` raises ``ValueError`` - - Expected Result - - ``commit()`` raises ``ValueError`` - - instance.response_data returns expected data - - MaintenanceMode()._properties are updated + # Summary + + Verify commit() unsuccessful case with RETURN_CODE 500. + + ## Classes and Methods + + - MaintenanceMode.__init__() + - MaintenanceMode.commit() + - MaintenanceMode.change_system_mode() + - MaintenanceMode.deploy_switches() + + ## Test + + - RETURN_CODE == 500 + - commit raises `ValueError` when change_system_mode() raises `ControllerResponseError` + - Controller response contains expected structure and values + + ## Code Flow - Setup + + - MaintenanceMode() is instantiated + - Sender() is mocked to return expected responses + - Required attributes are set + - MaintenanceMode().commit() is called + - responses_MaintenanceMode contains a dict with: + - RETURN_CODE == 500 + - DATA == {"status": "Failure"} + + ## Code Flow - Test + + - MaintenanceMode().commit() is called + - change_system_mode() raises `ControllerResponseError` + - commit() raises `ValueError` + + ## Expected Result + + - commit() raises `ValueError` + - instance.response_data returns expected data + - MaintenanceMode()._properties are updated """ method_name = inspect.stack()[0][3] key = f"{method_name}a" @@ -550,30 +591,35 @@ def responses(): def test_maintenance_mode_00300(maintenance_mode) -> None: """ - Classes and Methods - - MaintenanceMode() - - __init__() - - verify_config_parameters() - - config.setter - - Summary - - Verify MaintenanceMode().verify_config_parameters() raises - - ``TypeError`` if: - - value is not a list - - Verify MaintenanceMode().config.setter re-raises: - - ``TypeError`` as ``ValueError`` - - Code Flow - Setup - - MaintenanceMode() is instantiated - - config is set to a non-list value - - Code Flow - Test - - MaintenanceMode().config.setter is accessed with non-list - - Expected Result - - verify_config_parameters() raises ``TypeError``. - - config.setter re-raises as ``ValueError``. - - Exception message matches expected. + # Summary + + Verify MaintenanceMode().verify_config_parameters() raises `TypeError` if value is not a list. + + ## Classes and Methods + + - MaintenanceMode.__init__() + - MaintenanceMode.verify_config_parameters() + - MaintenanceMode.config.setter + + ## Test + + - Verify MaintenanceMode().verify_config_parameters() raises `TypeError` if value is not a list + - Verify MaintenanceMode().config.setter re-raises `TypeError` as `ValueError` + + ## Code Flow - Setup + + - MaintenanceMode() is instantiated + - config is set to a non-list value + + ## Code Flow - Test + + - MaintenanceMode().config.setter is accessed with non-list + + ## Expected Result + + - verify_config_parameters() raises `TypeError` + - config.setter re-raises as `ValueError` + - Exception message matches expected """ with does_not_raise(): instance = maintenance_mode @@ -597,33 +643,39 @@ def test_maintenance_mode_00300(maintenance_mode) -> None: ) def test_maintenance_mode_00310(maintenance_mode, remove_param) -> None: """ - Classes and Methods - - MaintenanceMode() - - __init__() - - verify_config_parameters() - - config.setter - - Summary - - Verify MaintenanceMode().verify_config_parameters() raises - - ``ValueError`` if: - - deploy is missing from config - - fabric_name is missing from config - - ip_address is missing from config - - mode is missing from config - - serial_number is missing from config - - wait_for_mode_change is missing from config - - - Code Flow - Setup - - MaintenanceMode() is instantiated - - Code Flow - Test - - MaintenanceMode().config is set to a dict with all of the above - keys present, except that each key, in turn, is removed. - - Expected Result - - ``ValueError`` is raised - - Exception message matches expected + # Summary + + Verify MaintenanceMode().verify_config_parameters() raises `ValueError` for missing config keys. + + ## Classes and Methods + + - MaintenanceMode.__init__() + - MaintenanceMode.verify_config_parameters() + - MaintenanceMode.config.setter + + ## Test + + Verify MaintenanceMode().verify_config_parameters() raises `ValueError` if: + + - deploy is missing from config + - fabric_name is missing from config + - ip_address is missing from config + - mode is missing from config + - serial_number is missing from config + - wait_for_mode_change is missing from config + + ## Code Flow - Setup + + - MaintenanceMode() is instantiated + + ## Code Flow - Test + + - MaintenanceMode().config is set to a dict with all of the above keys present, except that each key, in turn, is removed + + ## Expected Result + + - `ValueError` is raised + - Exception message matches expected """ with does_not_raise(): @@ -650,29 +702,34 @@ def test_maintenance_mode_00310(maintenance_mode, remove_param) -> None: ) def test_maintenance_mode_00400(maintenance_mode, param, raises) -> None: """ - Classes and Methods - - MaintenanceMode() - - __init__() - - verify_config_parameters() - - config.setter - - Summary - - Verify MaintenanceMode().verify_config_parameters() re-raises - - ``ValueError`` if: - - ``deploy`` raises ``TypeError`` - - Code Flow - Setup - - MaintenanceMode() is instantiated - - Code Flow - Test - - MaintenanceMode().config is set to a dict. - - The dict is updated with deploy set to valid and invalid - values of ``deploy`` - - Expected Result - - ``ValueError`` is raised when deploy is not a boolean - - Exception message matches expected - - Exception is not raised when deploy is a boolean + # Summary + + Verify MaintenanceMode().verify_config_parameters() validates deploy parameter type. + + ## Classes and Methods + + - MaintenanceMode.__init__() + - MaintenanceMode.verify_config_parameters() + - MaintenanceMode.config.setter + + ## Test + + - Verify MaintenanceMode().verify_config_parameters() re-raises `ValueError` if `deploy` raises `TypeError` + + ## Code Flow - Setup + + - MaintenanceMode() is instantiated + + ## Code Flow - Test + + - MaintenanceMode().config is set to a dict + - The dict is updated with deploy set to valid and invalid values of `deploy` + + ## Expected Result + + - `ValueError` is raised when deploy is not a boolean + - Exception message matches expected + - Exception is not raised when deploy is a boolean """ with does_not_raise(): @@ -703,30 +760,34 @@ def test_maintenance_mode_00400(maintenance_mode, param, raises) -> None: ) def test_maintenance_mode_00500(maintenance_mode, param, raises) -> None: """ - Classes and Methods - - MaintenanceMode() - - __init__() - - verify_config_parameters() - - config.setter - - Summary - - Verify MaintenanceMode().verify_config_parameters() re-raises - - ``ValueError`` if: - - ``fabric_name`` raises ``ValueError`` due to being an - invalid value. - - Code Flow - Setup - - MaintenanceMode() is instantiated - - Code Flow - Test - - MaintenanceMode().config is set to a dict. - - The dict is updated with fabric_name set to valid and invalid - values of ``fabric_name`` - - Expected Result - - ``ValueError`` is raised when fabric_name is not a valid value - - Exception message matches expected - - Exception is not raised when fabric_name is a valid value + # Summary + + Verify MaintenanceMode().verify_config_parameters() validates fabric_name parameter. + + ## Classes and Methods + + - MaintenanceMode.__init__() + - MaintenanceMode.verify_config_parameters() + - MaintenanceMode.config.setter + + ## Test + + - Verify MaintenanceMode().verify_config_parameters() re-raises `ValueError` if `fabric_name` raises `ValueError` due to being an invalid value + + ## Code Flow - Setup + + - MaintenanceMode() is instantiated + + ## Code Flow - Test + + - MaintenanceMode().config is set to a dict + - The dict is updated with fabric_name set to valid and invalid values of `fabric_name` + + ## Expected Result + + - `ValueError` is raised when fabric_name is not a valid value + - Exception message matches expected + - Exception is not raised when fabric_name is a valid value """ with does_not_raise(): @@ -758,30 +819,34 @@ def test_maintenance_mode_00500(maintenance_mode, param, raises) -> None: ) def test_maintenance_mode_00600(maintenance_mode, param, raises) -> None: """ - Classes and Methods - - MaintenanceMode() - - __init__() - - verify_config_parameters() - - config.setter - - Summary - - Verify MaintenanceMode().verify_config_parameters() re-raises - - ``ValueError`` if: - - ``mode`` raises ``ValueError`` due to being an - invalid value. - - Code Flow - Setup - - MaintenanceMode() is instantiated - - Code Flow - Test - - MaintenanceMode().config is set to a dict. - - The dict is updated with mode set to valid and invalid - values of ``mode`` - - Expected Result - - ``ValueError`` is raised when mode is not a valid value - - Exception message matches expected - - Exception is not raised when mode is a valid value + # Summary + + Verify MaintenanceMode().verify_config_parameters() validates mode parameter. + + ## Classes and Methods + + - MaintenanceMode.__init__() + - MaintenanceMode.verify_config_parameters() + - MaintenanceMode.config.setter + + ## Test + + - Verify MaintenanceMode().verify_config_parameters() re-raises `ValueError` if `mode` raises `ValueError` due to being an invalid value + + ## Code Flow - Setup + + - MaintenanceMode() is instantiated + + ## Code Flow - Test + + - MaintenanceMode().config is set to a dict + - The dict is updated with mode set to valid and invalid values of `mode` + + ## Expected Result + + - `ValueError` is raised when mode is not a valid value + - Exception message matches expected + - Exception is not raised when mode is a valid value """ with does_not_raise(): @@ -812,29 +877,34 @@ def test_maintenance_mode_00600(maintenance_mode, param, raises) -> None: ) def test_maintenance_mode_00700(maintenance_mode, param, raises) -> None: """ - Classes and Methods - - MaintenanceMode() - - __init__() - - verify_config_parameters() - - config.setter - - Summary - - Verify MaintenanceMode().verify_config_parameters() re-raises - - ``ValueError`` if: - - ``wait_for_mode_change`` raises ``TypeError`` - - Code Flow - Setup - - MaintenanceMode() is instantiated - - Code Flow - Test - - MaintenanceMode().config is set to a dict. - - The dict is updated with wait_for_mode_change set to valid and invalid - values of ``wait_for_mode_change`` - - Expected Result - - ``ValueError`` is raised when wait_for_mode_change is not a boolean - - Exception message matches expected - - Exception is not raised when wait_for_mode_change is a boolean + # Summary + + Verify MaintenanceMode().verify_config_parameters() validates wait_for_mode_change parameter type. + + ## Classes and Methods + + - MaintenanceMode.__init__() + - MaintenanceMode.verify_config_parameters() + - MaintenanceMode.config.setter + + ## Test + + - Verify MaintenanceMode().verify_config_parameters() re-raises `ValueError` if `wait_for_mode_change` raises `TypeError` + + ## Code Flow - Setup + + - MaintenanceMode() is instantiated + + ## Code Flow - Test + + - MaintenanceMode().config is set to a dict + - The dict is updated with wait_for_mode_change set to valid and invalid values of `wait_for_mode_change` + + ## Expected Result + + - `ValueError` is raised when wait_for_mode_change is not a boolean + - Exception message matches expected + - Exception is not raised when wait_for_mode_change is a boolean """ with does_not_raise(): @@ -871,32 +941,37 @@ def test_maintenance_mode_00800( mock_message, ) -> None: """ - Classes and Methods - - MaintenanceMode() - - __init__() - - commit() - - Summary - - Verify MaintenanceMode().change_system_mode() raises ``ValueError`` - when ``EpMaintenanceModeEnable`` or ``EpMaintenanceModeDisable`` raise - any of: - - ``TypeError`` - - ``ValueError`` - - Code Flow - Setup - - MaintenanceMode() is instantiated - - Required attributes are set - - EpMaintenanceModeEnable() is mocked to raise each - of the above exceptions - - EpMaintenanceModeDisable() is mocked to raise each - of the above exceptions - - Code Flow - Test - - MaintenanceMode().commit() is called for each exception - - Expected Result - - ``ValueError`` is raised. - - Exception message matches expected. + # Summary + + Verify MaintenanceMode().change_system_mode() raises `ValueError` when endpoint classes raise exceptions. + + ## Classes and Methods + + - MaintenanceMode.__init__() + - MaintenanceMode.commit() + + ## Test + + Verify MaintenanceMode().change_system_mode() raises `ValueError` when `EpMaintenanceModeEnable` or `EpMaintenanceModeDisable` raise any of: + + - `TypeError` + - `ValueError` + + ## Code Flow - Setup + + - MaintenanceMode() is instantiated + - Required attributes are set + - EpMaintenanceModeEnable() is mocked to raise each of the above exceptions + - EpMaintenanceModeDisable() is mocked to raise each of the above exceptions + + ## Code Flow - Test + + - MaintenanceMode().commit() is called for each exception + + ## Expected Result + + - `ValueError` is raised + - Exception message matches expected """ class MockEndpoint: @@ -960,29 +1035,36 @@ def test_maintenance_mode_00900( mock_message, ) -> None: """ - Classes and Methods - - MaintenanceMode() - - __init__() - - commit() + # Summary + + Verify MaintenanceMode().deploy_switches() raises `ValueError` when EpMaintenanceModeDeploy raises exceptions. - Summary - - Verify MaintenanceMode().deploy_switches() raises ``ValueError`` - when ``EpMaintenanceModeDeploy`` raises any of: - - ``TypeError`` - - ``ValueError`` + ## Classes and Methods + - MaintenanceMode.__init__() + - MaintenanceMode.commit() - Code Flow - Setup - - MaintenanceMode() is instantiated - - Required attributes are set - - EpMaintenanceModeDeploy() is mocked to raise each of the above exceptions + ## Test - Code Flow - Test - - MaintenanceMode().commit() is called for each exception + Verify MaintenanceMode().deploy_switches() raises `ValueError` when `EpMaintenanceModeDeploy` raises any of: - Expected Result - - ``TypeError`` and ``ValueError`` are raised. - - Exception message matches expected. + - `TypeError` + - `ValueError` + + ## Code Flow - Setup + + - MaintenanceMode() is instantiated + - Required attributes are set + - EpMaintenanceModeDeploy() is mocked to raise each of the above exceptions + + ## Code Flow - Test + + - MaintenanceMode().commit() is called for each exception + + ## Expected Result + + - `TypeError` and `ValueError` are raised + - Exception message matches expected """ class MockEndpoint: @@ -1063,35 +1145,38 @@ def responses(): (ValueError, ValueError, r"Converted ValueError to ValueError"), ], ) -def test_maintenance_mode_01000( - maintenance_mode, mock_exception, expected_exception, mock_message -) -> None: +def test_maintenance_mode_01000(maintenance_mode, mock_exception, expected_exception, mock_message) -> None: """ - Classes and Methods - - MaintenanceMode() - - __init__() - - change_system_mode() + # Summary + + Verify MaintenanceMode().change_system_mode() raises `ValueError` when Results() raises exceptions. + + ## Classes and Methods + + - MaintenanceMode.__init__() + - MaintenanceMode.change_system_mode() + + ## Test + + Verify MaintenanceMode().change_system_mode() raises `ValueError` when MaintenanceMode().results() raises any of: + - `TypeError` + - `ValueError` - Summary - - Verify MaintenanceMode().change_system_mode() raises ``ValueError`` - when ``MaintenanceMode().results()`` raises any of: - - ``TypeError`` - - ``ValueError`` + ## Code Flow - Setup + - MaintenanceMode() is instantiated + - Required attributes are set + - Results().response_current.setter is mocked to raise each of the above exceptions - Code Flow - Setup - - MaintenanceMode() is instantiated - - Required attributes are set - - Results().response_current.setter is mocked to raise each of the above - exceptions + ## Code Flow - Test - Code Flow - Test - - MaintenanceMode().commit() is called for each exception + - MaintenanceMode().commit() is called for each exception - Expected Result - - ``ValueError`` is raised - - Exception message matches expected + ## Expected Result + + - `ValueError` is raised + - Exception message matches expected """ class MockResults: @@ -1139,29 +1224,35 @@ def responses(): def test_maintenance_mode_01100(monkeypatch, maintenance_mode) -> None: """ - Classes and Methods - - MaintenanceMode() - - __init__() - - commit() - - Summary - - Verify MaintenanceMode().commit() raises ``ValueError`` when - ``MaintenanceMode().deploy_switches()`` raises - ``ControllerResponseError`` when the RETURN_CODE in the - response is not 200. - - Code Flow - Setup - - MaintenanceMode() is instantiated - - Required attributes are set - - Code Flow - Test - - MaintenanceMode().commit() is called with simulated responses: - - 200 response for ``change_system_mode()`` - - 500 response ``deploy_switches()`` - - Expected Result - - ``ValueError``is raised. - - Exception message matches expected. + # Summary + + Verify MaintenanceMode().commit() raises `ValueError` when deploy_switches() gets non-200 response. + + ## Classes and Methods + + - MaintenanceMode.__init__() + - MaintenanceMode.commit() + + ## Test + + - Verify MaintenanceMode().commit() raises `ValueError` when MaintenanceMode().deploy_switches() raises `ControllerResponseError` + when the RETURN_CODE in the response is not 200 + + ## Code Flow - Setup + + - MaintenanceMode() is instantiated + - Required attributes are set + + ## Code Flow - Test + + - MaintenanceMode().commit() is called with simulated responses: + - 200 response for `change_system_mode()` + - 500 response `deploy_switches()` + + ## Expected Result + + - `ValueError` is raised + - Exception message matches expected """ def responses(): diff --git a/tests/unit/module_utils/common/test_maintenance_mode_info.py b/tests/unit/module_utils/common/test_maintenance_mode_info.py index 6d20cc9f3..93ce78cdd 100644 --- a/tests/unit/module_utils/common/test_maintenance_mode_info.py +++ b/tests/unit/module_utils/common/test_maintenance_mode_info.py @@ -32,27 +32,22 @@ import inspect import pytest -from ansible_collections.cisco.dcnm.plugins.module_utils.common.conversion import \ - ConversionUtils -from ansible_collections.cisco.dcnm.plugins.module_utils.common.exceptions import \ - ControllerResponseError -from ansible_collections.cisco.dcnm.plugins.module_utils.common.maintenance_mode_info import \ - MaintenanceModeInfo -from ansible_collections.cisco.dcnm.plugins.module_utils.common.response_handler import \ - ResponseHandler -from ansible_collections.cisco.dcnm.plugins.module_utils.common.rest_send_v2 import \ - RestSend -from ansible_collections.cisco.dcnm.plugins.module_utils.common.results import \ - Results -from ansible_collections.cisco.dcnm.plugins.module_utils.common.sender_file import \ - Sender -from ansible_collections.cisco.dcnm.tests.unit.mocks.mock_fabric_details_by_name import \ - MockFabricDetailsByName -from ansible_collections.cisco.dcnm.tests.unit.mocks.mock_switch_details import \ - MockSwitchDetails +from ansible_collections.cisco.dcnm.plugins.module_utils.common.conversion import ConversionUtils +from ansible_collections.cisco.dcnm.plugins.module_utils.common.exceptions import ControllerResponseError +from ansible_collections.cisco.dcnm.plugins.module_utils.common.maintenance_mode_info import MaintenanceModeInfo +from ansible_collections.cisco.dcnm.plugins.module_utils.common.response_handler import ResponseHandler +from ansible_collections.cisco.dcnm.plugins.module_utils.common.rest_send_v2 import RestSend +from ansible_collections.cisco.dcnm.plugins.module_utils.common.results import Results +from ansible_collections.cisco.dcnm.plugins.module_utils.common.sender_file import Sender +from ansible_collections.cisco.dcnm.tests.unit.mocks.mock_fabric_details_by_name import MockFabricDetailsByName +from ansible_collections.cisco.dcnm.tests.unit.mocks.mock_switch_details import MockSwitchDetails from ansible_collections.cisco.dcnm.tests.unit.module_utils.common.common_utils import ( - ResponseGenerator, does_not_raise, maintenance_mode_info_fixture, - responses_fabric_details_by_name, responses_switch_details) + ResponseGenerator, + does_not_raise, + maintenance_mode_info_fixture, + responses_fabric_details_by_name, + responses_switch_details, +) FABRIC_NAME = "VXLAN_Fabric" CONFIG = ["192.168.1.2"] @@ -61,25 +56,35 @@ def test_maintenance_mode_info_00000(maintenance_mode_info) -> None: """ - ### Classes and Methods - - ``MaintenanceModeInfo()`` - - ``__init__()`` + # Summary + + Verify the `__init__()` method. + + ## Classes and Methods + + - MaintenanceModeInfo.__init__() + + ## Test + + - Class attributes are initialized to expected values. + - Exception is not raised. + + ## Setup - Data + + - None + + ## Setup - Code - ### Summary - - Verify the __init__() method. + - None - ### Setup - Data - - None + ## Trigger - ### Setup - Code - - None + - `MaintenanceModeInfo` is instantiated. - ### Trigger - - ``MaintenanceModeInfo`` is instantiated. + ## Expected Result - ### Expected Result - - Class attributes are initialized to expected values. - - Exception is not raised. + - Class attributes are initialized to expected values. + - Exception is not raised. """ with does_not_raise(): @@ -100,28 +105,39 @@ def test_maintenance_mode_info_00000(maintenance_mode_info) -> None: def test_maintenance_mode_info_00100(maintenance_mode_info) -> None: """ - ### Classes and Methods - - ``MaintenanceModeInfo()`` - - ``verify_refresh_parameters()`` - - ``refresh()`` + # Summary + + Verify `MaintenanceModeInfo().refresh()` raises `ValueError` when + `config` is not set. + + ## Classes and Methods + + - MaintenanceModeInfo.verify_refresh_parameters() + - MaintenanceModeInfo.refresh() + + ## Test + + - `ValueError` is raised. + - Exception message matches expectations. + + ## Setup - Data + + - None + + ## Setup - Code - ### Summary - - Verify MaintenanceModeInfo().refresh() raises ``ValueError`` when - ``config`` is not set. + - `MaintenanceModeInfo()` is instantiated. + - Other required attributes are set. - ### Setup - Data - - None + ## Trigger - ### Setup - Code - - ``MaintenanceModeInfo()`` is instantiated. - - Other required attributes are set. + - `refresh()` is called without having first set `config`. - ### Trigger - - ``refresh()`` is called without having first set ``config``. + ## Expected Result + + - `ValueError` is raised. + - Exception message matches expectations. - ### Expected Result - - ``ValueError`` is raised. - - Exception message matches expectations. """ with does_not_raise(): instance = maintenance_mode_info @@ -137,28 +153,38 @@ def test_maintenance_mode_info_00100(maintenance_mode_info) -> None: def test_maintenance_mode_info_00110(maintenance_mode_info) -> None: """ - ### Classes and Methods - - ``MaintenanceModeInfo()`` - - ``verify_refresh_parameters()`` - - ``refresh()`` + # Summary + + Verify `refresh()` raises `ValueError` when `rest_send` is not set. + + ## Classes and Methods + + - MaintenanceModeInfo.verify_refresh_parameters() + - MaintenanceModeInfo.refresh() + + ## Test + + - `ValueError` is raised. + - Exception message matches expectations. + + ## Setup - Data + + - None - ### Summary - - Verify ``refresh()`` raises ``ValueError`` when ``rest_send`` - is not set. + ## Setup - Code - ### Setup - Data - - None + - `MaintenanceModeInfo()` is instantiated. + - Other required attributes are set. - ### Setup - Code - - ``MaintenanceModeInfo()`` is instantiated. - - Other required attributes are set. + ## Trigger - ### Trigger - - ``refresh()`` is called without having first set ``rest_send``. + - `refresh()` is called without having first set `rest_send`. + + ## Expected Result + + - `ValueError` is raised. + - Exception message matches expectations. - ### Expected Result - - ``ValueError`` is raised. - - Exception message matches expectations. """ with does_not_raise(): instance = maintenance_mode_info @@ -174,27 +200,38 @@ def test_maintenance_mode_info_00110(maintenance_mode_info) -> None: def test_maintenance_mode_info_00120(maintenance_mode_info) -> None: """ - ### Classes and Methods - - ``MaintenanceModeInfo()`` - - ``verify_refresh_parameters()`` - - ``refresh()`` + # Summary + + Verify `refresh()` raises `ValueError` when `results` is not set. + + ## Classes and Methods + + - MaintenanceModeInfo.verify_refresh_parameters() + - MaintenanceModeInfo.refresh() + + ## Test + + - `ValueError` is raised. + - Exception message matches expectations. + + ## Setup - Data - ### Summary - - Verify ``refresh()`` raises ``ValueError`` when ``results`` is not set. + - None - ### Setup - Data - - None + ## Setup - Code - ### Setup - Code - - ``MaintenanceModeInfo()`` is instantiated. - - Other required attributes are set. + - `MaintenanceModeInfo()` is instantiated. + - Other required attributes are set. - ### Trigger - - ``refresh()`` is called without having first set ``results``. + ## Trigger + + - `refresh()` is called without having first set `results`. + + ## Expected Result + + - `ValueError` is raised. + - Exception message matches expectations. - ### Expected Result - - ``ValueError`` is raised. - - Exception message matches expectations. """ with does_not_raise(): instance = maintenance_mode_info @@ -264,32 +301,41 @@ def test_maintenance_mode_info_00200( mock_message, ) -> None: """ - ### Classes and Methods - - ``MaintenanceModeInfo()`` - - ``refresh()`` - - ### Summary - - Verify ``refresh()`` raises ``ValueError`` when: - - ``fabric_details`` properties ``rest_send`` and ``results`` - raise ``TypeError``. - - ``switch_details`` properties ``rest_send`` and ``results`` - raise ``TypeError``. - - ### Setup - Data - - None - - ### Setup - Code - - ``MaintenanceModeInfo()`` is instantiated - - Required attributes are set - - ``FabricDetails()`` is mocked to conditionally raise ``TypeError``. - - ``SwitchDetails()`` is mocked to conditionally raise ``TypeError``. - - ### Trigger - - ``refresh()`` is called. - - ### Expected Result - - ``ValueError`` is raised. - - Exception message matches expectations. + # Summary + + Verify `refresh()` raises `ValueError` when: + - `fabric_details` properties `rest_send` and `results` raise `TypeError`. + - `switch_details` properties `rest_send` and `results` raise `TypeError`. + + ## Classes and Methods + + - MaintenanceModeInfo.refresh() + + ## Test + + - `ValueError` is raised. + - Exception message matches expectations. + + ## Setup - Data + + - None + + ## Setup - Code + + - `MaintenanceModeInfo()` is instantiated + - Required attributes are set + - `FabricDetails()` is mocked to conditionally raise `TypeError`. + - `SwitchDetails()` is mocked to conditionally raise `TypeError`. + + ## Trigger + + - `refresh()` is called. + + ## Expected Result + + - `ValueError` is raised. + - Exception message matches expectations. + """ method_name = inspect.stack()[0][3] key = f"{method_name}a" @@ -351,31 +397,42 @@ def test_maintenance_mode_info_00210( mock_message, ) -> None: """ - ### Classes and Methods - - MaintenanceModeInfo() - - refresh() - - ### Summary - - Verify ``refresh()`` raises ``ValueError`` when - ``switch_details.serial_number`` raises ``ValueError``. - - ### Setup - Data - - ``responses_SwitchDetails.json``: - - RETURN_CODE: 200 - - MESSAGE: OK - - ### Setup - Code - - ``MaintenanceModeInfo()`` is instantiated - - Required attributes are set - - ``SwitchDetails()`` is mocked to conditionally raise - ``ValueError`` in the ``serial_number.getter`` property. - - ### Trigger - - ``refresh()`` is called. - - ### Expected Result - - ``ValueError`` is raised. - - Exception message matches expectations. + # Summary + + Verify `refresh()` raises `ValueError` when + `switch_details.serial_number` raises `ValueError`. + + ## Classes and Methods + + - MaintenanceModeInfo.refresh() + + ## Test + + - `ValueError` is raised. + - Exception message matches expectations. + + ## Setup - Data + + - `responses_SwitchDetails.json`: + - RETURN_CODE: 200 + - MESSAGE: OK + + ## Setup - Code + + - `MaintenanceModeInfo()` is instantiated + - Required attributes are set + - `SwitchDetails()` is mocked to conditionally raise + `ValueError` in the `serial_number.getter` property. + + ## Trigger + + - `refresh()` is called. + + ## Expected Result + + - `ValueError` is raised. + - Exception message matches expectations. + """ method_name = inspect.stack()[0][3] key = f"{method_name}a" @@ -411,43 +468,54 @@ def responses(): def test_maintenance_mode_info_00300() -> None: """ - ### Classes and Methods - - MaintenanceModeInfo() - - __init__() - - refresh() + # Summary - ### Summary - Verify ``refresh()`` raises ``ValueError`` when - ``switch_details._get()`` raises ``ValueError``. + Verify `refresh()` raises `ValueError` when + `switch_details._get()` raises `ValueError`. This happens when the switch is not found in the response from the controller. - ### Setup - Data - - ``ipAddress`` is set to something other than 192.168.1.2 - - ``responses_SwitchDetails.json``: - - "DATA[0].fabricName: VXLAN_Fabric", - - "DATA[0].freezeMode: null", - - "DATA[0].ipAddress: 192.168.1.1", - - "DATA[0].mode: Normal", - - "DATA[0].serialNumber: FDO211218FV", - - "DATA[0].switchRole: leaf", - - "DATA[0].systemMode: Normal" - - RETURN_CODE: 200 - - MESSAGE: OK - - ``responses_FabricDetailsByName.json``: - - RETURN_CODE: 200 - - MESSAGE: OK - - ### Setup - Code - - ``MaintenanceModeInfo()`` is instantiated - - Required attributes are set - - ### Trigger - - ``refresh()`` is called. - - ### Expected Result - - ``ValueError`` is raised. - - Exception message matches expectations. + ## Classes and Methods + + - MaintenanceModeInfo.__init__() + - MaintenanceModeInfo.refresh() + + ## Test + + - `ValueError` is raised. + - Exception message matches expectations. + + ## Setup - Data + + - `ipAddress` is set to something other than 192.168.1.2 + - `responses_SwitchDetails.json`: + - "DATA[0].fabricName: VXLAN_Fabric", + - "DATA[0].freezeMode: null", + - "DATA[0].ipAddress: 192.168.1.1", + - "DATA[0].mode: Normal", + - "DATA[0].serialNumber: FDO211218FV", + - "DATA[0].switchRole: leaf", + - "DATA[0].systemMode: Normal" + - RETURN_CODE: 200 + - MESSAGE: OK + - `responses_FabricDetailsByName.json`: + - RETURN_CODE: 200 + - MESSAGE: OK + + ## Setup - Code + + - `MaintenanceModeInfo()` is instantiated + - Required attributes are set + + ## Trigger + + - `refresh()` is called. + + ## Expected Result + + - `ValueError` is raised. + - Exception message matches expectations. + """ method_name = inspect.stack()[0][3] key = f"{method_name}a" @@ -477,45 +545,56 @@ def responses(): def test_maintenance_mode_info_00310() -> None: """ - ### Classes and Methods - - MaintenanceModeInfo() - - __init__() - - refresh() + # Summary - ### Summary - Verify ``refresh()`` raises ``ValueError`` when - ``switch_details.serial_number`` is ``None``. + Verify `refresh()` raises `ValueError` when + `switch_details.serial_number` is `None`. This happens when the switch exists on the controller but its serial_number is null. This is a negative test case since we expect the serial_number to be set. - ### Setup - Data - - ``ipAddress`` is set to something other than 192.168.1.2 - - ``responses_SwitchDetails.json``: - - "DATA[0].fabricName: VXLAN_Fabric", - - "DATA[0].freezeMode: null", - - "DATA[0].ipAddress: 192.168.1.2", - - "DATA[0].mode: Normal", - - "DATA[0].serialNumber: null", - - "DATA[0].switchRole: leaf", - - "DATA[0].systemMode: Normal" - - RETURN_CODE: 200 - - MESSAGE: OK - - ``responses_FabricDetailsByName.json``: - - RETURN_CODE: 200 - - MESSAGE: OK - - ### Setup - Code - - ``MaintenanceModeInfo()`` is instantiated - - Required attributes are set - - ### Trigger - - ``refresh()`` is called. - - ### Expected Result - - ``ValueError`` is raised. - - Exception message matches expectations. + ## Classes and Methods + + - MaintenanceModeInfo.__init__() + - MaintenanceModeInfo.refresh() + + ## Test + + - `ValueError` is raised. + - Exception message matches expectations. + + ## Setup - Data + + - `ipAddress` is set to something other than 192.168.1.2 + - `responses_SwitchDetails.json`: + - "DATA[0].fabricName: VXLAN_Fabric", + - "DATA[0].freezeMode: null", + - "DATA[0].ipAddress: 192.168.1.2", + - "DATA[0].mode: Normal", + - "DATA[0].serialNumber: null", + - "DATA[0].switchRole: leaf", + - "DATA[0].systemMode: Normal" + - RETURN_CODE: 200 + - MESSAGE: OK + - `responses_FabricDetailsByName.json`: + - RETURN_CODE: 200 + - MESSAGE: OK + + ## Setup - Code + + - `MaintenanceModeInfo()` is instantiated + - Required attributes are set + + ## Trigger + + - `refresh()` is called. + + ## Expected Result + + - `ValueError` is raised. + - Exception message matches expectations. + """ method_name = inspect.stack()[0][3] key = f"{method_name}a" @@ -565,38 +644,49 @@ def test_maintenance_mode_info_00400( mock_message, ) -> None: """ - ### Classes and Methods - - MaintenanceModeInfo() - - refresh() - - ### Summary - - Verify ``refresh()`` raises ``ValueError`` when - ``fabric_details.filter`` raises ``ValueError``. - - ### Setup - Data - - ``responses_SwitchDetails.json``: - - "DATA[0].fabricName: VXLAN_Fabric", - - "DATA[0].freezeMode: null", - - "DATA[0].ipAddress: 192.168.1.2", - - "DATA[0].mode: Normal", - - "DATA[0].serialNumber: FDO211218FV", - - "DATA[0].switchRole: leaf", - - "DATA[0].systemMode: Normal" - - RETURN_CODE: 200 - - MESSAGE: OK - - ### Code Flow - Setup - - ``MaintenanceModeInfo()`` is instantiated. - - Required attributes are set. - - ``FabricDetailsByName().filter`` is mocked to conditionally raise - ``ValueError``. - - ### Trigger - - ``refresh()`` is called. - - ### Expected Result - - ``ValueError`` is raised. - - Exception message matches expectations. + # Summary + + Verify `refresh()` raises `ValueError` when + `fabric_details.filter` raises `ValueError`. + + ## Classes and Methods + + - MaintenanceModeInfo.refresh() + + ## Test + + - `ValueError` is raised. + - Exception message matches expectations. + + ## Setup - Data + + - `responses_SwitchDetails.json`: + - "DATA[0].fabricName: VXLAN_Fabric", + - "DATA[0].freezeMode: null", + - "DATA[0].ipAddress: 192.168.1.2", + - "DATA[0].mode: Normal", + - "DATA[0].serialNumber: FDO211218FV", + - "DATA[0].switchRole: leaf", + - "DATA[0].systemMode: Normal" + - RETURN_CODE: 200 + - MESSAGE: OK + + ## Setup - Code + + - `MaintenanceModeInfo()` is instantiated. + - Required attributes are set. + - `FabricDetailsByName().filter` is mocked to conditionally raise + `ValueError`. + + ## Trigger + + - `refresh()` is called. + + ## Expected Result + + - `ValueError` is raised. + - Exception message matches expectations. + """ method_name = inspect.stack()[0][3] key = f"{method_name}a" @@ -632,39 +722,49 @@ def responses(): def test_maintenance_mode_info_00500() -> None: """ - ### Classes and Methods - - MaintenanceModeInfo() - - refresh() - - ### Summary - - Verify when ``freezeMode`` == null in the response, - ``freezeMode`` is set to False. - - ### Setup - Data - - ``responses_SwitchDetails.json``: - - "DATA[0].fabricName: VXLAN_Fabric", - - "DATA[0].freezeMode: null", - - "DATA[0].ipAddress: 192.168.1.2", - - "DATA[0].mode: Normal", - - "DATA[0].serialNumber: FDO211218FV", - - "DATA[0].switchRole: leaf", - - "DATA[0].systemMode: Normal" - - RETURN_CODE: 200 - - MESSAGE: OK - - ``responses_FabricDetailsByName.json``: - - RETURN_CODE: 200 - - MESSAGE: OK - - ### Setup - Code - - ``MaintenanceModeInfo()`` is instantiated - - Required attributes are set - - ### Trigger - - ``refresh()`` is called. - - ### Expected Result - - Exception is not raised. - - ``MaintenanceModeInfo().results`` contains expected data. + # Summary + + Verify when `freezeMode` == null in the response, + `freezeMode` is set to False. + + ## Classes and Methods + + - MaintenanceModeInfo.refresh() + + ## Test + + - Exception is not raised. + - `MaintenanceModeInfo().results` contains expected data. + + ## Setup - Data + + - `responses_SwitchDetails.json`: + - "DATA[0].fabricName: VXLAN_Fabric", + - "DATA[0].freezeMode: null", + - "DATA[0].ipAddress: 192.168.1.2", + - "DATA[0].mode: Normal", + - "DATA[0].serialNumber: FDO211218FV", + - "DATA[0].switchRole: leaf", + - "DATA[0].systemMode: Normal" + - RETURN_CODE: 200 + - MESSAGE: OK + - `responses_FabricDetailsByName.json`: + - RETURN_CODE: 200 + - MESSAGE: OK + + ## Setup - Code + + - `MaintenanceModeInfo()` is instantiated + - Required attributes are set + + ## Trigger + + - `refresh()` is called. + + ## Expected Result + + - Exception is not raised. + - `MaintenanceModeInfo().results` contains expected data. """ method_name = inspect.stack()[0][3] @@ -697,40 +797,50 @@ def responses(): def test_maintenance_mode_info_00510() -> None: """ - ### Classes and Methods - - MaintenanceModeInfo() - - __init__() - - refresh() - - ### Summary - - Verify happy path with: - - switch_details: freezeMode is True - - ### Setup - Data - - ``responses_SwitchDetails.json``: - - "DATA[0].fabricName: VXLAN_Fabric", - - "DATA[0].freezeMode: true", - - "DATA[0].ipAddress: 192.168.1.2", - - "DATA[0].mode: Normal", - - "DATA[0].serialNumber: FDO211218FV", - - "DATA[0].switchRole: leaf", - - "DATA[0].systemMode: Normal" - - RETURN_CODE: 200 - - MESSAGE: OK - - ``responses_FabricDetailsByName.json``: - - RETURN_CODE: 200 - - MESSAGE: OK - - ### Setup - Code - - ``MaintenanceModeInfo()`` is instantiated - - Required attributes are set - - ### Trigger - - ``refresh()`` is called. - - ### Expected Result - - Exception is not raised. - - ``MaintenanceModeInfo().results`` contains expected data. + # Summary + + Verify happy path with: + - switch_details: freezeMode is True + + ## Classes and Methods + + - MaintenanceModeInfo.__init__() + - MaintenanceModeInfo.refresh() + + ## Test + + - Exception is not raised. + - `MaintenanceModeInfo().results` contains expected data. + + ## Setup - Data + + - `responses_SwitchDetails.json`: + - "DATA[0].fabricName: VXLAN_Fabric", + - "DATA[0].freezeMode: true", + - "DATA[0].ipAddress: 192.168.1.2", + - "DATA[0].mode: Normal", + - "DATA[0].serialNumber: FDO211218FV", + - "DATA[0].switchRole: leaf", + - "DATA[0].systemMode: Normal" + - RETURN_CODE: 200 + - MESSAGE: OK + - `responses_FabricDetailsByName.json`: + - RETURN_CODE: 200 + - MESSAGE: OK + + ## Setup - Code + + - `MaintenanceModeInfo()` is instantiated + - Required attributes are set + + ## Trigger + + - `refresh()` is called. + + ## Expected Result + + - Exception is not raised. + - `MaintenanceModeInfo().results` contains expected data. """ method_name = inspect.stack()[0][3] @@ -763,41 +873,52 @@ def responses(): def test_maintenance_mode_info_00520() -> None: """ - ### Classes and Methods - - MaintenanceModeInfo() - - __init__() - - refresh() - - ### Summary - - Verify: - - ``mode`` == "inconsistent" when ``mode`` != ``systemMode``. - - ### Setup - Data - - ``responses_SwitchDetails.json``: - - DATA[0].fabricName: VXLAN_Fabric - - DATA[0].freezeMode: true - - DATA[0].ipAddress: 192.168.1.2 - - DATA[0].mode: Normal - - DATA[0].serialNumber: FDO211218FV - - DATA[0].switchRole: leaf - - DATA[0].systemMode: Maintenance - - RETURN_CODE: 200 - - MESSAGE: OK - - ``responses_FabricDetailsByName.json``: - - RETURN_CODE: 200 - - MESSAGE: OK - - ### Setup - Code - - ``MaintenanceModeInfo()`` is instantiated - - Required attributes are set - - ### Trigger - - ``refresh()`` is called. - - ### Expected Result - - Conditions in Summary are confirmed. - - Exception is not raised. - - ``MaintenanceModeInfo().results`` contains expected data. + # Summary + + Verify: + - `mode` == "inconsistent" when `mode` != `systemMode`. + + ## Classes and Methods + + - MaintenanceModeInfo.__init__() + - MaintenanceModeInfo.refresh() + + ## Test + + - Conditions in Summary are confirmed. + - Exception is not raised. + - `MaintenanceModeInfo().results` contains expected data. + + ## Setup - Data + + - `responses_SwitchDetails.json`: + - DATA[0].fabricName: VXLAN_Fabric + - DATA[0].freezeMode: true + - DATA[0].ipAddress: 192.168.1.2 + - DATA[0].mode: Normal + - DATA[0].serialNumber: FDO211218FV + - DATA[0].switchRole: leaf + - DATA[0].systemMode: Maintenance + - RETURN_CODE: 200 + - MESSAGE: OK + - `responses_FabricDetailsByName.json`: + - RETURN_CODE: 200 + - MESSAGE: OK + + ## Setup - Code + + - `MaintenanceModeInfo()` is instantiated + - Required attributes are set + + ## Trigger + + - `refresh()` is called. + + ## Expected Result + + - Conditions in Summary are confirmed. + - Exception is not raised. + - `MaintenanceModeInfo().results` contains expected data. """ method_name = inspect.stack()[0][3] @@ -831,45 +952,55 @@ def responses(): def test_maintenance_mode_info_00600() -> None: """ - ### Classes and Methods - - MaintenanceModeInfo() - - refresh() - - FabricDetailsByName() - - refresh() - - ### Summary - - Verify: - - ``fabric_read_only`` is set to True when ``IS_READ_ONLY`` - is true in the controller response (FabricDetailsByName). - - ### Setup - Data - - ``responses_SwitchDetails.json``: - - DATA[0].fabricName: LAN_Classic - - DATA[0].freezeMode: null - - DATA[0].ipAddress: 192.168.1.2 - - DATA[0].mode: Normal - - DATA[0].serialNumber: FDO211218FV - - DATA[0].switchRole: leaf - - DATA[0].systemMode: Normal - - RETURN_CODE: 200 - - MESSAGE: OK - - ``responses_FabricDetailsByName.json``: - - DATA[0].nvPairs.FABRIC_NAME: LAN_Classic - - DATA[0].nvPairs.IS_READ_ONLY: true - - RETURN_CODE: 200 - - MESSAGE: OK - - ### Setup - Code - - ``MaintenanceModeInfo()`` is instantiated - - Required attributes are set - - ### Trigger - - ``refresh()`` is called. - - ### Expected Result - - Conditions in Summary are confirmed. - - Exception is not raised. - - ``MaintenanceModeInfo().results`` contains expected data. + # Summary + + Verify: + - `fabric_read_only` is set to True when `IS_READ_ONLY` + is true in the controller response (FabricDetailsByName). + + ## Classes and Methods + + - MaintenanceModeInfo.refresh() + - FabricDetailsByName.refresh() + + ## Test + + - Conditions in Summary are confirmed. + - Exception is not raised. + - `MaintenanceModeInfo().results` contains expected data. + + ## Setup - Data + + - `responses_SwitchDetails.json`: + - DATA[0].fabricName: LAN_Classic + - DATA[0].freezeMode: null + - DATA[0].ipAddress: 192.168.1.2 + - DATA[0].mode: Normal + - DATA[0].serialNumber: FDO211218FV + - DATA[0].switchRole: leaf + - DATA[0].systemMode: Normal + - RETURN_CODE: 200 + - MESSAGE: OK + - `responses_FabricDetailsByName.json`: + - DATA[0].nvPairs.FABRIC_NAME: LAN_Classic + - DATA[0].nvPairs.IS_READ_ONLY: true + - RETURN_CODE: 200 + - MESSAGE: OK + + ## Setup - Code + + - `MaintenanceModeInfo()` is instantiated + - Required attributes are set + + ## Trigger + + - `refresh()` is called. + + ## Expected Result + + - Conditions in Summary are confirmed. + - Exception is not raised. + - `MaintenanceModeInfo().results` contains expected data. """ method_name = inspect.stack()[0][3] @@ -901,50 +1032,61 @@ def responses(): def test_maintenance_mode_info_00700() -> None: """ - ### Classes and Methods - - MaintenanceModeInfo() - - refresh() - - SwitchDetails() - - refresh() - - FabricDetailsByName() - - refresh() - - ### Summary - - Verify: - - ``role`` is set to "na" when ``switchRole`` is null in the - controller response. - - ### Setup - Data - - ``responses_SwitchDetails.json``: - - DATA[0].fabricName: LAN_Classic - - DATA[0].freezeMode: null - - DATA[0].ipAddress: 192.168.1.2 - - DATA[0].mode: Normal - - DATA[0].serialNumber: FDO211218FV - - DATA[0].switchRole: null - - DATA[0].systemMode: Normal - - RETURN_CODE: 200 - - MESSAGE: OK - - ``responses_FabricDetailsByName.json``: - - RETURN_CODE: 200 - - MESSAGE: OK - - ### Setup - Code - - ``MaintenanceModeInfo()`` is instantiated - - Required attributes are set - - ### Trigger - - ``refresh()`` is called. - - ### Expected Result - - Conditions in Summary are confirmed. - - Exception is not raised. - - ``MaintenanceModeInfo().results`` contains expected data. - - ### NOTES - - ``SwitchDetails().role`` is an alias of ``SwitchDetails().switch_role``. - - ``MaintenanceModeInfo().role`` is set based on the value of - ``SwitchDetails().role``. + # Summary + + Verify: + - `role` is set to "na" when `switchRole` is null in the + controller response. + + ## Classes and Methods + + - MaintenanceModeInfo.refresh() + - SwitchDetails.refresh() + - FabricDetailsByName.refresh() + + ## Test + + - Conditions in Summary are confirmed. + - Exception is not raised. + - `MaintenanceModeInfo().results` contains expected data. + + ## Setup - Data + + - `responses_SwitchDetails.json`: + - DATA[0].fabricName: LAN_Classic + - DATA[0].freezeMode: null + - DATA[0].ipAddress: 192.168.1.2 + - DATA[0].mode: Normal + - DATA[0].serialNumber: FDO211218FV + - DATA[0].switchRole: null + - DATA[0].systemMode: Normal + - RETURN_CODE: 200 + - MESSAGE: OK + - `responses_FabricDetailsByName.json`: + - RETURN_CODE: 200 + - MESSAGE: OK + + ## Setup - Code + + - `MaintenanceModeInfo()` is instantiated + - Required attributes are set + + ## Trigger + + - `refresh()` is called. + + ## Expected Result + + - Conditions in Summary are confirmed. + - Exception is not raised. + - `MaintenanceModeInfo().results` contains expected data. + + ## Notes + + - `SwitchDetails().role` is an alias of `SwitchDetails().switch_role`. + - `MaintenanceModeInfo().role` is set based on the value of + `SwitchDetails().role`. + """ method_name = inspect.stack()[0][3] key = f"{method_name}a" @@ -975,30 +1117,38 @@ def responses(): def test_maintenance_mode_info_00800() -> None: """ - ### Classes and Methods - - MaintenanceModeInfo() - - refresh() - - SwitchDetails() - - refresh() - - FabricDetailsByName() - - refresh() - - ### Summary - - Verify: - - _get() raises ``ValueError`` if ``filter`` is not set. - - ### Setup - Data + # Summary + + Verify: + - _get() raises `ValueError` if `filter` is not set. + + ## Classes and Methods + + - MaintenanceModeInfo.refresh() + - SwitchDetails.refresh() + - FabricDetailsByName.refresh() + + ## Test + + - Conditions in Summary are confirmed. + + ## Setup - Data + None - ### Setup - Code - - ``MaintenanceModeInfo()`` is instantiated + ## Setup - Code + + - `MaintenanceModeInfo()` is instantiated + + ## Trigger - ### Trigger - - ``MaintenanceModeInfo().role`` is accessed without setting - ``filter``. + - `MaintenanceModeInfo().role` is accessed without setting + `filter`. + + ## Expected Result + + - Conditions in Summary are confirmed. - ### Expected Result - - Conditions in Summary are confirmed. """ with does_not_raise(): instance = MaintenanceModeInfo(PARAMS) @@ -1012,49 +1162,56 @@ def test_maintenance_mode_info_00800() -> None: def test_maintenance_mode_info_00810() -> None: """ - ### Classes and Methods - - MaintenanceModeInfo() - - refresh() - - SwitchDetails() - - refresh() - - FabricDetailsByName() - - refresh() - - ### Summary - - Verify: - - ``_get()`` raises ``ValueError`` if ``filter`` (switch IP) - is not found in the controller response when the user accesses - a property. - - ### Setup - Data - - ``CONFIG``: ["192.168.1.2"] - - ``responses_SwitchDetails.json``: - - DATA[0].fabricName: LAN_Classic - - DATA[0].freezeMode: null - - DATA[0].ipAddress: 192.168.1.2 - - DATA[0].mode: Normal - - DATA[0].serialNumber: FDO211218FV - - DATA[0].switchRole: null - - DATA[0].systemMode: Normal - - RETURN_CODE: 200 - - MESSAGE: OK - - ``responses_FabricDetailsByName.json``: - - DATA[0].nvPairs.FABRIC_NAME: VXLAN_Fabric - - RETURN_CODE: 200 - - MESSAGE: OK - - ### Setup - Code - - ``MaintenanceModeInfo()`` is instantiated - - Required attributes are set - - ``refresh()`` is called. - - ``filter`` is set to 1.2.3.4 - - - ### Trigger - - ``serial_number`` is accessed - - ### Expected Result - - Conditions in Summary are confirmed. + # Summary + + Verify: + - `_get()` raises `ValueError` if `filter` (switch IP) + is not found in the controller response when the user accesses + a property. + + ## Classes and Methods + + - MaintenanceModeInfo.refresh() + - SwitchDetails.refresh() + - FabricDetailsByName.refresh() + + ## Test + + - Conditions in Summary are confirmed. + + ## Setup - Data + + - `CONFIG`: ["192.168.1.2"] + - `responses_SwitchDetails.json`: + - DATA[0].fabricName: LAN_Classic + - DATA[0].freezeMode: null + - DATA[0].ipAddress: 192.168.1.2 + - DATA[0].mode: Normal + - DATA[0].serialNumber: FDO211218FV + - DATA[0].switchRole: null + - DATA[0].systemMode: Normal + - RETURN_CODE: 200 + - MESSAGE: OK + - `responses_FabricDetailsByName.json`: + - DATA[0].nvPairs.FABRIC_NAME: VXLAN_Fabric + - RETURN_CODE: 200 + - MESSAGE: OK + + ## Setup - Code + + - `MaintenanceModeInfo()` is instantiated + - Required attributes are set + - `refresh()` is called. + - `filter` is set to 1.2.3.4 + + ## Trigger + + - `serial_number` is accessed + + ## Expected Result + + - Conditions in Summary are confirmed. + """ method_name = inspect.stack()[0][3] key = f"{method_name}a" @@ -1084,48 +1241,55 @@ def responses(): def test_maintenance_mode_info_00820() -> None: """ - ### Classes and Methods - - MaintenanceModeInfo() - - refresh() - - SwitchDetails() - - refresh() - - FabricDetailsByName() - - refresh() - - ### Summary - - Verify: - - ``refresh`` re-raises ``ValueError`` raised by - ``SwitchDetails()._get()`` when ``item`` is not found in the - controller response. In this, case ``item`` is ``freezeMode``. - - ### Setup - Data - - ``CONFIG``: ["192.168.1.2"] - - ``responses_SwitchDetails.json`` is missing the key ``freezeMode``. - - ``responses_SwitchDetails.json``: - - DATA[0].fabricName: LAN_Classic - - DATA[0].ipAddress: 192.168.1.2 - - DATA[0].mode: Normal - - DATA[0].serialNumber: FDO211218FV - - DATA[0].switchRole: null - - DATA[0].systemMode: Normal - - RETURN_CODE: 200 - - MESSAGE: OK - - ``responses_FabricDetailsByName.json``: - - DATA[0].nvPairs.FABRIC_NAME: VXLAN_Fabric - - DATA[0].nvPairs.IS_READ_ONLY: false - - RETURN_CODE: 200 - - MESSAGE: OK - - ### Setup - Code - - ``MaintenanceModeInfo()`` is instantiated - - Required attributes are set - - - ### Trigger - - ``refresh()`` is called. - - ### Expected Result - - Conditions in Summary are confirmed. + # Summary + + Verify: + - `refresh` re-raises `ValueError` raised by + `SwitchDetails()._get()` when `item` is not found in the + controller response. In this, case `item` is `freezeMode`. + + ## Classes and Methods + + - MaintenanceModeInfo.refresh() + - SwitchDetails.refresh() + - FabricDetailsByName.refresh() + + ## Test + + - Conditions in Summary are confirmed. + + ## Setup - Data + + - `CONFIG`: ["192.168.1.2"] + - `responses_SwitchDetails.json` is missing the key `freezeMode`. + - `responses_SwitchDetails.json`: + - DATA[0].fabricName: LAN_Classic + - DATA[0].ipAddress: 192.168.1.2 + - DATA[0].mode: Normal + - DATA[0].serialNumber: FDO211218FV + - DATA[0].switchRole: null + - DATA[0].systemMode: Normal + - RETURN_CODE: 200 + - MESSAGE: OK + - `responses_FabricDetailsByName.json`: + - DATA[0].nvPairs.FABRIC_NAME: VXLAN_Fabric + - DATA[0].nvPairs.IS_READ_ONLY: false + - RETURN_CODE: 200 + - MESSAGE: OK + + ## Setup - Code + + - `MaintenanceModeInfo()` is instantiated + - Required attributes are set + + ## Trigger + + - `refresh()` is called. + + ## Expected Result + + - Conditions in Summary are confirmed. + """ method_name = inspect.stack()[0][3] key = f"{method_name}a" @@ -1157,26 +1321,36 @@ def responses(): def test_maintenance_mode_info_00900() -> None: """ - ### Classes and Methods - - ``MaintenanceModeInfo()`` - - ``config.setter`` + # Summary + + Verify: + - `config` raises `TypeError` when set to an invalid type. + + ## Classes and Methods - ### Summary - - Verify: - - ``config`` raises ``TypeError`` when set to an invalid type. + - MaintenanceModeInfo.config setter + + ## Test + + - Conditions in Summary are confirmed. + + ## Setup - Data - ### Setup - Data None - ### Setup - Code - - ``MaintenanceModeInfo()`` is instantiated - - Required attributes are set + ## Setup - Code + + - `MaintenanceModeInfo()` is instantiated + - Required attributes are set - ### Trigger - - ``config`` is set to a value that is not a ``list``. + ## Trigger + + - `config` is set to a value that is not a `list`. + + ## Expected Result + + - Conditions in Summary are confirmed. - ### Expected Result - - Conditions in Summary are confirmed. """ with does_not_raise(): instance = MaintenanceModeInfo(PARAMS) @@ -1190,27 +1364,37 @@ def test_maintenance_mode_info_00900() -> None: def test_maintenance_mode_info_00910() -> None: """ - ### Classes and Methods - - ``MaintenanceModeInfo()`` - - ``config.setter`` + # Summary + + Verify: + - `config` raises `TypeError` when an element in the list is + not a `str`. - ### Summary - - Verify: - - ``config`` raises ``TypeError`` when an element in the list is - not a ``str``. + ## Classes and Methods + + - MaintenanceModeInfo.config setter + + ## Test + + - Conditions in Summary are confirmed. + + ## Setup - Data - ### Setup - Data None - ### Setup - Code - - ``MaintenanceModeInfo()`` is instantiated - - Required attributes are set + ## Setup - Code + + - `MaintenanceModeInfo()` is instantiated + - Required attributes are set + + ## Trigger + + - `config` is set to a value that is not a `list`. + + ## Expected Result - ### Trigger - - ``config`` is set to a value that is not a ``list``. + - Conditions in Summary are confirmed. - ### Expected Result - - Conditions in Summary are confirmed. """ with does_not_raise(): instance = MaintenanceModeInfo(PARAMS) @@ -1226,27 +1410,37 @@ def test_maintenance_mode_info_00910() -> None: def test_maintenance_mode_info_01000() -> None: """ - ### Classes and Methods - - ``MaintenanceModeInfo()`` - - ``info.getter`` + # Summary - ### Summary - - Verify: - - ``info`` raises ``ValueError`` when accessed before - ``refresh()`` is called. + Verify: + - `info` raises `ValueError` when accessed before + `refresh()` is called. + + ## Classes and Methods + + - MaintenanceModeInfo.info getter + + ## Test + + - Conditions in Summary are confirmed. + + ## Setup - Data - ### Setup - Data None - ### Setup - Code - - ``MaintenanceModeInfo()`` is instantiated - - Required attributes are set + ## Setup - Code + + - `MaintenanceModeInfo()` is instantiated + - Required attributes are set + + ## Trigger + + - `info` is accessed without having first called `refresh()`. - ### Trigger - - ``info`` is accessed without having first called ``refresh()``. + ## Expected Result + + - Conditions in Summary are confirmed. - ### Expected Result - - Conditions in Summary are confirmed. """ with does_not_raise(): instance = MaintenanceModeInfo(PARAMS) @@ -1260,41 +1454,51 @@ def test_maintenance_mode_info_01000() -> None: def test_maintenance_mode_info_01010() -> None: """ - ### Classes and Methods - - ``MaintenanceModeInfo()`` - - ``info.getter`` - - ### Summary - - Verify: - - ``info`` returns expected information in the happy path. - - ### Setup - Data - - ``CONFIG``: ["192.168.1.2"] - - ``responses_SwitchDetails.json``: - - DATA[0].fabricName: VXLAN_Fabric - - DATA[0].freezeMode: null - - DATA[0].ipAddress: 192.168.1.2 - - DATA[0].mode: Normal - - DATA[0].serialNumber: FDO211218FV - - DATA[0].switchRole: leaf - - DATA[0].systemMode: Maintenance - - RETURN_CODE: 200 - - MESSAGE: OK - - ``responses_FabricDetailsByName.json``: - - DATA[0].nvPairs.FABRIC_NAME: VXLAN_Fabric - - DATA[0].nvPairs.IS_READ_ONLY: false - - RETURN_CODE: 200 - - MESSAGE: OK - - ### Setup - Code - - ``MaintenanceModeInfo()`` is instantiated - - Required attributes are set - - ### Trigger - - ``info`` is accessed without having first called ``refresh()``. - - ### Expected Result - - Conditions in Summary are confirmed. + # Summary + + Verify: + - `info` returns expected information in the happy path. + + ## Classes and Methods + + - MaintenanceModeInfo.info getter + + ## Test + + - Conditions in Summary are confirmed. + + ## Setup - Data + + - `CONFIG`: ["192.168.1.2"] + - `responses_SwitchDetails.json`: + - DATA[0].fabricName: VXLAN_Fabric + - DATA[0].freezeMode: null + - DATA[0].ipAddress: 192.168.1.2 + - DATA[0].mode: Normal + - DATA[0].serialNumber: FDO211218FV + - DATA[0].switchRole: leaf + - DATA[0].systemMode: Maintenance + - RETURN_CODE: 200 + - MESSAGE: OK + - `responses_FabricDetailsByName.json`: + - DATA[0].nvPairs.FABRIC_NAME: VXLAN_Fabric + - DATA[0].nvPairs.IS_READ_ONLY: false + - RETURN_CODE: 200 + - MESSAGE: OK + + ## Setup - Code + + - `MaintenanceModeInfo()` is instantiated + - Required attributes are set + + ## Trigger + + - `info` is accessed without having first called `refresh()`. + + ## Expected Result + + - Conditions in Summary are confirmed. + """ method_name = inspect.stack()[0][3] key = f"{method_name}a" @@ -1327,26 +1531,36 @@ def responses(): def test_maintenance_mode_info_01020() -> None: """ - ### Classes and Methods - - ``MaintenanceModeInfo()`` - - ``info.setter`` + # Summary + + Verify: + - `info` raises `TypeError` when set to an invalid type. - ### Summary - - Verify: - - ``info`` raises ``TypeError`` when set to an invalid type. + ## Classes and Methods + + - MaintenanceModeInfo.info setter + + ## Test + + - Conditions in Summary are confirmed. + + ## Setup - Data - ### Setup - Data None - ### Setup - Code - - ``MaintenanceModeInfo()`` is instantiated - - Required attributes are set + ## Setup - Code + + - `MaintenanceModeInfo()` is instantiated + - Required attributes are set + + ## Trigger + + - `info` is set to a value that is not a `dict`. + + ## Expected Result - ### Trigger - - ``info`` is set to a value that is not a ``dict``. + - Conditions in Summary are confirmed. - ### Expected Result - - Conditions in Summary are confirmed. """ with does_not_raise(): instance = MaintenanceModeInfo(PARAMS) diff --git a/tests/unit/modules/dcnm/dcnm_maintenance_mode/test_dcnm_maintenance_mode_common.py b/tests/unit/modules/dcnm/dcnm_maintenance_mode/test_dcnm_maintenance_mode_common.py index 734cc5826..b3e38491f 100644 --- a/tests/unit/modules/dcnm/dcnm_maintenance_mode/test_dcnm_maintenance_mode_common.py +++ b/tests/unit/modules/dcnm/dcnm_maintenance_mode/test_dcnm_maintenance_mode_common.py @@ -29,12 +29,9 @@ import inspect import pytest -from ansible_collections.cisco.dcnm.plugins.modules.dcnm_maintenance_mode import \ - Common -from ansible_collections.cisco.dcnm.tests.unit.module_utils.common.common_utils import \ - ResponseGenerator -from ansible_collections.cisco.dcnm.tests.unit.modules.dcnm.dcnm_maintenance_mode.utils import ( - common_fixture, configs_common, does_not_raise, params) +from ansible_collections.cisco.dcnm.plugins.modules.dcnm_maintenance_mode import Common +from ansible_collections.cisco.dcnm.tests.unit.module_utils.common.common_utils import ResponseGenerator +from ansible_collections.cisco.dcnm.tests.unit.modules.dcnm.dcnm_maintenance_mode.utils import common_fixture, configs_common, does_not_raise, params def test_dcnm_maintenance_mode_common_00000(common) -> None: diff --git a/tests/unit/modules/dcnm/dcnm_maintenance_mode/test_dcnm_maintenance_mode_merged.py b/tests/unit/modules/dcnm/dcnm_maintenance_mode/test_dcnm_maintenance_mode_merged.py index c4b43a40c..088441875 100644 --- a/tests/unit/modules/dcnm/dcnm_maintenance_mode/test_dcnm_maintenance_mode_merged.py +++ b/tests/unit/modules/dcnm/dcnm_maintenance_mode/test_dcnm_maintenance_mode_merged.py @@ -1,4 +1,7 @@ -# Copyright (c) 2024 Cisco and/or its affiliates. +""" +Unit tests for dcnm_maintenance_mode Merged class. +""" +# Copyright (c) 2024-2025 Cisco and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -21,45 +24,48 @@ from __future__ import absolute_import, division, print_function -__metaclass__ = type +__metaclass__ = type # pylint: disable=invalid-name -__copyright__ = "Copyright (c) 2024 Cisco and/or its affiliates." +__copyright__ = "Copyright (c) 2024-2025 Cisco and/or its affiliates." __author__ = "Allen Robel" import copy import inspect import pytest -from ansible_collections.cisco.dcnm.plugins.module_utils.common.response_handler import \ - ResponseHandler -from ansible_collections.cisco.dcnm.plugins.module_utils.common.rest_send_v2 import \ - RestSend -from ansible_collections.cisco.dcnm.plugins.module_utils.common.sender_file import \ - Sender -from ansible_collections.cisco.dcnm.plugins.modules.dcnm_maintenance_mode import \ - Merged -from ansible_collections.cisco.dcnm.tests.unit.module_utils.common.common_utils import \ - ResponseGenerator +from ansible_collections.cisco.dcnm.plugins.module_utils.common.response_handler import ResponseHandler +from ansible_collections.cisco.dcnm.plugins.module_utils.common.rest_send_v2 import RestSend +from ansible_collections.cisco.dcnm.plugins.module_utils.common.sender_file import Sender +from ansible_collections.cisco.dcnm.plugins.modules.dcnm_maintenance_mode import Merged +from ansible_collections.cisco.dcnm.tests.unit.module_utils.common.common_utils import ResponseGenerator from ansible_collections.cisco.dcnm.tests.unit.modules.dcnm.dcnm_maintenance_mode.utils import ( - MockAnsibleModule, configs_merged, does_not_raise, params, - responses_ep_all_switches, responses_ep_fabrics, + MockAnsibleModule, + configs_merged, + does_not_raise, + params, + responses_ep_all_switches, + responses_ep_fabrics, responses_ep_maintenance_mode_deploy, responses_ep_maintenance_mode_disable, - responses_ep_maintenance_mode_enable) + responses_ep_maintenance_mode_enable, +) def test_dcnm_maintenance_mode_merged_00000() -> None: """ - ### Classes and Methods - - Common - - __init__() + # Summary + + Verify the class attributes are initialized to expected values. - ### Summary - - Verify the class attributes are initialized to expected values. + ## Test - ### Test - Class attributes are initialized to expected values. - Exception is not raised. + + ## Classes and Methods + + - Common + - `__init__()` """ with does_not_raise(): instance = Merged(params) @@ -92,15 +98,18 @@ def test_dcnm_maintenance_mode_merged_00000() -> None: def test_dcnm_maintenance_mode_merged_00100() -> None: """ - ### Classes and Methods - - Merged() - - commit() + # Summary + + Verify `commit()` happy path. + + - Change switch mode from maintenance to normal. + - No exceptions are raised. + - want contains expected structure and values. - ### Summary - - Verify ``commit()`` happy path. - - Change switch mode from maintenance to normal. - - No exceptions are raised. - - want contains expected structure and values. + ## Classes and Methods + + - Merged() + - `commit()` """ method_name = inspect.stack()[0][3] key = f"{method_name}" @@ -188,15 +197,18 @@ def responses(): def test_dcnm_maintenance_mode_merged_00110() -> None: """ - ### Classes and Methods - - Merged() - - commit() + # Summary + + Verify `commit()` happy path. - ### Summary - - Verify ``commit()`` happy path. - - Change switch mode from normal to maintenance. - - No exceptions are raised. - - want contains expected structure and values. + - Change switch mode from normal to maintenance. + - No exceptions are raised. + - want contains expected structure and values. + + ## Classes and Methods + + - Merged() + - `commit()` """ method_name = inspect.stack()[0][3] key = f"{method_name}" @@ -284,17 +296,20 @@ def responses(): def test_dcnm_maintenance_mode_merged_00115() -> None: """ - ### Classes and Methods + # Summary + + Verify `commit()` happy path. + + - User wants to change switches to maintenance mode, but all + switches are already in maintenance mode. + - `send_need()` returns without sending any requests since + `instance.need` is empty. + - No exceptions are raised. + + ## Classes and Methods + - Merged() - - commit() - - ### Summary - - Verify ``commit()`` happy path. - - User wants to change switches to maintenance mode, but all - switches are already in maintenance mode. - - send_need() returns without sending any requests since - instance.need is empty. - - No exceptions are raised. + - `commit()` """ method_name = inspect.stack()[0][3] key = f"{method_name}" @@ -346,14 +361,16 @@ def responses(): def test_dcnm_maintenance_mode_merged_00120() -> None: """ - ### Classes and Methods - - Merged() - - get_need() - - commit() + # Summary + + Verify `get_have()` raises `ValueError` when `ip_address` + does not exist on the controller. - ### Summary - - Verify ``get_have()`` raises ``ValueError`` when ip_address - does not exist on the controller. + ## Classes and Methods + + - Merged() + - `get_need()` + - `commit()` """ method_name = inspect.stack()[0][3] key = f"{method_name}" @@ -414,14 +431,16 @@ def responses(): def test_dcnm_maintenance_mode_merged_00130() -> None: """ - ### Classes and Methods - - Merged() - - fabric_deployment_disabled() - - commit() + # Summary + + Verify `fabric_deployment_disabled()` raises `ValueError` when + have `ip_address` is in migration mode. - ### Summary - - Verify ``fabric_deployment_disabled()`` raises ``ValueError`` when - have ip_address is in migration mode. + ## Classes and Methods + + - Merged() + - `fabric_deployment_disabled()` + - `commit()` """ method_name = inspect.stack()[0][3] key = f"{method_name}" @@ -495,14 +514,16 @@ def responses(): def test_dcnm_maintenance_mode_merged_00140() -> None: """ - ### Classes and Methods - - Merged() - - fabric_deployment_disabled() - - commit() + # Summary + + Verify `fabric_deployment_disabled()` raises `ValueError` when + the fabric is in read-only mode. + + ## Classes and Methods - ### Summary - - Verify ``fabric_deployment_disabled()`` raises ``ValueError`` when - the fabric is in read-only mode. + - Merged() + - `fabric_deployment_disabled()` + - `commit()` """ method_name = inspect.stack()[0][3] key = f"{method_name}" @@ -568,14 +589,16 @@ def responses(): def test_dcnm_maintenance_mode_merged_00150() -> None: """ - ### Classes and Methods - - Merged() - - fabric_deployment_disabled() - - commit() + # Summary + + Verify `fabric_deployment_disabled()` raises `ValueError` when + fabric freeze-mode is True. + + ## Classes and Methods - ### Summary - - Verify ``fabric_deployment_disabled()`` raises ``ValueError`` when - fabric freeze-mode is True. + - Merged() + - `fabric_deployment_disabled()` + - `commit()` """ method_name = inspect.stack()[0][3] key = f"{method_name}" @@ -606,9 +629,7 @@ def responses(): instance.rest_send = rest_send instance.config = params_test.get("config") match = r"Merged\.fabric_deployment_disabled:\s+" - match += ( - r"The hosting fabric is in 'Deployment Disable' state for the switch with\s+" - ) + match += r"The hosting fabric is in 'Deployment Disable' state for the switch with\s+" match += r"ip_address 192\.168\.1\.2,\s+" match += r"serial_number FD2222222GA\.\s+" match += r"Review the 'Deployment Enable / Deployment Disable' setting on the controller at:\s+" @@ -643,13 +664,15 @@ def responses(): def test_dcnm_maintenance_mode_merged_00200() -> None: """ - ### Classes and Methods - - Merged() - - commit() + # Summary + + Verify `commit()` raises `ValueError` when `rest_send` has not + been set. + + ## Classes and Methods - ### Summary - - Verify ``commit()`` raises ``ValueError`` when rest_send has not - been set. + - Merged() + - `commit()` """ with does_not_raise(): instance = Merged(params) @@ -666,14 +689,16 @@ def test_dcnm_maintenance_mode_merged_00200() -> None: def test_dcnm_maintenance_mode_merged_00300(monkeypatch) -> None: """ - ### Classes and Methods - - Merged() - - get_need() - - commit() + # Summary + + Verify `get_need()` raises `ValueError` when `ip_address` + does not exist in `self.have`. + + ## Classes and Methods - ### Summary - - Verify ``get_need()`` raises ``ValueError`` when ip_address - does not exist in self.have. + - Merged() + - `get_need()` + - `commit()` """ method_name = inspect.stack()[0][3] key = f"{method_name}" @@ -720,14 +745,16 @@ def mock_get_have(): def test_dcnm_maintenance_mode_merged_00400(monkeypatch) -> None: """ - ### Classes and Methods - - Merged() - - get_want() - - commit() + # Summary + + Verify `commit()` re-raises `ValueError` when `get_want()` + raises `ValueError`. - ### Summary - - Verify ``commit`` re-raises ``ValueError`` when ``get_want()`` - raises ``ValueError``. + ## Classes and Methods + + - Merged() + - `get_want()` + - `commit()` """ params_test = copy.deepcopy(params) params_test.update({"config": {}}) @@ -755,13 +782,15 @@ def mock_get_want(): def test_dcnm_maintenance_mode_merged_00500() -> None: """ - ### Classes and Methods - - Merged() - - __init__() + # Summary + + Verify `__init__()` re-raises `ValueError` when `Common().__init__()` + raises `ValueError`. - ### Summary - - Verify ``__init__`` re-raises ``ValueError`` when ``Common().__init__`` - raises ``ValueError``. + ## Classes and Methods + + - Merged() + - `__init__()` """ params_test = copy.deepcopy(params) params_test.update({"config": {}}) @@ -777,14 +806,16 @@ def test_dcnm_maintenance_mode_merged_00500() -> None: def test_dcnm_maintenance_mode_merged_00600(monkeypatch) -> None: """ - ### Classes and Methods - - Merged() - - send_need() - - commit() + # Summary - ### Summary - - Verify ``commit()`` re-raises ``ValueError`` when - send_need() raises ``ValueError``. + Verify `commit()` re-raises `ValueError` when + `send_need()` raises `ValueError`. + + ## Classes and Methods + + - Merged() + - `send_need()` + - `commit()` """ method_name = inspect.stack()[0][3] key = f"{method_name}" @@ -845,14 +876,16 @@ def mock_send_need(): def test_dcnm_maintenance_mode_merged_00700(monkeypatch) -> None: """ - ### Classes and Methods - - Merged() - - send_need() - - commit() + # Summary - ### Summary - - Verify ``send_need()`` re-raises ``ValueError`` when - MaintenanceMode.commit() raises ``ValueError``. + Verify `send_need()` re-raises `ValueError` when + `MaintenanceMode.commit()` raises `ValueError`. + + ## Classes and Methods + + - Merged() + - `send_need()` + - `commit()` """ method_name = inspect.stack()[0][3] key = f"{method_name}" @@ -902,9 +935,7 @@ def commit(self): match += r"Error detail:\s+" match += r"MockMaintenanceModeInfo\.refresh: Mocked ValueError\." with pytest.raises(ValueError, match=match): - monkeypatch.setattr( - instance, "maintenance_mode", MockMaintenanceMode(params_test) - ) + monkeypatch.setattr(instance, "maintenance_mode", MockMaintenanceMode(params_test)) instance.commit() assert len(instance.results.diff) == 2 diff --git a/tests/unit/modules/dcnm/dcnm_maintenance_mode/test_dcnm_maintenance_mode_params_spec.py b/tests/unit/modules/dcnm/dcnm_maintenance_mode/test_dcnm_maintenance_mode_params_spec.py index 9b80c1456..a7ea359ed 100644 --- a/tests/unit/modules/dcnm/dcnm_maintenance_mode/test_dcnm_maintenance_mode_params_spec.py +++ b/tests/unit/modules/dcnm/dcnm_maintenance_mode/test_dcnm_maintenance_mode_params_spec.py @@ -1,4 +1,7 @@ -# Copyright (c) 2024 Cisco and/or its affiliates. +""" +Unit tests for dcnm_maintenance_mode ParamsSpec class. +""" +# Copyright (c) 2024-2025 Cisco and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -24,32 +27,33 @@ from __future__ import absolute_import, division, print_function -__metaclass__ = type +__metaclass__ = type # pylint: disable=invalid-name -__copyright__ = "Copyright (c) 2024 Cisco and/or its affiliates." +__copyright__ = "Copyright (c) 2024-2025 Cisco and/or its affiliates." __author__ = "Allen Robel" import copy import pytest -from ansible_collections.cisco.dcnm.plugins.modules.dcnm_maintenance_mode import \ - ParamsSpec -from ansible_collections.cisco.dcnm.tests.unit.modules.dcnm.dcnm_maintenance_mode.utils import ( - does_not_raise, params) +from ansible_collections.cisco.dcnm.plugins.modules.dcnm_maintenance_mode import ParamsSpec +from ansible_collections.cisco.dcnm.tests.unit.modules.dcnm.dcnm_maintenance_mode.utils import does_not_raise, params def test_dcnm_maintenance_mode_params_spec_00000() -> None: """ - ### Classes and Methods - - ParamsSpec - - __init__() + # Summary + + Verify the class attributes are initialized to expected values. - ### Summary - - Verify the class attributes are initialized to expected values. + ## Test - ### Test - Class attributes are initialized to expected values - - ``ValueError`` is not called + - `ValueError` is not called + + ## Classes and Methods + + - ParamsSpec + - `__init__()` """ with does_not_raise(): instance = ParamsSpec() @@ -61,13 +65,16 @@ def test_dcnm_maintenance_mode_params_spec_00000() -> None: def test_dcnm_maintenance_mode_params_spec_00100() -> None: """ - ### Classes and Methods - - ParamsSpec - - params.setter + # Summary + + Verify `TypeError` is raised. + + - `params` is not a dict. + + ## Classes and Methods - ### Summary - - Verify ``TypeError`` is raised. - - params is not a dict. + - ParamsSpec + - `params.setter` """ params_test = "foo" @@ -82,13 +89,16 @@ def test_dcnm_maintenance_mode_params_spec_00100() -> None: def test_dcnm_maintenance_mode_params_spec_00110() -> None: """ - ### Classes and Methods - - ParamsSpec - - params.setter + # Summary + + Verify `ValueError` is raised. + + - `params` is missing `state` key/value. - ### Summary - - Verify ``ValueError`` is raised. - - params is missing ``state`` key/value. + ## Classes and Methods + + - ParamsSpec + - `params.setter` """ params_test = copy.deepcopy(params) params_test.pop("state", None) @@ -104,13 +114,16 @@ def test_dcnm_maintenance_mode_params_spec_00110() -> None: def test_dcnm_maintenance_mode_params_spec_00120() -> None: """ - ### Classes and Methods - - ParamsSpec - - params.setter + # Summary + + Verify `ValueError` is raised. - ### Summary - - Verify ``ValueError`` is raised. - - params ``state`` has invalid value. + - `params` `state` has invalid value. + + ## Classes and Methods + + - ParamsSpec + - `params.setter` """ params_test = copy.deepcopy(params) params_test.update({"state": "foo"}) @@ -126,13 +139,15 @@ def test_dcnm_maintenance_mode_params_spec_00120() -> None: def test_dcnm_maintenance_mode_params_spec_00200() -> None: """ - ### Classes and Methods - - ParamsSpec - - params.setter - - commit() + # Summary - ### Summary - - Verify commit() happy path for merged state. + Verify `commit()` happy path for merged state. + + ## Classes and Methods + + - ParamsSpec + - `params.setter` + - `commit()` """ params_test = copy.deepcopy(params) @@ -162,13 +177,15 @@ def test_dcnm_maintenance_mode_params_spec_00200() -> None: def test_dcnm_maintenance_mode_params_spec_00210() -> None: """ - ### Classes and Methods - - ParamsSpec - - params.setter - - commit() + # Summary - ### Summary - - Verify commit() happy path for query state. + Verify `commit()` happy path for query state. + + ## Classes and Methods + + - ParamsSpec + - `params.setter` + - `commit()` """ params_test = copy.deepcopy(params) params_test.update({"state": "query"}) @@ -186,15 +203,18 @@ def test_dcnm_maintenance_mode_params_spec_00210() -> None: def test_dcnm_maintenance_mode_params_spec_00220() -> None: """ - ### Classes and Methods - - ParamsSpec - - params.setter - - commit() + # Summary - ### Summary - - Verify commit() sad path. - - params is not set before calling commit. - - commit() raises ``ValueError`` when params is not set. + Verify `commit()` sad path. + + - `params` is not set before calling `commit()`. + - `commit()` raises `ValueError` when `params` is not set. + + ## Classes and Methods + + - ParamsSpec + - `params.setter` + - `commit()` """ params_test = copy.deepcopy(params) params_test.update({"state": "query"}) diff --git a/tests/unit/modules/dcnm/dcnm_maintenance_mode/test_dcnm_maintenance_mode_query.py b/tests/unit/modules/dcnm/dcnm_maintenance_mode/test_dcnm_maintenance_mode_query.py index 934912b82..be814015d 100644 --- a/tests/unit/modules/dcnm/dcnm_maintenance_mode/test_dcnm_maintenance_mode_query.py +++ b/tests/unit/modules/dcnm/dcnm_maintenance_mode/test_dcnm_maintenance_mode_query.py @@ -1,4 +1,7 @@ -# Copyright (c) 2024 Cisco and/or its affiliates. +""" +Unit tests for dcnm_maintenance_mode Query class. +""" +# Copyright (c) 2024-2025 Cisco and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -21,42 +24,45 @@ from __future__ import absolute_import, division, print_function -__metaclass__ = type +__metaclass__ = type # pylint: disable=invalid-name -__copyright__ = "Copyright (c) 2024 Cisco and/or its affiliates." +__copyright__ = "Copyright (c) 2024-2025 Cisco and/or its affiliates." __author__ = "Allen Robel" import copy import inspect import pytest -from ansible_collections.cisco.dcnm.plugins.module_utils.common.response_handler import \ - ResponseHandler -from ansible_collections.cisco.dcnm.plugins.module_utils.common.rest_send_v2 import \ - RestSend -from ansible_collections.cisco.dcnm.plugins.module_utils.common.sender_file import \ - Sender -from ansible_collections.cisco.dcnm.plugins.modules.dcnm_maintenance_mode import \ - Query -from ansible_collections.cisco.dcnm.tests.unit.module_utils.common.common_utils import \ - ResponseGenerator +from ansible_collections.cisco.dcnm.plugins.module_utils.common.response_handler import ResponseHandler +from ansible_collections.cisco.dcnm.plugins.module_utils.common.rest_send_v2 import RestSend +from ansible_collections.cisco.dcnm.plugins.module_utils.common.sender_file import Sender +from ansible_collections.cisco.dcnm.plugins.modules.dcnm_maintenance_mode import Query +from ansible_collections.cisco.dcnm.tests.unit.module_utils.common.common_utils import ResponseGenerator from ansible_collections.cisco.dcnm.tests.unit.modules.dcnm.dcnm_maintenance_mode.utils import ( - MockAnsibleModule, configs_query, does_not_raise, params_query, - responses_ep_all_switches, responses_ep_fabrics) + MockAnsibleModule, + configs_query, + does_not_raise, + params_query, + responses_ep_all_switches, + responses_ep_fabrics, +) def test_dcnm_maintenance_mode_query_00000() -> None: """ - ### Classes and Methods - - Common - - __init__() + # Summary + + Verify the class attributes are initialized to expected values. - ### Summary - - Verify the class attributes are initialized to expected values. + ## Test - ### Test - Class attributes are initialized to expected values. - Exception is not raised. + + ## Classes and Methods + + - Common + - `__init__()` """ with does_not_raise(): instance = Query(params_query) @@ -83,14 +89,17 @@ def test_dcnm_maintenance_mode_query_00000() -> None: def test_dcnm_maintenance_mode_query_00100() -> None: """ - ### Classes and Methods - - Query() - - commit() + # Summary + + Verify `commit()` happy path. + + - No exceptions are raised. + - want contains expected structure and values. - ### Summary - - Verify ``commit()`` happy path. - - No exceptions are raised. - - want contains expected structure and values. + ## Classes and Methods + + - Query() + - `commit()` """ method_name = inspect.stack()[0][3] key = f"{method_name}" @@ -175,13 +184,15 @@ def responses(): def test_dcnm_maintenance_mode_query_00200() -> None: """ - ### Classes and Methods - - Query() - - commit() + # Summary + + Verify `commit()` raises `ValueError` when `rest_send` has not + been set. - ### Summary - - Verify ``commit()`` raises ``ValueError`` when rest_send has not - been set. + ## Classes and Methods + + - Query() + - `commit()` """ with does_not_raise(): instance = Query(params_query) @@ -198,14 +209,16 @@ def test_dcnm_maintenance_mode_query_00200() -> None: def test_dcnm_maintenance_mode_query_00300(monkeypatch) -> None: """ - ### Classes and Methods - - Query() - - get_need() - - commit() + # Summary + + Verify `get_need()` raises `ValueError` when `ip_address` + does not exist in `self.have`. - ### Summary - - Verify ``get_need()`` raises ``ValueError`` when ip_address - does not exist in self.have. + ## Classes and Methods + + - Query() + - `get_need()` + - `commit()` """ method_name = inspect.stack()[0][3] key = f"{method_name}" @@ -253,14 +266,16 @@ def mock_get_have(): def test_dcnm_maintenance_mode_query_00400(monkeypatch) -> None: """ - ### Classes and Methods - - Merged() - - get_want() - - commit() - - ### Summary - - Verify ``commit`` re-raises ``ValueError`` when ``get_want()`` - raises ``ValueError``. + # Summary + + Verify `commit()` re-raises `ValueError` when `get_want()` + raises `ValueError`. + + ## Classes and Methods + + - Query() + - `get_want()` + - `commit()` """ params_test = copy.deepcopy(params_query) params_test.update({"config": {}}) @@ -288,13 +303,15 @@ def mock_get_want(): def test_dcnm_maintenance_mode_query_00500() -> None: """ - ### Classes and Methods - - Query() - - __init__() + # Summary + + Verify `__init__()` re-raises `ValueError` when `Common().__init__()` + raises `ValueError`. - ### Summary - - Verify ``__init__`` re-raises ``ValueError`` when ``Common().__init__`` - raises ``ValueError``. + ## Classes and Methods + + - Query() + - `__init__()` """ params_test = copy.deepcopy(params_query) params_test.update({"config": {}}) @@ -310,13 +327,15 @@ def test_dcnm_maintenance_mode_query_00500() -> None: def test_dcnm_maintenance_mode_query_00600(monkeypatch) -> None: """ - ### Classes and Methods - - Query() - - commit() + # Summary + + Verify `commit()` re-raises `ValueError` when `get_have()` + raises `ValueError`. - ### Summary - - Verify ``commit`` re-raises ``ValueError`` when ``get_have()`` - raises ``ValueError``. + ## Classes and Methods + + - Query() + - `commit()` """ method_name = inspect.stack()[0][3] key = f"{method_name}" @@ -350,6 +369,7 @@ class MockMaintenanceModeInfo: # pylint: disable=too-few-public-methods """ Mocked MaintenanceModeInfo class. """ + def __init__(self, *args): pass @@ -367,7 +387,5 @@ def refresh(self): match += r"Error detail: MockMaintenanceModeInfo\.refresh:\s+" match += r"Mocked ValueError\." with pytest.raises(ValueError, match=match): - monkeypatch.setattr( - instance, "maintenance_mode_info", MockMaintenanceModeInfo() - ) + monkeypatch.setattr(instance, "maintenance_mode_info", MockMaintenanceModeInfo()) instance.commit() diff --git a/tests/unit/modules/dcnm/dcnm_maintenance_mode/test_dcnm_maintenance_mode_want.py b/tests/unit/modules/dcnm/dcnm_maintenance_mode/test_dcnm_maintenance_mode_want.py index 31d79f753..500352185 100644 --- a/tests/unit/modules/dcnm/dcnm_maintenance_mode/test_dcnm_maintenance_mode_want.py +++ b/tests/unit/modules/dcnm/dcnm_maintenance_mode/test_dcnm_maintenance_mode_want.py @@ -1,4 +1,7 @@ -# Copyright (c) 2024 Cisco and/or its affiliates. +""" +Unit tests for dcnm_maintenance_mode Want class. +""" +# Copyright (c) 2024-2025 Cisco and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -21,37 +24,36 @@ from __future__ import absolute_import, division, print_function -__metaclass__ = type +__metaclass__ = type # pylint: disable=invalid-name -__copyright__ = "Copyright (c) 2024 Cisco and/or its affiliates." +__copyright__ = "Copyright (c) 2024-2025 Cisco and/or its affiliates." __author__ = "Allen Robel" import copy import inspect import pytest -from ansible_collections.cisco.dcnm.plugins.modules.dcnm_maintenance_mode import ( - ParamsSpec, Want) -from ansible_collections.cisco.dcnm.tests.unit.module_utils.common.common_utils import \ - ResponseGenerator -from ansible_collections.cisco.dcnm.tests.unit.module_utils.common.test_params_validate_v2 import \ - ParamsValidate -from ansible_collections.cisco.dcnm.tests.unit.modules.dcnm.dcnm_maintenance_mode.utils import ( - configs_want, does_not_raise, params) +from ansible_collections.cisco.dcnm.plugins.modules.dcnm_maintenance_mode import ParamsSpec, Want +from ansible_collections.cisco.dcnm.tests.unit.module_utils.common.common_utils import ResponseGenerator +from ansible_collections.cisco.dcnm.tests.unit.module_utils.common.test_params_validate_v2 import ParamsValidate +from ansible_collections.cisco.dcnm.tests.unit.modules.dcnm.dcnm_maintenance_mode.utils import configs_want, does_not_raise, params def test_dcnm_maintenance_mode_want_00000() -> None: """ - ### Classes and Methods - - Common - - __init__() + # Summary + + Verify the class attributes are initialized to expected values. - ### Summary - - Verify the class attributes are initialized to expected values. + ## Test - ### Test - Class attributes are initialized to expected values - - ``ValueError`` is not called + - `ValueError` is not called + + ## Classes and Methods + + - Common + - `__init__()` """ with does_not_raise(): instance = Want() @@ -68,14 +70,17 @@ def test_dcnm_maintenance_mode_want_00000() -> None: def test_dcnm_maintenance_mode_want_00100() -> None: """ - ### Classes and Methods - - Want() - - commit() + # Summary - ### Summary - - Verify ``commit()`` happy path. - - No exceptions are raised. - - want contains expected structure and values. + Verify `commit()` happy path. + + - No exceptions are raised. + - want contains expected structure and values. + + ## Classes and Methods + + - Want() + - `commit()` """ method_name = inspect.stack()[0][3] key = f"{method_name}a" @@ -108,13 +113,16 @@ def configs(): def test_dcnm_maintenance_mode_want_00110() -> None: """ - ### Classes and Methods - - Want() - - commit() + # Summary + + Verify `ValueError` is raised. - ### Summary - - Verify ``ValueError`` is raised. - - Want().validator is not set prior to calling commit(). + - `Want().validator` is not set prior to calling `commit()`. + + ## Classes and Methods + + - Want() + - `commit()` """ method_name = inspect.stack()[0][3] key = f"{method_name}a" @@ -141,14 +149,17 @@ def configs(): def test_dcnm_maintenance_mode_want_00120() -> None: """ - ### Classes and Methods - - Want() - - commit() + # Summary + + Verify `Want().commit()` catches and re-raises `ValueError`. + + - `Want().generate_params_spec()` raises `ValueError` because + `params` is not set. - ### Summary - - Verify Want().commit() catches and re-raises ``ValueError``. - - Want().generate_params_spec() raises ``ValueError`` because - ``params`` is not set. + ## Classes and Methods + + - Want() + - `commit()` """ method_name = inspect.stack()[0][3] key = f"{method_name}a" @@ -178,14 +189,17 @@ def configs(): def test_dcnm_maintenance_mode_want_00121() -> None: """ - ### Classes and Methods - - Want() - - commit() + # Summary + + Verify `Want().commit()` catches and re-raises `ValueError`. + + - `Want().generate_params_spec()` raises `ValueError` because + `params_spec` is not set. - ### Summary - - Verify Want().commit() catches and re-raises ``ValueError``. - - Want().generate_params_spec() raises ``ValueError`` because - ``params_spec`` is not set. + ## Classes and Methods + + - Want() + - `commit()` """ method_name = inspect.stack()[0][3] key = f"{method_name}a" @@ -215,14 +229,17 @@ def configs(): def test_dcnm_maintenance_mode_want_00130() -> None: """ - ### Classes and Methods - - Want() - - commit() + # Summary + + Verify `Want().commit()` catches and re-raises `ValueError`. + + - `Want()._merge_global_and_item_configs()` raises `ValueError` + because `config` is not set. + + ## Classes and Methods - ### Summary - - Verify Want().commit() catches and re-raises ``ValueError``. - - Want()._merge_global_and_item_configs() raises ``ValueError`` - because ``config`` is not set. + - Want() + - `commit()` """ method_name = inspect.stack()[0][3] key = f"{method_name}a" @@ -252,14 +269,17 @@ def configs(): def test_dcnm_maintenance_mode_want_00131() -> None: """ - ### Classes and Methods - - Want() - - commit() + # Summary + + Verify `Want().commit()` catches and re-raises `ValueError`. - ### Summary - - Verify Want().commit() catches and re-raises ``ValueError``. - - Want()._merge_global_and_item_configs() raises ``ValueError`` - because ``items_key`` is not set. + - `Want()._merge_global_and_item_configs()` raises `ValueError` + because `items_key` is not set. + + ## Classes and Methods + + - Want() + - `commit()` """ method_name = inspect.stack()[0][3] key = f"{method_name}a" @@ -289,14 +309,17 @@ def configs(): def test_dcnm_maintenance_mode_want_00132() -> None: """ - ### Classes and Methods - - Want() - - commit() + # Summary + + Verify `Want().commit()` catches and re-raises `ValueError`. + + - `Want()._merge_global_and_item_configs()` raises `ValueError` + because `config` is missing the key specified by `items_key`. - ### Summary - - Verify Want().commit() catches and re-raises ``ValueError``. - - Want()._merge_global_and_item_configs() raises ``ValueError`` - because ``config`` is missing the key specified by items_key. + ## Classes and Methods + + - Want() + - `commit()` """ method_name = inspect.stack()[0][3] key = f"{method_name}a" @@ -327,14 +350,17 @@ def configs(): def test_dcnm_maintenance_mode_want_00133(monkeypatch) -> None: """ - ### Classes and Methods - - Want() - - commit() + # Summary - ### Summary - - Verify Want().commit() catches and re-raises ``ValueError``. - - Want()._merge_global_and_item_configs() raises ``ValueError`` - because MergeDict().commit() raises ``ValueError``. + Verify `Want().commit()` catches and re-raises `ValueError`. + + - `Want()._merge_global_and_item_configs()` raises `ValueError` + because `MergeDict().commit()` raises `ValueError`. + + ## Classes and Methods + + - Want() + - `commit()` """ method_name = inspect.stack()[0][3] key = f"{method_name}a" @@ -355,11 +381,13 @@ class MockMergeDicts: # pylint: disable=too-few-public-methods @staticmethod def commit(): """ - ### Summary - Mock method for MergeDicts().commit(). + # Summary + + Mock method for `MergeDicts().commit()`. - ### Raises - ValueError: Always + ## Raises + + - `ValueError`: Always """ raise ValueError("MergeDicts().commit(). ValueError.") @@ -382,14 +410,17 @@ def commit(): def test_dcnm_maintenance_mode_want_00140(monkeypatch) -> None: """ - ### Classes and Methods - - Want() - - commit() + # Summary + + Verify `Want().commit()` catches and re-raises `ValueError` + when `Want().validate_configs()` raises `ValueError`. - ### Summary - - Verify Want().commit() catches and re-raises ``ValueError`` - when Want().validate_configs() raises ``ValueError``. - - Want().validate_configs() is mocked to raise ``ValueError``. + - `Want().validate_configs()` is mocked to raise `ValueError`. + + ## Classes and Methods + + - Want() + - `commit()` """ method_name = inspect.stack()[0][3] key = f"{method_name}a" @@ -422,12 +453,14 @@ def mock_def(): def test_dcnm_maintenance_mode_want_00200() -> None: """ - ### Classes and Methods - - Want() - - config.setter + # Summary + + Verify `Want().config` raises `TypeError` when `config` is not a dict. + + ## Classes and Methods - ### Summary - - Verify Want().config raises ``TypeError`` when config is not a dict. + - Want() + - `config.setter` """ with does_not_raise(): instance = Want() @@ -440,13 +473,15 @@ def test_dcnm_maintenance_mode_want_00200() -> None: def test_dcnm_maintenance_mode_want_00300() -> None: """ - ### Classes and Methods - - Want() - - items_key.setter + # Summary + + Verify `Want().items_key` raises `TypeError` when `items_key` is not + a string. - ### Summary - - Verify Want().items_key raises ``TypeError`` when items_key is not - a string. + ## Classes and Methods + + - Want() + - `items_key.setter` """ with does_not_raise(): instance = Want() @@ -459,12 +494,14 @@ def test_dcnm_maintenance_mode_want_00300() -> None: def test_dcnm_maintenance_mode_want_00400() -> None: """ - ### Classes and Methods - - Want() - - params.setter + # Summary - ### Summary - Verify Want().params happy path. + Verify `Want().params` happy path. + + ## Classes and Methods + + - Want() + - `params.setter` """ with does_not_raise(): instance = Want() @@ -473,12 +510,14 @@ def test_dcnm_maintenance_mode_want_00400() -> None: def test_dcnm_maintenance_mode_want_00410() -> None: """ - ### Classes and Methods - - Want() - - params.setter + # Summary + + Verify `Want().params` raises `TypeError` when `params` is not a dict. + + ## Classes and Methods - ### Summary - - Verify Want().params raises ``TypeError`` when params is not a dict. + - Want() + - `params.setter` """ with does_not_raise(): instance = Want() @@ -491,12 +530,14 @@ def test_dcnm_maintenance_mode_want_00410() -> None: def test_dcnm_maintenance_mode_want_00500() -> None: """ - ### Classes and Methods - - Want() - - params_spec.setter + # Summary - ### Summary - Verify Want().params_spec happy path. + Verify `Want().params_spec` happy path. + + ## Classes and Methods + + - Want() + - `params_spec.setter` """ with does_not_raise(): instance = Want() @@ -505,13 +546,15 @@ def test_dcnm_maintenance_mode_want_00500() -> None: def test_dcnm_maintenance_mode_want_00510() -> None: """ - ### Classes and Methods - - Want() - - params_spec.setter + # Summary + + Verify `Want().params_spec` raises `TypeError` when `params_spec` + is not an instance of `ParamsSpec()`. + + ## Classes and Methods - ### Summary - - Verify Want().params_spec raises ``TypeError`` when params_spec - is not an instance of ParamsSpec(). + - Want() + - `params_spec.setter` """ with does_not_raise(): instance = Want() @@ -526,14 +569,16 @@ def test_dcnm_maintenance_mode_want_00510() -> None: def test_dcnm_maintenance_mode_want_00520() -> None: """ - ### Classes and Methods - - Want() - - params_spec.setter + # Summary - ### Summary - Verify Want().params_spec raises ``TypeError`` when params_spec - is not an instance of ParamsSpec(), but IS an instance of another + Verify `Want().params_spec` raises `TypeError` when `params_spec` + is not an instance of `ParamsSpec()`, but IS an instance of another class. + + ## Classes and Methods + + - Want() + - `params_spec.setter` """ with does_not_raise(): instance = Want() @@ -547,12 +592,14 @@ def test_dcnm_maintenance_mode_want_00520() -> None: def test_dcnm_maintenance_mode_want_00600() -> None: """ - ### Classes and Methods - - Want() - - validator.setter + # Summary - ### Summary - Verify Want().validator happy path. + Verify `Want().validator` happy path. + + ## Classes and Methods + + - Want() + - `validator.setter` """ with does_not_raise(): instance = Want() @@ -561,13 +608,15 @@ def test_dcnm_maintenance_mode_want_00600() -> None: def test_dcnm_maintenance_mode_want_00610() -> None: """ - ### Classes and Methods - - Want() - - validator.setter + # Summary + + Verify `Want().validator` raises `TypeError` when `validator` + is not an instance of `ParamsValidate()`. + + ## Classes and Methods - ### Summary - - Verify Want().validator raises ``TypeError`` when validator - is not an instance of ParamsValidate(). + - Want() + - `validator.setter` """ with does_not_raise(): instance = Want() @@ -582,14 +631,16 @@ def test_dcnm_maintenance_mode_want_00610() -> None: def test_dcnm_maintenance_mode_want_00620() -> None: """ - ### Classes and Methods - - Want() - - validator.setter + # Summary - ### Summary - Verify Want().validator raises ``TypeError`` when validator - is not an instance of ParamsValidate(), but IS an instance of + Verify `Want().validator` raises `TypeError` when `validator` + is not an instance of `ParamsValidate()`, but IS an instance of another class. + + ## Classes and Methods + + - Want() + - `validator.setter` """ with does_not_raise(): instance = Want() diff --git a/tests/unit/modules/dcnm/dcnm_maintenance_mode/utils.py b/tests/unit/modules/dcnm/dcnm_maintenance_mode/utils.py index 93245efd8..829316ab3 100644 --- a/tests/unit/modules/dcnm/dcnm_maintenance_mode/utils.py +++ b/tests/unit/modules/dcnm/dcnm_maintenance_mode/utils.py @@ -20,16 +20,11 @@ from contextlib import contextmanager import pytest -from ansible_collections.ansible.netcommon.tests.unit.modules.utils import \ - AnsibleFailJson -from ansible_collections.cisco.dcnm.plugins.module_utils.common.response_handler import \ - ResponseHandler -from ansible_collections.cisco.dcnm.plugins.module_utils.fabric.fabric_details_v2 import \ - FabricDetailsByName as FabricDetailsByNameV2 -from ansible_collections.cisco.dcnm.plugins.modules.dcnm_maintenance_mode import \ - Common -from ansible_collections.cisco.dcnm.tests.unit.modules.dcnm.dcnm_maintenance_mode.fixture import \ - load_fixture +from ansible_collections.ansible.netcommon.tests.unit.modules.utils import AnsibleFailJson +from ansible_collections.cisco.dcnm.plugins.module_utils.common.response_handler import ResponseHandler +from ansible_collections.cisco.dcnm.plugins.module_utils.fabric.fabric_details_v2 import FabricDetailsByName as FabricDetailsByNameV2 +from ansible_collections.cisco.dcnm.plugins.modules.dcnm_maintenance_mode import Common +from ansible_collections.cisco.dcnm.tests.unit.modules.dcnm.dcnm_maintenance_mode.fixture import load_fixture params_query = { "state": "query",