Skip to content

Commit

Permalink
Initial unit tests and fixtures, more...
Browse files Browse the repository at this point in the history
Adding some initial unit tests.  As a result of these, found several issues which are address in the tested code for this commit.

Within tests/unit/modules/dcnm/dcnm_image_policy:
- utils.py: Add fixtures, add comments for unused fixtures to remove later
- test_image_policy_create.py: initial unit tests for ImagePolicyCreate()
- test_image_policy_create_bulk.py: initial unit tests for ImagePolicyCreateBulk()
- Add json data for above test cases

Within module_utils/image_policy
- update.py: refactor, run through linters, test changes
- replace.py: refactor, run through linters, test changes
- params_spec.py: run though linters
- delete.py: run through linters
- create.py: run through linters, refactor
- common.py: self.module should be self.ansible_module
  • Loading branch information
allenrobel committed Feb 9, 2024
1 parent 57accb0 commit 8b12057
Show file tree
Hide file tree
Showing 11 changed files with 598 additions and 114 deletions.
11 changes: 7 additions & 4 deletions plugins/module_utils/image_policy/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,12 @@
from typing import Any, Dict

# Using only for its failed_result property
# pylint: disable=line-too-long
from ansible_collections.cisco.dcnm.plugins.module_utils.image_policy.image_policy_task_result import \
ImagePolicyTaskResult

# pylint: enable=line-too-long


class ImagePolicyCommon:
"""
Expand Down Expand Up @@ -236,7 +239,7 @@ def response_current(self, value):
msg = f"{self.class_name}.{method_name}: "
msg += "instance.response_current must be a dict. "
msg += f"Got {value}."
self.module.fail_json(msg, **self.failed_result)
self.ansible_module.fail_json(msg, **self.failed_result)
self.properties["response_current"] = value

@property
Expand All @@ -256,7 +259,7 @@ def response(self, value):
msg = f"{self.class_name}.{method_name}: "
msg += "instance.response must be a dict. "
msg += f"Got {value}."
self.module.fail_json(msg, **self.failed_result)
self.ansible_module.fail_json(msg, **self.failed_result)
self.properties["response"].append(value)

@property
Expand Down Expand Up @@ -287,7 +290,7 @@ def result(self, value):
msg = f"{self.class_name}.{method_name}: "
msg += "instance.result must be a dict. "
msg += f"Got {value}."
self.module.fail_json(msg, **self.failed_result)
self.ansible_module.fail_json(msg, **self.failed_result)
self.properties["result"].append(value)

@property
Expand All @@ -307,5 +310,5 @@ def result_current(self, value):
msg = f"{self.class_name}.{method_name}: "
msg += "instance.result_current must be a dict. "
msg += f"Got {value}."
self.module.fail_json(msg, **self.failed_result)
self.ansible_module.fail_json(msg, **self.failed_result)
self.properties["result_current"] = value
63 changes: 34 additions & 29 deletions plugins/module_utils/image_policy/create.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# TODO: needs_testing

from __future__ import absolute_import, division, print_function

Expand All @@ -23,7 +22,6 @@
import inspect
import json
import logging
from typing import Any, Dict

from ansible_collections.cisco.dcnm.plugins.module_utils.image_mgmt.image_policies import \
ImagePolicies
Expand All @@ -50,8 +48,16 @@ def __init__(self, ansible_module):
self.log.debug("ENTERED ImagePolicyCreateCommon()")

self.endpoints = ApiEndpoints()
self._image_policies = ImagePolicies(self.ansible_module)

self.action = "create"
self._payloads_to_commit = []
self.response_ok = []
self.result_ok = []
self.diff_ok = []
self.response_nok = []
self.result_nok = []
self.diff_nok = []

self.path = self.endpoints.policy_create.get("path")
self.verb = self.endpoints.policy_create.get("verb")
Expand All @@ -69,7 +75,7 @@ def _verify_payload(self, payload):
if not isinstance(payload, dict):
msg = f"{self.class_name}.{method_name}: "
msg += "payload must be a dict. "
msg += f"gpt type {type(payload).__name__}, "
msg += f"Got type {type(payload).__name__}, "
msg += f"value {payload}"
self.ansible_module.fail_json(msg, **self.failed_result)

Expand All @@ -81,7 +87,7 @@ def _verify_payload(self, payload):
return

msg = f"{self.class_name}.{method_name}: "
msg += f"payload is missing mandatory keys: "
msg += "payload is missing mandatory keys: "
msg += f"{sorted(missing_keys)}"
self.ansible_module.fail_json(msg, **self.failed_result)

Expand All @@ -96,7 +102,6 @@ def _build_payloads_to_commit(self):
Populates self._payloads_to_commit with a list of payloads
to commit.
"""
self._image_policies = ImagePolicies(self.ansible_module)
self._image_policies.refresh()

