244 lines
9.5 KiB
Python
244 lines
9.5 KiB
Python
#
|
|
# 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.base import BaseState
|
|
from dcmanager.orchestrator.states.firmware import creating_vim_strategy
|
|
from dcmanager.tests.unit.orchestrator.states.firmware.test_base \
|
|
import TestFwUpdateState
|
|
|
|
|
|
@mock.patch("dcmanager.orchestrator.states.firmware.creating_vim_strategy."
|
|
"DEFAULT_MAX_QUERIES", 3)
|
|
@mock.patch("dcmanager.orchestrator.states.firmware.creating_vim_strategy."
|
|
"DEFAULT_SLEEP_DURATION", 1)
|
|
class TestFwUpdateCreatingVIMStrategyStage(TestFwUpdateState):
|
|
|
|
def setUp(self):
|
|
super(TestFwUpdateCreatingVIMStrategyStage, self).setUp()
|
|
|
|
# set the next state in the chain (when this state is successful)
|
|
self.on_success_state =\
|
|
consts.STRATEGY_STATE_APPLYING_FW_UPDATE_STRATEGY
|
|
|
|
# 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, consts.STRATEGY_STATE_CREATING_FW_UPDATE_STRATEGY)
|
|
|
|
# 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,
|
|
self._create_fake_strategy(vim.STATE_BUILDING),
|
|
self._create_fake_strategy(vim.STATE_READY_TO_APPLY),
|
|
]
|
|
|
|
# API calls acts as expected
|
|
self.vim_client.create_strategy.return_value = \
|
|
self._create_fake_strategy(vim.STATE_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 = \
|
|
self._create_fake_strategy(vim.STATE_BUILD_FAILED)
|
|
|
|
# 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,
|
|
self._create_fake_strategy(vim.STATE_BUILDING),
|
|
self._create_fake_strategy(vim.STATE_BUILD_FAILED),
|
|
]
|
|
|
|
# API calls acts as expected
|
|
self.vim_client.create_strategy.return_value = \
|
|
self._create_fake_strategy(vim.STATE_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(self._create_fake_strategy(vim.STATE_BUILDING))
|
|
)
|
|
|
|
# API calls acts as expected
|
|
self.vim_client.create_strategy.return_value = \
|
|
self._create_fake_strategy(vim.STATE_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
|
|
# and a new one recreated
|
|
# remainder are during the loop
|
|
self.vim_client.get_strategy.side_effect = [
|
|
# old strategy that gets deleted
|
|
self._create_fake_strategy(vim.STATE_BUILD_FAILED),
|
|
# new strategy gets built
|
|
self._create_fake_strategy(vim.STATE_BUILDING),
|
|
# new strategy succeeds during while loop
|
|
self._create_fake_strategy(vim.STATE_READY_TO_APPLY),
|
|
]
|
|
# The strategy should be deleted and then created
|
|
self.vim_client.create_strategy.return_value = \
|
|
self._create_fake_strategy(vim.STATE_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.
|
|
# If it is building,aborting or applying it does not get deleted
|
|
# and the strategy goes to failed state
|
|
self.vim_client.get_strategy.side_effect = [
|
|
self._create_fake_strategy(vim.STATE_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)
|
|
|
|
@mock.patch.object(BaseState, 'stopped', return_value=True)
|
|
def test_creating_vim_strategy_fails_with_strategy_stop(self, _):
|
|
"""Test creating a VIM strategy fails when strategy stops"""
|
|
|
|
self.vim_client.get_strategy.side_effect = [None]
|
|
|
|
self.vim_client.create_strategy.return_value = \
|
|
self._create_fake_strategy(vim.STATE_BUILDING)
|
|
|
|
self.worker.perform_state_action(self.strategy_step)
|
|
|
|
self.assert_step_updated(
|
|
self.strategy_step.subcloud_id, consts.STRATEGY_STATE_FAILED
|
|
)
|
|
|
|
def test_creating_vim_strategy_fails_with_build_timeout_strategy(self):
|
|
"""Test creating a VIM strategy fails when strategy is build timeout"""
|
|
|
|
self.vim_client.get_strategy.side_effect = [
|
|
None,
|
|
self._create_fake_strategy(vim.STATE_BUILDING),
|
|
self._create_fake_strategy(vim.STATE_BUILD_TIMEOUT)
|
|
]
|
|
|
|
self.vim_client.create_strategy.return_value = \
|
|
self._create_fake_strategy(vim.STATE_BUILDING)
|
|
|
|
self.worker.perform_state_action(self.strategy_step)
|
|
|
|
self.assert_step_updated(
|
|
self.strategy_step.subcloud_id, consts.STRATEGY_STATE_FAILED
|
|
)
|
|
|
|
def test_creating_vim_strategy_fails_with_invalid_strategy(self):
|
|
"""Test creating a VIM strategy fails when strategy is aborted"""
|
|
|
|
self.vim_client.get_strategy.side_effect = [
|
|
None,
|
|
self._create_fake_strategy(vim.STATE_BUILDING),
|
|
self._create_fake_strategy(vim.STATE_ABORTED)
|
|
]
|
|
|
|
self.vim_client.create_strategy.return_value = \
|
|
self._create_fake_strategy(vim.STATE_BUILDING)
|
|
|
|
self.worker.perform_state_action(self.strategy_step)
|
|
|
|
self.assert_step_updated(
|
|
self.strategy_step.subcloud_id, consts.STRATEGY_STATE_FAILED
|
|
)
|