nova/nova/tests/functional/libvirt/test_machine_type.py

202 lines
7.6 KiB
Python

# 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.
import copy
import fixtures
from oslo_utils.fixture import uuidsentinel
from nova import context as nova_context
from nova import objects
from nova.tests.functional.libvirt import base
from nova.virt.libvirt import machine_type_utils
class LibvirtMachineTypeTest(base.ServersTestBase):
microversion = 'latest'
def setUp(self):
super().setUp()
self.context = nova_context.get_admin_context()
# Add the q35 image to the glance fixture
hw_machine_type_q35_image = copy.deepcopy(self.glance.image1)
hw_machine_type_q35_image['id'] = uuidsentinel.q35_image_id
hw_machine_type_q35_image['properties']['hw_machine_type'] = 'q35'
self.glance.create(self.context, hw_machine_type_q35_image)
# Create a pass-through mock around _get_guest_config to capture the
# config of an instance so we can assert things about it later.
# TODO(lyarwood): This seems like a useful thing to do in the libvirt
# func tests for all computes we start?
self.start_compute()
self.guest_configs = {}
orig_get_config = self.computes['compute1'].driver._get_guest_config
def _get_guest_config(_self, *args, **kwargs):
guest_config = orig_get_config(*args, **kwargs)
instance = args[0]
self.guest_configs[instance.uuid] = guest_config
return self.guest_configs[instance.uuid]
self.useFixture(fixtures.MonkeyPatch(
'nova.virt.libvirt.LibvirtDriver._get_guest_config',
_get_guest_config))
def _create_servers(self):
server_with = self._create_server(
image_uuid=uuidsentinel.q35_image_id,
networks='none',
)
server_without = self._create_server(
image_uuid=self.glance.image1['id'],
networks='none',
)
return (server_with, server_without)
def _assert_machine_type(self, server_id, expected_machine_type):
instance = objects.Instance.get_by_uuid(self.context, server_id)
self.assertEqual(
expected_machine_type,
instance.image_meta.properties.hw_machine_type
)
self.assertEqual(
expected_machine_type,
instance.system_metadata['image_hw_machine_type']
)
self.assertEqual(
expected_machine_type,
self.guest_configs[server_id].os_mach_type
)
def _unset_machine_type(self, server_id):
instance = objects.Instance.get_by_uuid(
self.context,
server_id,
)
instance.system_metadata.pop('image_hw_machine_type')
instance.save()
def test_init_host_register_machine_type(self):
"""Assert that the machine type of an instance is recorded during
init_host if not already captured by an image prop.
"""
self.flags(hw_machine_type='x86_64=pc', group='libvirt')
server_with, server_without = self._create_servers()
self._assert_machine_type(server_with['id'], 'q35')
self._assert_machine_type(server_without['id'], 'pc')
# Stop n-cpu and clear the recorded machine type from server_without to
# allow init_host to register the machine type.
self.computes['compute1'].stop()
self._unset_machine_type(server_without['id'])
self.flags(hw_machine_type='x86_64=pc-q35-1.2.3', group='libvirt')
# Restart the compute
self.computes['compute1'].start()
# Assert the server_with remains pinned to q35
self._assert_machine_type(server_with['id'], 'q35')
# reboot the server so the config is rebuilt and _assert_machine_type
# is able to pass. This just keeps the tests clean.
self._reboot_server(server_without, hard=True)
# Assert server_without now has a machine type of pc-q35-1.2.3 picked
# up from [libvirt]hw_machine_type during init_host
self._assert_machine_type(server_without['id'], 'pc-q35-1.2.3')
def test_machine_type_after_config_change(self):
"""Assert new instances pick up a new default machine type after the
config has been updated.
"""
self.flags(hw_machine_type='x86_64=pc', group='libvirt')
server_with, server_without = self._create_servers()
self._assert_machine_type(server_with['id'], 'q35')
self._assert_machine_type(server_without['id'], 'pc')
self.flags(hw_machine_type='x86_64=pc-q35-1.2.3', group='libvirt')
server_with_new, server_without_new = self._create_servers()
self._assert_machine_type(server_with_new['id'], 'q35')
self._assert_machine_type(server_without_new['id'], 'pc-q35-1.2.3')
def test_machine_type_after_server_rebuild(self):
"""Assert that the machine type of an instance changes with a full
rebuild of the instance pointing at a new image.
"""
self.flags(hw_machine_type='x86_64=pc', group='libvirt')
server_with, server_without = self._create_servers()
self._assert_machine_type(server_with['id'], 'q35')
self._assert_machine_type(server_without['id'], 'pc')
# rebuild each server with the opposite image
self._rebuild_server(
server_with,
'155d900f-4e14-4e4c-a73d-069cbf4541e6',
)
self._rebuild_server(
server_without,
uuidsentinel.q35_image_id
)
# Assert that the machine types were updated during the rebuild
self._assert_machine_type(server_with['id'], 'pc')
self._assert_machine_type(server_without['id'], 'q35')
def _test_machine_type_after_server_reboot(self, hard=False):
"""Assert that the recorded machine types don't change with the
reboot of a server, even when the underlying config changes.
"""
self.flags(hw_machine_type='x86_64=pc', group='libvirt')
server_with, server_without = self._create_servers()
self._assert_machine_type(server_with['id'], 'q35')
self._assert_machine_type(server_without['id'], 'pc')
self.flags(hw_machine_type='x86_64=pc-q35-1.2.3', group='libvirt')
self._reboot_server(server_with, hard=hard)
self._reboot_server(server_without, hard=hard)
# Assert that the machine types don't change after a reboot
self._assert_machine_type(server_with['id'], 'q35')
self._assert_machine_type(server_without['id'], 'pc')
def test_machine_type_after_server_soft_reboot(self):
self._test_machine_type_after_server_reboot()
def test_machine_type_after_server_hard_reboot(self):
self._test_machine_type_after_server_reboot(hard=True)
def test_machine_type_get(self):
self.flags(hw_machine_type='x86_64=pc', group='libvirt')
server_with, server_without = self._create_servers()
self.assertEqual(
'q35',
machine_type_utils.get_machine_type(
self.context, server_with['id']
)
)
self.assertEqual(
'pc',
machine_type_utils.get_machine_type(
self.context, server_without['id']
)
)