From 0888d4c2a2d3300b4252ad4b405bee2fa752e42c Mon Sep 17 00:00:00 2001 From: Julien Le Jeune Date: Wed, 10 Sep 2025 11:16:29 +0200 Subject: [PATCH] Adds regression test for bug LP#2044235 Related-bug: #2044235 Change-Id: Ic63ac71c3253fb24ffef8c954bc86fcb46e59ad7 Signed-off-by: Julien Le Jeune (cherry picked from commit efc8a124218a628d0bd61ad266a0735c82ff8015) (cherry picked from commit 326b5910f547e80acc2bd5b4c431889f2d6e3870) --- .../regressions/test_bug_2044235.py | 61 +++++++++++++++++++ nova/tests/unit/compute/test_compute_mgr.py | 20 ++++++ 2 files changed, 81 insertions(+) create mode 100644 nova/tests/functional/regressions/test_bug_2044235.py diff --git a/nova/tests/functional/regressions/test_bug_2044235.py b/nova/tests/functional/regressions/test_bug_2044235.py new file mode 100644 index 000000000000..c81847f58fe8 --- /dev/null +++ b/nova/tests/functional/regressions/test_bug_2044235.py @@ -0,0 +1,61 @@ +# Copyright 2021, Canonical, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + + +from unittest import mock + +from nova.tests.functional.api import client +from nova.tests.functional import integrated_helpers + + +class TestMessagingTimeoutDuringLiveMigrationCheck( + integrated_helpers._IntegratedTestBase +): + """Reproducer for bug #2044235 + + This regression test demonstrates that nova-condutor puts instances in + error state for any raised error in check_can_live_migrate_source function + during check_can_live_migrate_destination step. + """ + + # Default self.api to the self.admin_api as live migration is admin only + ADMIN_API = True + microversion = "latest" + + def setUp(self): + super(TestMessagingTimeoutDuringLiveMigrationCheck, self).setUp() + + def _setup_compute_service(self): + self._start_compute("compute-1") + self._start_compute("compute-2") + + def test_source_error_during_pre_live_migration(self): + # Create an instance on compute-1 + server = self._create_server(host="compute-1", networks="none") + self._wait_for_state_change(server, "ACTIVE") + + with mock.patch.object( + self.computes["compute-2"].compute_rpcapi, + "check_can_live_migrate_source", + side_effect=Exception, + ): + # Migrate the instance and wait until the migration errors out + # thanks to our mocked version of check_can_live_migrate_source + self.assertRaises( + client.OpenStackApiException, + self._live_migrate, server, "failed" + ) + + # bug lp-2044235 - instance is in ERROR but it should not + self._wait_for_state_change(server, "ERROR") diff --git a/nova/tests/unit/compute/test_compute_mgr.py b/nova/tests/unit/compute/test_compute_mgr.py index 43b359e2f544..76fcce134fe8 100644 --- a/nova/tests/unit/compute/test_compute_mgr.py +++ b/nova/tests/unit/compute/test_compute_mgr.py @@ -5400,6 +5400,26 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase, self.compute.check_can_live_migrate_destination, self.context, instance, None, None, None, None) + @mock.patch('nova.objects.InstanceGroup.get_by_instance_uuid', mock.Mock( + side_effect=exception.InstanceGroupNotFound(group_uuid=''))) + @mock.patch.object(compute_utils, 'add_instance_fault_from_exc') + def test_check_can_live_migrate_destination_precheck_exception( + self, mock_fail_db): + @mock.patch.object(self.compute, '_get_compute_info') + def _do_test(mock_get): + instance = fake_instance.fake_instance_obj( + self.context, host=self.compute.host, + vm_state=vm_states.ACTIVE, node='fake-node') + + with mock.patch.object(self.compute.compute_rpcapi, + 'check_can_live_migrate_source', + side_effect=messaging.MessagingTimeout): + self.assertRaises( + messaging.MessagingTimeout, + self.compute.check_can_live_migrate_destination, + self.context, instance, None, None, None, None) + _do_test() + def test_dest_can_numa_live_migrate(self): positive_dest_check_data = objects.LibvirtLiveMigrateData( dst_supports_numa_live_migration=True)