Merge "Improve unit test coverage for dcmanager's orchestrator/states/software/cache"

This commit is contained in:
Zuul 2024-03-27 13:32:09 +00:00 committed by Gerrit Code Review
commit ef1f466b2e
3 changed files with 244 additions and 0 deletions

View File

@ -0,0 +1,134 @@
# Copyright (c) 2024 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
import copy
import mock
from keystoneauth1 import exceptions as keystone_exceptions
from dcmanager.common import consts
from dcmanager.common.exceptions import InvalidParameterValue
from dcmanager.orchestrator.states.software.cache.cache_specifications import \
REGION_ONE_LICENSE_CACHE_TYPE
from dcmanager.orchestrator.states.software.cache.cache_specifications import \
REGION_ONE_RELEASE_USM_CACHE_TYPE
from dcmanager.orchestrator.states.software.cache.cache_specifications import \
REGION_ONE_SYSTEM_INFO_CACHE_TYPE
from dcmanager.orchestrator.states.software.cache import clients
from dcmanager.orchestrator.states.software.cache.shared_cache_repository import \
SharedCacheRepository
from dcmanager.tests import base
SOFTWARE_CLIENT_QUERY_RETURN = {
"stx_23.09.0": {
"sw_version": "23.09.0",
"state": "available",
"reboot_required": "N",
},
"stx_23.09.1": {
"sw_version": "23.09.1",
"state": "available",
"reboot_required": "N",
},
"stx_23.09.2": {
"sw_version": "23.09.2",
"state": "unavailable",
"reboot_required": "N",
}
}
class TestSharedCacheRepository(base.DCManagerTestCase):
def setUp(self):
"""Initializes the shared cache repository"""
super().setUp()
self._mock_openstack_driver(clients)
self._mock_sysinv_client(clients)
self._mock_software_client()
self.shared_cache_repository = SharedCacheRepository(
operation_type=consts.SW_UPDATE_TYPE_SOFTWARE
)
self.shared_cache_repository.initialize_caches()
self.software_client().query.return_value = SOFTWARE_CLIENT_QUERY_RETURN
def _mock_software_client(self):
mock_patch = mock.patch.object(clients, 'SoftwareClient')
self.software_client = mock_patch.start()
self.addCleanup(mock_patch.stop)
def test_read_succeeds_with_license_cache_type(self):
"""Test read cache succeeds when using the REGION_ONE_LICENSE_CACHE_TYPE"""
self.mock_sysinv_client().get_license.return_value = 'fake license'
response = self.shared_cache_repository.read(REGION_ONE_LICENSE_CACHE_TYPE)
self.assertEqual(response, 'fake license')
def test_read_succeeds_with_system_info_cache_type(self):
"""Test read cache succeeds when using REGION_ONE_SYSTEM_INFO_CACHE_TYPE"""
self.mock_sysinv_client().get_system.return_value = 'fake system info'
response = \
self.shared_cache_repository.read(REGION_ONE_SYSTEM_INFO_CACHE_TYPE)
self.assertEqual(response, 'fake system info')
def test_read_succeeds_with_release_usm_cache_type(self):
"""Test read cache succeeds when using REGION_ONE_RELEASE_USM_CACHE_TYPE"""
response = \
self.shared_cache_repository.read(REGION_ONE_RELEASE_USM_CACHE_TYPE)
self.assertEqual(response, SOFTWARE_CLIENT_QUERY_RETURN)
def test_read_fails_with_invalid_cache_type(self):
"""Test read cache fails when using an invalid cache type"""
self.assertRaises(
InvalidParameterValue,
self.shared_cache_repository.read,
'fake parameter'
)
def test_read_fails_when_openstack_driver_raises_exception(self):
"""Test read cache fails when the OpenStackDriver raises an Exception"""
self.mock_openstack_driver.side_effect = \
keystone_exceptions.ConnectFailure()
self.assertRaises(
keystone_exceptions.ConnectFailure,
self.shared_cache_repository.read,
REGION_ONE_RELEASE_USM_CACHE_TYPE
)
def test_read_succeeds_with_filter_params(self):
"""Test read cache succeeds when filter_params is sent"""
response = self.shared_cache_repository.read(
REGION_ONE_RELEASE_USM_CACHE_TYPE,
state='available'
)
expected_response = copy.copy(SOFTWARE_CLIENT_QUERY_RETURN)
del expected_response["stx_23.09.2"]
self.assertEqual(response, expected_response)
def test_read_fails_with_invalid_filter_params(self):
"""Test read cache succeeds when and invalid filter_params is sent"""
self.assertRaises(
InvalidParameterValue,
self.shared_cache_repository.read,
REGION_ONE_RELEASE_USM_CACHE_TYPE,
invalid='available'
)

