# # Copyright (c) 2020-2022, 2024 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # import itertools import mock from dccommon.drivers.openstack import vim from dcmanager.common import consts from dcmanager.orchestrator.states import creating_vim_strategy from dcmanager.tests.unit.fakes import FakeVimStrategy from dcmanager.tests.unit.orchestrator.states.upgrade.test_base \ import TestSwUpgradeState STRATEGY_BUILDING = FakeVimStrategy(state=vim.STATE_BUILDING) STRATEGY_DONE_BUILDING = FakeVimStrategy(state=vim.STATE_READY_TO_APPLY) STRATEGY_FAILED_BUILDING = FakeVimStrategy(state=vim.STATE_BUILD_FAILED) @mock.patch("dcmanager.orchestrator.states.creating_vim_strategy." "DEFAULT_MAX_QUERIES", 3) @mock.patch("dcmanager.orchestrator.states.creating_vim_strategy." "DEFAULT_SLEEP_DURATION", 1) class CreatingVIMStrategyStageMixin(object): def set_state(self, state, success_state): self.state = state self.on_success_state = success_state # Add the subcloud being processed by this unit test self.subcloud = self.setup_subcloud() # Add the strategy_step state being processed by this unit test self.strategy_step = self.setup_strategy_step(self.subcloud.id, self.state) # Add mock API endpoints for sysinv client calls invcked by this state self.vim_client.create_strategy = mock.MagicMock() self.vim_client.delete_strategy = mock.MagicMock() self.vim_client.get_strategy = mock.MagicMock() def test_creating_vim_strategy_success(self): """Test creating a VIM strategy""" # first api query is before the create # remaining api query results are waiting for the strategy to build self.vim_client.get_strategy.side_effect = [ None, STRATEGY_BUILDING, STRATEGY_DONE_BUILDING, ] # API calls acts as expected self.vim_client.create_strategy.return_value = STRATEGY_BUILDING # invoke the strategy state operation on the orch thread self.worker.perform_state_action(self.strategy_step) # Successful promotion to next state self.assert_step_updated(self.strategy_step.subcloud_id, self.on_success_state) def test_creating_vim_strategy_raises_exception(self): """Test creating a VIM strategy that raises an exception""" # first api query is before the create self.vim_client.get_strategy.return_value = None # raise an exception during create_strategy self.vim_client.create_strategy.side_effect =\ Exception("HTTPBadRequest: this is a fake exception") # invoke the strategy state operation on the orch thread self.worker.perform_state_action(self.strategy_step) # Failure case self.assert_step_updated(self.strategy_step.subcloud_id, consts.STRATEGY_STATE_FAILED) def test_creating_vim_strategy_fails_create_immediately(self): """Test creating a VIM strategy that returns a failed create""" # first api query is before the create self.vim_client.get_strategy.return_value = None # return a failed strategy self.vim_client.create_strategy.return_value = STRATEGY_FAILED_BUILDING # invoke the strategy state operation on the orch thread self.worker.perform_state_action(self.strategy_step) # Failure case self.assert_step_updated(self.strategy_step.subcloud_id, consts.STRATEGY_STATE_FAILED) def test_creating_vim_strategy_fails_create_later(self): """Test creating a VIM strategy that starts to build but then fails""" # first api query is before the create self.vim_client.get_strategy.side_effect = [ None, STRATEGY_BUILDING, STRATEGY_FAILED_BUILDING, ] # API calls acts as expected self.vim_client.create_strategy.return_value = STRATEGY_BUILDING # invoke the strategy state operation on the orch thread self.worker.perform_state_action(self.strategy_step) # Failure case self.assert_step_updated(self.strategy_step.subcloud_id, consts.STRATEGY_STATE_FAILED) def test_creating_vim_strategy_timeout(self): """Test creating a VIM strategy that times out""" # first api query is before the create self.vim_client.get_strategy.side_effect = itertools.chain( [None, ], itertools.repeat(STRATEGY_BUILDING)) # API calls acts as expected self.vim_client.create_strategy.return_value = STRATEGY_BUILDING # invoke the strategy state operation on the orch thread self.worker.perform_state_action(self.strategy_step) # verify the max number of queries was attempted (plus 1) self.assertEqual(creating_vim_strategy.DEFAULT_MAX_QUERIES + 1, self.vim_client.get_strategy.call_count) # Failure case self.assert_step_updated(self.strategy_step.subcloud_id, consts.STRATEGY_STATE_FAILED) def test_creating_vim_strategy_already_exists_and_completes(self): """Test creating a VIM strategy while one already exists""" # first api query is what already exists # If it is not building, aborting or applying it should be deleted # remainder are during the loop self.vim_client.get_strategy.side_effect = [ STRATEGY_FAILED_BUILDING, # old strategy that gets deleted STRATEGY_BUILDING, # new strategy gets built STRATEGY_DONE_BUILDING, # new strategy succeeds during while loop ] # The strategy should be deleted and then created self.vim_client.create_strategy.return_value = STRATEGY_BUILDING # invoke the strategy state operation on the orch thread self.worker.perform_state_action(self.strategy_step) # delete API should have been invoked self.assertEqual(1, self.vim_client.delete_strategy.call_count) # create API call should be invoked self.assertEqual(1, self.vim_client.create_strategy.call_count) # SUCCESS case self.assert_step_updated(self.strategy_step.subcloud_id, self.on_success_state) def test_creating_vim_strategy_already_exists_and_is_broken(self): """Test creating a VIM strategy while a broken strategy exists""" # first api query is what already exists # remainder are during the loop self.vim_client.get_strategy.side_effect = [ STRATEGY_BUILDING, ] # invoke the strategy state operation on the orch thread self.worker.perform_state_action(self.strategy_step) # create API call should never be invoked self.vim_client.create_strategy.assert_not_called() # Failure case self.assert_step_updated(self.strategy_step.subcloud_id, consts.STRATEGY_STATE_FAILED) class TestSwUpgradeCreatingVIMStrategyStage(CreatingVIMStrategyStageMixin, TestSwUpgradeState): """Test Creating Vim Strategy for a SW upgrade""" def setUp(self): super(TestSwUpgradeCreatingVIMStrategyStage, self).setUp() self.set_state(consts.STRATEGY_STATE_CREATING_VIM_UPGRADE_STRATEGY, consts.STRATEGY_STATE_APPLYING_VIM_UPGRADE_STRATEGY)