self._payloads_to_commit = []
Expand Down Expand Up @@ -186,6 +191,29 @@ def _process_responses(self):
msg += f"response(s): {self.response_nok}"
self.ansible_module.fail_json(msg, **result)

@property
def payloads(self):
"""
Return the image policy payloads
Payloads must be a list of dict. Each dict is a
payload for the image policy create API endpoint.
"""
return self.properties["payloads"]

@payloads.setter
def payloads(self, value):
method_name = inspect.stack()[0][3]
if not isinstance(value, list):
msg = f"{self.class_name}.{method_name}: "
msg += "payloads must be a list of dict. "
msg += f"got {type(value).__name__} for "
msg += f"value {value}"
self.ansible_module.fail_json(msg, **self.failed_result)
for item in value:
self._verify_payload(item)
self.properties["payloads"] = value


class ImagePolicyCreateBulk(ImagePolicyCreateCommon):
"""
Expand Down Expand Up @@ -241,29 +269,6 @@ def _build_properties(self):
# properties dict is already initialized in the parent class
self.properties["payloads"] = None

@property
def payloads(self):
"""
Return the image policy payloads
Payloads must be a list of dict. Each dict is a
payload for the image policy create API endpoint.
"""
return self.properties["payloads"]

@payloads.setter
def payloads(self, value):
method_name = inspect.stack()[0][3]
if not isinstance(value, list):
msg = f"{self.class_name}.{method_name}: "
msg += "payloads must be a list of dict. "
msg += f"got {type(value).__name__} for "
msg += f"value {value}"
self.ansible_module.fail_json(msg, **self.failed_result)
for item in value:
self._verify_payload(item)
self.properties["payloads"] = value

def commit(self):
"""
create policies. Skip any policies that already exist
Expand Down Expand Up @@ -358,7 +363,7 @@ def commit(self):
self.payloads = [self.payload]
self._build_payloads_to_commit()

if self._payloads_to_commit == []:
if not self._payloads_to_commit:
return

self._send_payloads()
Expand Down
11 changes: 6 additions & 5 deletions plugins/module_utils/image_policy/delete.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import inspect
import json
import logging
from typing import Any, Dict

from ansible_collections.cisco.dcnm.plugins.module_utils.image_mgmt.image_policies import \
ImagePolicies
Expand Down Expand Up @@ -53,9 +52,10 @@ def __init__(self, ansible_module):
self.log = logging.getLogger(f"dcnm.{self.class_name}")
self.log.debug("ENTERED ImagePolicyDelete()")

self.endpoints = ApiEndpoints()
self.image_policies = ImagePolicies(self.ansible_module)
self.action = "delete"
self._build_properties()
self.endpoints = ApiEndpoints()

def _build_properties(self):
"""
Expand Down Expand Up @@ -87,7 +87,6 @@ def _get_policies_to_delete(self):
Retrieve policies from the controller and return the list of
controller policies that are in our policy_names list.
"""
self.image_policies = ImagePolicies(self.ansible_module)
self.image_policies.refresh()

policies_to_delete = []
Expand Down Expand Up @@ -119,15 +118,17 @@ def commit(self):
return

policy_names = policies_to_delete
self.log.debug(f"Deleting policies {policy_names}")
msg = f"Deleting policies {policy_names}"
self.log.debug(msg)

request_body = {"policyNames": policy_names}
response = dcnm_send(
self.ansible_module, verb, path, data=json.dumps(request_body)
)
result = self._handle_response(response, verb)

self.log.debug(f"response: {response}")
msg = f"response: {response}"
self.log.debug(msg)

if result["success"]:
self.changed = True
Expand Down
8 changes: 7 additions & 1 deletion plugins/module_utils/image_policy/params_spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,12 @@ def __init__(self, ansible_module):
self._params_spec: Dict[str, Any] = {}

def commit(self):
"""
build the parameter specification based on the state
"""
method_name = inspect.stack()[0][3]

if self.ansible_module.params["state"] == None:
if self.ansible_module.params["state"] is None:
self.ansible_module.fail_json(msg="state is None")

if self.ansible_module.params["state"] == "merged":
Expand Down Expand Up @@ -206,4 +209,7 @@ def _build_params_spec_for_replaced_state(self) -> None:

@property
def params_spec(self) -> Dict[str, Any]:
"""
return the parameter specification
"""
return self._params_spec
Loading

0 comments on commit 8b12057

Please sign in to comment.