View File

@ -0,0 +1,110 @@
# Copyright (c) 2024 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
import socket
import mock
from dcmanager.orchestrator.states.software.cache.cache_specifications import \
CacheSpecification
from dcmanager.orchestrator.states.software.cache.cache_specifications import \
REGION_ONE_LICENSE_CACHE_SPECIFICATION
from dcmanager.orchestrator.states.software.cache.cache_specifications import \
REGION_ONE_LICENSE_CACHE_TYPE
from dcmanager.orchestrator.states.software.cache import clients
from dcmanager.orchestrator.states.software.cache.shared_client_cache import \
SharedClientCache
from dcmanager.tests import base
SOFTWARE_CLIENT_QUERY_RETURN = {
"stx_23.09.0": {
"sw_version": "23.09.0",
"state": "available",
"reboot_required": "N",
},
"stx_23.09.1": {
"sw_version": "23.09.1",
"state": "available",
"reboot_required": "N",
}
}
class TestSharedClientCache(base.DCManagerTestCase):
def setUp(self):
"""Initializes the shared client cache"""
super().setUp()
self._mock_openstack_driver(clients)
self._mock_sysinv_client(clients)
def test_read_succeeds_when_cache_data_is_stored(self):
"""Test read cache succeeds when the data is cached after the first request
In the second request, instead of reacquiring the data using get_system,
the previously stored information should be returned
"""
shared_client_cache = SharedClientCache(
REGION_ONE_LICENSE_CACHE_TYPE, REGION_ONE_LICENSE_CACHE_SPECIFICATION
)
self.mock_sysinv_client().get_license.return_value = 'fake license'
self.assertIsNone(shared_client_cache._cache)
response = shared_client_cache.read()
self.assertEqual(response, 'fake license')
self.mock_sysinv_client().get_license.assert_called_once()
self.assertIsNotNone(shared_client_cache._cache)
response = shared_client_cache.read()
self.assertEqual(response, 'fake license')
self.mock_sysinv_client().get_license.assert_called_once()
def test_read_fails_when_client_lock_is_writer_and_cache_is_not_stored(self):
"""Test read cache fails with writer client lock and without cache stored"""
shared_client_cache = SharedClientCache(
REGION_ONE_LICENSE_CACHE_TYPE, REGION_ONE_LICENSE_CACHE_SPECIFICATION
)
with shared_client_cache._client_lock.write_lock():
self.assertRaises(RuntimeError, shared_client_cache.read)
def test_read_succeeds_without_retry_on_exception(self):
"""Test read cache succeeds without retry on exception"""
cache_specification = CacheSpecification(
lambda: clients.get_sysinv_client().get_license(),
retry_on_exception=False
)
self.shared_client_cache = SharedClientCache(
REGION_ONE_LICENSE_CACHE_TYPE, cache_specification
)
self.mock_sysinv_client().get_license.return_value = 'fake license'
response = self.shared_client_cache.read()
self.assertEqual(response, 'fake license')
self.mock_sysinv_client().get_license.assert_called_once()
def test_read_fails_with_retry_on_exception(self):
"""Test read cache fails with retry on exception"""
fetch_implementation = mock.MagicMock(side_effect=socket.timeout)
shared_client_cache = SharedClientCache(
REGION_ONE_LICENSE_CACHE_TYPE, CacheSpecification(fetch_implementation)
)
self.assertRaises(socket.timeout, shared_client_cache.read)
self.assertEqual(
fetch_implementation.call_count, shared_client_cache._max_attempts
)