Skip to content

Commit 95fc161

Browse files
committed
Add regression test for bug #1899649
Related-Bug: #1899649 Change-Id: If795b603d812917c9257ee5166a979c1fd6687f3 (cherry picked from commit 770c139)
1 parent 8fab5fc commit 95fc161

File tree

1 file changed

+110
-0
lines changed

1 file changed

+110
-0
lines changed
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
# Copyright 2020, Red Hat, Inc. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
4+
# not use this file except in compliance with the License. You may obtain
5+
# a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12+
# License for the specific language governing permissions and limitations
13+
# under the License.
14+
15+
from nova.tests import fixtures as nova_fixtures
16+
from nova.tests.functional.libvirt import base
17+
from nova.tests.unit.virt.libvirt import fakelibvirt
18+
19+
20+
class TestVolAttachmentsAfterFailureToScheduleOrBuild(base.ServersTestBase):
21+
"""Regression test for bug .
22+
23+
This regression test aims to ensure a volume attachment remains in place
24+
after a failure to either schedule a server or when building a server
25+
directly on a compute after skipping the scheduler.
26+
27+
A volume attachment is required to remain after such failures to ensure the
28+
volume itself remains marked as reserved.
29+
30+
To ensure this is as accurate as possible the tests use the libvirt
31+
functional base class to mimic a real world example with NUMA nodes being
32+
requested via flavor extra specs. The underlying compute being unable to
33+
meet this request ensuring a failure.
34+
"""
35+
36+
microversion = 'latest'
37+
38+
def setUp(self):
39+
super().setUp()
40+
41+
# Launch a single libvirt based compute service with a single NUMA node
42+
host_info = fakelibvirt.HostInfo(
43+
cpu_nodes=1, cpu_sockets=1, cpu_cores=2, kB_mem=15740000)
44+
self.start_compute(host_info=host_info, hostname='compute1')
45+
46+
# Use a flavor requesting 2 NUMA nodes that we know will always fail
47+
self.flavor_id = self._create_flavor(extra_spec={'hw:numa_nodes': '2'})
48+
49+
# Craft a common bfv server request for use within each test
50+
self.volume_id = nova_fixtures.CinderFixture.IMAGE_BACKED_VOL
51+
self.server = {
52+
'name': 'test',
53+
'flavorRef': self.flavor_id,
54+
'imageRef': '',
55+
'networks': 'none',
56+
'block_device_mapping_v2': [{
57+
'source_type': 'volume',
58+
'destination_type': 'volume',
59+
'boot_index': 0,
60+
'uuid': self.volume_id}]
61+
}
62+
63+
def _assert_failure_and_volume_attachments(self, server):
64+
# Assert that the server is in an ERROR state
65+
self._wait_for_state_change(server, 'ERROR')
66+
67+
# Assert that the volume is in a reserved state. As this isn't modelled
68+
# by the CinderFixture we just assert that a single volume attachment
69+
# remains after the failure and that it is referenced by the server.
70+
attachments = self.cinder.volume_to_attachment.get(self.volume_id)
71+
self.assertEqual(1, len(attachments))
72+
self.assertIn(
73+
self.volume_id, self.cinder.volume_ids_for_instance(server['id']))
74+
75+
def test_failure_to_schedule(self):
76+
# Assert that a volume attachment remains after a failure to schedule
77+
server = self.api.post_server({'server': self.server})
78+
self._assert_failure_and_volume_attachments(server)
79+
80+
def test_failure_to_schedule_with_az(self):
81+
# Assert that a volume attachment remains after a failure to schedule
82+
# with the addition of an availability_zone in the request
83+
self.server['availability_zone'] = 'nova'
84+
server = self.api.post_server({'server': self.server})
85+
self._assert_failure_and_volume_attachments(server)
86+
87+
def test_failure_to_schedule_with_host(self):
88+
# Assert that a volume attachment remains after a failure to schedule
89+
# using the optional host parameter introduced in microversion 2.74
90+
self.server['host'] = 'compute1'
91+
server = self.admin_api.post_server({'server': self.server})
92+
self._assert_failure_and_volume_attachments(server)
93+
94+
def test_failure_to_build_with_az_and_host(self):
95+
# Assert that a volume attachments does not remain after a failure to
96+
# build and reschedule by providing an availability_zone *and* host,
97+
# skipping the scheduler. This is bug #1899649.
98+
self.server['availability_zone'] = 'nova:compute1'
99+
server = self.admin_api.post_server({'server': self.server})
100+
101+
# Assert the server ends up in an ERROR state
102+
self._wait_for_state_change(server, 'ERROR')
103+
104+
# FIXME(lyarwood): A single volume attachment should be present for the
105+
# instance at this stage as the volume *can* otherwise be marked as
106+
# available within Cinder if it isn't multi-attached.
107+
attachments = self.cinder.volume_to_attachment.get(self.volume_id)
108+
self.assertEqual(0, len(attachments))
109+
self.assertNotIn(
110+
self.volume_id, self.cinder.volume_ids_for_instance(server['id']))

0 commit comments

Comments
 (0)