Skip to content

Commit

Permalink
Fixed end2end test concept and testcases
Browse files Browse the repository at this point in the history
Details:

* Test: Added missing env.vars in the pytest invocation for end2end tests.

* Test: Added support for specifying 'hmc_auth.ca_certs' and 'hmc_auth.verify'
  from the 'hmc_verify_cert' parameter in the HMC definition file in
  end2end test cases for zhmc_partition and zhmc_user.

* Test: Made end2end testing compatible with zhmcclient.testutils support for
  HMC definition files.
  The HMC definition file is now by default ~/.hmc_hmc_definitions.yaml, and
  the env.var to override that is now TESTHMCFILE.

* Test: Added support for a TESTCASES env.var for filtering testcases with the
  pytest -k option.

* Fixed incorrect assumption about defaulting of optional module parameters:
  This is only done automatically when the module is invoked by ansible,
  but not when invoked by the end2end testcases. Changed the end2end testcases
  for zhmc_partition and zhmc_user to specify the optional parameters.

Signed-off-by: Andreas Maier <maiera@de.ibm.com>
  • Loading branch information
andy-maier committed Apr 10, 2022
1 parent f34d582 commit 82a5d61
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 51 deletions.
40 changes: 24 additions & 16 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -86,16 +86,16 @@ test_py_files := \
$(wildcard $(test_dir)/*/*.py) \
$(wildcard $(test_dir)/*/*/*.py) \

# Directory with hmc_definitions.yaml file for end2end tests
default_test_hmc_dir := ../python-zhmcclient/tests
ifndef TESTHMCDIR
TESTHMCDIR := $(default_test_hmc_dir)
# Path name of default HMC definitions file used for end2end tests.
default_testhmcfile := ~/.zhmc_hmc_definitions.yaml
ifndef TESTHMCFILE
TESTHMCFILE := $(default_testhmcfile)
endif

# Nickname of test HMC in hmc_definitions.yaml file for end2end tests
default_test_hmc := default
# Default HMC nickname in HMC definitions file
default_testhmc := default
ifndef TESTHMC
TESTHMC := $(default_test_hmc)
TESTHMC := $(default_testhmc)
endif

# Flake8 options
Expand Down Expand Up @@ -144,7 +144,11 @@ dist_dependent_files := \
sphinx_opts := -v

# Pytest options
pytest_opts := $(TESTOPTS) -s
ifdef TESTCASES
pytest_opts := --color=yes -s $(TESTOPTS) -k "$(TESTCASES)"
else
pytest_opts := --color=yes -s $(TESTOPTS)
endif
ifeq ($(python_m_n_version),3.4)
pytest_cov_opts :=
else
Expand Down Expand Up @@ -172,14 +176,18 @@ help:
@echo ' linkcheck - Check links in documentation'
@echo ' all - Do all of the above'
@echo ' end2end - Run end2end tests'
@echo ' upload - Publish the collection to Ansible Galaxy'
@echo ' upload - Publish the collection to Ansible Galaxy and AutomationHub'
@echo ' clobber - Remove any produced files'
@echo 'Environment variables:'
@echo ' TESTHMC=... - Nickname of HMC to be used in end2end tests. Default: $(default_test_hmc)'
@echo ' TESTHMCDIR=... - Path name of directory with hmc_definitions.yaml file. Default: $(default_test_hmc_dir)'
@echo ' TESTOPTS=... - Additional options for py.test (e.g. "-k test_module.py")'
@echo ' PACKAGE_LEVEL="minimum" - Install minimum version of dependent Python packages'
@echo ' PACKAGE_LEVEL="latest" - Default: Install latest version of dependent Python packages'
@echo " TESTCASES=... - Testcase filter for pytest -k (e.g. 'test_func' or 'test_mod.py')"
@echo " TESTOPTS=... - Additional options for pytest (e.g. '-x')"
@echo " TESTHMC=... - HMC nickname in HMC definitions file used in end2end tests. Default: $(default_testhmc)"
@echo " TESTHMCFILE=... - Path name of HMC definitions file used in end2end tests. Default: $(default_testhmcfile)"
@echo " PACKAGE_LEVEL - Package level to be used for installing dependent Python"
@echo " packages in 'install' and 'develop' targets:"
@echo " latest - Latest package versions available on Pypi"
@echo " minimum - A minimum version as defined in minimum-constraints.txt"
@echo " Optional, defaults to 'latest'."
@echo ' PYTHON_CMD=... - Name of python command. Default: python'
@echo ' PIP_CMD=... - Name of pip command. Default: pip'
@echo ' GALAXY_TOKEN=... - Your Ansible Galaxy API token, required for upload (see https://galaxy.ansible.com/me/preferences)'
Expand Down Expand Up @@ -212,7 +220,7 @@ linkcheck: _check_version develop_$(pymn).done $(doc_rst_files)

.PHONY: test
test: _check_version develop_$(pymn).done
bash -c 'PYTHONWARNINGS=default ANSIBLE_LIBRARY=$(module_py_dir) PYTHONPATH=. pytest $(pytest_cov_opts) $(pytest_opts) $(test_dir)/unit $(test_dir)/function'
bash -c 'PYTHONWARNINGS=default ANSIBLE_LIBRARY=$(module_py_dir) PYTHONPATH=. TESTHMCFILE=$(TESTHMCFILE) TESTHMC=$(TESTHMC) pytest $(pytest_cov_opts) $(pytest_opts) $(test_dir)/unit $(test_dir)/function'
@echo '$@ done.'

.PHONY: check
Expand All @@ -239,7 +247,7 @@ endif

.PHONY: end2end
end2end: _check_version develop_$(pymn).done
bash -c 'PYTHONWARNINGS=default TESTHMCDIR=$(TESTHMCDIR) TESTHMC=$(TESTHMC) py.test -v $(pytest_opts) $(test_dir)/end2end'
bash -c 'PYTHONWARNINGS=default ANSIBLE_LIBRARY=$(module_py_dir) PYTHONPATH=. TESTHMCFILE=$(TESTHMCFILE) TESTHMC=$(TESTHMC) pytest -v $(pytest_opts) $(test_dir)/end2end'
@echo '$@ done.'

.PHONY: upload
Expand Down
16 changes: 16 additions & 0 deletions docs/source/release_notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,24 @@ Availability: `AutomationHub`_, `Galaxy`_, `GitHub`_
module, and made the module result in check mode consistent with non-check
mode. (issue #507)

* Test: Added missing env.vars in the pytest invocation for end2end tests.

* Test: Added missing optional module parameters in the end2end tests.

* Test: Added support for specifying 'hmc_auth.ca_certs' and 'hmc_auth.verify'
from the 'hmc_verify_cert' parameter in the HMC definition file in
end2end test cases for zhmc_partition and zhmc_user.

**Enhancements:**

* Test: Made end2end testing compatible with zhmcclient.testutils support for
HMC definition files.
The HMC definition file is now by default ~/.hmc_hmc_definitions.yaml, and
the env.var to override that is now TESTHMCFILE.

* Test: Added support for a TESTCASES env.var for filtering testcases with the
pytest -k option.

**Cleanup:**

**Known issues:**
Expand Down
16 changes: 13 additions & 3 deletions tests/end2end/test_zhmc_partition.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import pytest
import mock
import requests.packages.urllib3
import six
import zhmcclient
from zhmcclient.testutils.hmc_definition_fixtures import hmc_definition, hmc_session # noqa: F401, E501

Expand Down Expand Up @@ -109,8 +110,14 @@ def test_partition_facts(ansible_mod_cls, check_mode, hmc_session): # noqa: F81

hd = hmc_session.hmc_definition

hmc_auth = dict(userid=hd.hmc_userid, password=hd.hmc_password)
if isinstance(hd.hmc_verify_cert, six.string_types):
hmc_auth['ca_certs'] = hd.hmc_verify_cert
elif isinstance(hd.hmc_verify_cert, bool):
hmc_auth['verify'] = hd.hmc_verify_cert

# Determine one of the CPCs in the HMC definition file to test
cpc_names = hd.cpcs.keys()
cpc_names = list(hd.cpcs.keys())
assert len(cpc_names) >= 1
cpc_name = cpc_names[0]

Expand All @@ -122,13 +129,16 @@ def test_partition_facts(ansible_mod_cls, check_mode, hmc_session): # noqa: F81
assert len(partitions) >= 1
partition = partitions[0] # Pick first partition in list

# Prepare module input parameters
# Prepare module input parameters (required + optional with default)
params = {
'hmc_host': hd.hmc_host,
'hmc_auth': dict(userid=hd.hmc_userid, password=hd.hmc_password),
'hmc_auth': hmc_auth,
'cpc_name': cpc_name,
'name': partition.name,
'state': 'facts',
'properties': {},
'expand_storage_groups': False,
'expand_crypto_adapters': False,
'log_file': None,
}

Expand Down
85 changes: 53 additions & 32 deletions tests/end2end/test_zhmc_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@
import uuid
import pytest
import mock
import random
import requests.packages.urllib3
from collections import OrderedDict
from pprint import pformat
import six
import zhmcclient
from zhmcclient.testutils.hmc_definition_fixtures import hmc_definition, hmc_session # noqa: F401, E501

Expand Down Expand Up @@ -214,41 +216,49 @@ def test_user_facts(ansible_mod_cls, expand, check_mode, hmc_session): # noqa:

hd = hmc_session.hmc_definition

hmc_auth = dict(userid=hd.hmc_userid, password=hd.hmc_password)
if isinstance(hd.hmc_verify_cert, six.string_types):
hmc_auth['ca_certs'] = hd.hmc_verify_cert
elif isinstance(hd.hmc_verify_cert, bool):
hmc_auth['verify'] = hd.hmc_verify_cert

# Determine an existing user to test.
client = zhmcclient.Client(hmc_session)
console = client.consoles.console

# Pick a random existing user to test
users = console.users.list()
assert len(users) >= 1

for user in users:

# Prepare module input parameters
params = {
'hmc_host': hd.hmc_host,
'hmc_auth': dict(userid=hd.hmc_userid, password=hd.hmc_password),
'name': user.name,
'state': 'facts',
'expand': expand,
'log_file': LOG_FILE,
}

# Prepare mocks for AnsibleModule object
mod_obj = mock_ansible_module(ansible_mod_cls, params, check_mode)

# Exercise the code to be tested
with pytest.raises(SystemExit) as exc_info:
zhmc_user.main()
exit_code = exc_info.value.args[0]

# Assert module exit code
assert exit_code == 0, \
"Module unexpectedly failed with this message:\n{0}". \
format(get_failure_msg(mod_obj))

# Assert module output
changed, user_props = get_module_output(mod_obj)
assert changed is False
assert_user_props(user_props, expand)
user = random.choice(users)

# Prepare module input parameters (required + optional with default)
params = {
'hmc_host': hd.hmc_host,
'hmc_auth': hmc_auth,
'name': user.name,
'state': 'facts',
'properties': {},
'expand': expand,
'log_file': LOG_FILE,
}

# Prepare mocks for AnsibleModule object
mod_obj = mock_ansible_module(ansible_mod_cls, params, check_mode)

# Exercise the code to be tested
with pytest.raises(SystemExit) as exc_info:
zhmc_user.main()
exit_code = exc_info.value.args[0]

# Assert module exit code
assert exit_code == 0, \
"Module unexpectedly failed with this message:\n{0}". \
format(get_failure_msg(mod_obj))

# Assert module output
changed, user_props = get_module_output(mod_obj)
assert changed is False
assert_user_props(user_props, expand)


USER_ABSENT_PRESENT_TESTCASES = [
Expand Down Expand Up @@ -335,8 +345,16 @@ def test_user_absent_present(
"""
Test the zhmc_user module with all combinations of absent & present state.
"""
expand = False # Expansion is tested elsewhere

hd = hmc_session.hmc_definition

hmc_auth = dict(userid=hd.hmc_userid, password=hd.hmc_password)
if isinstance(hd.hmc_verify_cert, six.string_types):
hmc_auth['ca_certs'] = hd.hmc_verify_cert
elif isinstance(hd.hmc_verify_cert, bool):
hmc_auth['verify'] = hd.hmc_verify_cert

expand = False # Expansion is tested elsewhere
client = zhmcclient.Client(hmc_session)
console = client.consoles.console

Expand Down Expand Up @@ -368,16 +386,19 @@ def test_user_absent_present(

try:

# Prepare module input parameters (required + optional with default)
params = {
'hmc_host': hd.hmc_host,
'hmc_auth': dict(userid=hd.hmc_userid, password=hd.hmc_password),
'hmc_auth': hmc_auth,
'name': user_name,
'state': input_state,
'expand': expand,
'log_file': LOG_FILE,
}
if input_props is not None:
params['properties'] = input_props
else:
params['properties'] = {}

mod_obj = mock_ansible_module(ansible_mod_cls, params, check_mode)

Expand Down
4 changes: 4 additions & 0 deletions tests/end2end/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
def mock_ansible_module(ansible_mod_cls, params, check_mode):
"""
Prepare mocks for AnsibleModule object.
Note: The params must include all required parameters declared in the
the module's argument_spec as well as all optional parameters with a
default value.
"""
mod_obj = ansible_mod_cls.return_value
mod_obj.params = params
Expand Down

0 comments on commit 82a5d61

Please sign in to comment.