From e0de6916445407a98c63e87d88d7276e66c445a0 Mon Sep 17 00:00:00 2001 From: Patricia Reinoso Date: Wed, 26 Oct 2022 08:53:26 +0000 Subject: [PATCH] Add PaaS service creation UTs Change-Id: I1d789c3abd5ee5d75dfce64ac386ddd8bb73c46b Signed-off-by: Patricia Reinoso --- osmclient/scripts/tests/test_ns_operations.py | 116 ++++++++ osmclient/sol005/ns.py | 7 +- osmclient/sol005/tests/test_sol005_ns.py | 261 ++++++++++++++++++ 3 files changed, 380 insertions(+), 4 deletions(-) create mode 100644 osmclient/scripts/tests/test_ns_operations.py create mode 100644 osmclient/sol005/tests/test_sol005_ns.py diff --git a/osmclient/scripts/tests/test_ns_operations.py b/osmclient/scripts/tests/test_ns_operations.py new file mode 100644 index 0000000..cc6b2ca --- /dev/null +++ b/osmclient/scripts/tests/test_ns_operations.py @@ -0,0 +1,116 @@ +# Copyright 2022 Canonical Ltd. +# +# 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. + + +import unittest +from unittest.mock import Mock, patch +from click.testing import CliRunner +from osmclient.common.exceptions import ClientException +from osmclient.scripts import osm + + +@patch("osmclient.scripts.osm.client.Client") +class TestNS(unittest.TestCase): + def setUp(self): + self.runner = CliRunner() + self.ctx_obj = Mock() + + def test_ns_create_with_vim_account(self, mock_client): + mock_client.return_value = self.ctx_obj + result = self.runner.invoke( + osm.cli_osm, + [ + "ns-create", + "--ns_name", + "ns_name", + "--nsd_name", + "nsd_name", + "--vim_account", + "vim_account", + ], + ) + self.ctx_obj.ns.create.assert_called_with( + "nsd_name", + "ns_name", + config=None, + ssh_keys=None, + vim_account="vim_account", + paas_account=None, + admin_status="ENABLED", + wait=False, + timeout=None, + ) + assert not result.exception + + def test_ns_create_with_paas_account(self, mock_client): + mock_client.return_value = self.ctx_obj + result = self.runner.invoke( + osm.cli_osm, + [ + "ns-create", + "--ns_name", + "ns_name", + "--nsd_name", + "nsd_name", + "--paas_account", + "paas_account", + ], + ) + self.ctx_obj.ns.create.assert_called_with( + "nsd_name", + "ns_name", + config=None, + ssh_keys=None, + vim_account=None, + paas_account="paas_account", + admin_status="ENABLED", + wait=False, + timeout=None, + ) + assert not result.exception + + def test_ns_create_with_paas_and_vim_account_raises_exception(self, mock_client): + mock_client.return_value = self.ctx_obj + result = self.runner.invoke( + osm.cli_osm, + [ + "ns-create", + "--ns_name", + "ns_name", + "--nsd_name", + "nsd_name", + "--vim_account", + "vim_account", + "--paas_account", + "paas_account", + ], + ) + self.ctx_obj.ns.create.assert_not_called() + expected_msg = '"vim_account" and "paas_account" can not be used together, use only one of them' + assert result.exception + assert isinstance(result.exception, ClientException) + assert expected_msg in str(result.exception) + + def test_ns_creat_without_paas_or_vim_account_raises_exception(self, mock_client): + mock_client.return_value = self.ctx_obj + result = self.runner.invoke( + osm.cli_osm, ["ns-create", "--ns_name", "ns_name", "--nsd_name", "nsd_name"] + ) + self.ctx_obj.ns.create.assert_not_called() + expected_msg = ( + 'specify "vim_account" or "paas_account", both options can not be empty' + ) + assert result.exception + assert isinstance(result.exception, ClientException) + assert expected_msg in str(result.exception) diff --git a/osmclient/sol005/ns.py b/osmclient/sol005/ns.py index fe3a2ba..992bf0f 100644 --- a/osmclient/sol005/ns.py +++ b/osmclient/sol005/ns.py @@ -498,14 +498,13 @@ class Ns(object): endpoint=self._apiBase, postfields_dict=ns ) - if resp: - resp = json.loads(resp) - print(str(resp["id"])) - if not resp or "id" not in resp: raise ClientException( "unexpected response from server - {} ".format(resp) ) + if resp: + resp = json.loads(resp) + print(str(resp["id"])) if wait: # Wait for status for NS instance creation self._wait(resp.get("nslcmop_id"), wait) diff --git a/osmclient/sol005/tests/test_sol005_ns.py b/osmclient/sol005/tests/test_sol005_ns.py new file mode 100644 index 0000000..77bdf70 --- /dev/null +++ b/osmclient/sol005/tests/test_sol005_ns.py @@ -0,0 +1,261 @@ +# Copyright 2022 Canonical Ltd. +# +# 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. + +import yaml +import unittest +from unittest.mock import Mock, MagicMock + +from osmclient.common.exceptions import ClientException, NotFound +from osmclient.sol005.ns import Ns + + +class TestNs(unittest.TestCase): + def setUp(self): + self.ns = Ns(Mock(), Mock()) + self.set_http_header() + self.endpoint = "/nslcm/v1/ns_instances_content" + self.nsd_id = "nsd_id" + self.nsd_name = {"name": "nsd_name"} + self.nsr_name = {"name": "network service name"} + self.ns._client.nsd.get.return_value = {"_id": self.nsd_id} + + def set_http_header(self): + headers = {"key_1": "value"} + self.ns._client._headers = MagicMock() + self.ns._client._headers.__getitem__.side_effect = headers.__getitem__ + self.ns._client._headers.items = headers.items + + def test_create_ns_vim_account(self): + vim_account = "my_vim_id" + timeout = 15 + description = "description_for_my_NS" + + self.ns._client.vim.get.return_value = {"_id": vim_account} + self.ns._http.post_cmd.return_value = (200, '{"id": "1234"}') + + ns = { + "nsdId": self.nsd_id, + "nsName": self.nsr_name, + "nsDescription": description, + "vimAccountId": vim_account, + "timeout_ns_deploy": timeout, + } + + resp_id = self.ns.create( + nsd_name=self.nsd_name, + nsr_name=self.nsr_name, + vim_account=vim_account, + paas_account=None, + description=description, + timeout=timeout, + ) + + self.ns._client.get_token.assert_called() + self.ns._client.nsd.get.assert_called_with(self.nsd_name) + self.ns._http.post_cmd.assert_called_with( + endpoint=self.endpoint, postfields_dict=ns + ) + + self.assertEqual(resp_id, "1234") + + def test_create_ns_paas_account(self): + paas_account = "my_paas_id" + timeout = 10 + description = "description_for_my_NS" + config = { + "additionalParamsForNs": {}, + "additionalParamsForVnf": [ + {"additional_param0": "val", "member-vnf-index": "index"} + ], + } + + ns = { + "nsdId": self.nsd_id, + "nsName": self.nsr_name, + "nsDescription": description, + "paasAccountId": paas_account, + "timeout_ns_deploy": timeout, + "additionalParamsForNs": config["additionalParamsForNs"], + "additionalParamsForVnf": config["additionalParamsForVnf"], + } + + self.ns._client.paas.get.return_value = {"_id": paas_account} + self.ns._http.post_cmd.return_value = (200, '{"id": "1234"}') + + resp_id = self.ns.create( + nsd_name=self.nsd_name, + nsr_name=self.nsr_name, + vim_account=None, + paas_account=paas_account, + description=description, + timeout=timeout, + config=yaml.dump(config), + ) + + self.ns._client.get_token.assert_called() + self.ns._client.nsd.get.assert_called_with(self.nsd_name) + self.ns._http.post_cmd.assert_called_with( + endpoint=self.endpoint, postfields_dict=ns + ) + + self.assertEqual(resp_id, "1234") + + def test_create_ns_paas_account_does_not_exist(self): + paas_account = "my_paas_id" + + self.ns._client.paas.get.side_effect = NotFound() + + with self.assertRaises(NotFound): + self.ns.create( + nsd_name=self.nsd_name, + nsr_name=self.nsr_name, + vim_account=None, + paas_account=paas_account, + ) + + self.ns._client.get_token.assert_called() + self.ns._client.nsd.get.assert_called_with(self.nsd_name) + self.ns._http.set_http_header.assert_not_called() + self.ns._http.post_cmd.assert_not_called() + + def test_create_ns_paas_account_post_raises_exception(self): + paas_account = "my_paas_id" + + ns = { + "nsdId": self.nsd_id, + "nsName": self.nsr_name, + "nsDescription": "default description", + "paasAccountId": paas_account, + } + + self.ns._client.paas.get.return_value = {"_id": paas_account} + self.ns._http.post_cmd.side_effect = ClientException() + + with self.assertRaises(ClientException): + self.ns.create( + nsd_name=self.nsd_name, + nsr_name=self.nsr_name, + vim_account=None, + paas_account=paas_account, + ) + + self.ns._client.get_token.assert_called() + self.ns._client.nsd.get.assert_called_with(self.nsd_name) + self.ns._http.post_cmd.assert_called_with( + endpoint=self.endpoint, postfields_dict=ns + ) + + def test_create_ns_paas_account_id_is_not_in_response(self): + paas_account = "my_paas_id" + + ns = { + "nsdId": self.nsd_id, + "nsName": self.nsr_name, + "nsDescription": "default description", + "paasAccountId": paas_account, + } + + self.ns._client.paas.get.return_value = {"_id": paas_account} + self.ns._http.post_cmd.return_value = (200, "{}") + + with self.assertRaises(ClientException): + self.ns.create( + nsd_name=self.nsd_name, + nsr_name=self.nsr_name, + vim_account=None, + paas_account=paas_account, + ) + + self.ns._client.get_token.assert_called() + self.ns._client.nsd.get.assert_called_with(self.nsd_name) + self.ns._http.post_cmd.assert_called_with( + endpoint=self.endpoint, postfields_dict=ns + ) + + def invalid_config_test(self, config, exception): + paas_account = "my_paas_id" + + self.ns._client.paas.get.return_value = {"_id": paas_account} + + with self.assertRaises(ClientException) as e: + self.ns.create( + nsd_name=self.nsd_name, + nsr_name=self.nsr_name, + vim_account=None, + paas_account=paas_account, + config=yaml.dump(config), + ) + assert str(e.value) == exception + + self.ns._client.get_token.assert_called() + self.ns._client.nsd.get.assert_called_with(self.nsd_name) + self.ns._http.set_http_header.assert_not_called() + self.ns._http.post_cmd.assert_not_called() + + def test_create_ns_paas_invalid_additional_params_ns(self): + config = {"additionalParamsForNs": [], "additionalParamsForVnf": {}} + exception = "Error at --config 'additionalParamsForNs' must be a dictionary" + self.invalid_config_test(config, exception) + + def test_create_ns_paas_invalid_additional_params_vnf(self): + config = {"additionalParamsForNs": {}, "additionalParamsForVnf": {}} + exception = "Error at --config 'additionalParamsForVnf' must be a list" + self.invalid_config_test(config, exception) + + def test_create_ns_paas_invalid_additional_param_vnf(self): + config = {"additionalParamsForNs": {}, "additionalParamsForVnf": [[]]} + exception = ( + "Error at --config 'additionalParamsForVnf' items must be dictionaries" + ) + self.invalid_config_test(config, exception) + + def test_create_ns_paas_invalid_config_member_vnf_index_missing(self): + config = { + "additionalParamsForNs": {}, + "additionalParamsForVnf": [{"additional_param0": "val"}], + } + exception = "Error at --config 'additionalParamsForVnf' items must contain 'member-vnf-index'" + self.invalid_config_test(config, exception) + + def test_create_ns_without_paas_or_vim_account_raises_exception(self): + with self.assertRaises(ClientException) as e: + self.ns.create( + nsd_name=self.nsd_name, + nsr_name=self.nsr_name, + vim_account=None, + paas_account=None, + ) + error_msg = "Both of vim_account and paas_account options are empty." + assert str(e.value) == error_msg + + self.ns._client.get_token.assert_not_called() + self.ns._client.nsd.get.assert_not_called() + self.ns._http.set_http_header.assert_not_called() + self.ns._http.post_cmd.assert_not_called() + + def test_create_ns_with_paas_and_vim_account_raises_exception(self): + with self.assertRaises(ClientException) as e: + self.ns.create( + nsd_name=self.nsd_name, + nsr_name=self.nsr_name, + vim_account="vim_account", + paas_account="paas_account", + ) + error_msg = "Both of vim_account and paas_account options are set." + assert str(e.value) == error_msg + + self.ns._client.get_token.assert_not_called() + self.ns._client.nsd.get.assert_not_called() + self.ns._http.set_http_header.assert_not_called() + self.ns._http.post_cmd.assert_not_called() -- 2.25.1