summaryrefslogtreecommitdiffstats
path: root/mod/onboardingapi/dcae_cli/util/tests
diff options
context:
space:
mode:
Diffstat (limited to 'mod/onboardingapi/dcae_cli/util/tests')
-rw-r--r--mod/onboardingapi/dcae_cli/util/tests/test_cdap_util.py93
-rw-r--r--mod/onboardingapi/dcae_cli/util/tests/test_config.py137
-rw-r--r--mod/onboardingapi/dcae_cli/util/tests/test_discovery.py447
-rw-r--r--mod/onboardingapi/dcae_cli/util/tests/test_dmaap.py259
-rw-r--r--mod/onboardingapi/dcae_cli/util/tests/test_docker_util.py62
-rw-r--r--mod/onboardingapi/dcae_cli/util/tests/test_inputs.py37
-rw-r--r--mod/onboardingapi/dcae_cli/util/tests/test_profiles.py162
-rw-r--r--mod/onboardingapi/dcae_cli/util/tests/test_remove.py24
-rw-r--r--mod/onboardingapi/dcae_cli/util/tests/test_undeploy.py62
9 files changed, 1283 insertions, 0 deletions
diff --git a/mod/onboardingapi/dcae_cli/util/tests/test_cdap_util.py b/mod/onboardingapi/dcae_cli/util/tests/test_cdap_util.py
new file mode 100644
index 0000000..9282691
--- /dev/null
+++ b/mod/onboardingapi/dcae_cli/util/tests/test_cdap_util.py
@@ -0,0 +1,93 @@
+# ============LICENSE_START=======================================================
+# org.onap.dcae
+# ================================================================================
+# Copyright (c) 2017 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.
+
+from dcae_cli.util.cdap_util import _merge_spec_config_into_broker_put, normalize_cdap_params
+
+
+def test_normalize_cdap_params():
+ spec = {"parameters" : {}}
+ normalized = normalize_cdap_params(spec)
+ assert normalized == {"app_preferences" : {},
+ "app_config" : {},
+ "program_preferences" : []}
+
+def test_cdap_util():
+ """
+ Tests both _merge_spec_config_into_broker_put and normalize_cdap_params
+ """
+ jar = "bahphomet.com/nexus/doomsday.jar"
+ config = {
+ "artifact_name" : "testname",
+ "artifact_version" : "6.6.6",
+ "streamname" : "stream",
+ "programs" : [{"program_type" : "flows", "program_id" : "flow_id"}],
+ "namespace" : "underworld"
+ }
+ spec = {
+ "self": {
+ "version": "6.6.6",
+ "description": "description",
+ "component_type": "cdap",
+ "name": "name"
+ },
+ "parameters" : {
+ "app_preferences" : [{"name" : "he", "description" : "", "value" : "shall rise"}],
+ "program_preferences" : [{"program_type" : "flows", "program_id" : "flow_id", "program_pref" : [{"name": "foo", "description" : "", "value" : "bar"}]}]
+ },
+
+ "streams": {
+ "publishes": [],
+ "subscribes" : []
+ },
+ "services": {
+ "calls" : [],
+ 'provides': [
+ {"request": {"format" : 'std.format_one', "version" : "1.0.0"},
+ "response" : {"format" : "std.format_two", "version" : "1.5.0"},
+ "service_name" : "baphomet",
+ "service_endpoint" : "rises",
+ "verb" : "GET"}
+ ]
+ },
+ }
+ parsed_parameters = normalize_cdap_params(spec)
+ templated_conf = {"streams_publishes":{}, "streams_subscribes": {},
+ "services_calls": {}} #TODO: Incorporate a test templated_conf
+ broker_put = _merge_spec_config_into_broker_put(jar, config, spec, parsed_parameters, templated_conf)
+
+ expected = {
+ "app_config": {"services_calls" : {},
+ "streams_publishes" : {},
+ "streams_subscribes": {}
+ },
+ "app_preferences": {"he" : "shall rise"},
+ "artifact_name" : "testname",
+ "artifact_version" : "6.6.6",
+ "jar_url": "bahphomet.com/nexus/doomsday.jar",
+ "namespace": "underworld",
+ "program_preferences" : [{"program_type" : "flows", "program_id" : "flow_id", "program_pref" : {"foo" : "bar"}}],
+ "programs" : [{"program_type" : "flows", "program_id" : "flow_id"}],
+ "service_component_type": "cdap",
+ "services": [{"service_name" : "baphomet", "service_endpoint" : "rises", "endpoint_method" : "GET"}],
+ "streamname": "stream",
+ "cdap_application_type" : "program-flowlet"
+ }
+
+ assert broker_put == expected
diff --git a/mod/onboardingapi/dcae_cli/util/tests/test_config.py b/mod/onboardingapi/dcae_cli/util/tests/test_config.py
new file mode 100644
index 0000000..3b4cd6e
--- /dev/null
+++ b/mod/onboardingapi/dcae_cli/util/tests/test_config.py
@@ -0,0 +1,137 @@
+# ============LICENSE_START=======================================================
+# org.onap.dcae
+# ================================================================================
+# Copyright (c) 2017 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.
+
+# -*- coding: utf-8 -*-
+"""
+Tests the config functionality
+"""
+import os, json
+from functools import partial
+from mock import patch
+
+import pytest
+import click
+
+import dcae_cli
+from dcae_cli.util import config, write_pref
+from dcae_cli.util.config import get_app_dir, get_config, get_config_path
+
+
+def test_no_config(monkeypatch, tmpdir):
+ '''Tests the creation and initialization of a config on a clean install'''
+ monkeypatch.setattr(click, "get_app_dir", lambda app: str(tmpdir.realpath()))
+
+ mock_config = {'user': 'mock-user'}
+
+ config_file = tmpdir.join("config.json")
+ config_file.write(json.dumps(mock_config))
+
+ assert get_config() == mock_config
+
+
+def test_init_config_user(monkeypatch):
+ good_case = "abc123"
+ values = [ good_case, "d-e-f", "g*h*i", "j k l" ]
+
+ def fake_input(values, message, type="red"):
+ return values.pop()
+
+ monkeypatch.setattr(click, 'prompt', partial(fake_input, values))
+ assert config._init_config_user() == good_case
+
+
+def test_init_config(monkeypatch):
+ monkeypatch.setattr(config, '_init_config_user', lambda: "bigmama")
+ monkeypatch.setattr(config, '_init_config_server_url',
+ lambda: "http://some-nexus-in-the-sky.com")
+ monkeypatch.setattr(dcae_cli.util, 'fetch_file_from_web',
+ lambda server_url, path: { "db_url": "conn" })
+ monkeypatch.setattr("dcae_cli._version.__version__", "2.X.X")
+
+ expected = {'cli_version': '2.X.X', 'user': 'bigmama', 'db_url': 'conn',
+ 'server_url': 'http://some-nexus-in-the-sky.com',
+ 'active_profile': 'default' }
+ assert expected == config._init_config()
+
+ # Test using of db fallback
+
+ monkeypatch.setattr(dcae_cli.util, 'fetch_file_from_web',
+ lambda server_url, path: { "db_url": "" })
+
+ db_url = "postgresql://king:of@mountain:5432/dcae_onboarding_db"
+
+ def fake_init_config_db_url():
+ return db_url
+
+ monkeypatch.setattr(config, "_init_config_db_url",
+ fake_init_config_db_url)
+
+ assert db_url == config._init_config()["db_url"]
+
+ monkeypatch.setattr(dcae_cli.util, 'fetch_file_from_web',
+ lambda server_url, path: {})
+
+ assert db_url == config._init_config()["db_url"]
+
+ # Simulate error trying to fetch
+
+ def fetch_simulate_error(server_url, path):
+ raise RuntimeError("Simulated error")
+
+ monkeypatch.setattr(dcae_cli.util, 'fetch_file_from_web',
+ fetch_simulate_error)
+ # Case when user opts out of manually setting up
+ monkeypatch.setattr(click, "confirm", lambda msg: False)
+
+ with pytest.raises(config.ConfigurationInitError):
+ config._init_config()
+
+
+def test_should_force_reinit():
+ bad_config = {}
+ assert config.should_force_reinit(bad_config) == True
+
+ old_config = { "cli_version": "1.0.0" }
+ assert config.should_force_reinit(old_config) == True
+
+ uptodate_config = { "cli_version": "2.0.0" }
+ assert config.should_force_reinit(uptodate_config) == False
+
+
+def test_reinit_config(monkeypatch, tmpdir):
+ monkeypatch.setattr(click, "get_app_dir", lambda app: str(tmpdir.realpath()))
+
+ new_config = { "user": "ninny", "db_url": "some-db" }
+
+ def init():
+ return new_config
+
+ assert config._reinit_config(init) == new_config
+
+ old_config = { "user": "super", "db_url": "other-db", "hidden": "yo" }
+ write_pref(old_config, get_config_path())
+
+ new_config["hidden"] = "yo"
+ assert config._reinit_config(init) == new_config
+
+
+if __name__ == '__main__':
+ '''Test area'''
+ pytest.main([__file__, ])
diff --git a/mod/onboardingapi/dcae_cli/util/tests/test_discovery.py b/mod/onboardingapi/dcae_cli/util/tests/test_discovery.py
new file mode 100644
index 0000000..2148ea3
--- /dev/null
+++ b/mod/onboardingapi/dcae_cli/util/tests/test_discovery.py
@@ -0,0 +1,447 @@
+# ============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.
+
+# -*- coding: utf-8 -*-
+'''
+Provides tests for the discovery module
+'''
+import json
+from functools import partial
+from copy import deepcopy
+
+import pytest
+
+from dcae_cli.util import discovery as dis
+from dcae_cli.util.discovery import create_config, Consul, config_context, DiscoveryNoDownstreamComponentError
+
+
+user = 'bob'
+cname = 'asimov.test_comp'
+cver = '0.0.0'
+inst_pref = 'abc123'
+params = {'param0': 12345}
+
+
+def test_create_config():
+ '''
+ Test explanation:
+ 1. param1 in the component spec has 2 compatible component types, comp1 and comp2. however infrastructure
+ support only allows for 1. thus comp2 shouldn't make it to the rels.
+ 2. comp1 has two instances, so both should make it to the rels
+ 3. param2 is compatible with comp3, but there are no comp3 instances. thus it's missing from rels.
+ '''
+ expected_ckey = 'bob.abc123.0-0-0.asimov-test_comp'
+ expected_conf = {'param1': '{{1-1-1.foo-bar-comp1}}', 'param0': 12345, 'param2': '{{3-3-3.foo-bar-comp3}}'}
+ expected_rkey = 'bob.abc123.0-0-0.asimov-test_comp:rel'
+ expected_rels = ['bob.aaa111.1-1-1.foo-bar-comp1.suffix',
+ 'bob.bbb222.1-1-1.foo-bar-comp1.suffix',
+ 'bob.ddd444.3-3-3.foo-bar-comp3.suffix']
+ expected_dmaap_key = 'bob.abc123.0-0-0.asimov-test_comp:dmaap'
+ expected_dmaap_map = {}
+
+ interface_map = {'param1': [('foo.bar.comp1', '1.1.1'),
+ ('foo.bar.comp2', '2.2.2')],
+ 'param2': [('foo.bar.comp3', '3.3.3')]
+ }
+ instance_map = {('foo.bar.comp1', '1.1.1'): ['bob.aaa111.1-1-1.foo-bar-comp1.suffix',
+ 'bob.bbb222.1-1-1.foo-bar-comp1.suffix'],
+ ('foo.bar.comp2', '2.2.2'): ['bob.ccc333.2-2-2.foo-bar-comp2.suffix'],
+ ('foo.bar.comp3', '3.3.3'): ['bob.ddd444.3-3-3.foo-bar-comp3.suffix']}
+
+ ckey, conf, rkey, rels, dmaap_key, dmaap_map = create_config(user, cname, cver,
+ params, interface_map, instance_map, expected_dmaap_map, inst_pref)
+
+ assert ckey == expected_ckey
+ assert conf == expected_conf
+ assert rkey == expected_rkey
+ assert sorted(rels) == sorted(expected_rels)
+ assert dmaap_key == expected_dmaap_key
+ assert dmaap_map == expected_dmaap_map
+
+ #
+ # Fail cases: When a downstream dependency does not exist
+ #
+
+ # (1) Case when there's no actual instance
+ instance_map_missing_3 = deepcopy(instance_map)
+ instance_map_missing_3[('foo.bar.comp3', '3.3.3')] = []
+
+ with pytest.raises(DiscoveryNoDownstreamComponentError):
+ create_config(user, cname, cver, params, interface_map, instance_map_missing_3,
+ expected_dmaap_map, inst_pref)
+
+ # (2) Case when there's no existence in instance_map
+ interface_map_extra = deepcopy(interface_map)
+ interface_map_extra["param_not_exist"] = []
+
+ with pytest.raises(DiscoveryNoDownstreamComponentError):
+ create_config(user, cname, cver, params, interface_map_extra, instance_map,
+ expected_dmaap_map, inst_pref)
+
+ #
+ # Force the fail cases to succeed
+ #
+
+ # (1)
+ ckey, conf, rkey, rels, dmaap_key, dmaap_map = create_config(user, cname, cver,
+ params, interface_map, instance_map_missing_3, expected_dmaap_map, inst_pref,
+ force=True)
+
+ assert ckey == expected_ckey
+ assert conf == expected_conf
+ assert rkey == expected_rkey
+ # Remove the foo.bar.comp3:3.3.3 instance because we are simulating when that
+ # instance does not exist
+ assert sorted(rels) == sorted(expected_rels[:2])
+ assert dmaap_key == expected_dmaap_key
+ assert dmaap_map == expected_dmaap_map
+
+ # (2)
+ ckey, conf, rkey, rels, dmaap_key, dmaap_map = create_config(user, cname, cver,
+ params, interface_map_extra, instance_map, expected_dmaap_map, inst_pref,
+ force=True)
+
+ expected_conf["param_not_exist"] = "{{}}"
+
+ assert ckey == expected_ckey
+ assert conf == expected_conf
+ assert rkey == expected_rkey
+ assert sorted(rels) == sorted(expected_rels)
+ assert dmaap_key == expected_dmaap_key
+ assert dmaap_map == expected_dmaap_map
+
+ #
+ # Test differnt dashes scenario
+ #
+
+ # Component has been added with dashes but the instance comes back with dots
+ # because the discovery layer always brings back instances with dots
+ interface_map_dashes = {'param1': [('foo-bar-comp1', '1.1.1')]}
+ instance_map_dashes = {('foo.bar.comp1', '1.1.1'):
+ ['bob.aaa111.1-1-1.foo-bar-comp1.suffix']}
+
+ with pytest.raises(DiscoveryNoDownstreamComponentError):
+ create_config(user, cname, cver, params, interface_map_dashes, instance_map_dashes,
+ expected_dmaap_map, inst_pref)
+
+ # The fix in v2.3.2 was to have the caller to send in instances with dots and
+ # with dashes
+ instance_map_dashes = {
+ ('foo.bar.comp1', '1.1.1'): ['bob.aaa111.1-1-1.foo-bar-comp1.suffix'],
+ ('foo-bar-comp1', '1.1.1'): ['bob.aaa111.1-1-1.foo-bar-comp1.suffix'] }
+
+ ckey, conf, rkey, rels, dmaap_key, dmaap_map = create_config(user, cname, cver,
+ params, interface_map_dashes, instance_map_dashes, expected_dmaap_map, inst_pref)
+
+ # The expecteds have changed because the inputs have been narrowed to just
+ # one
+ assert ckey == expected_ckey
+ assert conf == {'param1': '{{1-1-1.foo-bar-comp1}}', 'param0': 12345}
+ assert rkey == expected_rkey
+ assert sorted(rels) == sorted(['bob.aaa111.1-1-1.foo-bar-comp1.suffix'])
+ assert dmaap_key == expected_dmaap_key
+ assert dmaap_map == expected_dmaap_map
+
+ # Pass in a non-empty dmaap map
+ dmaap_map_input = { "some-config-key": { "type": "message_router",
+ "dmaap_info": {"topic_url": "http://some-topic-url.com/abc"} } }
+ del expected_conf["param_not_exist"]
+ expected_conf["some-config-key"] = { "type": "message_router",
+ "dmaap_info": "<<some-config-key>>" }
+
+ ckey, conf, rkey, rels, dmaap_key, dmaap_map = create_config(user, cname, cver,
+ params, interface_map, instance_map, dmaap_map_input, inst_pref)
+
+ assert ckey == expected_ckey
+ assert conf == expected_conf
+ assert rkey == expected_rkey
+ assert sorted(rels) == sorted(expected_rels)
+ assert dmaap_key == expected_dmaap_key
+ assert dmaap_map == {'some-config-key': {'topic_url': 'http://some-topic-url.com/abc'}}
+
+
+@pytest.mark.skip(reason="Not a pure unit test")
+def test_config_context(mock_cli_config):
+ interface_map = {'param1': [('foo.bar.comp1', '1.1.1'),
+ ('foo.bar.comp2', '2.2.2')],
+ 'param2': [('foo.bar.comp3', '3.3.3')]
+ }
+ instance_map = {('foo.bar.comp1', '1.1.1'): ['bob.aaa111.1-1-1.foo-bar-comp1.suffix',
+ 'bob.bbb222.1-1-1.foo-bar-comp1.suffix'],
+ ('foo.bar.comp2', '2.2.2'): ['bob.ccc333.2-2-2.foo-bar-comp2.suffix'],
+ ('foo.bar.comp3', '3.3.3'): ['bob.ddd444.3-3-3.foo-bar-comp3.suffix']}
+
+ config_key_map = {"param1": {"group": "streams_publishes", "type": "http"},
+ "param2": {"group": "services_calls", "type": "http"}}
+
+ ckey = 'bob.abc123.0-0-0.asimov-test_comp'
+ rkey = 'bob.abc123.0-0-0.asimov-test_comp:rel'
+ expected_conf = {"streams_publishes": {'param1': '{{1-1-1.foo-bar-comp1}}'},
+ 'param0': 12345, "streams_subscribes": {},
+ "services_calls": {'param2': '{{3-3-3.foo-bar-comp3}}'}}
+ expected_rels = ['bob.aaa111.1-1-1.foo-bar-comp1.suffix',
+ 'bob.bbb222.1-1-1.foo-bar-comp1.suffix',
+ 'bob.ddd444.3-3-3.foo-bar-comp3.suffix']
+
+ c = Consul(dis.default_consul_host())
+ with config_context(user, cname, cver, params, interface_map, instance_map,
+ config_key_map, instance_prefix=inst_pref) as (instance,_):
+ assert json.loads(c.kv.get(ckey)[1]['Value'].decode('utf-8')) == expected_conf
+ assert sorted(json.loads(c.kv.get(rkey)[1]['Value'].decode('utf-8'))) \
+ == sorted(expected_rels)
+ assert instance == ckey
+
+ assert c.kv.get(ckey)[1] is None
+ assert c.kv.get(rkey)[1] is None
+
+ # Fail case: When a downstream dependency does not exist
+ interface_map_extra = deepcopy(interface_map)
+ interface_map_extra["param_not_exist"] = []
+
+ with pytest.raises(DiscoveryNoDownstreamComponentError):
+ with config_context(user, cname, cver, params, interface_map_extra,
+ instance_map, config_key_map, instance_prefix=inst_pref) as (instance,_):
+ pass
+
+ # Force fail case to succeed
+ expected_conf["param_not_exist"] = "{{}}"
+
+ with config_context(user, cname, cver, params, interface_map_extra,
+ instance_map, config_key_map, instance_prefix=inst_pref,
+ force_config=True) as (instance,_):
+ assert json.loads(c.kv.get(ckey)[1]['Value'].decode('utf-8')) == expected_conf
+ assert sorted(json.loads(c.kv.get(rkey)[1]['Value'].decode('utf-8'))) \
+ == sorted(expected_rels)
+ assert instance == ckey
+
+
+def test_inst_regex():
+ ckey = 'bob.abc123.0-0-0.asimov-test_comp'
+ match = dis._inst_re.match(ckey)
+ assert match != None
+
+ # Big version case
+
+ ckey = 'bob.abc123.100-100-100.asimov-test_comp'
+ match = dis._inst_re.match(ckey)
+ assert match != None
+
+
+def test_is_healthy_pure():
+ component = { 'CreateIndex': 204546, 'Flags': 0,
+ 'Key': 'mike.21fbcabd-fac1-4b9b-9d18-2f624bfa44a5.0-4-0.sandbox-platform-dummy_subscriber', 'LockIndex': 0, 'ModifyIndex': 204546,
+ 'Value': b'{}' }
+
+ component_health_good = ('262892',
+ [{'Checks': [{'CheckID': 'serfHealth',
+ 'CreateIndex': 3,
+ 'ModifyIndex': 3,
+ 'Name': 'Serf Health Status',
+ 'Node': 'agent-one',
+ 'Notes': '',
+ 'Output': 'Agent alive and reachable',
+ 'ServiceID': '',
+ 'ServiceName': '',
+ 'Status': 'passing'},
+ {'CheckID': 'service:rework-central-swarm-master:mike.21fbcabd-fac1-4b9b-9d18-2f624bfa44a5.0-4-0.sandbox-platform-dummy_subscriber:8080',
+ 'CreateIndex': 204550,
+ 'ModifyIndex': 204551,
+ 'Name': 'Service '
+ "'mike.21fbcabd-fac1-4b9b-9d18-2f624bfa44a5.0-4-0.sandbox-platform-dummy_subscriber' "
+ 'check',
+ 'Node': 'agent-one',
+ 'Notes': '',
+ 'Output': '',
+ 'ServiceID': 'rework-central-swarm-master:mike.21fbcabd-fac1-4b9b-9d18-2f624bfa44a5.0-4-0.sandbox-platform-dummy_subscriber:8080',
+ 'ServiceName': 'mike.21fbcabd-fac1-4b9b-9d18-2f624bfa44a5.0-4-0.sandbox-platform-dummy_subscriber',
+ 'Status': 'passing'}],
+ 'Node': {'Address': '10.170.2.17',
+ 'CreateIndex': 3,
+ 'ModifyIndex': 262877,
+ 'Node': 'agent-one',
+ 'TaggedAddresses': {'wan': '10.170.2.17'}},
+ 'Service': {'Address': '196.207.170.175',
+ 'CreateIndex': 204550,
+ 'EnableTagOverride': False,
+ 'ID': 'rework-central-swarm-master:mike.21fbcabd-fac1-4b9b-9d18-2f624bfa44a5.0-4-0.sandbox-platform-dummy_subscriber:8080',
+ 'ModifyIndex': 204551,
+ 'Port': 33064,
+ 'Service': 'mike.21fbcabd-fac1-4b9b-9d18-2f624bfa44a5.0-4-0.sandbox-platform-dummy_subscriber',
+ 'Tags': None}}])
+
+ assert True == dis._is_healthy_pure(lambda name: component_health_good, component)
+
+ # Case: Check is failing
+
+ component_health_bad = deepcopy(component_health_good)
+ # NOTE: The failed status here. Not sure if this is what Consul actually sends
+ # but at least its not "passing"
+ component_health_bad[1][0]["Checks"][0]["Status"] = "failing"
+
+ assert False == dis._is_healthy_pure(lambda name: component_health_bad, component)
+
+ # Case: No health for a component
+
+ component_health_nothing = ('262892', [])
+ assert False == dis._is_healthy_pure(lambda name: component_health_nothing, component)
+
+
+def test_get_instances_from_kv():
+
+ def get_from_kv_fake(result, user, recurse=True):
+ return "don't care about first arg", result
+
+ user = "jane"
+ kvs_nothing = []
+
+ assert dis._get_instances_from_kv(partial(get_from_kv_fake, kvs_nothing), user) == []
+
+ kvs_success = [ { "Value": "some value", "Key": "jane.1344a03a-06a8-4b92-bfac-d8f89df0c0cd.1-0-0.dcae-controller-ves-collector:rel"
+ },
+ { "Value": "some value", "Key": "jane.1344a03a-06a8-4b92-bfac-d8f89df0c0cd.1-0-0.dcae-controller-ves-collector" } ]
+
+ assert dis._get_instances_from_kv(partial(get_from_kv_fake, kvs_success), user) == ["jane.1344a03a-06a8-4b92-bfac-d8f89df0c0cd.1-0-0.dcae-controller-ves-collector"]
+
+ kvs_partial = [ { "Value": "some value", "Key": "jane.1344a03a-06a8-4b92-bfac-d8f89df0c0cd.1-0-0.dcae-controller-ves-collector:rel"
+ } ]
+
+ assert dis._get_instances_from_kv(partial(get_from_kv_fake, kvs_partial), user) == ["jane.1344a03a-06a8-4b92-bfac-d8f89df0c0cd.1-0-0.dcae-controller-ves-collector"]
+
+
+def test_get_instances_from_catalog():
+
+ def get_from_catalog_fake(result):
+ return ("some Consul index", result)
+
+ user = "jane"
+ services_nothing = {}
+
+ assert dis._get_instances_from_catalog(
+ partial(get_from_catalog_fake, services_nothing), user) == []
+
+ services_no_matching = { '4f09bb72-8578-4e82-a6a4-9b7d679bd711.cdap_app_hello_world.hello-world-cloudify-test': [],
+ '666.fake_testing_service.rework-central.com': [],
+ 'Platform_Dockerhost_Solutioning_Test': [],
+ 'jack.2271ec6b-9224-4f42-b0b0-bfa91b41218f.1-0-1.cdap-event-proc-map-app': [],
+ 'jack.bca28c8c-a352-41f1-81bc-63ff46db2582.1-0-1.cdap-event-proc-supplement-app':
+ [] }
+
+ assert dis._get_instances_from_catalog(
+ partial(get_from_catalog_fake, services_no_matching), user) == []
+
+ services_success = { '4f09bb72-8578-4e82-a6a4-9b7d679bd711.cdap_app_hello_world.hello-world-cloudify-test': [],
+ '666.fake_testing_service.rework-central.com': [],
+ 'Platform_Dockerhost_Solutioning_Test': [],
+ 'jack.2271ec6b-9224-4f42-b0b0-bfa91b41218f.1-0-1.cdap-event-proc-map-app': [],
+ 'jane.bca28c8c-a352-41f1-81bc-63ff46db2582.1-0-1.cdap-event-proc-supplement-app':
+ [] }
+
+ assert dis._get_instances_from_catalog(
+ partial(get_from_catalog_fake, services_success), user) == ['jane.bca28c8c-a352-41f1-81bc-63ff46db2582.1-0-1.cdap-event-proc-supplement-app']
+
+
+def test_merge_instances():
+ user = "somebody"
+ group_one = [ "123", "456" ]
+ group_two = [ "123", "abc" ]
+ group_three = []
+
+ assert sorted(dis._merge_instances(user, lambda user: group_one, lambda user: group_two,
+ lambda user: group_three)) == sorted([ "123", "456", "abc" ])
+
+
+def test_make_instance_map():
+ instances_latest_format = ["mike.112e4faa-2ac8-4b13-93e9-8924150538d5.0-5-0.sandbox-platform-laika"]
+
+ instances_map = dis._make_instances_map(instances_latest_format)
+ assert instances_map.get(("sandbox.platform.laika", "0.5.0")) == set(instances_latest_format)
+
+
+def test_get_component_instances(monkeypatch):
+ instances = [
+ 'jane.b493b48b-5fdf-4c1d-bd2a-8ce747b918ba.1-0-0.dcae-controller-ves-collector',
+ 'jane.2455ec5c-67e6-4d4d-8581-79037c7b5f8e.1-0-0.dcae-controller-ves-collector.rework-central.dcae.com',
+ 'jane.bfbb1356-d703-4007-8799-759a9e1fc8c2.1-0-0.dcae-controller-ves-collector.rework-central.dcae.com',
+ 'jane.89d82ff6-1482-4c01-8758-db9325aad085.1-0-0.dcae-controller-ves-collector'
+ ]
+
+ instances_map = { ('dcae.controller.ves.collector', '1.0.0'): set(instances) }
+
+ def get_user_instances_mock(user, consul_host=None, filter_instances_func=None):
+ return instances_map
+
+ monkeypatch.setattr(dis, 'get_user_instances', get_user_instances_mock)
+
+ def always_true_filter(consul_host, instance):
+ return True
+
+ # Test base case
+
+ user = "jane"
+ cname = "dcae.controller.ves.collector"
+ cver = "1.0.0"
+ consul_host = "bogus"
+
+ assert sorted(dis._get_component_instances(always_true_filter, user, cname, cver,
+ consul_host)) == sorted(instances)
+
+ # Test for dashes
+
+ cname = "dcae-controller-ves-collector"
+
+ assert sorted(dis._get_component_instances(always_true_filter, user, cname, cver,
+ consul_host)) == sorted(instances)
+
+
+def test_group_config():
+ config_key_map = {'call1': {'group': 'services_calls'}, 'pub1': {'type': 'http', 'group': 'streams_publishes'}, 'sub2': {'type': 'message_router', 'group': 'streams_subscribes'}, 'pub2': {'type': 'message_router', 'group': 'streams_publishes'}}
+
+ config = { "call1": "{{yo}}", "pub1": "{{target}}", "some-param": 123,
+ "sub2": { "dmaap_info": "<<sub2>>" }, "pub2": { "dmaap_info": "<<pub2>>" } }
+
+ gc = dis._group_config(config, config_key_map)
+ expected = {'services_calls': {'call1': '{{yo}}'}, 'streams_publishes': {'pub2': {'dmaap_info': '<<pub2>>'}, 'pub1': '{{target}}'}, 'some-param': 123, 'streams_subscribes': {'sub2': {'dmaap_info': '<<sub2>>'}}}
+
+ assert gc == expected
+
+
+def test_parse_instance_lookup():
+ results = [{"ServiceAddress": "192.168.1.100", "ServicePort": "8080"},
+ {"ServiceAddress": "10.100.1.100", "ServicePort": "8081"}]
+ assert dis.parse_instance_lookup(results) == "192.168.1.100:8080"
+
+
+def test_apply_inputs():
+ updated_config = dis._apply_inputs({"foo": "bar"}, {"foo": "baz"})
+ assert updated_config == {"foo": "baz"}
+
+
+def test_choose_consul_host(monkeypatch):
+ def fake_default_consul_host():
+ return "default-consul-host"
+
+ monkeypatch.setattr(dis, "default_consul_host", fake_default_consul_host)
+ assert "default-consul-host" == dis._choose_consul_host(None)
+ assert "provided-consul-host" == dis._choose_consul_host("provided-consul-host")
+
+
+if __name__ == '__main__':
+ '''Test area'''
+ pytest.main([__file__, ])
diff --git a/mod/onboardingapi/dcae_cli/util/tests/test_dmaap.py b/mod/onboardingapi/dcae_cli/util/tests/test_dmaap.py
new file mode 100644
index 0000000..dabc737
--- /dev/null
+++ b/mod/onboardingapi/dcae_cli/util/tests/test_dmaap.py
@@ -0,0 +1,259 @@
+# ============LICENSE_START=======================================================
+# org.onap.dcae
+# ================================================================================
+# Copyright (c) 2017 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.
+
+"""
+Tests for dmaap module
+"""
+import pytest
+from dcae_cli.util import dmaap
+from dcae_cli.util.exc import DcaeException
+
+
+def test_validate_dmaap_map_schema_message_router():
+ def pack_her_up(entry):
+ return { "some-config-key": entry }
+
+ good = {
+ "type": "message_router",
+ "aaf_username": "foo3",
+ "aaf_password": "bar3",
+ "dmaap_info": {
+ "client_role":"com.dcae.member",
+ "client_id":"1500462518108",
+ "location":"mtc5",
+ "topic_url":"https://dcae-msrt-ftl2.com:3905/events/com.dcae.dmaap.FTL2.TommyTestTopic2"
+ }
+ }
+ dmaap.validate_dmaap_map_schema(pack_her_up(good))
+
+ good_minimal = {
+ "type": "message_router",
+ "dmaap_info": {
+ "topic_url":"https://dcae-msrt-ftl2.com:3905/events/com.dcae.dmaap.FTL2.TommyTestTopic2"
+ }
+ }
+ dmaap.validate_dmaap_map_schema(pack_her_up(good_minimal))
+
+ bad_extra = {
+ "type": "message_router",
+ "aaf_username": "foo3",
+ "aaf_password": "bar3",
+ "something_else": "boo",
+ "dmaap_info": {
+ "client_role":"com.dcae.member",
+ "client_id":"1500462518108",
+ "location":"mtc5",
+ "topic_url":"https://dcae-msrt-ftl2.com:3905/events/com.dcae.dmaap.FTL2.TommyTestTopic2"
+ }
+ }
+ dm = { "some-config-key": bad_extra }
+
+
+ with pytest.raises(DcaeException):
+ dmaap.validate_dmaap_map_schema(dm)
+
+ bad_missing = {
+ "type": "message_router",
+ "aaf_username": "foo3",
+ "aaf_password": "bar3",
+ "dmaap_info": {
+ "client_role":"com.dcae.member",
+ "client_id":"1500462518108",
+ "location":"mtc5"
+ }
+ }
+ dm = { "some-config-key": bad_missing }
+
+ with pytest.raises(DcaeException):
+ dmaap.validate_dmaap_map_schema(dm)
+
+
+def test_validate_dmaap_map_schema_data_router():
+ def pack_her_up(entry):
+ return { "some-config-key": entry }
+
+ # Publishers
+ good = {
+ "type": "data_router",
+ "dmaap_info": {
+ "location": "mtc5",
+ "publish_url": "http://some-publish-url/123",
+ "log_url": "http://some-log-url/456",
+ "username": "jane",
+ "password": "abc"
+ }
+ }
+ dmaap.validate_dmaap_map_schema(pack_her_up(good))
+
+ good_minimal = {
+ "type": "data_router",
+ "dmaap_info": {
+ "publish_url": "http://some-publish-url/123"
+ }
+ }
+ dmaap.validate_dmaap_map_schema(pack_her_up(good_minimal))
+
+ bad_extra = {
+ "type": "data_router",
+ "dmaap_info": {
+ "publish_url": "http://some-publish-url/123",
+ "unknown_key": "value"
+ }
+ }
+ with pytest.raises(DcaeException):
+ dmaap.validate_dmaap_map_schema(pack_her_up(bad_extra))
+
+ # Subscribers
+ good = {
+ "type": "data_router",
+ "dmaap_info": {
+ "username": "drdeliver",
+ "password": "1loveDataR0uter",
+ "location": "loc00",
+ "delivery_url": "https://example.com/whatever",
+ "subscriber_id": "1550"
+ }
+ }
+ dmaap.validate_dmaap_map_schema(pack_her_up(good))
+
+ good_minimal = {
+ "type": "data_router",
+ "dmaap_info": {
+ "delivery_url": "https://example.com/whatever"
+ }
+ }
+ dmaap.validate_dmaap_map_schema(pack_her_up(good_minimal))
+
+ bad_extra = {
+ "type": "data_router",
+ "dmaap_info": {
+ "delivery_url": "https://example.com/whatever",
+ "unknown_key": "value"
+ }
+ }
+ with pytest.raises(DcaeException):
+ dmaap.validate_dmaap_map_schema(pack_her_up(bad_extra))
+
+
+def test_validate_dmaap_map_entries():
+
+ # Success
+
+ dmaap_map = { "mr_pub_fun": { "foo": "bar" }, "mr_sub_fun": { "baz": "duh"} }
+ mr_config_keys = [ "mr_pub_fun", "mr_sub_fun" ]
+ dr_config_keys = []
+
+ assert dmaap.validate_dmaap_map_entries(dmaap_map, mr_config_keys, dr_config_keys) == True
+
+ # Not supposed to be empty
+
+ dmaap_map = {}
+
+ assert dmaap.validate_dmaap_map_entries(dmaap_map, mr_config_keys, dr_config_keys) == False
+
+ # Too many in dmaap map
+
+ # NOTE: This scenario has been changed to be a success case per Tommy who
+ # believes that having extra keys in the dmaap_map is harmless. People would
+ # want to have a master dmaap_map that has a superset of connections used
+ # across many components.
+
+ dmaap_map = { "mr_pub_fun": { "foo": "bar" }, "mr_sub_fun": { "baz": "duh"} }
+ mr_config_keys = [ "mr_pub_fun" ]
+ dr_config_keys = []
+
+ assert dmaap.validate_dmaap_map_entries(dmaap_map, mr_config_keys, dr_config_keys) == True
+
+ # Too little in dmaap map
+
+ dmaap_map = { "mr_pub_fun": { "foo": "bar" }, "mr_sub_fun": { "baz": "duh"} }
+ mr_config_keys = [ "mr_pub_fun", "mr_sub_fun", "mr_xxx" ]
+ dr_config_keys = []
+
+ assert dmaap.validate_dmaap_map_entries(dmaap_map, mr_config_keys, dr_config_keys) == False
+
+
+def test_apply_defaults_dmaap_map():
+ good = {
+ "type": "message_router",
+ "aaf_username": "foo3",
+ "aaf_password": "bar3",
+ "dmaap_info": {
+ "client_role":"com.dcae.member",
+ "client_id":"1500462518108",
+ "location":"mtc5",
+ "topic_url":"https://dcae-msrt-ftl2.com:3905/events/com.dcae.dmaap.FTL2.TommyTestTopic2"
+ }
+ }
+ dm = { "some-config-key": good }
+
+ assert dmaap.apply_defaults_dmaap_map(dm) == dm
+
+ minimal = {
+ "type": "message_router",
+ "dmaap_info": {
+ "topic_url":"https://dcae-msrt-ftl2.com:3905/events/com.dcae.dmaap.FTL2.TommyTestTopic2"
+ }
+ }
+ dm = { "some-config-key": minimal }
+
+ result = dmaap.apply_defaults_dmaap_map(dm)
+ assert result == {'some-config-key': {'aaf_username': None,
+ 'aaf_password': None, 'dmaap_info': {'client_role': None,
+ 'topic_url': 'https://dcae-msrt-ftl2.com:3905/events/com.dcae.dmaap.FTL2.TommyTestTopic2', 'client_id': None, 'location': None},
+ 'type': 'message_router'}}
+
+
+def test_update_delivery_urls():
+ def get_route_with_slash(config_key):
+ return "/eden"
+
+ dmaap_map = {"spade-key": {"type": "data_router", "dmaap_info": {"delivery_url": "bleh","username": "dolittle"}},
+ "clover-key": {"type": "data_router", "dmaap_info": {"publish_url": "manyfoos",
+ "username": "chickenlittle"}}}
+
+ dmaap_map = dmaap.update_delivery_urls(get_route_with_slash, "http://some-host.io", dmaap_map)
+
+ expected = {'spade-key': {"type": "data_router", 'dmaap_info': {'delivery_url': 'http://some-host.io/eden',
+ 'username': 'dolittle'}}, 'clover-key': {"type": "data_router", 'dmaap_info': {'publish_url': 'manyfoos',
+ 'username': 'chickenlittle'}}}
+ assert expected == dmaap_map
+
+ def get_route_no_slash(config_key):
+ return "eden"
+
+ dmaap_map = dmaap.update_delivery_urls(get_route_no_slash, "http://some-host.io", dmaap_map)
+ assert expected == dmaap_map
+
+ # Case when there is nothing to update
+ dmaap_map = {"clover-key": {"type": "data_router", "dmaap_info": {"publish_url": "manyfoos",
+ "username": "chickenlittle"}}}
+
+ assert dmaap_map == dmaap.update_delivery_urls(get_route_no_slash, "http://some-host.io",
+ dmaap_map)
+
+
+def test_list_delivery_urls():
+ dmaap_map = {"spade-key": {"type": "data_router", "dmaap_info": {"delivery_url": "bleh","username": "dolittle"}},
+ "clover-key": {"type": "data_router", "dmaap_info": {"publish_url": "manyfoos",
+ "username": "chickenlittle"}}}
+
+ result = dmaap.list_delivery_urls(dmaap_map)
+ assert result == [('spade-key', 'bleh')]
diff --git a/mod/onboardingapi/dcae_cli/util/tests/test_docker_util.py b/mod/onboardingapi/dcae_cli/util/tests/test_docker_util.py
new file mode 100644
index 0000000..1860357
--- /dev/null
+++ b/mod/onboardingapi/dcae_cli/util/tests/test_docker_util.py
@@ -0,0 +1,62 @@
+# ============LICENSE_START=======================================================
+# org.onap.dcae
+# ================================================================================
+# Copyright (c) 2017 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.
+
+# -*- coding: utf-8 -*-
+'''
+Provides tests for the docker_util module
+'''
+import pytest
+from dcae_cli.util.profiles import Profile, CONSUL_HOST, CONFIG_BINDING_SERVICE, CDAP_BROKER, DOCKER_HOST
+from dcae_cli.util import docker_util as du
+
+
+# TODO: formalize tests
+'''
+from dcae_cli.util.logger import set_verbose
+set_verbose()
+
+client = _get_docker_client()
+
+params = dict()
+interface_map = dict()
+instance_map = dict()
+# TODO: make-me-valid?
+external_ip ='196.207.143.209'
+
+# TODO: Need to replace the use of asimov
+_run_component('asimov-anomaly-viz:0.0.0',
+ 'bob', 'asimov.anomaly.viz', '1.0.0', params, interface_map, instance_map,
+ external_ip)
+'''
+
+def test_convert_profile_to_docker_envs():
+ expected = { CONSUL_HOST.upper(): "some.consul.somewhere",
+ CONFIG_BINDING_SERVICE.upper(): "some.config_binding.somewhere",
+ CDAP_BROKER.upper(): "broker",
+ DOCKER_HOST.upper(): "some-docker-host"
+ }
+ profile = Profile(**{ CONSUL_HOST: expected[CONSUL_HOST.upper()],
+ CONFIG_BINDING_SERVICE: expected[CONFIG_BINDING_SERVICE.upper()],
+ CDAP_BROKER: expected[CDAP_BROKER.upper()],
+ DOCKER_HOST: expected[DOCKER_HOST.upper()]
+ })
+ actual = du._convert_profile_to_docker_envs(profile)
+
+ assert actual == expected
diff --git a/mod/onboardingapi/dcae_cli/util/tests/test_inputs.py b/mod/onboardingapi/dcae_cli/util/tests/test_inputs.py
new file mode 100644
index 0000000..5271705
--- /dev/null
+++ b/mod/onboardingapi/dcae_cli/util/tests/test_inputs.py
@@ -0,0 +1,37 @@
+# ============LICENSE_START=======================================================
+# org.onap.dcae
+# ================================================================================
+# Copyright (c) 2017 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.
+
+"""
+Tests for inputs module
+"""
+import pytest
+from dcae_cli.util import inputs
+
+
+def test_filter_entries():
+ spec = { "parameters": [{"name": "foo"}, {"name": "bar",
+ "sourced_at_deployment": False}, {"name": "baz", "sourced_at_deployment": True}] }
+
+ with pytest.raises(inputs.InputsValidationError):
+ inputs.filter_entries({}, spec)
+
+ inputs_map = { "foo": "do not copy", "baz": "hello world", "extra": "do not copy" }
+
+ assert len(inputs.filter_entries(inputs_map, spec)) == 1
diff --git a/mod/onboardingapi/dcae_cli/util/tests/test_profiles.py b/mod/onboardingapi/dcae_cli/util/tests/test_profiles.py
new file mode 100644
index 0000000..969697a
--- /dev/null
+++ b/mod/onboardingapi/dcae_cli/util/tests/test_profiles.py
@@ -0,0 +1,162 @@
+# ============LICENSE_START=======================================================
+# org.onap.dcae
+# ================================================================================
+# Copyright (c) 2017 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.
+
+# -*- coding: utf-8 -*-
+"""
+Tests the profiles module
+"""
+import os, json, copy
+from functools import partial
+
+import click
+import pytest
+
+from dcae_cli import util
+from dcae_cli.util.exc import DcaeException
+from dcae_cli.util import profiles
+from dcae_cli.util.profiles import (get_active_name, get_profile, get_profiles, get_profiles_path,
+ create_profile, delete_profile, update_profile, ACTIVE,
+ activate_profile, CONSUL_HOST)
+from dcae_cli.util import config
+
+
+def test_profiles(monkeypatch, tmpdir):
+ '''Tests the creation and initialization of profiles on a clean install'''
+ # Setup config
+ config_dict = { "active_profile": "fake-solutioning", "db_url": "some-db" }
+ config_file = tmpdir.join("config.json")
+ config_file.write(json.dumps(config_dict))
+
+ # Setup profile
+ profile_dict = { "fake-solutioning": { "cdap_broker": "cdap_broker",
+ "config_binding_service": "config_binding_service",
+ "consul_host": "realsolcnsl00.dcae.solutioning.com",
+ "docker_host": "realsoldokr00.dcae.solutioning.com:2376" }}
+ profile_file = tmpdir.join("profiles.json")
+ profile_file.write(json.dumps(profile_dict))
+
+ monkeypatch.setattr(click, "get_app_dir", lambda app: str(tmpdir.realpath()))
+
+ assert get_active_name() == config_dict["active_profile"]
+ assert get_profile() == profiles.Profile(**profile_dict["fake-solutioning"])
+
+ # Failures looking for unknown profile
+
+ with pytest.raises(DcaeException):
+ get_profile('foo')
+
+ with pytest.raises(DcaeException):
+ delete_profile('foo')
+
+ with pytest.raises(DcaeException):
+ update_profile('foo', **{}) # doesn't exist
+
+ # Cannot delete active profile
+
+ assert delete_profile(get_active_name()) == False
+
+ # Do different get_profiles queries
+
+ assert get_profiles(user_only=True) == profile_dict
+ all_profiles = copy.deepcopy(profile_dict)
+ all_profiles[ACTIVE] = profile_dict["fake-solutioning"]
+ assert get_profiles(user_only=False) == all_profiles
+
+ # Create and activate new profile
+
+ create_profile('foo')
+ activate_profile('foo')
+ assert get_active_name() == 'foo'
+
+ # Update new profile
+
+ update_profile('foo', **{CONSUL_HOST:'bar'})
+ assert get_profiles()['foo'][CONSUL_HOST] == 'bar'
+ assert get_profile()._asdict()[CONSUL_HOST] == 'bar'
+
+ activate_profile("fake-solutioning")
+ assert delete_profile('foo') == True
+
+
+def test_reinit_via_get_profiles(monkeypatch, tmpdir):
+ monkeypatch.setattr(click, "get_app_dir", lambda app: str(tmpdir.realpath()))
+
+ def fake_reinit_failure():
+ raise profiles.ProfilesInitError("Faked failure")
+
+ monkeypatch.setattr(profiles, "reinit_profiles", fake_reinit_failure)
+
+ with pytest.raises(DcaeException):
+ get_profiles()
+
+
+def test_reinit_profiles(monkeypatch, tmpdir):
+ monkeypatch.setattr(click, "get_app_dir", lambda app: str(tmpdir.realpath()))
+
+ # Setup config (need this because the "active_profile" is needed)
+ config_dict = { "active_profile": "fake-solutioning", "db_url": "some-db" }
+ config_file = tmpdir.join("config.json")
+ config_file.write(json.dumps(config_dict))
+
+ # Start with empty profiles
+
+ profile_dict = { "fake-solutioning": { "cdap_broker": "cdap_broker",
+ "config_binding_service": "config_binding_service",
+ "consul_host": "realsolcnsl00.dcae.solutioning.com",
+ "docker_host": "realsoldokr00.dcae.solutioning.com:2376" }}
+
+ def fetch_profile(target_profile, server_url, path):
+ return target_profile
+
+ monkeypatch.setattr(util, "fetch_file_from_web", partial(fetch_profile,
+ profile_dict))
+ profiles.reinit_profiles()
+ assert profiles.get_profiles(include_active=False) == profile_dict
+
+ # Test update
+
+ profile_dict = { "fake-5g": { "cdap_broker": "cdap_broker",
+ "config_binding_service": "config_binding_service",
+ "consul_host": "realsolcnsl00.dcae.solutioning.com",
+ "docker_host": "realsoldokr00.dcae.solutioning.com:2376" }}
+
+ monkeypatch.setattr(util, "fetch_file_from_web", partial(fetch_profile,
+ profile_dict))
+ profiles.reinit_profiles()
+ all_profiles = profiles.get_profiles(include_active=False)
+ assert "fake-5g" in all_profiles
+ assert "fake-solutioning" in all_profiles
+
+ # Test fetch failure
+
+ def fetch_failure(server_url, path):
+ raise RuntimeError("Mysterious error")
+
+ monkeypatch.setattr(util, "fetch_file_from_web", fetch_failure)
+ # Case when user opts out of manually setting up
+ monkeypatch.setattr(click, "confirm", lambda msg: False)
+
+ with pytest.raises(profiles.ProfilesInitError):
+ profiles.reinit_profiles()
+
+
+if __name__ == '__main__':
+ '''Test area'''
+ pytest.main([__file__, ])
diff --git a/mod/onboardingapi/dcae_cli/util/tests/test_remove.py b/mod/onboardingapi/dcae_cli/util/tests/test_remove.py
new file mode 100644
index 0000000..92b8ce9
--- /dev/null
+++ b/mod/onboardingapi/dcae_cli/util/tests/test_remove.py
@@ -0,0 +1,24 @@
+# ============LICENSE_START=======================================================
+# org.onap.dcae
+# ================================================================================
+# Copyright (c) 2017 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.
+
+# -*- coding: utf-8 -*-
+'''
+TODO: Test removing components
+'''
diff --git a/mod/onboardingapi/dcae_cli/util/tests/test_undeploy.py b/mod/onboardingapi/dcae_cli/util/tests/test_undeploy.py
new file mode 100644
index 0000000..664c69c
--- /dev/null
+++ b/mod/onboardingapi/dcae_cli/util/tests/test_undeploy.py
@@ -0,0 +1,62 @@
+# ============LICENSE_START=======================================================
+# org.onap.dcae
+# ================================================================================
+# Copyright (c) 2017 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.
+
+# -*- coding: utf-8 -*-
+'''
+Provides tests for the undeploy module
+'''
+from dcae_cli.util.undeploy import _handler, _handler_report
+
+def test_handler():
+ instances = set(["some-instance-name", "another-instance-name"])
+
+ def fake_remove_config(config_key):
+ return True
+
+ def undeploy_success(config_key):
+ return True
+
+ failures, results = _handler([undeploy_success, fake_remove_config], instances)
+
+ assert len(results) == 2
+ assert len(failures) == 0
+
+ def undeploy_failure(config_key):
+ return False
+
+ failures, results = _handler([undeploy_failure, fake_remove_config], instances)
+
+ assert len(results) == 2
+ assert len(failures) == 2
+
+ def undeploy_failure_sometimes(config_key):
+ if "some-instance-name" == config_key:
+ return False
+ return True
+
+ failures, results = _handler([undeploy_failure_sometimes, fake_remove_config], instances)
+
+ assert len(results) == 2
+ assert len(failures) == 1
+
+ failures, results = _handler([undeploy_success, fake_remove_config], [])
+
+ assert len(results) == 0
+ assert len(failures) == 0