990 lines
45 KiB
Python
990 lines
45 KiB
Python
#
|
|
# Copyright (c) 2020-2022 Wind River Systems, Inc.
|
|
#
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
#
|
|
import mock
|
|
|
|
from dccommon import consts as dccommon_consts
|
|
from dcmanager.common import consts
|
|
from dcmanager.db.sqlalchemy import api as db_api
|
|
from dcmanager.tests import base
|
|
from dcmanager.tests.unit.common import fake_strategy
|
|
from dcmanager.tests.unit.common import fake_subcloud
|
|
from dcmanager.tests.unit.orchestrator.states.fakes import FakeAlarm
|
|
from dcmanager.tests.unit.orchestrator.states.fakes import FakeController
|
|
from dcmanager.tests.unit.orchestrator.states.fakes import FakeHostFilesystem
|
|
from dcmanager.tests.unit.orchestrator.states.fakes import FakeSystem
|
|
from dcmanager.tests.unit.orchestrator.states.fakes import FakeUpgrade
|
|
from dcmanager.tests.unit.orchestrator.states.upgrade.test_base \
|
|
import TestSwUpgradeState
|
|
|
|
CONTROLLER_0_LOCKED = FakeController(administrative=consts.ADMIN_LOCKED)
|
|
CONTROLLER_0_HOST_FS_SCRATCH_MIN_SIZED = FakeHostFilesystem(size=16)
|
|
CONTROLLER_0_HOST_FS_SCRATCH_UNDER_SIZED = FakeHostFilesystem(size=15)
|
|
CONTROLLER_0_LOCKED_AND_STANDBY = FakeController(administrative=consts.ADMIN_LOCKED,
|
|
capabilities={"Personality": "Controller-Standby"})
|
|
CONTROLLER_0_UNLOCKED_AND_STANDBY = FakeController(administrative=consts.ADMIN_UNLOCKED,
|
|
capabilities={"Personality": "Controller-Standby"})
|
|
CONTROLLER_0_UNLOCKED_AND_ACTIVE = FakeController(administrative=consts.ADMIN_UNLOCKED)
|
|
CONTROLLER_0_NOT_UPGRADED = FakeController(administrative=consts.ADMIN_UNLOCKED,
|
|
capabilities={"Personality": "Controller-Standby"})
|
|
CONTROLLER_0_UPGRADED_STANDBY = FakeController(administrative=consts.ADMIN_UNLOCKED,
|
|
capabilities={"Personality": "Controller-Standby"},
|
|
software_load='56.78')
|
|
CONTROLLER_0_UPGRADED_ACTIVE = FakeController(administrative=consts.ADMIN_UNLOCKED,
|
|
software_load='56.78')
|
|
CONTROLLER_1_LOCKED_AND_STANDBY = FakeController(host_id=2,
|
|
hostname='controller-1',
|
|
administrative=consts.ADMIN_LOCKED,
|
|
capabilities={"Personality": "Controller-Standby"})
|
|
CONTROLLER_1_UNLOCKED_AND_STANDBY = FakeController(host_id=2,
|
|
hostname='controller-1',
|
|
administrative=consts.ADMIN_UNLOCKED,
|
|
capabilities={"Personality": "Controller-Standby"})
|
|
CONTROLLER_1_UNLOCKED_AND_ACTIVE = FakeController(host_id=2,
|
|
hostname='controller-1',
|
|
administrative=consts.ADMIN_UNLOCKED)
|
|
CONTROLLER_1_NOT_UPGRADED = FakeController(host_id=2,
|
|
hostname='controller-1',
|
|
administrative=consts.ADMIN_UNLOCKED)
|
|
CONTROLLER_1_UPGRADED_ACTIVE = FakeController(host_id=2,
|
|
hostname='controller-1',
|
|
administrative=consts.ADMIN_UNLOCKED,
|
|
software_load='56.78')
|
|
CONTROLLER_1_UPGRADED_STANDBY = FakeController(host_id=2,
|
|
hostname='controller-1',
|
|
administrative=consts.ADMIN_UNLOCKED,
|
|
software_load='56.78',
|
|
capabilities={"Personality": "Controller-Standby"})
|
|
SYSTEM_HEALTH_UPGRADE_RESPONSE_SUCCESS = \
|
|
"System Health:\n" \
|
|
"All hosts are provisioned: [OK]\n" \
|
|
"All hosts are unlocked/enabled: [OK]\n" \
|
|
"All hosts have current configurations: [OK]\n" \
|
|
"All hosts are patch current: [OK]\n" \
|
|
"Ceph Storage Healthy: [OK]\n" \
|
|
"No alarms: [OK]\n" \
|
|
"All kubernetes nodes are ready: [OK]\n" \
|
|
"All kubernetes control plane pods are ready: [OK]\n" \
|
|
"Active kubernetes version is the latest supported version: [OK]\n" \
|
|
"No imported load found. Unable to test further"
|
|
|
|
SYSTEM_HEALTH_UPGRADE_RESPONSE_NON_MGMT_AFFECTING_ALARMS = \
|
|
"System Health:\n" \
|
|
"All hosts are provisioned: [OK]\n" \
|
|
"All hosts are unlocked/enabled: [OK]\n" \
|
|
"All hosts have current configurations: [OK]\n" \
|
|
"All hosts are patch current: [OK]\n" \
|
|
"Ceph Storage Healthy: [OK]\n" \
|
|
"No alarms: [Fail]\n" \
|
|
"[4] alarms found, [0] of which are management affecting\n" \
|
|
"All kubernetes nodes are ready: [OK]\n" \
|
|
"All kubernetes control plane pods are ready: [OK]\n" \
|
|
"Active kubernetes version is the latest supported version: [OK]\n" \
|
|
"No imported load found. Unable to test further"
|
|
|
|
SYSTEM_HEALTH_UPGRADE_RESPONSE_MGMT_AFFECTING_ALARM = \
|
|
"System Health:\n" \
|
|
"All hosts are provisioned: [OK]\n" \
|
|
"All hosts are unlocked/enabled: [OK]\n" \
|
|
"All hosts have current configurations: [OK]\n" \
|
|
"All hosts are patch current: [OK]\n" \
|
|
"Ceph Storage Healthy: [OK]\n" \
|
|
"No alarms: [Fail]\n" \
|
|
"[1] alarms found, [1] of which are management affecting\n" \
|
|
"All kubernetes nodes are ready: [OK]\n" \
|
|
"All kubernetes control plane pods are ready: [OK]\n" \
|
|
"Active kubernetes version is the latest supported version: [OK]\n" \
|
|
"No imported load found. Unable to test further"
|
|
|
|
SYSTEM_HEALTH_UPGRADE_RESPONSE_MULTIPLE_FAILED_HEALTH_CHECKS = \
|
|
"System Health:\n" \
|
|
"All hosts are provisioned: [OK]\n" \
|
|
"All hosts are unlocked/enabled: [OK]\n" \
|
|
"All hosts have current configurations: [OK]\n" \
|
|
"All hosts are patch current: [OK]\n" \
|
|
"Ceph Storage Healthy: [OK]\n" \
|
|
"No alarms: [Fail]\n" \
|
|
"[1] alarms found, [0] of which are management affecting\n" \
|
|
"All kubernetes nodes are ready: [Fail]\n" \
|
|
"Kubernetes nodes not ready: controller-0\n" \
|
|
"All kubernetes control plane pods are ready: [Fail]\n" \
|
|
"Kubernetes control plane pods not ready: kube-apiserver-controller-0\n" \
|
|
"Active kubernetes version is the latest supported version: [OK]\n" \
|
|
"No imported load found. Unable to test further"
|
|
|
|
SYSTEM_HEALTH_UPGRADE_RESPONSE_K8S_FAILED_HEALTH_CHECKS = \
|
|
"System Health:\n" \
|
|
"All hosts are provisioned: [OK]\n" \
|
|
"All hosts are unlocked/enabled: [OK]\n" \
|
|
"All hosts have current configurations: [OK]\n" \
|
|
"All hosts are patch current: [OK]\n" \
|
|
"Ceph Storage Healthy: [OK]\n" \
|
|
"No alarms: [OK]\n" \
|
|
"All kubernetes nodes are ready: [Fail]\n" \
|
|
"All kubernetes control plane pods are ready: [OK]\n" \
|
|
"Active kubernetes version is the latest supported version: [OK]\n" \
|
|
"No imported load found. Unable to test further"
|
|
|
|
SYSTEM_HEALTH_UPGRADE_RESPONSE_FAILED_ACTIVE_K8S_VERSION_CHECK = \
|
|
"System Health:\n" \
|
|
"All hosts are provisioned: [OK]\n" \
|
|
"All hosts are unlocked/enabled: [OK]\n" \
|
|
"All hosts have current configurations: [OK]\n" \
|
|
"All hosts are patch current: [OK]\n" \
|
|
"Ceph Storage Healthy: [OK]\n" \
|
|
"No alarms: [OK]\n" \
|
|
"All kubernetes nodes are ready: [OK]\n" \
|
|
"All kubernetes control plane pods are ready: [OK]\n" \
|
|
"Active kubernetes version is the latest supported version: [Fail]\n" \
|
|
"Upgrade kubernetes to the latest version: [v1.26.1]. See \"system kube-version-list\"\n" \
|
|
"No imported load found. Unable to test further"
|
|
|
|
UPGRADE_STARTED = FakeUpgrade(state='started')
|
|
|
|
UPGRADE_ALARM = FakeAlarm('900.005', 'True')
|
|
HOST_LOCKED_ALARM = FakeAlarm('200.001', 'True')
|
|
|
|
|
|
class TestSwUpgradePreCheckStage(TestSwUpgradeState):
|
|
|
|
def setUp(self):
|
|
super(TestSwUpgradePreCheckStage, self).setUp()
|
|
|
|
# Add the subcloud being processed by this unit test
|
|
# The subcloud is online, managed with deploy_state 'installed'
|
|
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_PRE_CHECK)
|
|
|
|
self.sysinv_client.get_host = mock.MagicMock()
|
|
self.sysinv_client.get_host_filesystem = mock.MagicMock()
|
|
self.sysinv_client.get_system_health_upgrade = mock.MagicMock()
|
|
self.sysinv_client.get_system = mock.MagicMock()
|
|
system_values = FakeSystem()
|
|
system_values.system_mode = consts.SYSTEM_MODE_SIMPLEX
|
|
self.sysinv_client.get_system.return_value = system_values
|
|
self.sysinv_client.get_upgrades = mock.MagicMock()
|
|
self.fm_client.get_alarms = mock.MagicMock()
|
|
|
|
def test_upgrade_pre_check_subcloud_online_fresh(self):
|
|
"""Test pre check step where the subcloud is online and running N load
|
|
|
|
The pre-check should transition in this scenario to the first state
|
|
of a normal upgrade orchestration which is 'installing license'.
|
|
"""
|
|
|
|
# Update the subcloud to have deploy state as "complete"
|
|
db_api.subcloud_update(self.ctx,
|
|
self.subcloud.id,
|
|
deploy_status=consts.DEPLOY_STATE_DONE)
|
|
|
|
self.sysinv_client.get_host_filesystem.side_effect = \
|
|
[CONTROLLER_0_HOST_FS_SCRATCH_MIN_SIZED]
|
|
|
|
self.sysinv_client.get_system_health_upgrade.return_value = \
|
|
SYSTEM_HEALTH_UPGRADE_RESPONSE_SUCCESS
|
|
|
|
# invoke the strategy state operation on the orch thread
|
|
self.worker.perform_state_action(self.strategy_step)
|
|
|
|
# verify the get system health upgrade API call was invoked
|
|
self.sysinv_client.get_system_health_upgrade.assert_called()
|
|
|
|
# verify the get host filesystem API call was invoked
|
|
self.sysinv_client.get_host_filesystem.assert_called()
|
|
|
|
# Verify the expected next state happened (installing license)
|
|
self.assert_step_updated(self.strategy_step.subcloud_id,
|
|
consts.STRATEGY_STATE_INSTALLING_LICENSE)
|
|
|
|
def test_upgrade_pre_check_subcloud_online_fresh_with_non_management_alarms(self):
|
|
"""Test pre check step where the subcloud is online with non mgmt alarms
|
|
|
|
The pre-check should transition in this scenario to the first state
|
|
of a normal upgrade orchestration which is 'installing license'.
|
|
"""
|
|
|
|
# Update the subcloud to have deploy state as "complete"
|
|
db_api.subcloud_update(self.ctx,
|
|
self.subcloud.id,
|
|
deploy_status=consts.DEPLOY_STATE_DONE)
|
|
|
|
self.sysinv_client.get_host_filesystem.side_effect = \
|
|
[CONTROLLER_0_HOST_FS_SCRATCH_MIN_SIZED]
|
|
|
|
self.sysinv_client.get_system_health_upgrade.return_value = \
|
|
SYSTEM_HEALTH_UPGRADE_RESPONSE_NON_MGMT_AFFECTING_ALARMS
|
|
|
|
# invoke the strategy state operation on the orch thread
|
|
self.worker.perform_state_action(self.strategy_step)
|
|
|
|
# verify the get system health upgrade API call was invoked
|
|
self.sysinv_client.get_system_health_upgrade.assert_called()
|
|
|
|
# verify the get host filesystem API call was invoked
|
|
self.sysinv_client.get_host_filesystem.assert_called()
|
|
|
|
# Verify the expected next state happened (installing license)
|
|
self.assert_step_updated(self.strategy_step.subcloud_id,
|
|
consts.STRATEGY_STATE_INSTALLING_LICENSE)
|
|
|
|
def test_upgrade_pre_check_subcloud_online_host_locked_upgrade_started_mgmt_alarms(self):
|
|
"""Test pre check step where the subcloud is online, locked and upgrade has started.
|
|
|
|
The pre-check should move to the next step as the upgrade alarm can
|
|
be ignored and the host locked alarm can also be ignored if upgrade has
|
|
started.
|
|
"""
|
|
|
|
# Update the subcloud to have deploy state as "complete"
|
|
db_api.subcloud_update(self.ctx,
|
|
self.subcloud.id,
|
|
deploy_status=consts.DEPLOY_STATE_DONE)
|
|
|
|
# subcloud is locked
|
|
self.sysinv_client.get_host.side_effect = [CONTROLLER_0_LOCKED]
|
|
|
|
# upgrade has started
|
|
self.sysinv_client.get_upgrades.return_value = [UPGRADE_STARTED, ]
|
|
|
|
self.sysinv_client.get_system_health_upgrade.return_value = \
|
|
SYSTEM_HEALTH_UPGRADE_RESPONSE_MGMT_AFFECTING_ALARM
|
|
|
|
self.fm_client.get_alarms.return_value = [UPGRADE_ALARM, HOST_LOCKED_ALARM, ]
|
|
|
|
self.sysinv_client.get_host_filesystem.side_effect = \
|
|
[CONTROLLER_0_HOST_FS_SCRATCH_MIN_SIZED]
|
|
|
|
# invoke the strategy state operation on the orch thread
|
|
self.worker.perform_state_action(self.strategy_step)
|
|
|
|
# verify the get system health upgrade API call was invoked
|
|
self.sysinv_client.get_system_health_upgrade.assert_called()
|
|
|
|
# verify the get alarms API call was invoked
|
|
self.fm_client.get_alarms.assert_called()
|
|
|
|
# verify the get host filesystem API call was invoked
|
|
self.sysinv_client.get_host_filesystem.assert_called()
|
|
|
|
# Verify the expected next state happened (installing license)
|
|
self.assert_step_updated(self.strategy_step.subcloud_id,
|
|
consts.STRATEGY_STATE_INSTALLING_LICENSE)
|
|
|
|
def test_upgrade_pre_check_subcloud_online_host_locked_no_upgrade_mgmt_alarms(self):
|
|
"""Test pre check step where subcloud is online, locked and upgrade has not started.
|
|
|
|
The pre-check should raise an exception and transition to the failed
|
|
state as host locked alarm cannot be skipped if upgrade has
|
|
not been started.
|
|
"""
|
|
|
|
# Update the subcloud to have deploy state as "complete"
|
|
db_api.subcloud_update(self.ctx,
|
|
self.subcloud.id,
|
|
deploy_status=consts.DEPLOY_STATE_DONE)
|
|
|
|
# subcloud is locked
|
|
self.sysinv_client.get_host.side_effect = [CONTROLLER_0_LOCKED]
|
|
|
|
self.sysinv_client.get_upgrades.return_value = []
|
|
|
|
self.sysinv_client.get_system_health_upgrade.return_value = \
|
|
SYSTEM_HEALTH_UPGRADE_RESPONSE_MGMT_AFFECTING_ALARM
|
|
|
|
self.fm_client.get_alarms.return_value = [HOST_LOCKED_ALARM, ]
|
|
|
|
# invoke the strategy state operation on the orch thread
|
|
self.worker.perform_state_action(self.strategy_step)
|
|
|
|
# verify the get system health API call was invoked
|
|
self.sysinv_client.get_system_health_upgrade.assert_called()
|
|
|
|
# verify the get alarms API call was invoked
|
|
self.fm_client.get_alarms.assert_called()
|
|
|
|
# Verify the exception caused the state to go to failed
|
|
self.assert_step_updated(self.strategy_step.subcloud_id,
|
|
consts.STRATEGY_STATE_FAILED)
|
|
|
|
def test_upgrade_pre_check_subcloud_online_multiple_failed_health_checks(self):
|
|
"""Test pre check step where the subcloud is online but is unhealthy
|
|
|
|
The pre-check should raise an exception and transition to the failed
|
|
state when the subcloud is not ready for upgrade due to multiple failed
|
|
health checks.
|
|
"""
|
|
|
|
# Update the subcloud to have deploy state as "complete"
|
|
db_api.subcloud_update(self.ctx,
|
|
self.subcloud.id,
|
|
deploy_status=consts.DEPLOY_STATE_DONE)
|
|
|
|
self.sysinv_client.get_system_health_upgrade.return_value = \
|
|
SYSTEM_HEALTH_UPGRADE_RESPONSE_MULTIPLE_FAILED_HEALTH_CHECKS
|
|
|
|
# invoke the strategy state operation on the orch thread
|
|
self.worker.perform_state_action(self.strategy_step)
|
|
|
|
# verify the get system health API call was invoked
|
|
self.sysinv_client.get_system_health_upgrade.assert_called()
|
|
|
|
# Verify the exception caused the state to go to failed
|
|
self.assert_step_updated(self.strategy_step.subcloud_id,
|
|
consts.STRATEGY_STATE_FAILED)
|
|
|
|
def test_upgrade_pre_check_subcloud_online_active_k8s_version_check_failed(self):
|
|
"""Test pre check step where the subcloud is online but is unhealthy
|
|
|
|
The pre-check should raise an exception and transition to the failed
|
|
state when the subcloud is not ready because subcloud k8s version is not
|
|
the latest supported kubernetes version.
|
|
"""
|
|
|
|
# Update the subcloud to have deploy state as "complete"
|
|
db_api.subcloud_update(self.ctx,
|
|
self.subcloud.id,
|
|
deploy_status=consts.DEPLOY_STATE_DONE)
|
|
|
|
self.sysinv_client.get_system_health_upgrade.return_value = \
|
|
SYSTEM_HEALTH_UPGRADE_RESPONSE_FAILED_ACTIVE_K8S_VERSION_CHECK
|
|
|
|
# invoke the strategy state operation on the orch thread
|
|
self.worker.perform_state_action(self.strategy_step)
|
|
|
|
# verify the get system health API call was invoked
|
|
self.sysinv_client.get_system_health_upgrade.assert_called()
|
|
|
|
# Verify the exception caused the state to go to failed
|
|
self.assert_step_updated(self.strategy_step.subcloud_id,
|
|
consts.STRATEGY_STATE_FAILED)
|
|
|
|
def test_upgrade_pre_check_subcloud_online_failed_health_checks_no_alarms(self):
|
|
"""Test pre check step where the subcloud is online but is unhealthy
|
|
|
|
The pre-check should raise an exception and transition to the failed
|
|
state when the subcloud is not ready for upgrade due to some failure
|
|
other than platform alarms.
|
|
"""
|
|
|
|
# Update the subcloud to have deploy state as "complete"
|
|
db_api.subcloud_update(self.ctx,
|
|
self.subcloud.id,
|
|
deploy_status=consts.DEPLOY_STATE_DONE)
|
|
|
|
self.sysinv_client.get_system_health_upgrade.return_value = \
|
|
SYSTEM_HEALTH_UPGRADE_RESPONSE_K8S_FAILED_HEALTH_CHECKS
|
|
|
|
# invoke the strategy state operation on the orch thread
|
|
self.worker.perform_state_action(self.strategy_step)
|
|
|
|
# verify the get system health API call was invoked
|
|
self.sysinv_client.get_system_health_upgrade.assert_called()
|
|
|
|
# Verify the exception caused the state to go to failed
|
|
self.assert_step_updated(self.strategy_step.subcloud_id,
|
|
consts.STRATEGY_STATE_FAILED)
|
|
|
|
def test_upgrade_pre_check_subcloud_online_scratch_undersized(self):
|
|
"""Test pre check step where the subcloud is online undersized scratch
|
|
|
|
The pre-check should raise an exception and transition to the failed
|
|
state when the subcloud scratch filesystem does not meet
|
|
minimum upgrade requirements.
|
|
"""
|
|
|
|
# Update the subcloud to have deploy state as "complete"
|
|
db_api.subcloud_update(self.ctx,
|
|
self.subcloud.id,
|
|
deploy_status=consts.DEPLOY_STATE_DONE)
|
|
|
|
self.sysinv_client.get_host_filesystem.side_effect = \
|
|
[CONTROLLER_0_HOST_FS_SCRATCH_UNDER_SIZED]
|
|
|
|
self.sysinv_client.get_system_health_upgrade.return_value = \
|
|
SYSTEM_HEALTH_UPGRADE_RESPONSE_SUCCESS
|
|
|
|
# invoke the strategy state operation on the orch thread
|
|
self.worker.perform_state_action(self.strategy_step)
|
|
|
|
# verify the get system health upgrade API call was invoked
|
|
self.sysinv_client.get_system_health_upgrade.assert_called()
|
|
|
|
# verify the get host filesystem API call was invoked
|
|
self.sysinv_client.get_host_filesystem.assert_called()
|
|
|
|
# Verify the exception caused the state to go to failed
|
|
self.assert_step_updated(self.strategy_step.subcloud_id,
|
|
consts.STRATEGY_STATE_FAILED)
|
|
|
|
|
|
class TestSwUpgradePreCheckSimplexStage(TestSwUpgradePreCheckStage):
|
|
|
|
def test_upgrade_pre_check_subcloud_online_migrated(self):
|
|
"""Test pre check step where the subcloud is online and running N+1 load
|
|
|
|
The pre-check in this scenario should advance directly to 'activating upgrade'.
|
|
"""
|
|
|
|
# Update the subcloud to have deploy state as "migrated"
|
|
db_api.subcloud_update(self.ctx,
|
|
self.subcloud.id,
|
|
deploy_status=consts.DEPLOY_STATE_MIGRATED)
|
|
|
|
# invoke the strategy state operation on the orch thread
|
|
self.worker.perform_state_action(self.strategy_step)
|
|
|
|
# verify the get system health API call was not invoked
|
|
self.sysinv_client.get_system_health_upgrade.assert_not_called()
|
|
|
|
# verify the get host filesystem API call was not invoked
|
|
self.sysinv_client.get_host_filesystem.assert_not_called()
|
|
|
|
# Verify the expected next state happened (activating upgrade)
|
|
self.assert_step_updated(self.strategy_step.subcloud_id,
|
|
consts.STRATEGY_STATE_ACTIVATING_UPGRADE)
|
|
|
|
def test_upgrade_pre_check_subcloud_online_migrate_failed(self):
|
|
"""Test pre check step where the subcloud is online following an unlock timeout
|
|
|
|
The pre-check in this scenario should advance directly to 'activating upgrade'.
|
|
"""
|
|
|
|
# Update the subcloud to have deploy state as "data-migration-failed"
|
|
db_api.subcloud_update(self.ctx,
|
|
self.subcloud.id,
|
|
deploy_status=consts.DEPLOY_STATE_DATA_MIGRATION_FAILED)
|
|
|
|
self.sysinv_client.get_system_health_upgrade.return_value = \
|
|
SYSTEM_HEALTH_UPGRADE_RESPONSE_MGMT_AFFECTING_ALARM
|
|
|
|
self.fm_client.get_alarms.return_value = [UPGRADE_ALARM, ]
|
|
|
|
self.sysinv_client.get_host_filesystem.side_effect = \
|
|
[CONTROLLER_0_HOST_FS_SCRATCH_MIN_SIZED]
|
|
|
|
# invoke the strategy state operation on the orch thread
|
|
self.worker.perform_state_action(self.strategy_step)
|
|
|
|
# verify the get system health API call was invoked
|
|
self.sysinv_client.get_system_health_upgrade.assert_called()
|
|
|
|
# verify the get host filesystem API call was invoked
|
|
self.sysinv_client.get_host_filesystem.assert_called()
|
|
|
|
# verify the DB update was invoked
|
|
updated_subcloud = db_api.subcloud_get(self.ctx,
|
|
self.subcloud.id)
|
|
self.assertEqual(updated_subcloud.deploy_status, consts.DEPLOY_STATE_MIGRATED)
|
|
|
|
# Verify the expected next state happened (activating upgrade)
|
|
self.assert_step_updated(self.strategy_step.subcloud_id,
|
|
consts.STRATEGY_STATE_ACTIVATING_UPGRADE)
|
|
|
|
def test_upgrade_pre_check_subcloud_online_no_data_install(self):
|
|
"""Test pre check step where the subcloud is online without data install
|
|
|
|
The pre-check should raise an exception and transition to the failed
|
|
state when the data install values for the online
|
|
subcloud does not exist.
|
|
"""
|
|
|
|
# Create a subcloud with deploy state as "complete"
|
|
# and no data install values
|
|
self.subcloud = fake_subcloud.create_fake_subcloud(
|
|
self.ctx,
|
|
name=base.SUBCLOUD_2['name'],
|
|
region_name=base.SUBCLOUD_2['region_name'],
|
|
data_install=None
|
|
)
|
|
|
|
# Update the subcloud to be online
|
|
db_api.subcloud_update(self.ctx,
|
|
self.subcloud.id,
|
|
availability_status=dccommon_consts.AVAILABILITY_ONLINE)
|
|
|
|
# Create a fake strategy
|
|
fake_strategy.create_fake_strategy_step(
|
|
self.ctx,
|
|
subcloud_id=self.subcloud.id,
|
|
state=consts.STRATEGY_STATE_PRE_CHECK)
|
|
|
|
self.strategy_step = db_api.strategy_step_get(self.ctx, self.subcloud.id)
|
|
|
|
# invoke the strategy state operation on the orch thread
|
|
self.worker.perform_state_action(self.strategy_step)
|
|
|
|
# Verify the exception caused the state to go to failed
|
|
self.assert_step_updated(self.strategy_step.subcloud_id,
|
|
consts.STRATEGY_STATE_FAILED)
|
|
|
|
def test_upgrade_pre_check_subcloud_online_host_locked_pre_install_failed(self):
|
|
"""Test pre check step where the subcloud is locked and install-failed
|
|
|
|
If the subcloud host is locked and the subcloud's deploy status is
|
|
pre-install-failed, this means the upgrading simplex step had previously
|
|
failed to retrieve the subcloud install data. Upon retry, the pre-check
|
|
should transition directly to upgrading simplex state.
|
|
"""
|
|
|
|
# Update the subcloud to have deploy state as "pre-install-failed"
|
|
db_api.subcloud_update(self.ctx,
|
|
self.subcloud.id,
|
|
deploy_status=consts.DEPLOY_STATE_INSTALL_FAILED)
|
|
|
|
# subcloud is locked
|
|
self.sysinv_client.get_host.side_effect = [CONTROLLER_0_LOCKED]
|
|
|
|
# invoke the strategy state operation on the orch thread
|
|
self.worker.perform_state_action(self.strategy_step)
|
|
|
|
# Verify the expected next state happened (upgrading)
|
|
self.assert_step_updated(self.strategy_step.subcloud_id,
|
|
consts.STRATEGY_STATE_UPGRADING_SIMPLEX)
|
|
|
|
def test_upgrade_pre_check_subcloud_online_host_locked_install_failed(self):
|
|
"""Test pre check step where the subcloud is locked and install-failed
|
|
|
|
If the subcloud host is locked and the subcloud's deploy status is
|
|
install-failed and it is still online, this means the upgrading simplex step
|
|
had previously failed early. Upon retry, the pre-check should transition
|
|
directly to upgrading simplex state.
|
|
"""
|
|
|
|
# Update the subcloud to have deploy state as "install-failed"
|
|
db_api.subcloud_update(self.ctx,
|
|
self.subcloud.id,
|
|
deploy_status=consts.DEPLOY_STATE_INSTALL_FAILED)
|
|
|
|
# subcloud is locked
|
|
self.sysinv_client.get_host.side_effect = [CONTROLLER_0_LOCKED]
|
|
|
|
# invoke the strategy state operation on the orch thread
|
|
self.worker.perform_state_action(self.strategy_step)
|
|
|
|
# Verify the expected next state happened (upgrading)
|
|
self.assert_step_updated(self.strategy_step.subcloud_id,
|
|
consts.STRATEGY_STATE_UPGRADING_SIMPLEX)
|
|
|
|
def test_upgrade_pre_check_subcloud_offline_no_data_install(self):
|
|
"""Test pre check step where the subcloud is offline without data install.
|
|
|
|
The pre-check should raise an exception and transition to the failed
|
|
state when the data install values for the offline subcloud
|
|
does not exist.
|
|
"""
|
|
|
|
# Create a subcloud with deploy state as "install-failed",
|
|
# availability status as "offline" and no data install values
|
|
self.subcloud = fake_subcloud.create_fake_subcloud(
|
|
self.ctx,
|
|
name=base.SUBCLOUD_2['name'],
|
|
region_name=base.SUBCLOUD_2['region_name'],
|
|
data_install=None,
|
|
deploy_status=consts.DEPLOY_STATE_INSTALL_FAILED
|
|
)
|
|
|
|
fake_strategy.create_fake_strategy_step(
|
|
self.ctx,
|
|
subcloud_id=self.subcloud.id,
|
|
state=consts.STRATEGY_STATE_PRE_CHECK)
|
|
|
|
self.strategy_step = db_api.strategy_step_get(self.ctx, self.subcloud.id)
|
|
|
|
# invoke the strategy state operation on the orch thread
|
|
self.worker.perform_state_action(self.strategy_step)
|
|
|
|
# Verify the exception caused the state to go to failed
|
|
self.assert_step_updated(self.strategy_step.subcloud_id,
|
|
consts.STRATEGY_STATE_FAILED)
|
|
|
|
def test_upgrade_pre_check_subcloud_jumps_to_migrating(self):
|
|
"""Test pre check step which jumps to the migrating data state
|
|
|
|
The pre-check should transition in this scenario to the migrating data
|
|
state if the subcloud is now offline, and the deploy status can be
|
|
handled by that state.
|
|
"""
|
|
|
|
# Update the subcloud to have deploy state as "installed",
|
|
# and availability status as "offline"
|
|
db_api.subcloud_update(self.ctx,
|
|
self.subcloud.id,
|
|
deploy_status=consts.DEPLOY_STATE_INSTALLED,
|
|
availability_status=dccommon_consts.AVAILABILITY_OFFLINE)
|
|
|
|
# invoke the strategy state operation on the orch thread
|
|
self.worker.perform_state_action(self.strategy_step)
|
|
|
|
# Verify the expected next state happened (migrating data)
|
|
self.assert_step_updated(self.strategy_step.subcloud_id,
|
|
consts.STRATEGY_STATE_MIGRATING_DATA)
|
|
|
|
def test_upgrade_pre_check_subcloud_jumps_to_upgrading(self):
|
|
"""Test pre check step which jumps to the upgrading state
|
|
|
|
The pre-check should transition in this scenario to the upgrading
|
|
state if the subcloud is now offline, and the deploy status can be
|
|
handled by that state.
|
|
"""
|
|
|
|
# Update the subcloud to have deploy state as "data-migration-failed",
|
|
# and availability status as "offline"
|
|
db_api.subcloud_update(self.ctx,
|
|
self.subcloud.id,
|
|
deploy_status=consts.DEPLOY_STATE_DATA_MIGRATION_FAILED,
|
|
availability_status=dccommon_consts.AVAILABILITY_OFFLINE)
|
|
|
|
# invoke the strategy state operation on the orch thread
|
|
self.worker.perform_state_action(self.strategy_step)
|
|
|
|
# Verify the expected next state happened (upgrading)
|
|
self.assert_step_updated(self.strategy_step.subcloud_id,
|
|
consts.STRATEGY_STATE_UPGRADING_SIMPLEX)
|
|
|
|
def test_upgrade_pre_check_subcloud_cannot_proceed(self):
|
|
"""Test pre check step which requires manual intervention to proceed
|
|
|
|
The pre-check should raise an exception and transition to the failed
|
|
state when an offline subcloud is not in a deploy_status that has a
|
|
known recovery route.
|
|
"""
|
|
|
|
# Update the subcloud to have deploy state as "bootstrap-failed",
|
|
# and availability status as "offline"
|
|
db_api.subcloud_update(self.ctx,
|
|
self.subcloud.id,
|
|
deploy_status=consts.DEPLOY_STATE_BOOTSTRAP_FAILED,
|
|
availability_status=dccommon_consts.AVAILABILITY_OFFLINE)
|
|
|
|
# invoke the strategy state operation on the orch thread
|
|
self.worker.perform_state_action(self.strategy_step)
|
|
|
|
# Verify the exception caused the state to go to failed
|
|
self.assert_step_updated(self.strategy_step.subcloud_id,
|
|
consts.STRATEGY_STATE_FAILED)
|
|
|
|
|
|
class TestSwUpgradePreCheckDuplexStage(TestSwUpgradePreCheckStage):
|
|
|
|
def setUp(self):
|
|
super(TestSwUpgradePreCheckDuplexStage, self).setUp()
|
|
self.sysinv_client.get_hosts = mock.MagicMock()
|
|
system_values = FakeSystem()
|
|
system_values.system_mode = consts.SYSTEM_MODE_DUPLEX
|
|
self.sysinv_client.get_system.return_value = system_values
|
|
self.sysinv_client.get_upgrades.return_value = []
|
|
# Update the subcloud to have deploy state as "complete"
|
|
db_api.subcloud_update(self.ctx,
|
|
self.subcloud.id,
|
|
deploy_status=consts.DEPLOY_STATE_DONE)
|
|
|
|
def test_upgrade_pre_check_subcloud_online_host_locked_upgrade_started_mgmt_alarms(self):
|
|
"""Test pre check step where the subcloud is online, locked and upgrade has started
|
|
|
|
The pre-check should move to the next step as the upgrade alarm can
|
|
be ignored and the host locked alarm can also be ignored if upgrade has
|
|
started.
|
|
"""
|
|
|
|
# subcloud's controller-0 is unlocked and active
|
|
# subcloud's controller-1 is locked and standby
|
|
self.sysinv_client.get_host.side_effect = [CONTROLLER_0_UNLOCKED_AND_ACTIVE,
|
|
CONTROLLER_1_LOCKED_AND_STANDBY]
|
|
|
|
# upgrade has started
|
|
upgrade = FakeUpgrade(state='started')
|
|
self.sysinv_client.get_upgrades.return_value = [upgrade, ]
|
|
|
|
# invoke the strategy state operation on the orch thread
|
|
self.worker.perform_state_action(self.strategy_step)
|
|
|
|
# Verify the expected next state happened (installing license)
|
|
self.assert_step_updated(self.strategy_step.subcloud_id,
|
|
consts.STRATEGY_STATE_INSTALLING_LICENSE)
|
|
|
|
def test_upgrade_pre_check_subcloud_data_migration_failed(self):
|
|
"""Test pre check step where the subcloud's controller-1 is locked and
|
|
|
|
data-migration-failed.
|
|
|
|
If the subcloud host is locked, the subcloud's upgrade status is
|
|
data-migration-failed; this means that one of the data migration scripts
|
|
failed to run. This failure is serious and requires manual recovery. Upon
|
|
retry, the pre-check should raise an exception and transition to the
|
|
failed state.
|
|
"""
|
|
|
|
# upgrade state is data-migration-failed
|
|
upgrade = FakeUpgrade(state=consts.UPGRADE_STATE_DATA_MIGRATION_FAILED)
|
|
self.sysinv_client.get_upgrades.return_value = [upgrade, ]
|
|
|
|
# subcloud's controller-0 is unlocked and active
|
|
# subcloud's controller-1 is locked and standby
|
|
self.sysinv_client.get_host.side_effect = [CONTROLLER_0_UNLOCKED_AND_ACTIVE,
|
|
CONTROLLER_1_LOCKED_AND_STANDBY]
|
|
|
|
# invoke the strategy state operation on the orch thread
|
|
self.worker.perform_state_action(self.strategy_step)
|
|
|
|
# Verify the exception caused the state to go to failed
|
|
self.assert_step_updated(self.strategy_step.subcloud_id,
|
|
consts.STRATEGY_STATE_FAILED)
|
|
|
|
def test_upgrade_pre_check_subcloud_in_data_migration_upgrade_state(self):
|
|
"""Test pre check step where the subcloud's controller-1 is locked and
|
|
|
|
upgrade state is data-migration.
|
|
|
|
If the subcloud host is locked, the subcloud's upgrade status is
|
|
data-migration; this means that installation failed on controller-1.
|
|
This failure is serious and requires manual recovery. Upon retry,
|
|
the pre-check should raise an exception and transition to the failed
|
|
state.
|
|
"""
|
|
|
|
# upgrade state is data-migration
|
|
upgrade = FakeUpgrade(state=consts.UPGRADE_STATE_DATA_MIGRATION)
|
|
self.sysinv_client.get_upgrades.return_value = [upgrade, ]
|
|
|
|
# invoke the strategy state operation on the orch thread
|
|
self.worker.perform_state_action(self.strategy_step)
|
|
|
|
# Verify the exception caused the state to go to failed
|
|
self.assert_step_updated(self.strategy_step.subcloud_id,
|
|
consts.STRATEGY_STATE_FAILED)
|
|
|
|
def test_upgrade_pre_check_jumps_to_unlock_controller_1(self):
|
|
"""Test pre check step which jumps to unlock controller-1 state.
|
|
|
|
The upgrade state is upgrading-controllers and subcloud's
|
|
controller-1 is locked. In this case the pre-check should transition
|
|
to the 'unlocking controller-1' state.
|
|
"""
|
|
|
|
# upgrade state is upgrading-controllers
|
|
upgrade = FakeUpgrade(state=consts.UPGRADE_STATE_UPGRADING_CONTROLLERS)
|
|
self.sysinv_client.get_upgrades.return_value = [upgrade, ]
|
|
|
|
# subcloud's controller-0 is unlocked and active
|
|
# subcloud's controller-1 is locked and standby
|
|
self.sysinv_client.get_host.side_effect = [CONTROLLER_0_UNLOCKED_AND_ACTIVE,
|
|
CONTROLLER_1_LOCKED_AND_STANDBY]
|
|
|
|
# invoke the strategy state operation on the orch thread
|
|
self.worker.perform_state_action(self.strategy_step)
|
|
|
|
# Verify the expected next state happened (upgrading)
|
|
self.assert_step_updated(self.strategy_step.subcloud_id,
|
|
consts.STRATEGY_STATE_UNLOCKING_CONTROLLER_1)
|
|
|
|
def test_upgrade_pre_check_jumps_to_swacting_to_controller_1(self):
|
|
"""Test pre check step which jumps to swacting to controller-1 state.
|
|
|
|
The upgrade state is upgrading-controllers and subcloud's
|
|
controller-1 is unlocked. In this case the pre-check should transition
|
|
to the 'swacting to controller-1' state.
|
|
"""
|
|
|
|
# upgrade state is upgrading-controllers
|
|
upgrade = FakeUpgrade(state=consts.UPGRADE_STATE_UPGRADING_CONTROLLERS)
|
|
self.sysinv_client.get_upgrades.return_value = [upgrade, ]
|
|
|
|
# subcloud's controller-0 is unlocked and active
|
|
# subcloud's controller-1 is unlocked and standby
|
|
self.sysinv_client.get_host.side_effect = [CONTROLLER_0_UNLOCKED_AND_ACTIVE,
|
|
CONTROLLER_1_UNLOCKED_AND_STANDBY]
|
|
|
|
# invoke the strategy state operation on the orch thread
|
|
self.worker.perform_state_action(self.strategy_step)
|
|
|
|
# Verify the expected next state happened (upgrading)
|
|
self.assert_step_updated(self.strategy_step.subcloud_id,
|
|
consts.STRATEGY_STATE_SWACTING_TO_CONTROLLER_1)
|
|
|
|
def test_upgrade_pre_check_jumps_to_creating_vim_strategy(self):
|
|
"""Test pre check step which jumps to creating vim startegy state.
|
|
|
|
The upgrade state is upgrading-controllers and subcloud's
|
|
controller-1 is unlocked and active. In this case the pre-check
|
|
should transition to the 'creating vim strategy' state.
|
|
"""
|
|
|
|
# upgrade state is upgrading-controllers
|
|
upgrade = FakeUpgrade(state=consts.UPGRADE_STATE_UPGRADING_CONTROLLERS)
|
|
self.sysinv_client.get_upgrades.return_value = [upgrade, ]
|
|
|
|
# subcloud's controller-0 is unlocked and active
|
|
# subcloud's controller-1 is unlocked and standby
|
|
self.sysinv_client.get_host.side_effect = [CONTROLLER_0_UNLOCKED_AND_STANDBY,
|
|
CONTROLLER_1_UNLOCKED_AND_ACTIVE]
|
|
|
|
# invoke the strategy state operation on the orch thread
|
|
self.worker.perform_state_action(self.strategy_step)
|
|
|
|
# Verify the expected next state happened (upgrading)
|
|
self.assert_step_updated(self.strategy_step.subcloud_id,
|
|
consts.STRATEGY_STATE_CREATING_VIM_UPGRADE_STRATEGY)
|
|
|
|
def test_upgrade_pre_check_subcloud_some_hosts_not_upgraded(self):
|
|
"""Test pre check step which jumps to creating vim strategy state.
|
|
|
|
The upgrade state is upgrading-hosts and subcloud's controller-0
|
|
is not upgraded. In this case the pre-check should transition to
|
|
the 'creating vim strategy' state.
|
|
"""
|
|
|
|
# upgrade state is upgrading-hosts
|
|
upgrade = FakeUpgrade(state=consts.UPGRADE_STATE_UPGRADING_HOSTS)
|
|
self.sysinv_client.get_upgrades.return_value = [upgrade, ]
|
|
|
|
# subcloud's controller-0 is unlocked, standby and not upgraded
|
|
# subcloud's controller-1 is unlocked, active and upgraded
|
|
self.sysinv_client.get_host.side_effect = [CONTROLLER_0_NOT_UPGRADED,
|
|
CONTROLLER_1_UPGRADED_ACTIVE]
|
|
|
|
self.sysinv_client.get_hosts.return_value = [CONTROLLER_0_NOT_UPGRADED,
|
|
CONTROLLER_1_UPGRADED_ACTIVE, ]
|
|
|
|
# invoke the strategy state operation on the orch thread
|
|
self.worker.perform_state_action(self.strategy_step)
|
|
|
|
# Verify the expected next state happened (upgrading)
|
|
self.assert_step_updated(self.strategy_step.subcloud_id,
|
|
consts.STRATEGY_STATE_CREATING_VIM_UPGRADE_STRATEGY)
|
|
|
|
def test_upgrade_pre_check_jumps_to_swacting_to_controller_0(self):
|
|
"""Test pre check step which jumps to swacting to controller-0 state.
|
|
|
|
The upgrade state is upgrading-hosts, all subcloud hosts are
|
|
upgraded, and subcloud's controller-0 is standby controller.
|
|
In this case the pre-check should transition to the 'swacting
|
|
to controller-0' state.
|
|
"""
|
|
|
|
# upgrade state is upgrading-hosts
|
|
upgrade = FakeUpgrade(state=consts.UPGRADE_STATE_UPGRADING_HOSTS)
|
|
self.sysinv_client.get_upgrades.return_value = [upgrade, ]
|
|
|
|
# subcloud's controller-0 is unlocked, standby and upgraded
|
|
# subcloud's controller-1 is unlocked, active and upgraded
|
|
self.sysinv_client.get_host.side_effect = [CONTROLLER_0_UPGRADED_STANDBY,
|
|
CONTROLLER_1_UPGRADED_ACTIVE]
|
|
|
|
self.sysinv_client.get_hosts.return_value = [CONTROLLER_0_UPGRADED_STANDBY,
|
|
CONTROLLER_1_UPGRADED_ACTIVE, ]
|
|
|
|
# invoke the strategy state operation on the orch thread
|
|
self.worker.perform_state_action(self.strategy_step)
|
|
|
|
# Verify the expected next state happened (upgrading)
|
|
self.assert_step_updated(self.strategy_step.subcloud_id,
|
|
consts.STRATEGY_STATE_SWACTING_TO_CONTROLLER_0)
|
|
|
|
def test_upgrade_pre_check_jumps_to_activating_upgrade(self):
|
|
"""Test pre check step which jumps to activating upgrade state.
|
|
|
|
The upgrade state is upgrading-hosts, all subcloud hosts are
|
|
upgraded, and subcloud's controller-0 is active controller.
|
|
In this case the pre-check should transition to the 'activating
|
|
upgrade' state.
|
|
"""
|
|
|
|
# upgrade state is upgrading-hosts
|
|
upgrade = FakeUpgrade(state=consts.UPGRADE_STATE_UPGRADING_HOSTS)
|
|
self.sysinv_client.get_upgrades.return_value = [upgrade, ]
|
|
|
|
# subcloud's controller-0 is unlocked, active and upgraded
|
|
# subcloud's controller-1 is unlocked, standby and upgraded
|
|
self.sysinv_client.get_host.side_effect = [CONTROLLER_0_UPGRADED_ACTIVE,
|
|
CONTROLLER_1_UPGRADED_STANDBY]
|
|
|
|
self.sysinv_client.get_hosts.return_value = [CONTROLLER_0_UPGRADED_ACTIVE,
|
|
CONTROLLER_1_UPGRADED_STANDBY, ]
|
|
|
|
# invoke the strategy state operation on the orch thread
|
|
self.worker.perform_state_action(self.strategy_step)
|
|
|
|
# Verify the expected next state happened (upgrading)
|
|
self.assert_step_updated(self.strategy_step.subcloud_id,
|
|
consts.STRATEGY_STATE_ACTIVATING_UPGRADE)
|
|
|
|
def test_upgrade_pre_check_activation_failed_controller_0_active(self):
|
|
"""Test pre check step which jumps to activating upgrade state.
|
|
|
|
The upgrade state is activation-failed, all subcloud hosts are
|
|
upgraded, and subcloud's controller-0 is active controller.
|
|
In this case the pre-check should transition to the 'activating
|
|
upgrade' state.
|
|
"""
|
|
|
|
# upgrade state is activation-failed
|
|
upgrade = FakeUpgrade(state=consts.UPGRADE_STATE_ACTIVATION_FAILED)
|
|
self.sysinv_client.get_upgrades.return_value = [upgrade, ]
|
|
|
|
# subcloud's controller-0 is unlocked, active and upgraded
|
|
# subcloud's controller-1 is unlocked, standby and upgraded
|
|
self.sysinv_client.get_host.side_effect = [CONTROLLER_0_UPGRADED_ACTIVE,
|
|
CONTROLLER_1_UPGRADED_STANDBY]
|
|
|
|
# invoke the strategy state operation on the orch thread
|
|
self.worker.perform_state_action(self.strategy_step)
|
|
|
|
# Verify the expected next state happened (upgrading)
|
|
self.assert_step_updated(self.strategy_step.subcloud_id,
|
|
consts.STRATEGY_STATE_ACTIVATING_UPGRADE)
|
|
|
|
def test_upgrade_pre_check_activation_failed_controller_1_active(self):
|
|
"""Test pre check step which jumps to activating upgrade state.
|
|
|
|
The upgrade state is activation-failed, all subcloud hosts are
|
|
upgraded, and subcloud's controller-0 is standby controller.
|
|
In this case the pre-check should transition to the 'swacting to
|
|
controller-0' upgrade' state.
|
|
"""
|
|
|
|
# upgrade state is activation-failed
|
|
upgrade = FakeUpgrade(state=consts.UPGRADE_STATE_ACTIVATION_FAILED)
|
|
self.sysinv_client.get_upgrades.return_value = [upgrade, ]
|
|
|
|
# subcloud's controller-0 is unlocked, standby and upgraded
|
|
# subcloud's controller-1 is unlocked, active and upgraded
|
|
self.sysinv_client.get_host.side_effect = [CONTROLLER_0_UPGRADED_STANDBY,
|
|
CONTROLLER_1_UPGRADED_ACTIVE]
|
|
|
|
# invoke the strategy state operation on the orch thread
|
|
self.worker.perform_state_action(self.strategy_step)
|
|
|
|
# Verify the expected next state happened (upgrading)
|
|
self.assert_step_updated(self.strategy_step.subcloud_id,
|
|
consts.STRATEGY_STATE_SWACTING_TO_CONTROLLER_0)
|
|
|
|
def test_upgrade_pre_check_jumps_to_completing_upgrade_state(self):
|
|
"""Test pre check step which jumps to completing upgrade state.
|
|
|
|
The upgrade state is activation-complete, all subcloud hosts are
|
|
upgraded, and subcloud's controller-0 is active controller.
|
|
In this case the pre-check should transition to the 'swacting to
|
|
controller-0' upgrade' state.
|
|
"""
|
|
|
|
# upgrade state is activation-complete
|
|
upgrade = FakeUpgrade(state=consts.UPGRADE_STATE_ACTIVATION_COMPLETE)
|
|
self.sysinv_client.get_upgrades.return_value = [upgrade, ]
|
|
|
|
# subcloud's controller-0 is unlocked, active and upgraded
|
|
# subcloud's controller-1 is unlocked, standby and upgraded
|
|
self.sysinv_client.get_host.side_effect = [CONTROLLER_0_UPGRADED_ACTIVE,
|
|
CONTROLLER_1_UPGRADED_STANDBY]
|
|
|
|
# invoke the strategy state operation on the orch thread
|
|
self.worker.perform_state_action(self.strategy_step)
|
|
|
|
# Verify the expected next state happened (upgrading)
|
|
self.assert_step_updated(self.strategy_step.subcloud_id,
|
|
consts.STRATEGY_STATE_COMPLETING_UPGRADE)
|