Skip to content

Commit

Permalink
tests: cover the module params generation (#77)
Browse files Browse the repository at this point in the history
tests: cover the module params generation

The generation of the final parameter structure is slightly complicated.
This commit breaks the _prepare_args() method in two and adds test coverage.

Reviewed-by: None <None>
Reviewed-by: Mike Graves <[email protected]>
Reviewed-by: Alina Buzachis <None>
Reviewed-by: None <None>
  • Loading branch information
goneri authored Sep 14, 2021
1 parent d43c018 commit c0e46bb
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 38 deletions.
83 changes: 45 additions & 38 deletions plugins/module_utils/turbo/module.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,47 @@ def get_collection_name_from_path():
return ".".join(ansiblez[8:].split(".")[:2])


def expand_argument_specs_aliases(argument_spec):
"""Returns a dict of accepted argument that includes the aliases"""
expanded_argument_specs = {}
for k, v in argument_spec.items():
for alias in [k] + v.get("aliases", []):
expanded_argument_specs[alias] = v
return expanded_argument_specs


def prepare_args(argument_specs, params):
"""Take argument_spec and the user params and prepare the final argument structure."""

def _keep_value(v, argument_specs, key, subkey=None):
if v is None: # cannot be a valide parameter
return False
if key not in argument_specs: # should never happen
return
if not subkey: # level 1 parameter
return v != argument_specs[key].get("default")
elif subkey not in argument_specs[key]: # Freeform
return True
elif isinstance(argument_specs[key][subkey], dict):
return v != argument_specs[key][subkey].get("default")
else: # should never happen
return True

new_params = {}
for k, v in params.items():
if not _keep_value(v, argument_specs, k):
continue

if isinstance(v, dict):
new_params[k] = {
i: j for i, j in v.items() if _keep_value(j, argument_specs, k, i)
}
else:
new_params[k] = v
args = {"ANSIBLE_MODULE_ARGS": new_params}
return args


class AnsibleTurboModule(ansible.module_utils.basic.AnsibleModule):
embedded_in_server = False
collection_name = None
Expand All @@ -47,43 +88,9 @@ def socket_path(self):
abs_remote_tmp = expanduser(self._remote_tmp)
return abs_remote_tmp + f"/turbo_mode.{self.collection_name}.socket"

def _get_argument_specs(self):
"""Returns a dict of accepted argument that includes the aliases"""
argument_specs = {}
for k, v in self.argument_spec.items():
for alias in [k] + v.get("aliases", []):
argument_specs[alias] = v
return argument_specs

def _prepare_args(self):
argument_specs = self._get_argument_specs()

def _keep_value(v, argument_specs, key, subkey=None):
if v is None: # cannot be a valide parameter
return False
if key not in argument_specs: # should never happen
return
if not subkey: # level 1 parameter
return v != argument_specs[key].get("default")
elif subkey not in argument_specs[key]: # Freeform
return True
elif isinstance(argument_specs[key][subkey], dict):
return v != argument_specs[key][subkey].get("default")
else: # should never happen
return True

new_params = {}
for k, v in self.params.items():
if not _keep_value(v, argument_specs, k):
continue

if isinstance(v, dict):
new_params[k] = {
i: j for i, j in v.items() if _keep_value(j, argument_specs, k, i)
}
else:
new_params[k] = v
args = {"ANSIBLE_MODULE_ARGS": new_params}
def init_args(self):
argument_specs = expand_argument_specs_aliases(self.argument_spec)
args = prepare_args(argument_specs, self.params)
for k in ansible.module_utils.basic.PASS_VARS:
attribute = ansible.module_utils.basic.PASS_VARS[k][0]
if not hasattr(self, attribute):
Expand All @@ -100,7 +107,7 @@ def run_on_daemon(self):
socket_path=self.socket_path(), ttl=ttl
) as turbo_socket:
ansiblez_path = sys.path[0]
args = self._prepare_args()
args = self.init_args()
data = [
ansiblez_path,
json.dumps(args),
Expand Down
34 changes: 34 additions & 0 deletions tests/unit/module_utils/test_turbo_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
import ansible.module_utils.basic
from ansible_collections.cloud.common.plugins.module_utils.turbo.module import (
get_collection_name_from_path,
expand_argument_specs_aliases,
prepare_args,
)
import ansible_collections.cloud.common.plugins.module_utils.turbo.common as turbo_common

Expand Down Expand Up @@ -92,3 +94,35 @@ def test_connect(monkeypatch):
turbo_socket = turbo_common.AnsibleTurboSocket(socket_path="/nowhere")
assert turbo_socket.bind()
mocked_socket.connect_assert_called_once_with("/nowhere")


def test_expand_argument_specs_aliases():
argspec = {"foo": {"type": int, "aliases": ["bar"]}}
assert expand_argument_specs_aliases(argspec) == {
"foo": {"type": int, "aliases": ["bar"]},
"bar": {"type": int, "aliases": ["bar"]},
}


def test_prepare_args():
argspec = {"foo": {"type": int}}
params = {"foo": 1}
assert prepare_args(argspec, params) == {"ANSIBLE_MODULE_ARGS": {"foo": 1}}


def test_prepare_args_ignore_none():
argspec = {"foo": {"type": int}}
params = {"foo": None}
assert prepare_args(argspec, params) == {"ANSIBLE_MODULE_ARGS": {}}


def test_prepare_args_subkey_freeform():
argspec = {"foo": {"type": dict, "default": {}}}
params = {"foo": {"bar": 1}}
assert prepare_args(argspec, params) == {"ANSIBLE_MODULE_ARGS": {"foo": {"bar": 1}}}


def test_prepare_args_subkey_with_default():
argspec = {"foo": {"bar": {"default": 1}}}
params = {"foo": {"bar": 1}}
assert prepare_args(argspec, params) == {"ANSIBLE_MODULE_ARGS": {"foo": {}}}

0 comments on commit c0e46bb

Please sign in to comment.