Skip to content

Commit 807ca85

Browse files
authored
crud_tests (#66)
* Create `test_crud.py` to run test playbooks with pytest * Remove Display import as it leads to import errors and it is not needed * Extend contribution documentation. Add steps to provide needed stuff when someone want to contribute.
1 parent 032fb35 commit 807ca85

File tree

8 files changed

+166
-10
lines changed

8 files changed

+166
-10
lines changed

CONTRIBUTING.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,38 @@
3030

3131
* If you want to start to work on a new module we suggest to read [How to write new phpipam [email protected]](https://codeaffen.org/2021-01-07-writing-phpipam-ansible-modules/).
3232

33+
### Create your feature in a branch of your fork
34+
35+
Fork our repository and create a new branch for your feature. Then start to work on your feature.
36+
37+
### Add tests for your new feature
38+
39+
To make sure that your feature is working as expected and to make sure that it is not breaking any existing functionality, you should add tests for your new feature. To do so, you
40+
41+
1. need to have a working phpipam installation.
42+
2. export the following environment variables:
43+
* PHPIPAM_URL - the URL of your phpipam installation (e.g. `https://localhost`)
44+
* PHPIPAM_USERNAME - the username to login to phpipam
45+
* PHPIPAM_PASSWORD - the password to login to phpipam
46+
* PHPIPAM_APPID - the appid to login to phpipam
47+
3. add a new task definition for your new feature in tests/test_playbooks/tasks/
48+
4. add a vars definition for your new feature in tests/test_playbooks/vars/
49+
5. add a crud playbook for your new feature in tests/test_playbooks/
50+
The playbook should contain the following steps:
51+
* import vars files `vars/server.yml` and `vars/<yourtest>.yml`
52+
* tasks for
53+
* create a new entity
54+
* create a new entity again to make sure that it will not changed
55+
* update the entity
56+
* delete the entity
57+
6. run your test with `ansible-playbook --inventory=tests/inventory/hosts tests/test_playbooks/<yourtest>.yml -vvv` to make sure that your feature is working as expected
58+
7. run your test again with `make test-<yourtest>`
59+
8. run all tests with `make test-all` to make sure that your feature does not break any existing functionality
60+
61+
### Create pull request for your new feature
62+
63+
When you are done, push your changes to your fork and create a pull request. Please make sure that you have squashed your changes before you create the pull request. Provide a clear description of your feature and the changes you made.
64+
3365
## Do you wnat to contribute to documentation?
3466

3567
* Fork me.

Makefile

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
YAML_INSTALLED:=$(shell pip install pyyaml)
12
NAMESPACE := $(shell python -c 'import yaml; print(yaml.safe_load(open("galaxy.yml"))["namespace"])')
23
NAME := $(shell python -c 'import yaml; print(yaml.safe_load(open("galaxy.yml"))["name"])')
34
VERSION := $(shell python -c 'import yaml; print(yaml.safe_load(open("galaxy.yml"))["version"])')
@@ -15,6 +16,9 @@ SANITY_OPTS = --venv
1516
TEST =
1617
PYTEST = pytest -n 4 --boxed -v
1718

19+
SHELL = bash
20+
.ONESHELL:
21+
1822
default: help
1923

2024
help:
@@ -43,6 +47,9 @@ $(NAMESPACE)-$(NAME)-$(VERSION).tar.gz: $(addprefix build/src/,$(DEPENDENCIES))
4347

4448
dist: $(NAMESPACE)-$(NAME)-$(VERSION).tar.gz
4549

50+
install: $(NAMESPACE)-$(NAME)-$(VERSION).tar.gz
51+
ansible-galaxy collection install $< --force
52+
4653
release-%:
4754
bumpversion $*
4855
antsibull-changelog release
@@ -67,6 +74,21 @@ doc: $(MANIFEST)
6774
antsibull-docs collection --use-current --squash-hierarchy --dest-dir ./docs/plugins codeaffen.phpipam
6875
make -C docs html
6976

77+
test-setup: | tests/test_playbooks/vars/server.yml install-deps install
78+
test -f tests/test_playbooks/vars/server.yml
79+
80+
test-all:
81+
coverage run -m pytest -n 4 --forked -vv 'tests/test_crud.py::test_crud'
82+
83+
test-%:
84+
coverage run -m pytest --forked -vv 'tests/test_crud.py::test_case_crud' --testcase $*
85+
86+
tests/test_playbooks/vars/server.yml:
87+
sed -e "s#~~url~~#$(PHPIPAM_URL)#" -e "s#~~app_id~~#$(PHPIPAM_APPID)#" -e "s#~~username~~#$(PHPIPAM_USERNAME)#" -e "s#~~password~~#$(PHPIPAM_PASSWORD)#" $@.example > $@
88+
89+
install-deps:
90+
pip install -r requirements-dev.txt
91+
7092
FORCE:
7193

72-
.PHONY: help dist lint doc-setup doc publish FORCE
94+
.PHONY: help dist lint doc-setup doc publish test-setup test-all test-% install-deps FORCE

plugins/module_utils/phpipam_helper.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,6 @@
2525

2626
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
2727

28-
from ansible.utils.display import Display
29-
display = Display()
30-
3128

3229
class PhpipamAnsibleException(Exception):
3330
pass

requirements-dev.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
ansible
2-
colour
3-
geopy
2+
ansible_runner<2.0; python_version < '3.6'
3+
ansible_runner; python_version >= '3.6'
4+
coverage
45
wheel
56
jinja2 # pyup: ignore
67
PyYAML~=5.3
@@ -9,6 +10,7 @@ packaging
910
requests
1011
phpypam
1112
pytest
13+
pytest-forked
1214
pytest-xdist
1315
flake8
1416
docker

tests/__init__.py

Whitespace-only changes.

tests/conftest.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import os
2+
3+
import ansible_runner
4+
import pytest
5+
import py.path # type: ignore
6+
import yaml
7+
8+
9+
TEST_PLAYBOOKS_PATH = py.path.local(__file__).realpath() / '..' / 'test_playbooks'
10+
11+
12+
def find_all_test_playbooks():
13+
for playbook in TEST_PLAYBOOKS_PATH.listdir(sort=True):
14+
playbook = playbook.basename
15+
if playbook.endswith('.yml'):
16+
yield playbook.replace('.yml', '')
17+
18+
19+
TEST_PLAYBOOKS = list(find_all_test_playbooks())
20+
21+
22+
def pytest_addoption(parser):
23+
parser.addoption(
24+
"--testcase",
25+
action="store",
26+
default="",
27+
help="testcase to run",
28+
)
29+
30+
31+
@pytest.fixture
32+
def testcase(request):
33+
return request.config.getoption('testcase')
34+
35+
36+
def get_phpipam_url():
37+
server_yml = py.path.local(__file__).realpath() / '..' / 'test_playbooks/vars/server.yml'
38+
with open(server_yml.strpath) as server_yml_file:
39+
server_yml_content = yaml.safe_load(server_yml_file)
40+
41+
return server_yml_content['phpipam_server_url']
42+
43+
44+
def run_playbook(module, extra_vars=None, limit=None, inventory=None, check_mode=False, extra_env=None):
45+
# Assemble parameters for playbook call
46+
os.environ['ANSIBLE_CONFIG'] = os.path.join(os.getcwd(), 'ansible.cfg')
47+
if extra_env is not None:
48+
os.environ.update(extra_env)
49+
kwargs = {}
50+
kwargs['playbook'] = os.path.join(os.getcwd(), 'tests', 'test_playbooks', '{}.yml'.format(module))
51+
if inventory is None:
52+
inventory = os.path.join(os.getcwd(), 'tests', 'inventory', 'hosts')
53+
kwargs['inventory'] = inventory
54+
kwargs['verbosity'] = 4
55+
if extra_vars:
56+
kwargs['extravars'] = extra_vars
57+
if limit:
58+
kwargs['limit'] = limit
59+
if check_mode:
60+
kwargs['cmdline'] = "--check"
61+
return ansible_runner.run(**kwargs)

tests/test_crud.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import os
2+
import sys
3+
4+
import pytest
5+
6+
from .conftest import TEST_PLAYBOOKS, run_playbook
7+
8+
IGNORED_WARNINGS = [
9+
"Activation Key 'Test Activation Key Copy' already exists.",
10+
]
11+
12+
if sys.version_info[0] == 2:
13+
for envvar in os.environ.keys():
14+
try:
15+
os.environ[envvar] = os.environ[envvar].decode('utf-8').encode('ascii', 'ignore')
16+
except UnicodeError:
17+
os.environ.pop(envvar)
18+
19+
20+
@pytest.mark.parametrize('module', TEST_PLAYBOOKS)
21+
def test_crud(module):
22+
run = run_playbook(module)
23+
assert run.rc == 0
24+
25+
_assert_no_warnings(run)
26+
27+
28+
def test_case_crud(testcase):
29+
run = run_playbook(testcase)
30+
assert run.rc == 0
31+
32+
_assert_no_warnings(run)
33+
34+
35+
def _assert_no_warnings(run):
36+
for event in run.events:
37+
# check for play level warnings
38+
assert not event.get('event_data', {}).get('warning', False)
39+
40+
# check for task level warnings
41+
event_warnings = [warning for warning in event.get('event_data', {}).get('res', {}).get('warnings', []) if warning not in IGNORED_WARNINGS]
42+
assert [] == event_warnings, str(event_warnings)
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
# Parameter for all tests
3-
phpipam_server_url: "https://ipam.example.com"
4-
phpipam_app_id: ansible
5-
phpipam_username: test
6-
phpipam_password: "test123"
3+
phpipam_server_url: '~~url~~'
4+
phpipam_app_id: ~~app_id~~
5+
phpipam_username: ~~username~~
6+
phpipam_password: ~~password~~

0 commit comments

Comments
 (0)