summaryrefslogtreecommitdiffstats
path: root/k8s/tests
diff options
context:
space:
mode:
Diffstat (limited to 'k8s/tests')
-rw-r--r--k8s/tests/conftest.py34
-rw-r--r--k8s/tests/test_decorators.py34
-rw-r--r--k8s/tests/test_discovery.py71
-rw-r--r--k8s/tests/test_tasks.py293
-rw-r--r--k8s/tests/test_utils.py33
5 files changed, 465 insertions, 0 deletions
diff --git a/k8s/tests/conftest.py b/k8s/tests/conftest.py
new file mode 100644
index 0000000..572a510
--- /dev/null
+++ b/k8s/tests/conftest.py
@@ -0,0 +1,34 @@
+# ============LICENSE_START=======================================================
+# org.onap.dcae
+# ================================================================================
+# Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# 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.
+# ============LICENSE_END=========================================================
+#
+# ECOMP is a trademark and service mark of AT&T Intellectual Property.
+
+import pytest
+
+@pytest.fixture()
+def mockconfig(monkeypatch):
+ """ Override the regular configure() routine that reads a file and calls Consul"""
+ def altconfig():
+ return {
+ "consul_host": "consul",
+ "namespace":"dcae",
+ "consul_dns_name" : "consul",
+ "image_pull_secrets" : []
+ }
+ from configure import configure
+ monkeypatch.setattr(configure, 'configure', altconfig) \ No newline at end of file
diff --git a/k8s/tests/test_decorators.py b/k8s/tests/test_decorators.py
new file mode 100644
index 0000000..552fa4b
--- /dev/null
+++ b/k8s/tests/test_decorators.py
@@ -0,0 +1,34 @@
+# ============LICENSE_START=======================================================
+# org.onap.dcae
+# ================================================================================
+# Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# 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.
+# ============LICENSE_END=========================================================
+#
+# ECOMP is a trademark and service mark of AT&T Intellectual Property.
+
+def test_wrapper_merge_inputs(mockconfig):
+ from k8splugin import decorators as dec
+
+ properties = { "app_config": {"nested": { "a": 123, "b": 456 }, "foo": "duh"},
+ "image": "some-docker-image" }
+ kwargs = { "app_config": {"nested": {"a": 789, "c": "zyx"}} }
+
+ def task_func(**inputs):
+ return inputs
+
+ expected = { "app_config": {"nested": { "a": 789, "b": 456, "c": "zyx" },
+ "foo": "duh"}, "image": "some-docker-image" }
+
+ assert expected == dec._wrapper_merge_inputs(task_func, properties, **kwargs) \ No newline at end of file
diff --git a/k8s/tests/test_discovery.py b/k8s/tests/test_discovery.py
new file mode 100644
index 0000000..24e45ee
--- /dev/null
+++ b/k8s/tests/test_discovery.py
@@ -0,0 +1,71 @@
+# ============LICENSE_START=======================================================
+# org.onap.dcae
+# ================================================================================
+# Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# 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.
+# ============LICENSE_END=========================================================
+#
+# ECOMP is a trademark and service mark of AT&T Intellectual Property.
+
+import pytest
+from functools import partial
+import requests
+
+def test_wrap_consul_call(mockconfig):
+ from k8splugin import discovery as dis
+
+ def foo(a, b, c="default"):
+ return " ".join([a, b, c])
+
+ wrapped_foo = partial(dis._wrap_consul_call, foo)
+ assert wrapped_foo("hello", "world") == "hello world default"
+ assert wrapped_foo("hello", "world", c="new masters") == "hello world new masters"
+
+ def foo_connection_error(a, b, c):
+ raise requests.exceptions.ConnectionError("simulate failed connection")
+
+ wrapped_foo = partial(dis._wrap_consul_call, foo_connection_error)
+ with pytest.raises(dis.DiscoveryConnectionError):
+ wrapped_foo("a", "b", "c")
+
+def test_generate_service_component_name(mockconfig):
+ from k8splugin import discovery as dis
+
+ component_type = "some-component-type"
+ name = dis.generate_service_component_name(component_type)
+ assert name.split("-", 1)[1] == component_type
+
+def test_find_matching_services(mockconfig):
+ from k8splugin import discovery as dis
+
+ services = { "component_dockerhost_1": ["foo", "bar"],
+ "platform_dockerhost": [], "component_dockerhost_2": ["baz"] }
+ assert sorted(["component_dockerhost_1", "component_dockerhost_2"]) \
+ == sorted(dis._find_matching_services(services, "component_dockerhost", []))
+
+ assert ["component_dockerhost_1"] == dis._find_matching_services(services, \
+ "component_dockerhost", ["foo", "bar"])
+
+ assert ["component_dockerhost_1"] == dis._find_matching_services(services, \
+ "component_dockerhost", ["foo"])
+
+ assert [] == dis._find_matching_services(services, "unknown", ["foo"])
+
+def test_is_healthy_pure(mockconfig):
+ from k8splugin import discovery as dis
+
+ def fake_is_healthy(name):
+ return 0, [{ "Checks": [{"Status": "passing"}] }]
+
+ assert True == dis._is_healthy_pure(fake_is_healthy, "some-component") \ No newline at end of file
diff --git a/k8s/tests/test_tasks.py b/k8s/tests/test_tasks.py
new file mode 100644
index 0000000..4d0aa90
--- /dev/null
+++ b/k8s/tests/test_tasks.py
@@ -0,0 +1,293 @@
+# ============LICENSE_START=======================================================
+# org.onap.dcae
+# ================================================================================
+# Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# 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.
+# ============LICENSE_END=========================================================
+#
+# ECOMP is a trademark and service mark of AT&T Intellectual Property.
+
+import copy
+import pytest
+from cloudify.exceptions import NonRecoverableError, RecoverableError
+
+
+def test_generate_component_name(mockconfig):
+ from k8splugin import tasks
+ kwargs = { "service_component_type": "doodle",
+ "service_component_name_override": None }
+
+ assert "doodle" in tasks._generate_component_name(**kwargs)["name"]
+
+ kwargs["service_component_name_override"] = "yankee"
+
+ assert "yankee" == tasks._generate_component_name(**kwargs)["name"]
+
+
+def test_parse_streams(monkeypatch, mockconfig):
+ import k8splugin
+ from k8splugin import tasks
+ # Good case for streams_publishes
+ test_input = { "streams_publishes": [{"name": "topic00", "type": "message_router"},
+ {"name": "feed00", "type": "data_router"}],
+ "streams_subscribes": {} }
+
+ expected = {'feed00': {'type': 'data_router', 'name': 'feed00'},
+ 'streams_publishes': [{'type': 'message_router', 'name': 'topic00'},
+ {'type': 'data_router', 'name': 'feed00'}],
+ 'streams_subscribes': {},
+ 'topic00': {'type': 'message_router', 'name': 'topic00'}
+ }
+
+ assert expected == tasks._parse_streams(**test_input)
+
+ # Good case for streams_subscribes (password provided)
+ test_input = { "streams_publishes": {},
+ "streams_subscribes": [{"name": "topic01", "type": "message_router"},
+ {"name": "feed01", "type": "data_router", "username": "hero",
+ "password": "123456"}] }
+
+ expected = {'feed01': {'type': 'data_router', 'name': 'feed01',
+ 'username': 'hero', 'password': '123456'},
+ 'streams_publishes': {},
+ 'streams_subscribes': [{'type': 'message_router', 'name': 'topic01'},
+ {'type': 'data_router', 'name': 'feed01', 'username': 'hero',
+ 'password': '123456'}],
+ 'topic01': {'type': 'message_router', 'name': 'topic01'}}
+
+ assert expected == tasks._parse_streams(**test_input)
+
+ # Good case for streams_subscribes (password generated)
+ test_input = { "streams_publishes": {},
+ "streams_subscribes": [{"name": "topic01", "type": "message_router"},
+ {"name": "feed01", "type": "data_router", "username": None,
+ "password": None}] }
+
+ def not_so_random(n):
+ return "nosurprise"
+
+ monkeypatch.setattr(k8splugin.utils, "random_string", not_so_random)
+
+ expected = {'feed01': {'type': 'data_router', 'name': 'feed01',
+ 'username': 'nosurprise', 'password': 'nosurprise'},
+ 'streams_publishes': {},
+ 'streams_subscribes': [{'type': 'message_router', 'name': 'topic01'},
+ {'type': 'data_router', 'name': 'feed01', 'username': None,
+ 'password': None}],
+ 'topic01': {'type': 'message_router', 'name': 'topic01'}}
+
+ assert expected == tasks._parse_streams(**test_input)
+
+
+def test_setup_for_discovery(monkeypatch, mockconfig):
+ import k8splugin
+ from k8splugin import tasks
+
+ test_input = { "name": "some-name",
+ "application_config": { "one": "a", "two": "b" } }
+
+ def fake_push_config(conn, name, application_config):
+ return
+
+ monkeypatch.setattr(k8splugin.discovery, "push_service_component_config",
+ fake_push_config)
+
+ assert test_input == tasks._setup_for_discovery(**test_input)
+
+ def fake_push_config_connection_error(conn, name, application_config):
+ raise k8splugin.discovery.DiscoveryConnectionError("Boom")
+
+ monkeypatch.setattr(k8splugin.discovery, "push_service_component_config",
+ fake_push_config_connection_error)
+
+ with pytest.raises(RecoverableError):
+ tasks._setup_for_discovery(**test_input)
+
+
+def test_setup_for_discovery_streams(monkeypatch, mockconfig):
+ import k8splugin
+ from k8splugin import tasks
+ test_input = {'feed01': {'type': 'data_router', 'name': 'feed01',
+ 'username': 'hero', 'password': '123456', 'location': 'Bedminster'},
+ 'streams_publishes': {},
+ 'streams_subscribes': [{'type': 'message_router', 'name': 'topic01'},
+ {'type': 'data_router', 'name': 'feed01', 'username': 'hero',
+ 'password': '123456', 'location': 'Bedminster'}],
+ 'topic01': {'type': 'message_router', 'name': 'topic01'}}
+ test_input["name"] = "some-foo-service-component"
+
+ # Good case
+ def fake_add_to_entry(conn, key, add_name, add_value):
+ """
+ This fake method will check all the pieces that are used to make store
+ details in Consul
+ """
+ if key != test_input["name"] + ":dmaap":
+ return None
+ if add_name != "feed01":
+ return None
+ if add_value != {"location": "Bedminster", "delivery_url": None,
+ "username": "hero", "password": "123456", "subscriber_id": None}:
+ return None
+
+ return "SUCCESS!"
+
+ monkeypatch.setattr(k8splugin.discovery, "add_to_entry",
+ fake_add_to_entry)
+
+ assert tasks._setup_for_discovery_streams(**test_input) == test_input
+
+ # Good case - no data router subscribers
+ test_input = {"streams_publishes": [{"name": "topic00", "type": "message_router"}],
+ 'streams_subscribes': [{'type': 'message_router', 'name': 'topic01'}]}
+ test_input["name"] = "some-foo-service-component"
+
+ assert tasks._setup_for_discovery_streams(**test_input) == test_input
+
+ # Bad case - something happened from the Consul call
+ test_input = {'feed01': {'type': 'data_router', 'name': 'feed01',
+ 'username': 'hero', 'password': '123456', 'location': 'Bedminster'},
+ 'streams_publishes': {},
+ 'streams_subscribes': [{'type': 'message_router', 'name': 'topic01'},
+ {'type': 'data_router', 'name': 'feed01', 'username': 'hero',
+ 'password': '123456', 'location': 'Bedminster'}],
+ 'topic01': {'type': 'message_router', 'name': 'topic01'}}
+ test_input["name"] = "some-foo-service-component"
+
+ def barf(conn, key, add_name, add_value):
+ raise RuntimeError("Barf")
+
+ monkeypatch.setattr(k8splugin.discovery, "add_to_entry",
+ barf)
+
+ with pytest.raises(NonRecoverableError):
+ tasks._setup_for_discovery_streams(**test_input)
+
+
+def test_lookup_service(monkeypatch, mockconfig):
+ import k8splugin
+ from k8splugin import tasks
+ def fake_lookup(conn, scn):
+ return [{"ServiceAddress": "192.168.1.1", "ServicePort": "80"}]
+
+ monkeypatch.setattr(k8splugin.discovery, "lookup_service",
+ fake_lookup)
+
+ assert "192.168.1.1" == tasks._lookup_service("some-component")
+ assert "192.168.1.1:80" == tasks._lookup_service("some-component",
+ with_port=True)
+
+
+def test_verify_container(monkeypatch, mockconfig):
+ from k8sclient import k8sclient
+ from k8splugin import tasks
+ from k8splugin.exceptions import DockerPluginDeploymentError
+
+ def fake_is_available_success(ch, scn):
+ return True
+
+ monkeypatch.setattr(k8sclient, "is_available",
+ fake_is_available_success)
+
+ assert tasks._verify_container("some-name", 3)
+
+ def fake_is_available_never_good(ch, scn):
+ return False
+
+ monkeypatch.setattr(k8sclient, "is_available",
+ fake_is_available_never_good)
+
+ with pytest.raises(DockerPluginDeploymentError):
+ tasks._verify_container("some-name", 2)
+
+
+def test_update_delivery_url(monkeypatch, mockconfig):
+ import k8splugin
+ from k8splugin import tasks
+ test_input = {'feed01': {'type': 'data_router', 'name': 'feed01',
+ 'username': 'hero', 'password': '123456', 'location': 'Bedminster',
+ 'route': 'some-path'},
+ 'streams_publishes': {},
+ 'streams_subscribes': [{'type': 'message_router', 'name': 'topic01'},
+ {'type': 'data_router', 'name': 'feed01', 'username': 'hero',
+ 'password': '123456', 'location': 'Bedminster',
+ 'route': 'some-path'}],
+ 'topic01': {'type': 'message_router', 'name': 'topic01'}}
+ test_input["service_component_name"] = "some-foo-service-component"
+
+ def fake_lookup_service(name, with_port=False):
+ if with_port:
+ return "10.100.1.100:8080"
+ else:
+ return
+
+ monkeypatch.setattr(k8splugin.tasks, "_lookup_service",
+ fake_lookup_service)
+
+ expected = copy.deepcopy(test_input)
+ expected["feed01"]["delivery_url"] = "http://10.100.1.100:8080/some-path"
+
+ assert tasks._update_delivery_url(**test_input) == expected
+
+
+def test_enhance_docker_params(mockconfig):
+ from k8splugin import tasks
+ # Good - Test empty docker config
+
+ test_kwargs = { "docker_config": {}, "service_id": None }
+ actual = tasks._enhance_docker_params(**test_kwargs)
+
+ assert actual == {'envs': {"SERVICE_TAGS": ""}, 'docker_config': {}, "service_id": None }
+
+ # Good - Test just docker config ports and volumes
+
+ test_kwargs = { "docker_config": { "ports": ["1:1", "2:2"],
+ "volumes": [{"container": "somewhere", "host": "somewhere else"}] },
+ "service_id": None }
+ actual = tasks._enhance_docker_params(**test_kwargs)
+
+ assert actual == {'envs': {"SERVICE_TAGS": ""}, 'docker_config': {'ports': ['1:1', '2:2'],
+ 'volumes': [{'host': 'somewhere else', 'container': 'somewhere'}]},
+ 'ports': ['1:1', '2:2'], 'volumes': [{'host': 'somewhere else',
+ 'container': 'somewhere'}], "service_id": None}
+
+ # Good - Test just docker config ports and volumes with overrrides
+
+ test_kwargs = { "docker_config": { "ports": ["1:1", "2:2"],
+ "volumes": [{"container": "somewhere", "host": "somewhere else"}] },
+ "ports": ["3:3", "4:4"], "volumes": [{"container": "nowhere", "host":
+ "nowhere else"}],
+ "service_id": None }
+ actual = tasks._enhance_docker_params(**test_kwargs)
+
+ assert actual == {'envs': {"SERVICE_TAGS": ""}, 'docker_config': {'ports': ['1:1', '2:2'],
+ 'volumes': [{'host': 'somewhere else', 'container': 'somewhere'}]},
+ 'ports': ['1:1', '2:2', '3:3', '4:4'], 'volumes': [{'host': 'somewhere else',
+ 'container': 'somewhere'}, {'host': 'nowhere else', 'container':
+ 'nowhere'}], "service_id": None}
+
+ # Good
+
+ test_kwargs = { "docker_config": {}, "service_id": "zed",
+ "deployment_id": "abc" }
+ actual = tasks._enhance_docker_params(**test_kwargs)
+
+ assert actual["envs"] == {"SERVICE_TAGS": "abc,zed"}
+
+
+def test_notify_container(mockconfig):
+ from k8splugin import tasks
+
+ test_input = { "docker_config": { "trigger_type": "unknown" } }
+ assert test_input == tasks._notify_container(**test_input) \ No newline at end of file
diff --git a/k8s/tests/test_utils.py b/k8s/tests/test_utils.py
new file mode 100644
index 0000000..0b7cba4
--- /dev/null
+++ b/k8s/tests/test_utils.py
@@ -0,0 +1,33 @@
+# ============LICENSE_START=======================================================
+# org.onap.dcae
+# ================================================================================
+# Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# 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.
+# ============LICENSE_END=========================================================
+#
+# ECOMP is a trademark and service mark of AT&T Intellectual Property.
+
+def test_random_string(mockconfig):
+ from k8splugin import utils
+
+ target_length = 10
+ assert len(utils.random_string(target_length)) == target_length
+
+
+def test_update_dict(mockconfig):
+ from k8splugin import utils
+
+ d = { "a": 1, "b": 2 }
+ u = { "a": 2, "b": 3 }
+ assert utils.update_dict(d, u) == u