# contact: alfonso.tiernosepulveda@telefonica.com
##
import logging
-from unittest.mock import Mock, patch, MagicMock
+import tempfile
+from unittest.mock import Mock, patch, MagicMock, mock_open
from unittest import TestCase
from osm_common.msgkafka import MsgKafka
from zipfile import BadZipfile
+tmpdir = tempfile.mkdtemp()[1]
+tmpfile = tempfile.mkstemp()[1]
+
+
class TestLcmBase(TestCase):
test_nsr_id = "f48163a6-c807-47bc-9682-f72caef5af85"
self.my_ns = LcmBase(self.msg, self.logger)
self.my_ns.fs = self.fs
self.my_ns.db = self.db
+ self.hexdigest = "031edd7d41651593c5fe5c006f"
def test_get_charm_name_successfully(self):
instance = self.my_ns
self.assertEqual(mock_charm_path.call_count, 1)
self.assertEqual(mock_metadata_file.call_count, 1)
self.assertEqual(mock_charm_name.call_count, 1)
+
+ @patch("builtins.open", new_callable=mock_open(read_data="charm content"))
+ @patch("osm_lcm.lcm_utils.hashlib")
+ def test_calculate_charm_hash_sucessfully(self, mock_hashlib, mocking_open):
+ """Calculate charm hash successfully."""
+ charm = tmpfile
+ hexdigest = self.hexdigest
+ mock_file_hash = MagicMock()
+ mock_hashlib.md5.return_value = mock_file_hash
+ mock_file_hash.hexdigest.return_value = hexdigest
+ result = LcmBase.calculate_charm_hash(charm)
+ self.assertEqual(result, hexdigest)
+ self.assertEqual(mocking_open.call_count, 1)
+ self.assertEqual(mock_file_hash.update.call_count, 1)
+ self.assertEqual(mock_file_hash.hexdigest.call_count, 1)
+ self.assertEqual(mock_hashlib.md5.call_count, 1)
+
+ @patch("builtins.open", new_callable=mock_open(read_data="charm content"))
+ @patch("osm_lcm.lcm_utils.hashlib")
+ def test_calculate_charm_hash_open_raises(self, mock_hashlib, mocking_open):
+ """builtins.open raises exception."""
+ charm = tmpfile
+ hexdigest = self.hexdigest
+ mock_file_hash = MagicMock()
+ mock_hashlib.md5.return_value = mock_file_hash
+ mock_file_hash.hexdigest.return_value = hexdigest
+ mocking_open.side_effect = IOError
+ with self.assertRaises(IOError):
+ LcmBase.calculate_charm_hash(charm)
+ self.assertEqual(mocking_open.call_count, 1)
+ mock_file_hash.update.assert_not_called()
+ mock_file_hash.hexdigest.assert_not_called()
+ self.assertEqual(mock_hashlib.md5.call_count, 1)
+
+ @patch("builtins.open", new_callable=mock_open(read_data="charm content"))
+ @patch("osm_lcm.lcm_utils.hashlib")
+ def test_calculate_charm_filehash_update_raises(self, mock_hashlib, mocking_open):
+ """Filehash update raises exception."""
+ charm = tmpfile
+ hexdigest = self.hexdigest
+ mock_file_hash = MagicMock()
+ mock_file_hash.update.side_effect = Exception
+ mock_hashlib.md5.return_value = mock_file_hash
+ mock_file_hash.hexdigest.return_value = hexdigest
+ with self.assertRaises(Exception):
+ LcmBase.calculate_charm_hash(charm)
+ self.assertEqual(mocking_open.call_count, 1)
+ self.assertEqual(mock_file_hash.update.call_count, 1)
+ mock_file_hash.hexdigest.assert_not_called()
+ self.assertEqual(mock_hashlib.md5.call_count, 1)
+
+ @patch("builtins.open", new_callable=mock_open(read_data="charm content"))
+ @patch("osm_lcm.lcm_utils.hashlib")
+ def test_calculate_charm_filehash_hexdigest_raises(
+ self, mock_hashlib, mocking_open
+ ):
+ """Filehash hexdigest raises exception."""
+ charm = tmpfile
+ mock_file_hash = MagicMock()
+ mock_hashlib.md5.return_value = mock_file_hash
+ mock_file_hash.hexdigest.side_effect = Exception
+ with self.assertRaises(Exception):
+ LcmBase.calculate_charm_hash(charm)
+ self.assertEqual(mocking_open.call_count, 1)
+ self.assertEqual(mock_file_hash.update.call_count, 1)
+ mock_file_hash.hexdigest.assert_called_once()
+ self.assertEqual(mock_hashlib.md5.call_count, 1)
+ mock_file_hash.update.assert_called_once()
+
+ @patch("builtins.open", new_callable=mock_open(read_data="charm content"))
+ @patch("osm_lcm.lcm_utils.hashlib")
+ def test_calculate_charm_filehash_hashlib_md5_raises(
+ self, mock_hashlib, mocking_open
+ ):
+ """Filehash hashlib md5 raises exception."""
+ charm = tmpfile
+ mock_hashlib.md5.side_effect = Exception
+ with self.assertRaises(Exception):
+ LcmBase.calculate_charm_hash(charm)
+ self.assertEqual(mock_hashlib.md5.call_count, 1)
+ mocking_open.assert_not_called()
+
+ @patch("builtins.open", new_callable=mock_open(read_data="charm content"))
+ @patch("osm_lcm.lcm_utils.hashlib")
+ def test_calculate_charm_hash_file_does_not_exist(self, mock_hashlib, mocking_open):
+ """Calculate charm hash, charm file does not exist."""
+ file = None
+ mock_file_hash = MagicMock()
+ mock_hashlib.md5.return_value = mock_file_hash
+ mocking_open.side_effect = FileNotFoundError
+ with self.assertRaises(FileNotFoundError):
+ LcmBase.calculate_charm_hash(file)
+ self.assertEqual(mocking_open.call_count, 1)
+ mock_file_hash.update.assert_not_called()
+ mock_file_hash.hexdigest.assert_not_called()
+ self.assertEqual(mock_hashlib.md5.call_count, 1)
+
+ @patch("osm_lcm.lcm_utils.LcmBase.calculate_charm_hash")
+ def test_compare_charm_hash_charm_changed(self, mock_calculate_charm_hash):
+ """Compare charm hash, charm files are different."""
+ output = True
+ charm1, charm2 = tmpfile, tmpfile
+ mock_calculate_charm_hash.side_effect = [
+ self.hexdigest,
+ "0dd7d4173747593c5fe5c006f",
+ ]
+ result = LcmBase.compare_charm_hash(charm1, charm2)
+ self.assertEqual(output, result)
+ self.assertEqual(mock_calculate_charm_hash.call_count, 2)
+
+ @patch("osm_lcm.lcm_utils.LcmBase.calculate_charm_hash")
+ def test_compare_charm_hash_charm_is_same(self, mock_calculate_charm_hash):
+ """Compare charm hash, charm files are same."""
+ output = False
+ charm1 = charm2 = tmpfile
+ mock_calculate_charm_hash.side_effect = [
+ self.hexdigest,
+ self.hexdigest,
+ ]
+ result = LcmBase.compare_charm_hash(charm1, charm2)
+ self.assertEqual(output, result)
+ self.assertEqual(mock_calculate_charm_hash.call_count, 2)
+
+ @patch("osm_lcm.lcm_utils.LcmBase.calculate_charm_hash")
+ def test_compare_charm_hash_one_charm_is_not_valid(self, mock_calculate_charm_hash):
+ """Compare charm hash, one charm file is not valid."""
+ charm1, charm2 = tmpdir, None
+ mock_calculate_charm_hash.side_effect = [
+ self.hexdigest,
+ FileNotFoundError,
+ ]
+
+ with self.assertRaises(FileNotFoundError):
+ LcmBase.compare_charm_hash(charm1, charm2)
+ self.assertEqual(mock_calculate_charm_hash.call_count, 2)
+
+ @patch("osm_lcm.lcm_utils.LcmBase.calculate_charm_hash")
+ def test_compare_charm_hash_both_charms_are_not_valid(
+ self, mock_calculate_charm_hash
+ ):
+ """Compare charm hash, both charm files are not valid."""
+ charm1, charm2 = None, None
+ mock_calculate_charm_hash.side_effect = [IOError, IOError]
+ with self.assertRaises(IOError):
+ LcmBase.compare_charm_hash(charm1, charm2)
+ self.assertEqual(mock_calculate_charm_hash.call_count, 1)
+
+ @patch("osm_lcm.lcm_utils.checksumdir")
+ def test_compare_charmdir_charm_changed(self, mock_checksum):
+ """Compare charm directory hash, charms are changed."""
+ expected_output = True
+ charm_dir1, charm_dir2 = tmpdir, tmpdir
+ mock_checksum.dirhash.side_effect = [
+ self.hexdigest,
+ "031eddtrtr651593c5fe5c006f",
+ ]
+ result = LcmBase.compare_charmdir_hash(charm_dir1, charm_dir2)
+ self.assertEqual(expected_output, result)
+ self.assertEqual(mock_checksum.dirhash.call_count, 2)
+
+ @patch("osm_lcm.lcm_utils.checksumdir")
+ def test_compare_charmdir_charm_is_same(self, mock_checksum):
+ """Compare charm directory hash, charms are same."""
+ expected_output = False
+ charm_dir1 = charm_dir2 = tmpdir
+ mock_checksum.dirhash.side_effect = [
+ self.hexdigest,
+ self.hexdigest,
+ ]
+ result = LcmBase.compare_charmdir_hash(charm_dir1, charm_dir2)
+ self.assertEqual(expected_output, result)
+ self.assertEqual(mock_checksum.dirhash.call_count, 2)
+
+ @patch("osm_lcm.lcm_utils.checksumdir")
+ def test_compare_charmdir_one_charmdir_is_not_valid(self, mock_checksum):
+ """Compare charm directory hash, one charm directory is not valid."""
+ charm_dir1, charm_dir2 = tmpdir, None
+ mock_checksum.dirhash.side_effect = [
+ self.hexdigest,
+ FileNotFoundError,
+ ]
+ with self.assertRaises(FileNotFoundError):
+ LcmBase.compare_charmdir_hash(charm_dir1, charm_dir2)
+ self.assertEqual(mock_checksum.dirhash.call_count, 2)
+
+ @patch("osm_lcm.lcm_utils.checksumdir")
+ def test_compare_charmdir_both_charmdirs_are_not_valid(self, mock_checksum):
+ """Compare charm directory hash, both charm directories are not valid."""
+ charm_dir1, charm_dir2 = None, None
+ mock_checksum.dirhash.side_effect = [FileNotFoundError, FileNotFoundError]
+ with self.assertRaises(FileNotFoundError):
+ LcmBase.compare_charmdir_hash(charm_dir1, charm_dir2)
+ self.assertEqual(mock_checksum.dirhash.call_count, 1)
import asynctest # pip3 install asynctest --user
import asyncio
+from copy import deepcopy
import yaml
import copy
from os import getenv
"ng": True,
},
}
+nsr_id = descriptors.test_ids["TEST-A"]["ns"]
+nslcmop_id = descriptors.test_ids["TEST-A"]["update"]
+vnfr_id = "6421c7c9-d865-4fb4-9a13-d4275d243e01"
+vnfd_id = "7637bcf8-cf14-42dc-ad70-c66fcf1e6e77"
+update_fs = Mock(autospec=True)
+update_fs.path.__add__ = Mock()
+update_fs.path.side_effect = ["/", "/", "/", "/"]
+update_fs.sync.side_effect = [None, None]
+
+
+def callable(a):
+ return a
class TestMyNS(asynctest.TestCase):
params={},
machine_spec={},
callback=None,
- *callback_args
+ *callback_args,
):
if callback:
for status, message in (
# self.assertEqual(db_nsr.get("errorDescription "), None, "errorDescription different than None")
# self.assertEqual(db_nsr.get("errorDetail"), None, "errorDetail different than None")
- # Test update method
-
- async def test_update(self):
-
- nsr_id = descriptors.test_ids["TEST-A"]["ns"]
- nslcmop_id = descriptors.test_ids["TEST-A"]["update"]
- vnfr_id = "6421c7c9-d865-4fb4-9a13-d4275d243e01"
- vnfd_id = "7637bcf8-cf14-42dc-ad70-c66fcf1e6e77"
-
- def mock_reset():
- mock_charm_hash.reset_mock()
- mock_juju_bundle.reset_mock()
- fs.sync.reset_mock()
- mock_charm_upgrade.reset_mock()
- mock_software_version.reset_mock()
-
- with self.subTest(
- i=1,
- t="Update type: CHANGE_VNFPKG, latest_vnfd revision changed,"
- "Charm package changed, sw-version is not changed.",
- ):
-
- self.db.set_one(
- "vnfds",
- q_filter={"_id": vnfd_id},
- update_dict={"_admin.revision": 3, "kdu": []},
- )
-
- self.db.set_one(
- "vnfds_revisions",
- q_filter={"_id": vnfd_id + ":1"},
- update_dict={"_admin.revision": 1, "kdu": []},
- )
-
- self.db.set_one(
- "vnfrs", q_filter={"_id": vnfr_id}, update_dict={"revision": 1}
- )
-
- mock_charm_hash = Mock(autospec=True)
- mock_charm_hash.return_value = True
-
- mock_juju_bundle = Mock(return_value=None)
-
- mock_software_version = Mock(autospec=True)
- mock_software_version.side_effect = ["1.0", "1.0"]
-
- mock_charm_upgrade = asynctest.Mock(autospec=True)
- task = asyncio.Future()
- task.set_result(("COMPLETED", "some_output"))
- mock_charm_upgrade.return_value = task
-
- fs = Mock(autospec=True)
- fs.path.__add__ = Mock()
- fs.path.side_effect = ["/", "/", "/", "/"]
- fs.sync.side_effect = [None, None]
-
- instance = self.my_ns
-
- expected_operation_state = "COMPLETED"
- expected_operation_error = ""
- expected_vnfr_revision = 3
- expected_ns_state = "INSTANTIATED"
- expected_ns_operational_state = "running"
-
- with patch.object(instance, "fs", fs), patch(
- "osm_lcm.lcm_utils.LcmBase.check_charm_hash_changed", mock_charm_hash
- ), patch("osm_lcm.ns.NsLcm._ns_charm_upgrade", mock_charm_upgrade), patch(
- "osm_lcm.data_utils.vnfd.find_software_version", mock_software_version
- ), patch(
- "osm_lcm.lcm_utils.check_juju_bundle_existence", mock_juju_bundle
- ):
-
- await instance.update(nsr_id, nslcmop_id)
- return_operation_state = self.db.get_one(
- "nslcmops", {"_id": nslcmop_id}
- ).get("operationState")
- return_operation_error = self.db.get_one(
- "nslcmops", {"_id": nslcmop_id}
- ).get("errorMessage")
- return_ns_operational_state = self.db.get_one(
- "nsrs", {"_id": nsr_id}
- ).get("operational-status")
-
- return_vnfr_revision = self.db.get_one("vnfrs", {"_id": vnfr_id}).get(
- "revision"
- )
-
- return_ns_state = self.db.get_one("nsrs", {"_id": nsr_id}).get(
- "nsState"
- )
-
- mock_charm_hash.assert_called_with(
- "7637bcf8-cf14-42dc-ad70-c66fcf1e6e77:1/hackfest_3charmed_vnfd/charms/simple",
- "7637bcf8-cf14-42dc-ad70-c66fcf1e6e77:3/hackfest_3charmed_vnfd/charms/simple",
- )
-
- self.assertEqual(fs.sync.call_count, 2)
- self.assertEqual(return_ns_state, expected_ns_state)
- self.assertEqual(return_operation_state, expected_operation_state)
- self.assertEqual(return_operation_error, expected_operation_error)
- self.assertEqual(
- return_ns_operational_state, expected_ns_operational_state
- )
- self.assertEqual(return_vnfr_revision, expected_vnfr_revision)
-
- mock_reset()
-
- with self.subTest(
- i=2, t="Update type: CHANGE_VNFPKG, latest_vnfd revision not changed"
- ):
-
- self.db.set_one(
- "vnfds", q_filter={"_id": vnfd_id}, update_dict={"_admin.revision": 1}
- )
-
- self.db.set_one(
- "vnfrs", q_filter={"_id": vnfr_id}, update_dict={"revision": 1}
- )
-
- mock_charm_hash = Mock(autospec=True)
- mock_charm_hash.return_value = True
-
- mock_juju_bundle = Mock(return_value=None)
- mock_software_version = Mock(autospec=True)
-
- mock_charm_upgrade = asynctest.Mock(autospec=True)
- task = asyncio.Future()
- task.set_result(("COMPLETED", "some_output"))
- mock_charm_upgrade.return_value = task
-
- fs = Mock(autospec=True)
- fs.path.__add__ = Mock()
- fs.path.side_effect = ["/", "/", "/", "/"]
- fs.sync.side_effect = [None, None]
-
- instance = self.my_ns
-
- expected_operation_state = "COMPLETED"
- expected_operation_error = ""
- expected_vnfr_revision = 1
- expected_ns_state = "INSTANTIATED"
- expected_ns_operational_state = "running"
-
- with patch.object(instance, "fs", fs), patch(
- "osm_lcm.lcm_utils.LcmBase.check_charm_hash_changed", mock_charm_hash
- ), patch("osm_lcm.ns.NsLcm._ns_charm_upgrade", mock_charm_upgrade), patch(
- "osm_lcm.lcm_utils.check_juju_bundle_existence", mock_juju_bundle
- ):
-
- await instance.update(nsr_id, nslcmop_id)
-
- return_operation_state = self.db.get_one(
- "nslcmops", {"_id": nslcmop_id}
- ).get("operationState")
-
- return_operation_error = self.db.get_one(
- "nslcmops", {"_id": nslcmop_id}
- ).get("errorMessage")
-
- return_ns_operational_state = self.db.get_one(
- "nsrs", {"_id": nsr_id}
- ).get("operational-status")
-
- return_ns_state = self.db.get_one("nsrs", {"_id": nsr_id}).get(
- "nsState"
- )
-
- return_vnfr_revision = self.db.get_one("vnfrs", {"_id": vnfr_id}).get(
- "revision"
- )
-
- mock_charm_hash.assert_not_called()
- mock_software_version.assert_not_called()
- mock_juju_bundle.assert_not_called()
- mock_charm_upgrade.assert_not_called()
- fs.sync.assert_not_called()
-
- self.assertEqual(return_ns_state, expected_ns_state)
- self.assertEqual(return_operation_state, expected_operation_state)
- self.assertEqual(return_operation_error, expected_operation_error)
- self.assertEqual(
- return_ns_operational_state, expected_ns_operational_state
- )
- self.assertEqual(return_vnfr_revision, expected_vnfr_revision)
-
- mock_reset()
-
- with self.subTest(
- i=3,
- t="Update type: CHANGE_VNFPKG, latest_vnfd revision changed, "
- "Charm package is not changed, sw-version is not changed.",
- ):
-
- self.db.set_one(
- "vnfds", q_filter={"_id": vnfd_id}, update_dict={"_admin.revision": 3}
- )
-
- self.db.set_one(
- "vnfds_revisions",
- q_filter={"_id": vnfd_id + ":1"},
- update_dict={"_admin.revision": 1},
- )
-
- self.db.set_one(
- "vnfrs", q_filter={"_id": vnfr_id}, update_dict={"revision": 1}
- )
-
- mock_charm_hash = Mock(autospec=True)
- mock_charm_hash.return_value = False
-
- mock_juju_bundle = Mock(return_value=None)
-
- mock_software_version = Mock(autospec=True)
-
- mock_charm_upgrade = asynctest.Mock(autospec=True)
- task = asyncio.Future()
- task.set_result(("COMPLETED", "some_output"))
- mock_charm_upgrade.return_value = task
- mock_software_version.side_effect = ["1.0", "1.0"]
-
- fs = Mock(autospec=True)
- fs.path.__add__ = Mock()
- fs.path.side_effect = ["/", "/", "/", "/"]
- fs.sync.side_effect = [None, None]
-
- instance = self.my_ns
-
- expected_operation_state = "COMPLETED"
- expected_operation_error = ""
- expected_vnfr_revision = 3
- expected_ns_state = "INSTANTIATED"
- expected_ns_operational_state = "running"
-
- with patch.object(instance, "fs", fs), patch(
- "osm_lcm.lcm_utils.LcmBase.check_charm_hash_changed", mock_charm_hash
- ), patch("osm_lcm.ns.NsLcm._ns_charm_upgrade", mock_charm_upgrade), patch(
- "osm_lcm.lcm_utils.check_juju_bundle_existence", mock_juju_bundle
- ):
-
- await instance.update(nsr_id, nslcmop_id)
-
- return_operation_state = self.db.get_one(
- "nslcmops", {"_id": nslcmop_id}
- ).get("operationState")
-
- return_operation_error = self.db.get_one(
- "nslcmops", {"_id": nslcmop_id}
- ).get("errorMessage")
-
- return_ns_operational_state = self.db.get_one(
- "nsrs", {"_id": nsr_id}
- ).get("operational-status")
-
- return_vnfr_revision = self.db.get_one("vnfrs", {"_id": vnfr_id}).get(
- "revision"
- )
-
- return_ns_state = self.db.get_one("nsrs", {"_id": nsr_id}).get(
- "nsState"
- )
-
- mock_charm_hash.assert_called_with(
- "7637bcf8-cf14-42dc-ad70-c66fcf1e6e77:1/hackfest_3charmed_vnfd/charms/simple",
- "7637bcf8-cf14-42dc-ad70-c66fcf1e6e77:3/hackfest_3charmed_vnfd/charms/simple",
- )
-
- self.assertEqual(fs.sync.call_count, 2)
- self.assertEqual(mock_charm_hash.call_count, 1)
-
- mock_juju_bundle.assert_not_called()
- mock_charm_upgrade.assert_not_called()
-
- self.assertEqual(return_ns_state, expected_ns_state)
- self.assertEqual(return_operation_state, expected_operation_state)
- self.assertEqual(return_operation_error, expected_operation_error)
- self.assertEqual(
- return_ns_operational_state, expected_ns_operational_state
- )
- self.assertEqual(return_vnfr_revision, expected_vnfr_revision)
-
- mock_reset()
-
- with self.subTest(
- i=4,
- t="Update type: CHANGE_VNFPKG, latest_vnfd revision changed, "
- "Charm package exists, sw-version changed.",
- ):
-
- self.db.set_one(
- "vnfds",
- q_filter={"_id": vnfd_id},
- update_dict={"_admin.revision": 3, "software-version": "3.0"},
- )
-
- self.db.set_one(
- "vnfds_revisions",
- q_filter={"_id": vnfd_id + ":1"},
- update_dict={"_admin.revision": 1},
- )
-
- self.db.set_one(
- "vnfrs",
- q_filter={"_id": vnfr_id},
- update_dict={"revision": 1},
- )
-
- mock_charm_hash = Mock(autospec=True)
- mock_charm_hash.return_value = False
-
- mock_juju_bundle = Mock(return_value=None)
-
- mock_charm_upgrade = asynctest.Mock(autospec=True)
- task = asyncio.Future()
- task.set_result(("COMPLETED", "some_output"))
- mock_charm_upgrade.return_value = task
-
- mock_charm_artifact = Mock(autospec=True)
- mock_charm_artifact.side_effect = [
- "7637bcf8-cf14-42dc-ad70-c66fcf1e6e77:1/hackfest_3charmed_vnfd/charms/simple",
- "7637bcf8-cf14-42dc-ad70-c66fcf1e6e77/hackfest_3charmed_vnfd/charms/simple",
- ]
-
- fs = Mock(autospec=True)
- fs.path.__add__ = Mock()
- fs.path.side_effect = ["/", "/", "/", "/"]
- fs.sync.side_effect = [None, None]
-
- instance = self.my_ns
-
- expected_operation_state = "FAILED"
- expected_operation_error = "FAILED Checking if existing VNF has charm: Software version change is not supported as VNF instance 6421c7c9-d865-4fb4-9a13-d4275d243e01 has charm."
- expected_vnfr_revision = 1
- expected_ns_state = "INSTANTIATED"
- expected_ns_operational_state = "running"
-
- with patch.object(instance, "fs", fs), patch(
- "osm_lcm.lcm_utils.LcmBase.check_charm_hash_changed", mock_charm_hash
- ), patch("osm_lcm.ns.NsLcm._ns_charm_upgrade", mock_charm_upgrade), patch(
- "osm_lcm.lcm_utils.get_charm_artifact_path", mock_charm_artifact
- ):
-
- await instance.update(nsr_id, nslcmop_id)
-
- return_operation_state = self.db.get_one(
- "nslcmops", {"_id": nslcmop_id}
- ).get("operationState")
-
- return_operation_error = self.db.get_one(
- "nslcmops", {"_id": nslcmop_id}
- ).get("errorMessage")
-
- return_ns_operational_state = self.db.get_one(
- "nsrs", {"_id": nsr_id}
- ).get("operational-status")
-
- return_vnfr_revision = self.db.get_one("vnfrs", {"_id": vnfr_id}).get(
- "revision"
- )
-
- return_ns_state = self.db.get_one("nsrs", {"_id": nsr_id}).get(
- "nsState"
- )
-
- self.assertEqual(fs.sync.call_count, 2)
- mock_charm_hash.assert_not_called()
-
- mock_juju_bundle.assert_not_called()
- mock_charm_upgrade.assert_not_called()
-
- self.assertEqual(return_ns_state, expected_ns_state)
- self.assertEqual(return_operation_state, expected_operation_state)
- self.assertEqual(return_operation_error, expected_operation_error)
- self.assertEqual(
- return_ns_operational_state, expected_ns_operational_state
- )
- self.assertEqual(return_vnfr_revision, expected_vnfr_revision)
-
- mock_reset()
-
- with self.subTest(
- i=5,
- t="Update type: CHANGE_VNFPKG, latest_vnfd revision changed,"
- "Charm package exists, sw-version not changed, juju-bundle exists",
- ):
-
- self.db.set_one(
- "vnfds",
- q_filter={"_id": vnfd_id},
- update_dict={
- "_admin.revision": 3,
- "software-version": "1.0",
- "kdu.0.juju-bundle": "stable/native-kdu",
- },
- )
-
- self.db.set_one(
- "vnfds_revisions",
- q_filter={"_id": vnfd_id + ":1"},
- update_dict={
- "_admin.revision": 1,
- "software-version": "1.0",
- "kdu.0.juju-bundle": "stable/native-kdu",
- },
- )
-
- self.db.set_one(
- "vnfrs", q_filter={"_id": vnfr_id}, update_dict={"revision": 1}
- )
-
- mock_charm_hash = Mock(autospec=True)
- mock_charm_hash.return_value = True
-
- mock_charm_artifact = Mock(autospec=True)
- mock_charm_artifact.side_effect = [
- "7637bcf8-cf14-42dc-ad70-c66fcf1e6e77:1/hackfest_3charmed_vnfd/charms/simple",
- "7637bcf8-cf14-42dc-ad70-c66fcf1e6e77/hackfest_3charmed_vnfd/charms/simple",
- ]
-
- fs = Mock(autospec=True)
- fs.path.__add__ = Mock()
- fs.path.side_effect = ["/", "/", "/", "/"]
- fs.sync.side_effect = [None, None]
-
- instance = self.my_ns
-
- expected_operation_state = "FAILED"
- expected_operation_error = "FAILED Checking whether VNF uses juju bundle: Charm upgrade is not supported for the instance which uses juju-bundle: stable/native-kdu"
- expected_vnfr_revision = 1
- expected_ns_state = "INSTANTIATED"
- expected_ns_operational_state = "running"
-
- with patch.object(instance, "fs", fs), patch(
- "osm_lcm.lcm_utils.LcmBase.check_charm_hash_changed", mock_charm_hash
- ), patch("osm_lcm.lcm_utils.get_charm_artifact_path", mock_charm_artifact):
-
- await instance.update(nsr_id, nslcmop_id)
-
- return_operation_state = self.db.get_one(
- "nslcmops", {"_id": nslcmop_id}
- ).get("operationState")
-
- return_operation_error = self.db.get_one(
- "nslcmops", {"_id": nslcmop_id}
- ).get("errorMessage")
-
- return_ns_operational_state = self.db.get_one(
- "nsrs", {"_id": nsr_id}
- ).get("operational-status")
-
- return_vnfr_revision = self.db.get_one("vnfrs", {"_id": vnfr_id}).get(
- "revision"
- )
-
- return_ns_state = self.db.get_one("nsrs", {"_id": nsr_id}).get(
- "nsState"
- )
-
- self.assertEqual(fs.sync.call_count, 2)
- self.assertEqual(mock_charm_hash.call_count, 1)
- self.assertEqual(mock_charm_hash.call_count, 1)
-
- mock_charm_upgrade.assert_not_called()
-
- self.assertEqual(return_ns_state, expected_ns_state)
- self.assertEqual(return_operation_state, expected_operation_state)
- self.assertEqual(return_operation_error, expected_operation_error)
- self.assertEqual(
- return_ns_operational_state, expected_ns_operational_state
- )
- self.assertEqual(return_vnfr_revision, expected_vnfr_revision)
-
- mock_reset()
-
- with self.subTest(
- i=6,
- t="Update type: CHANGE_VNFPKG, latest_vnfd revision changed,"
- "Charm package exists, sw-version not changed, charm-upgrade failed",
- ):
-
- self.db.set_one(
- "vnfds",
- q_filter={"_id": vnfd_id},
- update_dict={
- "_admin.revision": 3,
- "software-version": "1.0",
- "kdu": [],
- },
- )
-
- self.db.set_one(
- "vnfds_revisions",
- q_filter={"_id": vnfd_id + ":1"},
- update_dict={
- "_admin.revision": 1,
- "software-version": "1.0",
- "kdu": [],
- },
- )
-
- self.db.set_one(
- "vnfrs", q_filter={"_id": vnfr_id}, update_dict={"revision": 1}
- )
-
- mock_charm_hash = Mock(autospec=True)
- mock_charm_hash.return_value = True
-
- mock_charm_upgrade = asynctest.Mock(autospec=True)
- task = asyncio.Future()
- task.set_result(("FAILED", "some_error"))
- mock_charm_upgrade.return_value = task
-
- mock_charm_artifact = Mock(autospec=True)
- mock_charm_artifact.side_effect = [
- "7637bcf8-cf14-42dc-ad70-c66fcf1e6e77:1/hackfest_3charmed_vnfd/charms/simple",
- "7637bcf8-cf14-42dc-ad70-c66fcf1e6e77/hackfest_3charmed_vnfd/charms/simple",
- ]
-
- fs = Mock(autospec=True)
- fs.path.__add__ = Mock()
- fs.path.side_effect = ["/", "/", "/", "/"]
- fs.sync.side_effect = [None, None]
-
- instance = self.my_ns
-
- expected_operation_state = "FAILED"
- expected_operation_error = "some_error"
- expected_vnfr_revision = 1
- expected_ns_state = "INSTANTIATED"
- expected_ns_operational_state = "running"
-
- with patch.object(instance, "fs", fs), patch(
- "osm_lcm.lcm_utils.LcmBase.check_charm_hash_changed", mock_charm_hash
- ), patch("osm_lcm.ns.NsLcm._ns_charm_upgrade", mock_charm_upgrade):
-
- await instance.update(nsr_id, nslcmop_id)
-
- return_operation_state = self.db.get_one(
- "nslcmops", {"_id": nslcmop_id}
- ).get("operationState")
-
- return_operation_error = self.db.get_one(
- "nslcmops", {"_id": nslcmop_id}
- ).get("errorMessage")
-
- return_ns_operational_state = self.db.get_one(
- "nsrs", {"_id": nsr_id}
- ).get("operational-status")
-
- return_vnfr_revision = self.db.get_one("vnfrs", {"_id": vnfr_id}).get(
- "revision"
- )
-
- return_ns_state = self.db.get_one("nsrs", {"_id": nsr_id}).get(
- "nsState"
- )
-
- self.assertEqual(fs.sync.call_count, 2)
- self.assertEqual(mock_charm_hash.call_count, 1)
- self.assertEqual(mock_charm_upgrade.call_count, 1)
-
- self.assertEqual(return_ns_state, expected_ns_state)
- self.assertEqual(return_operation_state, expected_operation_state)
- self.assertEqual(return_operation_error, expected_operation_error)
- self.assertEqual(
- return_ns_operational_state, expected_ns_operational_state
- )
- self.assertEqual(return_vnfr_revision, expected_vnfr_revision)
-
- mock_reset()
-
- def test_ns_update_helper_methods(self):
- def mock_reset():
- fs.mock_reset()
- mock_path.mock_reset()
- mock_checksumdir.mock_reset()
-
- with self.subTest(
- i=1, t="Find software version, VNFD does not have have software version"
- ):
- # Testing method find_software_version
-
- db_vnfd = self.db.get_one(
- "vnfds", {"_id": "7637bcf8-cf14-42dc-ad70-c66fcf1e6e77"}
- )
- expected_result = "1.0"
- result = find_software_version(db_vnfd)
- self.assertEqual(
- result, expected_result, "Default sw version should be 1.0"
- )
-
- with self.subTest(
- i=2, t="Find software version, VNFD includes software version"
- ):
- # Testing method find_software_version
-
- db_vnfd = self.db.get_one(
- "vnfds", {"_id": "7637bcf8-cf14-42dc-ad70-c66fcf1e6e77"}
- )
- db_vnfd["software-version"] = "3.1"
- expected_result = "3.1"
- result = find_software_version(db_vnfd)
- self.assertEqual(result, expected_result, "VNFD software version is wrong")
-
- with self.subTest(i=3, t="Check charm hash, Hash did not change"):
- # Testing method check_charm_hash_changed
-
- current_path, target_path = "/tmp/charm1", "/tmp/charm1"
- fs = Mock(autospec=True)
- fs.path.__add__ = Mock()
- fs.path.side_effect = ["/", "/", "/", "/"]
-
- mock_path = Mock(autospec=True)
- mock_path.exists.side_effect = [True, True]
-
- mock_checksumdir = Mock(autospec=True)
- mock_checksumdir.dirhash.side_effect = ["hash_value", "hash_value"]
+ @patch("osm_lcm.lcm_utils.LcmBase.check_charm_hash_changed")
+ @patch(
+ "osm_lcm.ns.NsLcm._ns_charm_upgrade", new_callable=asynctest.Mock(autospec=True)
+ )
+ @patch("osm_lcm.data_utils.vnfd.find_software_version")
+ @patch("osm_lcm.lcm_utils.check_juju_bundle_existence")
+ async def test_update_change_vnfpkg_sw_version_not_changed(
+ self,
+ mock_juju_bundle,
+ mock_software_version,
+ mock_charm_upgrade,
+ mock_charm_hash,
+ ):
+ """Update type: CHANGE_VNFPKG, latest_vnfd revision changed,
+ Charm package changed, sw-version is not changed"""
+ self.db.set_one(
+ "vnfds",
+ q_filter={"_id": vnfd_id},
+ update_dict={"_admin.revision": 3, "kdu": []},
+ )
- instance = self.my_ns
- expected_result = False
+ self.db.set_one(
+ "vnfds_revisions",
+ q_filter={"_id": vnfd_id + ":1"},
+ update_dict={"_admin.revision": 1, "kdu": []},
+ )
- with patch.object(instance, "fs", fs), patch(
- "checksumdir.dirhash", mock_checksumdir.dirhash
- ), patch("os.path.exists", mock_path.exists):
+ self.db.set_one("vnfrs", q_filter={"_id": vnfr_id}, update_dict={"revision": 1})
- result = instance.check_charm_hash_changed(current_path, target_path)
- self.assertEqual(
- result, expected_result, "Wrong charm hash control value"
- )
- self.assertEqual(mock_path.exists.call_count, 2)
- self.assertEqual(mock_checksumdir.dirhash.call_count, 2)
+ mock_charm_hash.return_value = True
+ mock_software_version.side_effect = ["1.0", "1.0"]
- mock_reset()
+ task = asyncio.Future()
+ task.set_result(("COMPLETED", "some_output"))
+ mock_charm_upgrade.return_value = task
- with self.subTest(i=4, t="Check charm hash, Hash has changed"):
- # Testing method check_charm_hash_changed
+ instance = self.my_ns
+ fs = deepcopy(update_fs)
+ instance.fs = fs
- current_path, target_path = "/tmp/charm1", "/tmp/charm2"
- fs = Mock(autospec=True)
- fs.path.__add__ = Mock()
- fs.path.side_effect = ["/", "/", "/", "/"]
+ expected_operation_state = "COMPLETED"
+ expected_operation_error = ""
+ expected_vnfr_revision = 3
+ expected_ns_state = "INSTANTIATED"
+ expected_ns_operational_state = "running"
- mock_path = Mock(autospec=True)
- mock_path.exists.side_effect = [True, True]
+ await instance.update(nsr_id, nslcmop_id)
+ return_operation_state = self.db.get_one("nslcmops", {"_id": nslcmop_id}).get(
+ "operationState"
+ )
+ return_operation_error = self.db.get_one("nslcmops", {"_id": nslcmop_id}).get(
+ "errorMessage"
+ )
+ return_ns_operational_state = self.db.get_one("nsrs", {"_id": nsr_id}).get(
+ "operational-status"
+ )
+ return_vnfr_revision = self.db.get_one("vnfrs", {"_id": vnfr_id}).get(
+ "revision"
+ )
+ return_ns_state = self.db.get_one("nsrs", {"_id": nsr_id}).get("nsState")
+ mock_charm_hash.assert_called_with(
+ f"{vnfd_id}:1/hackfest_3charmed_vnfd/charms/simple",
+ f"{vnfd_id}:3/hackfest_3charmed_vnfd/charms/simple",
+ )
+ self.assertEqual(fs.sync.call_count, 2)
+ self.assertEqual(return_ns_state, expected_ns_state)
+ self.assertEqual(return_operation_state, expected_operation_state)
+ self.assertEqual(return_operation_error, expected_operation_error)
+ self.assertEqual(return_ns_operational_state, expected_ns_operational_state)
+ self.assertEqual(return_vnfr_revision, expected_vnfr_revision)
+
+ @patch("osm_lcm.lcm_utils.LcmBase.check_charm_hash_changed")
+ @patch(
+ "osm_lcm.ns.NsLcm._ns_charm_upgrade", new_callable=asynctest.Mock(autospec=True)
+ )
+ @patch("osm_lcm.data_utils.vnfd.find_software_version")
+ @patch("osm_lcm.lcm_utils.check_juju_bundle_existence")
+ async def test_update_change_vnfpkg_vnfd_revision_not_changed(
+ self,
+ mock_juju_bundle,
+ mock_software_version,
+ mock_charm_upgrade,
+ mock_charm_hash,
+ ):
+ """Update type: CHANGE_VNFPKG, latest_vnfd revision not changed"""
+ self.db.set_one(
+ "vnfds", q_filter={"_id": vnfd_id}, update_dict={"_admin.revision": 1}
+ )
+ self.db.set_one("vnfrs", q_filter={"_id": vnfr_id}, update_dict={"revision": 1})
- mock_checksumdir = Mock(autospec=True)
- mock_checksumdir.dirhash.side_effect = ["hash_value", "another_hash_value"]
+ mock_charm_hash.return_value = True
- instance = self.my_ns
- expected_result = True
+ task = asyncio.Future()
+ task.set_result(("COMPLETED", "some_output"))
+ mock_charm_upgrade.return_value = task
- with patch.object(instance, "fs", fs), patch(
- "checksumdir.dirhash", mock_checksumdir.dirhash
- ), patch("os.path.exists", mock_path.exists):
+ instance = self.my_ns
- result = instance.check_charm_hash_changed(current_path, target_path)
- self.assertEqual(
- result, expected_result, "Wrong charm hash control value"
- )
- self.assertEqual(mock_path.exists.call_count, 2)
- self.assertEqual(mock_checksumdir.dirhash.call_count, 2)
+ expected_operation_state = "COMPLETED"
+ expected_operation_error = ""
+ expected_vnfr_revision = 1
+ expected_ns_state = "INSTANTIATED"
+ expected_ns_operational_state = "running"
- mock_reset()
+ await instance.update(nsr_id, nslcmop_id)
+ return_operation_state = self.db.get_one("nslcmops", {"_id": nslcmop_id}).get(
+ "operationState"
+ )
+ return_operation_error = self.db.get_one("nslcmops", {"_id": nslcmop_id}).get(
+ "errorMessage"
+ )
+ return_ns_operational_state = self.db.get_one("nsrs", {"_id": nsr_id}).get(
+ "operational-status"
+ )
+ return_ns_state = self.db.get_one("nsrs", {"_id": nsr_id}).get("nsState")
+ return_vnfr_revision = self.db.get_one("vnfrs", {"_id": vnfr_id}).get(
+ "revision"
+ )
+ mock_charm_hash.assert_not_called()
+ mock_software_version.assert_not_called()
+ mock_juju_bundle.assert_not_called()
+ mock_charm_upgrade.assert_not_called()
+ update_fs.sync.assert_not_called()
+ self.assertEqual(return_ns_state, expected_ns_state)
+ self.assertEqual(return_operation_state, expected_operation_state)
+ self.assertEqual(return_operation_error, expected_operation_error)
+ self.assertEqual(return_ns_operational_state, expected_ns_operational_state)
+ self.assertEqual(return_vnfr_revision, expected_vnfr_revision)
+
+ @patch("osm_lcm.lcm_utils.LcmBase.check_charm_hash_changed")
+ @patch(
+ "osm_lcm.ns.NsLcm._ns_charm_upgrade", new_callable=asynctest.Mock(autospec=True)
+ )
+ @patch("osm_lcm.data_utils.vnfd.find_software_version")
+ @patch("osm_lcm.lcm_utils.check_juju_bundle_existence")
+ async def test_update_change_vnfpkg_charm_is_not_changed(
+ self,
+ mock_juju_bundle,
+ mock_software_version,
+ mock_charm_upgrade,
+ mock_charm_hash,
+ ):
+ """Update type: CHANGE_VNFPKG, latest_vnfd revision changed
+ Charm package is not changed, sw-version is not changed"""
+ self.db.set_one(
+ "vnfds",
+ q_filter={"_id": vnfd_id},
+ update_dict={"_admin.revision": 3, "kdu": []},
+ )
+ self.db.set_one(
+ "vnfds_revisions",
+ q_filter={"_id": vnfd_id + ":1"},
+ update_dict={"_admin.revision": 1, "kdu": []},
+ )
+ self.db.set_one("vnfrs", q_filter={"_id": vnfr_id}, update_dict={"revision": 1})
+
+ mock_charm_hash.return_value = False
+ mock_software_version.side_effect = ["1.0", "1.0"]
+
+ instance = self.my_ns
+ fs = deepcopy(update_fs)
+ instance.fs = fs
+ expected_operation_state = "COMPLETED"
+ expected_operation_error = ""
+ expected_vnfr_revision = 3
+ expected_ns_state = "INSTANTIATED"
+ expected_ns_operational_state = "running"
+
+ await instance.update(nsr_id, nslcmop_id)
+ return_operation_state = self.db.get_one("nslcmops", {"_id": nslcmop_id}).get(
+ "operationState"
+ )
+ return_operation_error = self.db.get_one("nslcmops", {"_id": nslcmop_id}).get(
+ "errorMessage"
+ )
+ return_ns_operational_state = self.db.get_one("nsrs", {"_id": nsr_id}).get(
+ "operational-status"
+ )
+ return_vnfr_revision = self.db.get_one("vnfrs", {"_id": vnfr_id}).get(
+ "revision"
+ )
+ return_ns_state = self.db.get_one("nsrs", {"_id": nsr_id}).get("nsState")
+ mock_charm_hash.assert_called_with(
+ f"{vnfd_id}:1/hackfest_3charmed_vnfd/charms/simple",
+ f"{vnfd_id}:3/hackfest_3charmed_vnfd/charms/simple",
+ )
+ self.assertEqual(fs.sync.call_count, 2)
+ self.assertEqual(mock_charm_hash.call_count, 1)
+ mock_juju_bundle.assert_not_called()
+ mock_charm_upgrade.assert_not_called()
+ self.assertEqual(return_ns_state, expected_ns_state)
+ self.assertEqual(return_operation_state, expected_operation_state)
+ self.assertEqual(return_operation_error, expected_operation_error)
+ self.assertEqual(return_ns_operational_state, expected_ns_operational_state)
+ self.assertEqual(return_vnfr_revision, expected_vnfr_revision)
+
+ @patch("osm_lcm.lcm_utils.check_juju_bundle_existence")
+ @patch("osm_lcm.lcm_utils.LcmBase.check_charm_hash_changed")
+ @patch(
+ "osm_lcm.ns.NsLcm._ns_charm_upgrade", new_callable=asynctest.Mock(autospec=True)
+ )
+ @patch("osm_lcm.lcm_utils.get_charm_artifact_path")
+ async def test_update_change_vnfpkg_sw_version_changed(
+ self, mock_charm_artifact, mock_charm_upgrade, mock_charm_hash, mock_juju_bundle
+ ):
+ """Update type: CHANGE_VNFPKG, latest_vnfd revision changed
+ Charm package exists, sw-version changed."""
+ self.db.set_one(
+ "vnfds",
+ q_filter={"_id": vnfd_id},
+ update_dict={"_admin.revision": 3, "software-version": "3.0", "kdu": []},
+ )
+ self.db.set_one(
+ "vnfds_revisions",
+ q_filter={"_id": vnfd_id + ":1"},
+ update_dict={"_admin.revision": 1, "kdu": []},
+ )
+ self.db.set_one(
+ "vnfrs",
+ q_filter={"_id": vnfr_id},
+ update_dict={"revision": 1},
+ )
+ mock_charm_hash.return_value = False
- with self.subTest(i=5, t="Check charm hash, Charm path does not exists"):
- # Testing method check_charm_hash_changed
+ mock_charm_artifact.side_effect = [
+ f"{vnfd_id}:1/hackfest_3charmed_vnfd/charms/simple",
+ f"{vnfd_id}:3/hackfest_3charmed_vnfd/charms/simple",
+ ]
- current_path, target_path = "/tmp/charm1", "/tmp/charm2"
- fs = Mock(autospec=True)
- fs.path.__add__ = Mock()
- fs.path.side_effect = ["/", "/", "/", "/"]
+ instance = self.my_ns
+ fs = deepcopy(update_fs)
+ instance.fs = fs
+ expected_operation_state = "FAILED"
+ expected_operation_error = "FAILED Checking if existing VNF has charm: Software version change is not supported as VNF instance 6421c7c9-d865-4fb4-9a13-d4275d243e01 has charm."
+ expected_vnfr_revision = 1
+ expected_ns_state = "INSTANTIATED"
+ expected_ns_operational_state = "running"
+
+ await instance.update(nsr_id, nslcmop_id)
+ return_operation_state = self.db.get_one("nslcmops", {"_id": nslcmop_id}).get(
+ "operationState"
+ )
+ return_operation_error = self.db.get_one("nslcmops", {"_id": nslcmop_id}).get(
+ "errorMessage"
+ )
+ return_ns_operational_state = self.db.get_one("nsrs", {"_id": nsr_id}).get(
+ "operational-status"
+ )
+ return_vnfr_revision = self.db.get_one("vnfrs", {"_id": vnfr_id}).get(
+ "revision"
+ )
+ return_ns_state = self.db.get_one("nsrs", {"_id": nsr_id}).get("nsState")
+ self.assertEqual(fs.sync.call_count, 2)
+ mock_charm_hash.assert_not_called()
+ mock_juju_bundle.assert_not_called()
+ mock_charm_upgrade.assert_not_called()
+ self.assertEqual(return_ns_state, expected_ns_state)
+ self.assertEqual(return_operation_state, expected_operation_state)
+ self.assertEqual(return_operation_error, expected_operation_error)
+ self.assertEqual(return_ns_operational_state, expected_ns_operational_state)
+ self.assertEqual(return_vnfr_revision, expected_vnfr_revision)
+
+ @patch("osm_lcm.lcm_utils.check_juju_bundle_existence")
+ @patch("osm_lcm.lcm_utils.LcmBase.check_charm_hash_changed")
+ @patch(
+ "osm_lcm.ns.NsLcm._ns_charm_upgrade", new_callable=asynctest.Mock(autospec=True)
+ )
+ @patch("osm_lcm.data_utils.vnfd.find_software_version")
+ async def test_update_change_vnfpkg_juju_bundle_exists(
+ self,
+ mock_software_version,
+ mock_charm_upgrade,
+ mock_charm_hash,
+ mock_juju_bundle,
+ ):
+ """Update type: CHANGE_VNFPKG, latest_vnfd revision changed
+ Charm package exists, sw-version not changed, juju-bundle exists"""
+ # Upgrade is not allowed with juju bundles, this will cause TypeError
+ self.db.set_one(
+ "vnfds",
+ q_filter={"_id": vnfd_id},
+ update_dict={
+ "_admin.revision": 5,
+ "software-version": "1.0",
+ "kdu": [{"kdu_name": "native-kdu", "juju-bundle": "stable/native-kdu"}],
+ },
+ )
+ self.db.set_one(
+ "vnfds_revisions",
+ q_filter={"_id": vnfd_id + ":1"},
+ update_dict={
+ "_admin.revision": 1,
+ "software-version": "1.0",
+ "kdu": [{"kdu_name": "native-kdu", "juju-bundle": "stable/native-kdu"}],
+ },
+ )
+ self.db.set_one(
+ "nsrs",
+ q_filter={"_id": nsr_id},
+ update_dict={
+ "_admin.deployed.VCA.0.kdu_name": "native-kdu",
+ },
+ )
+ self.db.set_one("vnfrs", q_filter={"_id": vnfr_id}, update_dict={"revision": 1})
+
+ mock_charm_hash.side_effect = [True]
+ mock_software_version.side_effect = ["1.0", "1.0"]
+ mock_juju_bundle.return_value = True
+ instance = self.my_ns
+ fs = deepcopy(update_fs)
+ instance.fs = fs
+
+ expected_vnfr_revision = 1
+ expected_ns_state = "INSTANTIATED"
+ expected_ns_operational_state = "running"
+
+ await instance.update(nsr_id, nslcmop_id)
+ return_ns_operational_state = self.db.get_one("nsrs", {"_id": nsr_id}).get(
+ "operational-status"
+ )
+ return_vnfr_revision = self.db.get_one("vnfrs", {"_id": vnfr_id}).get(
+ "revision"
+ )
+ return_ns_state = self.db.get_one("nsrs", {"_id": nsr_id}).get("nsState")
+ self.assertEqual(fs.sync.call_count, 2)
+ mock_charm_upgrade.assert_not_called()
+ mock_charm_hash.assert_not_called()
+ self.assertEqual(return_ns_state, expected_ns_state)
+ self.assertEqual(return_ns_operational_state, expected_ns_operational_state)
+ self.assertEqual(return_vnfr_revision, expected_vnfr_revision)
+
+ @patch("osm_lcm.lcm_utils.LcmBase.check_charm_hash_changed")
+ @patch(
+ "osm_lcm.ns.NsLcm._ns_charm_upgrade", new_callable=asynctest.Mock(autospec=True)
+ )
+ async def test_update_change_vnfpkg_charm_upgrade_failed(
+ self, mock_charm_upgrade, mock_charm_hash
+ ):
+ """ "Update type: CHANGE_VNFPKG, latest_vnfd revision changed"
+ Charm package exists, sw-version not changed, charm-upgrade failed"""
+ self.db.set_one(
+ "vnfds",
+ q_filter={"_id": vnfd_id},
+ update_dict={
+ "_admin.revision": 3,
+ "software-version": "1.0",
+ "kdu": [],
+ },
+ )
+ self.db.set_one(
+ "vnfds_revisions",
+ q_filter={"_id": vnfd_id + ":1"},
+ update_dict={
+ "_admin.revision": 1,
+ "software-version": "1.0",
+ "kdu": [],
+ },
+ )
+ self.db.set_one("vnfrs", q_filter={"_id": vnfr_id}, update_dict={"revision": 1})
- mock_path = Mock(autospec=True)
- mock_path.exists.side_effect = [True, False]
+ mock_charm_hash.return_value = True
- mock_checksumdir = Mock(autospec=True)
- mock_checksumdir.dirhash.side_effect = ["hash_value", "hash_value"]
+ task = asyncio.Future()
+ task.set_result(("FAILED", "some_error"))
+ mock_charm_upgrade.return_value = task
- instance = self.my_ns
+ instance = self.my_ns
+ fs = deepcopy(update_fs)
+ instance.fs = fs
+ expected_operation_state = "FAILED"
+ expected_operation_error = "some_error"
+ expected_vnfr_revision = 1
+ expected_ns_state = "INSTANTIATED"
+ expected_ns_operational_state = "running"
- with patch.object(instance, "fs", fs), patch(
- "checksumdir.dirhash", mock_checksumdir.dirhash
- ), patch("os.path.exists", mock_path.exists):
+ await instance.update(nsr_id, nslcmop_id)
+ return_operation_state = self.db.get_one("nslcmops", {"_id": nslcmop_id}).get(
+ "operationState"
+ )
+ return_operation_error = self.db.get_one("nslcmops", {"_id": nslcmop_id}).get(
+ "errorMessage"
+ )
+ return_ns_operational_state = self.db.get_one("nsrs", {"_id": nsr_id}).get(
+ "operational-status"
+ )
+ return_vnfr_revision = self.db.get_one("vnfrs", {"_id": vnfr_id}).get(
+ "revision"
+ )
+ return_ns_state = self.db.get_one("nsrs", {"_id": nsr_id}).get("nsState")
+ self.assertEqual(fs.sync.call_count, 2)
+ self.assertEqual(mock_charm_hash.call_count, 1)
+ self.assertEqual(mock_charm_upgrade.call_count, 1)
+ self.assertEqual(return_ns_state, expected_ns_state)
+ self.assertEqual(return_operation_state, expected_operation_state)
+ self.assertEqual(return_operation_error, expected_operation_error)
+ self.assertEqual(return_ns_operational_state, expected_ns_operational_state)
+ self.assertEqual(return_vnfr_revision, expected_vnfr_revision)
+
+ def test_ns_update_find_sw_version_vnfd_not_includes(self):
+ """Find software version, VNFD does not have software version"""
+
+ db_vnfd = self.db.get_one("vnfds", {"_id": vnfd_id})
+ expected_result = "1.0"
+ result = find_software_version(db_vnfd)
+ self.assertEqual(result, expected_result, "Default sw version should be 1.0")
+
+ def test_ns_update_find_sw_version_vnfd_includes(self):
+ """Find software version, VNFD includes software version"""
+
+ db_vnfd = self.db.get_one("vnfds", {"_id": vnfd_id})
+ db_vnfd["software-version"] = "3.1"
+ expected_result = "3.1"
+ result = find_software_version(db_vnfd)
+ self.assertEqual(result, expected_result, "VNFD software version is wrong")
+
+ @patch("os.path.exists")
+ @patch("osm_lcm.lcm_utils.LcmBase.compare_charmdir_hash")
+ @patch("osm_lcm.lcm_utils.LcmBase.compare_charm_hash")
+ def test_ns_update_check_charm_hash_not_changed(
+ self, mock_compare_charm_hash, mock_compare_charmdir_hash, mock_path_exists
+ ):
+ """Check charm hash, Hash did not change"""
- with self.assertRaises(LcmException):
+ current_path, target_path = "/tmp/charm1", "/tmp/charm1"
- instance.check_charm_hash_changed(current_path, target_path)
- self.assertEqual(mock_path.exists.call_count, 2)
- self.assertEqual(mock_checksumdir.dirhash.call_count, 0)
+ fs = Mock()
+ fs.path.__add__ = Mock()
+ fs.path.side_effect = [current_path, target_path]
+ fs.path.__add__.side_effect = [current_path, target_path]
- mock_reset()
+ mock_path_exists.side_effect = [True, True]
- with self.subTest(i=6, t="Check juju bundle existence"):
- # Testing method check_juju_bundle_existence
+ mock_compare_charmdir_hash.return_value = callable(False)
+ mock_compare_charm_hash.return_value = callable(False)
- test_vnfd1 = self.db.get_one(
- "vnfds", {"_id": "7637bcf8-cf14-42dc-ad70-c66fcf1e6e77"}
- )
- test_vnfd2 = self.db.get_one(
- "vnfds", {"_id": "d96b1cdf-5ad6-49f7-bf65-907ada989293"}
- )
+ instance = self.my_ns
+ instance.fs = fs
+ expected_result = False
- expected_result = None
- result = check_juju_bundle_existence(test_vnfd1)
- self.assertEqual(result, expected_result, "Wrong juju bundle name")
+ result = instance.check_charm_hash_changed(current_path, target_path)
+ self.assertEqual(result, expected_result, "Wrong charm hash control value")
+ self.assertEqual(mock_path_exists.call_count, 2)
+ self.assertEqual(mock_compare_charmdir_hash.call_count, 1)
+ self.assertEqual(mock_compare_charm_hash.call_count, 0)
- expected_result = "stable/native-kdu"
- result = check_juju_bundle_existence(test_vnfd2)
- self.assertEqual(result, expected_result, "Wrong juju bundle name")
+ @patch("os.path.exists")
+ @patch("osm_lcm.lcm_utils.LcmBase.compare_charmdir_hash")
+ @patch("osm_lcm.lcm_utils.LcmBase.compare_charm_hash")
+ def test_ns_update_check_charm_hash_changed(
+ self, mock_compare_charm_hash, mock_compare_charmdir_hash, mock_path_exists
+ ):
+ """Check charm hash, Hash has changed"""
+
+ current_path, target_path = "/tmp/charm1", "/tmp/charm2"
+
+ fs = Mock()
+ fs.path.__add__ = Mock()
+ fs.path.side_effect = [current_path, target_path, current_path, target_path]
+ fs.path.__add__.side_effect = [
+ current_path,
+ target_path,
+ current_path,
+ target_path,
+ ]
- with self.subTest(i=7, t="Check charm artifacts"):
- # Testing method check_juju_bundle_existence
+ mock_path_exists.side_effect = [True, True]
+ mock_compare_charmdir_hash.return_value = callable(True)
+ mock_compare_charm_hash.return_value = callable(True)
+
+ instance = self.my_ns
+ instance.fs = fs
+ expected_result = True
+
+ result = instance.check_charm_hash_changed(current_path, target_path)
+ self.assertEqual(result, expected_result, "Wrong charm hash control value")
+ self.assertEqual(mock_path_exists.call_count, 2)
+ self.assertEqual(mock_compare_charmdir_hash.call_count, 1)
+ self.assertEqual(mock_compare_charm_hash.call_count, 0)
+
+ @patch("os.path.exists")
+ @patch("osm_lcm.lcm_utils.LcmBase.compare_charmdir_hash")
+ @patch("osm_lcm.lcm_utils.LcmBase.compare_charm_hash")
+ def test_ns_update_check_no_charm_path(
+ self, mock_compare_charm_hash, mock_compare_charmdir_hash, mock_path_exists
+ ):
+ """Check charm hash, Charm path does not exist"""
+
+ current_path, target_path = "/tmp/charm1", "/tmp/charm2"
+
+ fs = Mock()
+ fs.path.__add__ = Mock()
+ fs.path.side_effect = [current_path, target_path, current_path, target_path]
+ fs.path.__add__.side_effect = [
+ current_path,
+ target_path,
+ current_path,
+ target_path,
+ ]
- base_folder = {
- "folder": "7637bcf8-cf14-42dc-ad70-c66fcf1e6e77",
- "pkg-dir": "hackfest_3charmed_vnfd",
- }
- charm_name = "simple"
- charm_type = "lxc_proxy_charm"
- revision = 3
+ mock_path_exists.side_effect = [True, False]
- expected_result = "7637bcf8-cf14-42dc-ad70-c66fcf1e6e77:3/hackfest_3charmed_vnfd/charms/simple"
- result = get_charm_artifact_path(
- base_folder, charm_name, charm_type, revision
- )
- self.assertEqual(result, expected_result, "Wrong charm artifact path")
+ mock_compare_charmdir_hash.return_value = callable(False)
+ mock_compare_charm_hash.return_value = callable(False)
+ instance = self.my_ns
+ instance.fs = fs
- # SOL004 packages
- base_folder = {
- "folder": "7637bcf8-cf14-42dc-ad70-c66fcf1e6e77",
- }
- charm_name = "basic"
- charm_type = ""
- revision = ""
+ with self.assertRaises(LcmException):
+ instance.check_charm_hash_changed(current_path, target_path)
+ self.assertEqual(mock_path_exists.call_count, 2)
+ self.assertEqual(mock_compare_charmdir_hash.call_count, 0)
+ self.assertEqual(mock_compare_charm_hash.call_count, 0)
- expected_result = (
- "7637bcf8-cf14-42dc-ad70-c66fcf1e6e77/Scripts/helm-charts/basic"
- )
- result = get_charm_artifact_path(
- base_folder, charm_name, charm_type, revision
- )
- self.assertEqual(result, expected_result, "Wrong charm artifact path")
+ def test_ns_update_check_juju_bundle_existence_bundle_exists(self):
+ """Check juju bundle existence"""
+ test_vnfd2 = self.db.get_one(
+ "vnfds", {"_id": "d96b1cdf-5ad6-49f7-bf65-907ada989293"}
+ )
+ expected_result = "stable/native-kdu"
+ result = check_juju_bundle_existence(test_vnfd2)
+ self.assertEqual(result, expected_result, "Wrong juju bundle name")
+
+ def test_ns_update_check_juju_bundle_existence_bundle_does_not_exist(self):
+ """Check juju bundle existence"""
+ test_vnfd1 = self.db.get_one("vnfds", {"_id": vnfd_id})
+ expected_result = None
+ result = check_juju_bundle_existence(test_vnfd1)
+ self.assertEqual(result, expected_result, "Wrong juju bundle name")
+
+ def test_ns_update_check_juju_bundle_existence_empty_vnfd(self):
+ """Check juju bundle existence"""
+ test_vnfd1 = {}
+ expected_result = None
+ result = check_juju_bundle_existence(test_vnfd1)
+ self.assertEqual(result, expected_result, "Wrong juju bundle name")
+
+ def test_ns_update_check_juju_bundle_existence_invalid_vnfd(self):
+ """Check juju bundle existence"""
+ test_vnfd1 = [{"_id": vnfd_id}]
+ with self.assertRaises(AttributeError):
+ check_juju_bundle_existence(test_vnfd1)
+
+ def test_ns_update_check_juju_charm_artifacts_base_folder_wth_pkgdir(self):
+ """Check charm artifacts"""
+ base_folder = {
+ "folder": vnfd_id,
+ "pkg-dir": "hackfest_3charmed_vnfd",
+ }
+ charm_name = "simple"
+ charm_type = "lxc_proxy_charm"
+ revision = 3
+ expected_result = f"{vnfd_id}:3/hackfest_3charmed_vnfd/charms/simple"
+ result = get_charm_artifact_path(base_folder, charm_name, charm_type, revision)
+ self.assertEqual(result, expected_result, "Wrong charm artifact path")
+
+ def test_ns_update_check_juju_charm_artifacts_base_folder_wthout_pkgdir(self):
+ """Check charm artifacts, SOL004 packages"""
+ base_folder = {
+ "folder": vnfd_id,
+ }
+ charm_name = "basic"
+ charm_type, revision = "", ""
+ expected_result = f"{vnfd_id}/Scripts/helm-charts/basic"
+ result = get_charm_artifact_path(base_folder, charm_name, charm_type, revision)
+ self.assertEqual(result, expected_result, "Wrong charm artifact path")
if __name__ == "__main__":