diff options
Diffstat (limited to 'collections-debian-merged/ansible_collections/community/kubevirt/tests')
19 files changed, 943 insertions, 0 deletions
diff --git a/collections-debian-merged/ansible_collections/community/kubevirt/tests/integration/targets/inventory_kubevirt/aliases b/collections-debian-merged/ansible_collections/community/kubevirt/tests/integration/targets/inventory_kubevirt/aliases new file mode 100644 index 00000000..765b70da --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/kubevirt/tests/integration/targets/inventory_kubevirt/aliases @@ -0,0 +1 @@ +shippable/posix/group2 diff --git a/collections-debian-merged/ansible_collections/community/kubevirt/tests/integration/targets/inventory_kubevirt/constraints.txt b/collections-debian-merged/ansible_collections/community/kubevirt/tests/integration/targets/inventory_kubevirt/constraints.txt new file mode 100644 index 00000000..c44f44e9 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/kubevirt/tests/integration/targets/inventory_kubevirt/constraints.txt @@ -0,0 +1 @@ +setuptools < 45 ; python_version <= '2.7' # setuptools 45 and later require python 3.5 or later diff --git a/collections-debian-merged/ansible_collections/community/kubevirt/tests/integration/targets/inventory_kubevirt/inventory_diff.py b/collections-debian-merged/ansible_collections/community/kubevirt/tests/integration/targets/inventory_kubevirt/inventory_diff.py new file mode 100755 index 00000000..df5a7661 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/kubevirt/tests/integration/targets/inventory_kubevirt/inventory_diff.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import json +import sys + + +def check_hosts(contrib, plugin): + contrib_hosts = sorted(contrib['_meta']['hostvars'].keys()) + plugin_hosts = sorted(plugin['_meta']['hostvars'].keys()) + assert contrib_hosts == plugin_hosts + return contrib_hosts, plugin_hosts + + +def check_groups(contrib, plugin): + contrib_groups = set(contrib.keys()) + plugin_groups = set(plugin.keys()) + missing_groups = contrib_groups.difference(plugin_groups) + if missing_groups: + print("groups: %s are missing from the plugin" % missing_groups) + assert not missing_groups + return contrib_groups, plugin_groups + + +def check_host_vars(key, value, plugin, host): + # tags are a dict in the plugin + if key.startswith('ec2_tag'): + print('assert tag', key, value) + assert 'tags' in plugin['_meta']['hostvars'][host], 'b file does not have tags in host' + btags = plugin['_meta']['hostvars'][host]['tags'] + tagkey = key.replace('ec2_tag_', '') + assert tagkey in btags, '%s tag not in b file host tags' % tagkey + assert value == btags[tagkey], '%s != %s' % (value, btags[tagkey]) + else: + print('assert var', key, value, key in plugin['_meta']['hostvars'][host], plugin['_meta']['hostvars'][host].get(key)) + assert key in plugin['_meta']['hostvars'][host], "%s not in b's %s hostvars" % (key, host) + assert value == plugin['_meta']['hostvars'][host][key], "%s != %s" % (value, plugin['_meta']['hostvars'][host][key]) + + +def main(): + # a should be the source of truth (the script output) + a = sys.argv[1] + # b should be the thing to check (the plugin output) + b = sys.argv[2] + + with open(a, 'r') as f: + adata = json.loads(f.read()) + with open(b, 'r') as f: + bdata = json.loads(f.read()) + + print(adata) + print(bdata) + + # all hosts should be present obviously + ahosts, bhosts = check_hosts(adata, bdata) + + # all groups should be present obviously + agroups, bgroups = check_groups(adata, bdata) + + # check host vars can be reconstructed + for ahost in ahosts: + contrib_host_vars = adata['_meta']['hostvars'][ahost] + for key, value in contrib_host_vars.items(): + check_host_vars(key, value, bdata, ahost) + + +if __name__ == "__main__": + main() diff --git a/collections-debian-merged/ansible_collections/community/kubevirt/tests/integration/targets/inventory_kubevirt/runme.sh b/collections-debian-merged/ansible_collections/community/kubevirt/tests/integration/targets/inventory_kubevirt/runme.sh new file mode 100755 index 00000000..ea163ab1 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/kubevirt/tests/integration/targets/inventory_kubevirt/runme.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash + +if [[ $(python --version 2>&1) =~ 2\.6 ]] + then + echo "Openshift client is not supported on Python 2.6" + exit 0 +fi + +set -eux + +# TODO: quay.io/ansible/default-test-container:2.7.0 doesn't have virtualenv included +apt -y update +apt -y install python3-virtualenv + +source virtualenv.sh +pip install openshift -c constraints.txt + +./server.py & + +cleanup() { + kill -9 "$(jobs -p)" +} + +trap cleanup INT TERM EXIT + +# Fake auth file +mkdir -p ~/.kube/ +cat <<EOF > ~/.kube/config +apiVersion: v1 +clusters: +- cluster: + insecure-skip-tls-verify: true + server: http://localhost:12345 + name: development +contexts: +- context: + cluster: development + user: developer + name: dev-frontend +current-context: dev-frontend +kind: Config +preferences: {} +users: +- name: developer + user: + token: ZDNg7LzSlp8a0u0fht_tRnPMTOjxqgJGCyi_iy0ecUw +EOF + +################################################# +# RUN THE PLUGIN +################################################# + +# run the plugin second +export ANSIBLE_INVENTORY_ENABLED=community.kubevirt.kubevirt +export ANSIBLE_INVENTORY=test.kubevirt.yml + +cat << EOF > "$OUTPUT_DIR/test.kubevirt.yml" +plugin: community.kubevirt.kubevirt +connections: + - namespaces: + - default +EOF + +ANSIBLE_JINJA2_NATIVE=1 ansible-inventory -vvvv -i "$OUTPUT_DIR/test.kubevirt.yml" --list --output="$OUTPUT_DIR/plugin.out" + +################################################# +# DIFF THE RESULTS +################################################# + +./inventory_diff.py "$(pwd)/test.out" "$OUTPUT_DIR/plugin.out" diff --git a/collections-debian-merged/ansible_collections/community/kubevirt/tests/integration/targets/inventory_kubevirt/server.py b/collections-debian-merged/ansible_collections/community/kubevirt/tests/integration/targets/inventory_kubevirt/server.py new file mode 100755 index 00000000..376889e7 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/kubevirt/tests/integration/targets/inventory_kubevirt/server.py @@ -0,0 +1,163 @@ +#!/usr/bin/env python +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import json +import os + +try: + from http.server import HTTPServer + from http.server import SimpleHTTPRequestHandler +except ImportError: + from BaseHTTPServer import HTTPServer + from SimpleHTTPServer import SimpleHTTPRequestHandler + +from threading import Thread + +try: + from urllib.parse import urlparse +except ImportError: + from urlparse import urlparse + + +class TestHandler(SimpleHTTPRequestHandler): + # Path handlers: + handlers = {} + + def log_message(self, format, *args): + """ + Empty method, so we don't mix output of HTTP server with tests + """ + pass + + def do_GET(self): + params = urlparse(self.path) + + if params.path in self.handlers: + self.handlers[params.path](self) + else: + SimpleHTTPRequestHandler.do_GET(self) + + def do_POST(self): + params = urlparse(self.path) + + if params.path in self.handlers: + self.handlers[params.path](self) + else: + SimpleHTTPRequestHandler.do_POST(self) + + +class TestServer(object): + # The host and port and path used by the embedded tests web server: + PORT = None + + # The embedded web server: + _httpd = None + # Thread for http server: + _thread = None + + def set_json_response(self, path, code, body): + def _handle_request(handler): + handler.send_response(code) + handler.send_header('Content-Type', 'application/json') + handler.end_headers() + + data = json.dumps(body, ensure_ascii=False).encode('utf-8') + handler.wfile.write(data) + + TestHandler.handlers[path] = _handle_request + + def start_server(self, host='localhost'): + self._httpd = HTTPServer((host, 12345), TestHandler) + self._thread = Thread(target=self._httpd.serve_forever) + self._thread.start() + + def stop_server(self): + self._httpd.shutdown() + self._thread.join() + + +if __name__ == '__main__': + print(os.getpid()) + server = TestServer() + server.start_server() + server.set_json_response(path="/version", code=200, body={}) + server.set_json_response(path="/api", code=200, body={ + "kind": "APIVersions", "versions": ["v1"], "serverAddressByClientCIDRs": [{"clientCIDR": "0.0.0.0/0", "serverAddress": "localhost:12345"}] + }) + server.set_json_response(path="/api/v1", code=200, body={'resources': {}}) + server.set_json_response(path="/apis", code=200, body={ + "kind": "APIGroupList", "apiVersion": "v1", + "groups": [{ + "name": "kubevirt.io", "versions": [{"groupVersion": "kubevirt.io/v1alpha3", "version": "v1alpha3"}], + "preferredVersion": {"groupVersion": "kubevirt.io/v1alpha3", "version": "v1alpha3"} + }] + }) + server.set_json_response( + path="/apis/kubevirt.io/v1alpha3", + code=200, + body={ + "kind": "APIResourceList", "apiVersion": "v1", "groupVersion": "kubevirt.io/v1alpha3", + "resources": [{ + "name": "virtualmachineinstances", "singularName": "virtualmachineinstance", + "namespaced": True, "kind": "VirtualMachineInstance", + "verbs": ["delete", "deletecollection", "get", "list", "patch", "create", "update", "watch"], + "shortNames":["vmi", "vmis"] + }] + } + ) + server.set_json_response( + path="/apis/kubevirt.io/v1alpha3/namespaces/default/virtualmachineinstances", + code=200, + body={'apiVersion': 'kubevirt.io/v1alpha3', + 'items': [{'apiVersion': 'kubevirt.io/v1alpha3', + 'kind': 'VirtualMachineInstance', + 'metadata': {'annotations': {'ansible': '{"data1": "yes", "data2": "no"}'}, + 'creationTimestamp': '2019-04-05T14:17:02Z', + 'generateName': 'myvm', + 'generation': 1, + 'labels': {'kubevirt.io/nodeName': 'localhost', + 'label': 'x', + 'vm.cnv.io/name': 'myvm'}, + 'name': 'myvm', + 'namespace': 'default', + 'ownerReferences': [{'apiVersion': 'kubevirt.io/v1alpha3', + 'blockOwnerDeletion': True, + 'controller': True, + 'kind': 'VirtualMachine', + 'name': 'myvm', + 'uid': 'f78ebe62-5666-11e9-a214-0800279ffc6b'}], + 'resourceVersion': '1614085', + 'selfLink': '/apis/kubevirt.io/v1alpha3/namespaces/default/virtualmachineinstances/myvm', + 'uid': '7ba1b196-57ad-11e9-9e2e-0800279ffc6b'}, + 'spec': {'domain': {'devices': {'disks': [{'disk': {'bus': 'virtio'}, + 'name': 'containerdisk'}, + {'disk': {'bus': 'virtio'}, 'name': 'ansiblecloudinitdisk'}], + 'interfaces': [{'bridge': {}, 'name': 'default'}]}, + 'firmware': {'uuid': 'cdf77e9e-871b-5acb-a707-80ef3d4b9849'}, + 'machine': {'type': ''}, + 'resources': {'requests': {'memory': '64M'}}}, + 'networks': [{'name': 'default', 'pod': {}}], + 'volumes': [{'containerDisk': {'image': 'kubevirt/cirros-container-disk-demo:v0.11.0'}, + 'name': 'containerdisk'}, + {'cloudInitNoCloud': {'userData': '#cloud-config\npassword: password\nchpasswd: { expire: False }'}, + 'name': 'ansiblecloudinitdisk'}]}, + 'status': {'conditions': [{'lastProbeTime': None, + 'lastTransitionTime': None, + 'status': 'True', + 'type': 'LiveMigratable'}, + {'lastProbeTime': None, + 'lastTransitionTime': '2019-04-05T14:17:27Z', + 'status': 'True', + 'type': 'Ready'}], + 'interfaces': [{'ipAddress': '172.17.0.19', + 'mac': '02:42:ac:11:00:13', + 'name': 'default'}], + 'migrationMethod': 'BlockMigration', + 'nodeName': 'localhost', + 'phase': 'Running'}}], + 'kind': 'VirtualMachineInstanceList', + 'metadata': {'continue': '', + 'resourceVersion': '1614862', + 'selfLink': '/apis/kubevirt.io/v1alpha3/namespaces/default/virtualmachineinstances'}} + ) diff --git a/collections-debian-merged/ansible_collections/community/kubevirt/tests/integration/targets/inventory_kubevirt/test.out b/collections-debian-merged/ansible_collections/community/kubevirt/tests/integration/targets/inventory_kubevirt/test.out new file mode 100644 index 00000000..932aade0 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/kubevirt/tests/integration/targets/inventory_kubevirt/test.out @@ -0,0 +1,61 @@ +{ + "_meta": { + "hostvars": { + "default-myvm-7ba1b196-57ad-11e9-9e2e-0800279ffc6b": { + "annotations": { + "ansible": "{\"data1\": \"yes\", \"data2\": \"no\"}" + }, + "ansible_host": "172.17.0.19", + "data1": "yes", + "data2": "no", + "labels": { + "kubevirt.io/nodeName": "localhost", + "label": "x", + "vm.cnv.io/name": "myvm" + }, + "object_type": "vm", + "resource_version": "1614085", + "uid": "7ba1b196-57ad-11e9-9e2e-0800279ffc6b" + } + } + }, + "all": { + "children": [ + "label_kubevirt_io_nodeName_localhost", + "label_label_x", + "label_vm_cnv_io_name_myvm", + "localhost_12345", + "ungrouped" + ] + }, + "label_kubevirt_io_nodeName_localhost": { + "hosts": [ + "default-myvm-7ba1b196-57ad-11e9-9e2e-0800279ffc6b" + ] + }, + "label_label_x": { + "hosts": [ + "default-myvm-7ba1b196-57ad-11e9-9e2e-0800279ffc6b" + ] + }, + "label_vm_cnv_io_name_myvm": { + "hosts": [ + "default-myvm-7ba1b196-57ad-11e9-9e2e-0800279ffc6b" + ] + }, + "localhost_12345": { + "children": [ + "namespace_default" + ] + }, + "namespace_default": { + "children": [ + "namespace_default_vms" + ] + }, + "namespace_default_vms": { + "hosts": [ + "default-myvm-7ba1b196-57ad-11e9-9e2e-0800279ffc6b" + ] + } +} diff --git a/collections-debian-merged/ansible_collections/community/kubevirt/tests/sanity/ignore-2.10.txt b/collections-debian-merged/ansible_collections/community/kubevirt/tests/sanity/ignore-2.10.txt new file mode 100644 index 00000000..63be782b --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/kubevirt/tests/sanity/ignore-2.10.txt @@ -0,0 +1,20 @@ +plugins/modules/kubevirt_cdi_upload.py validate-modules:doc-missing-type +plugins/modules/kubevirt_cdi_upload.py validate-modules:doc-required-mismatch +plugins/modules/kubevirt_cdi_upload.py validate-modules:mutually_exclusive-unknown +plugins/modules/kubevirt_cdi_upload.py validate-modules:parameter-list-no-elements +plugins/modules/kubevirt_preset.py validate-modules:mutually_exclusive-unknown +plugins/modules/kubevirt_preset.py validate-modules:parameter-list-no-elements +plugins/modules/kubevirt_preset.py validate-modules:parameter-type-not-in-doc +plugins/modules/kubevirt_pvc.py validate-modules:mutually_exclusive-unknown +plugins/modules/kubevirt_pvc.py validate-modules:parameter-list-no-elements +plugins/modules/kubevirt_pvc.py validate-modules:parameter-type-not-in-doc +plugins/modules/kubevirt_pvc.py validate-modules:return-syntax-error +plugins/modules/kubevirt_rs.py validate-modules:doc-required-mismatch +plugins/modules/kubevirt_rs.py validate-modules:mutually_exclusive-unknown +plugins/modules/kubevirt_rs.py validate-modules:parameter-list-no-elements +plugins/modules/kubevirt_rs.py validate-modules:parameter-type-not-in-doc +plugins/modules/kubevirt_template.py validate-modules:mutually_exclusive-unknown +plugins/modules/kubevirt_template.py validate-modules:parameter-list-no-elements +plugins/modules/kubevirt_vm.py validate-modules:mutually_exclusive-unknown +plugins/modules/kubevirt_vm.py validate-modules:parameter-list-no-elements +plugins/modules/kubevirt_vm.py validate-modules:parameter-type-not-in-doc diff --git a/collections-debian-merged/ansible_collections/community/kubevirt/tests/sanity/ignore-2.11.txt b/collections-debian-merged/ansible_collections/community/kubevirt/tests/sanity/ignore-2.11.txt new file mode 100644 index 00000000..63be782b --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/kubevirt/tests/sanity/ignore-2.11.txt @@ -0,0 +1,20 @@ +plugins/modules/kubevirt_cdi_upload.py validate-modules:doc-missing-type +plugins/modules/kubevirt_cdi_upload.py validate-modules:doc-required-mismatch +plugins/modules/kubevirt_cdi_upload.py validate-modules:mutually_exclusive-unknown +plugins/modules/kubevirt_cdi_upload.py validate-modules:parameter-list-no-elements +plugins/modules/kubevirt_preset.py validate-modules:mutually_exclusive-unknown +plugins/modules/kubevirt_preset.py validate-modules:parameter-list-no-elements +plugins/modules/kubevirt_preset.py validate-modules:parameter-type-not-in-doc +plugins/modules/kubevirt_pvc.py validate-modules:mutually_exclusive-unknown +plugins/modules/kubevirt_pvc.py validate-modules:parameter-list-no-elements +plugins/modules/kubevirt_pvc.py validate-modules:parameter-type-not-in-doc +plugins/modules/kubevirt_pvc.py validate-modules:return-syntax-error +plugins/modules/kubevirt_rs.py validate-modules:doc-required-mismatch +plugins/modules/kubevirt_rs.py validate-modules:mutually_exclusive-unknown +plugins/modules/kubevirt_rs.py validate-modules:parameter-list-no-elements +plugins/modules/kubevirt_rs.py validate-modules:parameter-type-not-in-doc +plugins/modules/kubevirt_template.py validate-modules:mutually_exclusive-unknown +plugins/modules/kubevirt_template.py validate-modules:parameter-list-no-elements +plugins/modules/kubevirt_vm.py validate-modules:mutually_exclusive-unknown +plugins/modules/kubevirt_vm.py validate-modules:parameter-list-no-elements +plugins/modules/kubevirt_vm.py validate-modules:parameter-type-not-in-doc diff --git a/collections-debian-merged/ansible_collections/community/kubevirt/tests/sanity/ignore-2.9.txt b/collections-debian-merged/ansible_collections/community/kubevirt/tests/sanity/ignore-2.9.txt new file mode 100644 index 00000000..beccb65d --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/kubevirt/tests/sanity/ignore-2.9.txt @@ -0,0 +1,5 @@ +plugins/modules/kubevirt_cdi_upload.py validate-modules:doc-missing-type +plugins/modules/kubevirt_preset.py validate-modules:parameter-type-not-in-doc +plugins/modules/kubevirt_pvc.py validate-modules:parameter-type-not-in-doc +plugins/modules/kubevirt_rs.py validate-modules:parameter-type-not-in-doc +plugins/modules/kubevirt_vm.py validate-modules:parameter-type-not-in-doc diff --git a/collections-debian-merged/ansible_collections/community/kubevirt/tests/unit/compat/__init__.py b/collections-debian-merged/ansible_collections/community/kubevirt/tests/unit/compat/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/kubevirt/tests/unit/compat/__init__.py diff --git a/collections-debian-merged/ansible_collections/community/kubevirt/tests/unit/compat/mock.py b/collections-debian-merged/ansible_collections/community/kubevirt/tests/unit/compat/mock.py new file mode 100644 index 00000000..0972cd2e --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/kubevirt/tests/unit/compat/mock.py @@ -0,0 +1,122 @@ +# (c) 2014, Toshio Kuratomi <tkuratomi@ansible.com> +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +''' +Compat module for Python3.x's unittest.mock module +''' +import sys + +# Python 2.7 + +# Note: Could use the pypi mock library on python3.x as well as python2.x. It +# is the same as the python3 stdlib mock library + +try: + # Allow wildcard import because we really do want to import all of mock's + # symbols into this compat shim + # pylint: disable=wildcard-import,unused-wildcard-import + from unittest.mock import * +except ImportError: + # Python 2 + # pylint: disable=wildcard-import,unused-wildcard-import + try: + from mock import * + except ImportError: + print('You need the mock library installed on python2.x to run tests') + + +# Prior to 3.4.4, mock_open cannot handle binary read_data +if sys.version_info >= (3,) and sys.version_info < (3, 4, 4): + file_spec = None + + def _iterate_read_data(read_data): + # Helper for mock_open: + # Retrieve lines from read_data via a generator so that separate calls to + # readline, read, and readlines are properly interleaved + sep = b'\n' if isinstance(read_data, bytes) else '\n' + data_as_list = [l + sep for l in read_data.split(sep)] + + if data_as_list[-1] == sep: + # If the last line ended in a newline, the list comprehension will have an + # extra entry that's just a newline. Remove this. + data_as_list = data_as_list[:-1] + else: + # If there wasn't an extra newline by itself, then the file being + # emulated doesn't have a newline to end the last line remove the + # newline that our naive format() added + data_as_list[-1] = data_as_list[-1][:-1] + + for line in data_as_list: + yield line + + def mock_open(mock=None, read_data=''): + """ + A helper function to create a mock to replace the use of `open`. It works + for `open` called directly or used as a context manager. + + The `mock` argument is the mock object to configure. If `None` (the + default) then a `MagicMock` will be created for you, with the API limited + to methods or attributes available on standard file handles. + + `read_data` is a string for the `read` methoddline`, and `readlines` of the + file handle to return. This is an empty string by default. + """ + def _readlines_side_effect(*args, **kwargs): + if handle.readlines.return_value is not None: + return handle.readlines.return_value + return list(_data) + + def _read_side_effect(*args, **kwargs): + if handle.read.return_value is not None: + return handle.read.return_value + return type(read_data)().join(_data) + + def _readline_side_effect(): + if handle.readline.return_value is not None: + while True: + yield handle.readline.return_value + for line in _data: + yield line + + global file_spec + if file_spec is None: + import _io + file_spec = list(set(dir(_io.TextIOWrapper)).union(set(dir(_io.BytesIO)))) + + if mock is None: + mock = MagicMock(name='open', spec=open) + + handle = MagicMock(spec=file_spec) + handle.__enter__.return_value = handle + + _data = _iterate_read_data(read_data) + + handle.write.return_value = None + handle.read.return_value = None + handle.readline.return_value = None + handle.readlines.return_value = None + + handle.read.side_effect = _read_side_effect + handle.readline.side_effect = _readline_side_effect() + handle.readlines.side_effect = _readlines_side_effect + + mock.return_value = handle + return mock diff --git a/collections-debian-merged/ansible_collections/community/kubevirt/tests/unit/compat/unittest.py b/collections-debian-merged/ansible_collections/community/kubevirt/tests/unit/compat/unittest.py new file mode 100644 index 00000000..98f08ad6 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/kubevirt/tests/unit/compat/unittest.py @@ -0,0 +1,38 @@ +# (c) 2014, Toshio Kuratomi <tkuratomi@ansible.com> +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +''' +Compat module for Python2.7's unittest module +''' + +import sys + +# Allow wildcard import because we really do want to import all of +# unittests's symbols into this compat shim +# pylint: disable=wildcard-import,unused-wildcard-import +if sys.version_info < (2, 7): + try: + # Need unittest2 on python2.6 + from unittest2 import * + except ImportError: + print('You need unittest2 installed on python2.6.x to run tests') +else: + from unittest import * diff --git a/collections-debian-merged/ansible_collections/community/kubevirt/tests/unit/plugins/module_utils/test_kubevirt.py b/collections-debian-merged/ansible_collections/community/kubevirt/tests/unit/plugins/module_utils/test_kubevirt.py new file mode 100644 index 00000000..5cec7d4e --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/kubevirt/tests/unit/plugins/module_utils/test_kubevirt.py @@ -0,0 +1,54 @@ +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import json +import pytest + +from ansible_collections.community.kubevirt.plugins.module_utils import kubevirt as mymodule + + +def test_simple_merge_dicts(): + dict1 = {'labels': {'label1': 'value'}} + dict2 = {'labels': {'label2': 'value'}} + dict3 = json.dumps({'labels': {'label1': 'value', 'label2': 'value'}}, sort_keys=True) + assert dict3 == json.dumps(dict(mymodule.KubeVirtRawModule.merge_dicts(dict1, dict2)), sort_keys=True) + + +def test_simple_multi_merge_dicts(): + dict1 = {'labels': {'label1': 'value', 'label3': 'value'}} + dict2 = {'labels': {'label2': 'value'}} + dict3 = json.dumps({'labels': {'label1': 'value', 'label2': 'value', 'label3': 'value'}}, sort_keys=True) + assert dict3 == json.dumps(dict(mymodule.KubeVirtRawModule.merge_dicts(dict1, dict2)), sort_keys=True) + + +def test_double_nested_merge_dicts(): + dict1 = {'metadata': {'labels': {'label1': 'value', 'label3': 'value'}}} + dict2 = {'metadata': {'labels': {'label2': 'value'}}} + dict3 = json.dumps({'metadata': {'labels': {'label1': 'value', 'label2': 'value', 'label3': 'value'}}}, sort_keys=True) + assert dict3 == json.dumps(dict(mymodule.KubeVirtRawModule.merge_dicts(dict1, dict2)), sort_keys=True) + + +@pytest.mark.parametrize("lval, operations, rval, result", [ + ('v1', ['<', '<='], 'v2', True), + ('v1', ['>', '>=', '=='], 'v2', False), + ('v1', ['>'], 'v1alpha1', True), + ('v1', ['==', '<', '<='], 'v1alpha1', False), + ('v1beta5', ['==', '<=', '>='], 'v1beta5', True), + ('v1beta5', ['<', '>', '!='], 'v1beta5', False), + +]) +def test_kubeapiversion_comparisons(lval, operations, rval, result): + KubeAPIVersion = mymodule.KubeAPIVersion + for op in operations: + test = '(KubeAPIVersion("{0}") {1} KubeAPIVersion("{2}")) == {3}'.format(lval, op, rval, result) + assert eval(test) + + +@pytest.mark.parametrize("ver", ('nope', 'v1delta7', '1.5', 'v1beta', 'v')) +def test_kubeapiversion_unsupported_versions(ver): + threw = False + try: + mymodule.KubeAPIVersion(ver) + except ValueError: + threw = True + assert threw diff --git a/collections-debian-merged/ansible_collections/community/kubevirt/tests/unit/plugins/modules/__init__.py b/collections-debian-merged/ansible_collections/community/kubevirt/tests/unit/plugins/modules/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/kubevirt/tests/unit/plugins/modules/__init__.py diff --git a/collections-debian-merged/ansible_collections/community/kubevirt/tests/unit/plugins/modules/kubevirt_fixtures.py b/collections-debian-merged/ansible_collections/community/kubevirt/tests/unit/plugins/modules/kubevirt_fixtures.py new file mode 100644 index 00000000..645c70ca --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/kubevirt/tests/unit/plugins/modules/kubevirt_fixtures.py @@ -0,0 +1,74 @@ +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import pytest + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.community.kubevirt.tests.unit.compat.mock import MagicMock + +from ansible_collections.community.kubernetes.plugins.module_utils.common import K8sAnsibleMixin +from ansible_collections.community.kubernetes.plugins.module_utils.raw import KubernetesRawModule +from ansible_collections.community.kubevirt.plugins.module_utils.kubevirt import KubeVirtRawModule + +import openshift.dynamic + +RESOURCE_DEFAULT_ARGS = {'api_version': 'v1alpha3', 'group': 'kubevirt.io', + 'prefix': 'apis', 'namespaced': True} + + +class AnsibleExitJson(Exception): + """Exception class to be raised by module.exit_json and caught + by the test case""" + def __init__(self, **kwargs): + for k in kwargs: + setattr(self, k, kwargs[k]) + + def __getitem__(self, attr): + return getattr(self, attr) + + +class AnsibleFailJson(Exception): + """Exception class to be raised by module.fail_json and caught + by the test case""" + def __init__(self, **kwargs): + for k in kwargs: + setattr(self, k, kwargs[k]) + + def __getitem__(self, attr): + return getattr(self, attr) + + +def exit_json(*args, **kwargs): + kwargs['success'] = True + if 'changed' not in kwargs: + kwargs['changed'] = False + raise AnsibleExitJson(**kwargs) + + +def fail_json(*args, **kwargs): + kwargs['success'] = False + raise AnsibleFailJson(**kwargs) + + +@pytest.fixture() +def base_fixture(monkeypatch): + monkeypatch.setattr( + AnsibleModule, "exit_json", exit_json) + monkeypatch.setattr( + AnsibleModule, "fail_json", fail_json) + # Create mock methods in Resource directly, otherwise dyn client + # tries binding those to corresponding methods in DynamicClient + # (with partial()), which is more problematic to intercept + openshift.dynamic.Resource.get = MagicMock() + openshift.dynamic.Resource.create = MagicMock() + openshift.dynamic.Resource.delete = MagicMock() + openshift.dynamic.Resource.patch = MagicMock() + openshift.dynamic.Resource.search = MagicMock() + openshift.dynamic.Resource.watch = MagicMock() + # Globally mock some methods, since all tests will use this + KubernetesRawModule.patch_resource = MagicMock() + KubernetesRawModule.patch_resource.return_value = ({}, None) + K8sAnsibleMixin.get_api_client = MagicMock() + K8sAnsibleMixin.get_api_client.return_value = None + K8sAnsibleMixin.find_resource = MagicMock() + KubeVirtRawModule.find_supported_resource = MagicMock() diff --git a/collections-debian-merged/ansible_collections/community/kubevirt/tests/unit/plugins/modules/test_kubevirt_rs.py b/collections-debian-merged/ansible_collections/community/kubevirt/tests/unit/plugins/modules/test_kubevirt_rs.py new file mode 100644 index 00000000..b9425ee9 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/kubevirt/tests/unit/plugins/modules/test_kubevirt_rs.py @@ -0,0 +1,78 @@ +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import pytest + +openshiftdynamic = pytest.importorskip("openshift.dynamic") + +from ansible_collections.community.kubevirt.tests.unit.plugins.modules.utils import set_module_args +from .kubevirt_fixtures import base_fixture, RESOURCE_DEFAULT_ARGS, AnsibleExitJson + +from ansible_collections.community.kubernetes.plugins.module_utils.raw import KubernetesRawModule +from ansible_collections.community.kubevirt.plugins.modules import kubevirt_rs as mymodule + +KIND = 'VirtualMachineInstanceReplicaSet' + + +@pytest.mark.usefixtures("base_fixture") +@pytest.mark.parametrize("_replicas, _changed", ((1, True), + (3, True), + (2, False), + (5, True),)) +def test_scale_rs_nowait(_replicas, _changed): + _name = 'test-rs' + # Desired state: + args = dict(name=_name, namespace='vms', replicas=_replicas, wait=False) + set_module_args(args) + + # Mock pre-change state: + resource_args = dict(kind=KIND, **RESOURCE_DEFAULT_ARGS) + mymodule.KubeVirtVMIRS.find_supported_resource.return_value = openshiftdynamic.Resource(**resource_args) + res_inst = openshiftdynamic.ResourceInstance('', dict(kind=KIND, metadata={'name': _name}, spec={'replicas': 2})) + openshiftdynamic.Resource.get.return_value = res_inst + openshiftdynamic.Resource.search.return_value = [res_inst] + + # Final state, after patching the object + KubernetesRawModule.patch_resource.return_value = dict(kind=KIND, metadata={'name': _name}, + spec={'replicas': _replicas}), None + + # Run code: + with pytest.raises(AnsibleExitJson) as result: + mymodule.KubeVirtVMIRS().execute_module() + + # Verify result: + assert result.value['changed'] == _changed + + +@pytest.mark.usefixtures("base_fixture") +@pytest.mark.parametrize("_replicas, _success", ((1, False), + (2, False), + (5, True),)) +def test_scale_rs_wait(_replicas, _success): + _name = 'test-rs' + # Desired state: + args = dict(name=_name, namespace='vms', replicas=5, wait=True) + set_module_args(args) + + # Mock pre-change state: + resource_args = dict(kind=KIND, **RESOURCE_DEFAULT_ARGS) + mymodule.KubeVirtVMIRS.find_supported_resource.return_value = openshiftdynamic.Resource(**resource_args) + res_inst = openshiftdynamic.ResourceInstance('', dict(kind=KIND, metadata={'name': _name}, spec={'replicas': 2})) + openshiftdynamic.Resource.get.return_value = res_inst + openshiftdynamic.Resource.search.return_value = [res_inst] + + # ~Final state, after patching the object (`replicas` match desired state) + KubernetesRawModule.patch_resource.return_value = dict(kind=KIND, name=_name, metadata={'name': _name}, + spec={'replicas': 5}), None + + # Final final state, as returned by resource.watch() + final_obj = dict(metadata=dict(name=_name), status=dict(readyReplicas=_replicas), **resource_args) + event = openshiftdynamic.ResourceInstance(None, final_obj) + openshiftdynamic.Resource.watch.return_value = [dict(object=event)] + + # Run code: + with pytest.raises(Exception) as result: + mymodule.KubeVirtVMIRS().execute_module() + + # Verify result: + assert result.value['success'] == _success diff --git a/collections-debian-merged/ansible_collections/community/kubevirt/tests/unit/plugins/modules/test_kubevirt_vm.py b/collections-debian-merged/ansible_collections/community/kubevirt/tests/unit/plugins/modules/test_kubevirt_vm.py new file mode 100644 index 00000000..975876e7 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/kubevirt/tests/unit/plugins/modules/test_kubevirt_vm.py @@ -0,0 +1,113 @@ +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import pytest + +openshiftdynamic = pytest.importorskip("openshift.dynamic") + +from ansible_collections.community.kubevirt.tests.unit.plugins.modules.utils import set_module_args +from .kubevirt_fixtures import base_fixture, RESOURCE_DEFAULT_ARGS, AnsibleExitJson + +from ansible_collections.community.kubevirt.plugins.module_utils.kubevirt import KubeVirtRawModule +from ansible_collections.community.kubevirt.plugins.modules import kubevirt_vm as mymodule + +KIND = 'VirtulMachine' + + +@pytest.mark.usefixtures("base_fixture") +def test_create_vm_with_multus_nowait(): + # Desired state: + args = dict( + state='present', name='testvm', + namespace='vms', + interfaces=[ + {'bridge': {}, 'name': 'default', 'network': {'pod': {}}}, + {'bridge': {}, 'name': 'mynet', 'network': {'multus': {'networkName': 'mynet'}}}, + ], + wait=False, + ) + set_module_args(args) + + # State as "returned" by the "k8s cluster": + resource_args = dict(kind=KIND, **RESOURCE_DEFAULT_ARGS) + KubeVirtRawModule.find_supported_resource.return_value = openshiftdynamic.Resource(**resource_args) + openshiftdynamic.Resource.get.return_value = None # Object doesn't exist in the cluster + + # Run code: + with pytest.raises(AnsibleExitJson) as result: + mymodule.KubeVirtVM().execute_module() + + # Verify result: + assert result.value['changed'] + assert result.value['method'] == 'create' + + +@pytest.mark.usefixtures("base_fixture") +@pytest.mark.parametrize("_wait", (False, True)) +def test_vm_is_absent(_wait): + # Desired state: + args = dict( + state='absent', name='testvmi', + namespace='vms', + wait=_wait, + ) + set_module_args(args) + + # State as "returned" by the "k8s cluster": + resource_args = dict(kind=KIND, **RESOURCE_DEFAULT_ARGS) + KubeVirtRawModule.find_supported_resource.return_value = openshiftdynamic.Resource(**resource_args) + openshiftdynamic.Resource.get.return_value = None # Object doesn't exist in the cluster + + # Run code: + with pytest.raises(AnsibleExitJson) as result: + mymodule.KubeVirtVM().execute_module() + + # Verify result: + assert not result.value['kubevirt_vm'] + assert result.value['method'] == 'delete' + # Note: nothing actually gets deleted, as we mock that there's not object in the cluster present, + # so if the method changes to something other than 'delete' at some point, that's fine + + +@pytest.mark.usefixtures("base_fixture") +def test_vmpreset_create(): + KIND = 'VirtulMachineInstancePreset' + # Desired state: + args = dict(state='present', name='testvmipreset', namespace='vms', memory='1024Mi', wait=False) + set_module_args(args) + + # State as "returned" by the "k8s cluster": + resource_args = dict(kind=KIND, **RESOURCE_DEFAULT_ARGS) + KubeVirtRawModule.find_supported_resource.return_value = openshiftdynamic.Resource(**resource_args) + openshiftdynamic.Resource.get.return_value = None # Object doesn't exist in the cluster + + # Run code: + with pytest.raises(AnsibleExitJson) as result: + mymodule.KubeVirtVM().execute_module() + + # Verify result: + assert result.value['changed'] + assert result.value['method'] == 'create' + + +@pytest.mark.usefixtures("base_fixture") +def test_vmpreset_is_absent(): + KIND = 'VirtulMachineInstancePreset' + # Desired state: + args = dict(state='absent', name='testvmipreset', namespace='vms') + set_module_args(args) + + # State as "returned" by the "k8s cluster": + resource_args = dict(kind=KIND, **RESOURCE_DEFAULT_ARGS) + KubeVirtRawModule.find_supported_resource.return_value = openshiftdynamic.Resource(**resource_args) + openshiftdynamic.Resource.get.return_value = None # Object doesn't exist in the cluster + + # Run code: + with pytest.raises(AnsibleExitJson) as result: + mymodule.KubeVirtVM().execute_module() + + # Verify result: + assert not result.value['kubevirt_vm'] + assert result.value['method'] == 'delete' + # Note: nothing actually gets deleted, as we mock that there's not object in the cluster present, + # so if the method changes to something other than 'delete' at some point, that's fine diff --git a/collections-debian-merged/ansible_collections/community/kubevirt/tests/unit/plugins/modules/utils.py b/collections-debian-merged/ansible_collections/community/kubevirt/tests/unit/plugins/modules/utils.py new file mode 100644 index 00000000..a340d28d --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/kubevirt/tests/unit/plugins/modules/utils.py @@ -0,0 +1,52 @@ +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import json + +from ansible_collections.community.kubevirt.tests.unit.compat import unittest +from ansible_collections.community.kubevirt.tests.unit.compat.mock import patch +from ansible.module_utils import basic +from ansible.module_utils._text import to_bytes + + +def set_module_args(args): + if '_ansible_remote_tmp' not in args: + args['_ansible_remote_tmp'] = '/tmp' + if '_ansible_keep_remote_files' not in args: + args['_ansible_keep_remote_files'] = False + + args = json.dumps({'ANSIBLE_MODULE_ARGS': args}) + basic._ANSIBLE_ARGS = to_bytes(args) + + +class AnsibleExitJson(Exception): + pass + + +class AnsibleFailJson(Exception): + pass + + +def exit_json(*args, **kwargs): + if 'changed' not in kwargs: + kwargs['changed'] = False + raise AnsibleExitJson(kwargs) + + +def fail_json(*args, **kwargs): + kwargs['failed'] = True + raise AnsibleFailJson(kwargs) + + +class ModuleTestCase(unittest.TestCase): + + def setUp(self): + self.mock_module = patch.multiple(basic.AnsibleModule, exit_json=exit_json, fail_json=fail_json) + self.mock_module.start() + self.mock_sleep = patch('time.sleep') + self.mock_sleep.start() + set_module_args({}) + self.addCleanup(self.mock_module.stop) + self.addCleanup(self.mock_sleep.stop) diff --git a/collections-debian-merged/ansible_collections/community/kubevirt/tests/unit/requirements.txt b/collections-debian-merged/ansible_collections/community/kubevirt/tests/unit/requirements.txt new file mode 100644 index 00000000..73fafe55 --- /dev/null +++ b/collections-debian-merged/ansible_collections/community/kubevirt/tests/unit/requirements.txt @@ -0,0 +1,2 @@ +# requirement for kubevirt modules +openshift ; python_version >= '2.7' |