193 lines
7.4 KiB
Python
193 lines
7.4 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 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)
|