summaryrefslogtreecommitdiff
path: root/nova/virt/fake.py
diff options
context:
space:
mode:
Diffstat (limited to 'nova/virt/fake.py')
-rw-r--r--nova/virt/fake.py105
1 files changed, 100 insertions, 5 deletions
diff --git a/nova/virt/fake.py b/nova/virt/fake.py
index 41524b69d2..bf7dc8fc72 100644
--- a/nova/virt/fake.py
+++ b/nova/virt/fake.py
@@ -32,6 +32,7 @@ import fixtures
import os_resource_classes as orc
from oslo_log import log as logging
from oslo_serialization import jsonutils
+from oslo_utils.fixture import uuidsentinel as uuids
from oslo_utils import versionutils
from nova.compute import power_state
@@ -48,6 +49,7 @@ from nova.objects import migrate_data
from nova.virt import driver
from nova.virt import hardware
from nova.virt.ironic import driver as ironic
+import nova.virt.node
from nova.virt import virtapi
CONF = nova.conf.CONF
@@ -116,6 +118,7 @@ class FakeDriver(driver.ComputeDriver):
"supports_trusted_certs": True,
"supports_pcpus": False,
"supports_accelerators": True,
+ "supports_remote_managed_ports": True,
# Supported image types
"supports_image_type_raw": True,
@@ -159,8 +162,8 @@ class FakeDriver(driver.ComputeDriver):
self._host = host
# NOTE(gibi): this is unnecessary complex and fragile but this is
# how many current functional sample tests expect the node name.
- self._nodes = (['fake-mini'] if self._host == 'compute'
- else [self._host])
+ self._set_nodes(['fake-mini'] if self._host == 'compute'
+ else [self._host])
def _set_nodes(self, nodes):
# NOTE(gibi): this is not part of the driver interface but used
@@ -503,6 +506,12 @@ class FakeDriver(driver.ComputeDriver):
host_status['host_hostname'] = nodename
host_status['host_name_label'] = nodename
host_status['cpu_info'] = jsonutils.dumps(cpu_info)
+ # NOTE(danms): Because the fake driver runs on the same host
+ # in tests, potentially with multiple nodes, we need to
+ # control our node uuids. Make sure we return a unique and
+ # consistent uuid for each node we are responsible for to
+ # avoid the persistent local node identity from taking over.
+ host_status['uuid'] = str(getattr(uuids, 'node_%s' % nodename))
return host_status
def update_provider_tree(self, provider_tree, nodename, allocations=None):
@@ -645,6 +654,10 @@ class FakeDriver(driver.ComputeDriver):
def get_available_nodes(self, refresh=False):
return self._nodes
+ def get_nodenames_by_uuid(self, refresh=False):
+ return {str(getattr(uuids, 'node_%s' % n)): n
+ for n in self.get_available_nodes()}
+
def instance_on_disk(self, instance):
return False
@@ -763,7 +776,7 @@ class PredictableNodeUUIDDriver(SmallFakeDriver):
PredictableNodeUUIDDriver, self).get_available_resource(nodename)
# This is used in ComputeNode.update_from_virt_driver which is called
# from the ResourceTracker when creating a ComputeNode.
- resources['uuid'] = uuid.uuid5(uuid.NAMESPACE_DNS, nodename)
+ resources['uuid'] = str(uuid.uuid5(uuid.NAMESPACE_DNS, nodename))
return resources
@@ -890,6 +903,36 @@ class FakeLiveMigrateDriverWithNestedCustomResources(
class FakeDriverWithPciResources(SmallFakeDriver):
+ """NOTE: this driver provides symmetric compute nodes. Each compute will
+ have the same resources with the same addresses. It is dangerous as using
+ this driver can hide issues when in an asymmetric environment nova fails to
+ update entities according to the host specific addresses (e.g. pci_slot of
+ the neutron port bindings).
+
+ The current non virt driver specific functional test environment has many
+ shortcomings making it really hard to simulate host specific virt drivers.
+
+ 1) The virt driver is instantiated by the service logic from the name of
+ the driver class. This makes passing input to the driver instance from the
+ test at init time pretty impossible. This could be solved with some
+ fixtures around nova.virt.driver.load_compute_driver()
+
+ 2) The compute service access the hypervisor not only via the virt
+ interface but also reads the sysfs of the host. So simply providing a fake
+ virt driver instance is not enough to isolate simulated compute services
+ that are running on the same host. Also these low level sysfs reads are not
+ having host specific information in the call params. So simply mocking the
+ low level call does not give a way to provide host specific return values.
+
+ 3) CONF is global, and it is read dynamically by the driver. So
+ providing host specific CONF to driver instances without race conditions
+ between the drivers are extremely hard especially if periodic tasks are
+ enabled.
+
+ The libvirt based functional test env under nova.tests.functional.libvirt
+ has better support to create asymmetric environments. So please consider
+ using that if possible instead.
+ """
PCI_ADDR_PF1 = '0000:01:00.0'
PCI_ADDR_PF1_VF1 = '0000:01:00.1'
@@ -905,7 +948,7 @@ class FakeDriverWithPciResources(SmallFakeDriver):
def setUp(self):
super(FakeDriverWithPciResources.
FakeDriverWithPciResourcesConfigFixture, self).setUp()
- # Set passthrough_whitelist before the compute node starts to match
+ # Set device_spec before the compute node starts to match
# with the PCI devices reported by this fake driver.
# NOTE(gibi): 0000:01:00 is tagged to physnet1 and therefore not a
@@ -920,7 +963,7 @@ class FakeDriverWithPciResources(SmallFakeDriver):
# Having two PFs on the same physnet will allow us to test the
# placement allocation - physical allocation matching based on the
# bandwidth allocation in the future.
- CONF.set_override('passthrough_whitelist', override=[
+ CONF.set_override('device_spec', override=[
jsonutils.dumps(
{
"address": {
@@ -954,6 +997,19 @@ class FakeDriverWithPciResources(SmallFakeDriver):
],
group='pci')
+ # These mocks should be removed after bug
+ # https://bugs.launchpad.net/nova/+bug/1961587 has been fixed and
+ # every SRIOV device related information is transferred through the
+ # virt driver and the PciDevice object instead of queried with
+ # sysfs calls by the network.neutron.API code.
+ self.useFixture(fixtures.MockPatch(
+ 'nova.pci.utils.get_mac_by_pci_address',
+ return_value='52:54:00:1e:59:c6'))
+
+ self.useFixture(fixtures.MockPatch(
+ 'nova.pci.utils.get_vf_num_by_pci_address',
+ return_value=1))
+
def get_available_resource(self, nodename):
host_status = super(
FakeDriverWithPciResources, self).get_available_resource(nodename)
@@ -1055,3 +1111,42 @@ class FakeDriverWithCaching(FakeDriver):
else:
self.cached_images.add(image_id)
return True
+
+
+class EphEncryptionDriver(MediumFakeDriver):
+ capabilities = dict(
+ FakeDriver.capabilities,
+ supports_ephemeral_encryption=True)
+
+
+class EphEncryptionDriverLUKS(MediumFakeDriver):
+ capabilities = dict(
+ FakeDriver.capabilities,
+ supports_ephemeral_encryption=True,
+ supports_ephemeral_encryption_luks=True)
+
+
+class EphEncryptionDriverPLAIN(MediumFakeDriver):
+ capabilities = dict(
+ FakeDriver.capabilities,
+ supports_ephemeral_encryption=True,
+ supports_ephemeral_encryption_plain=True)
+
+
+class FakeDriverWithoutFakeNodes(FakeDriver):
+ """FakeDriver that behaves like a real single-node driver.
+
+ This behaves like a real virt driver from the perspective of its
+ nodes, with a stable nodename and use of the global node identity
+ stuff to provide a stable node UUID.
+ """
+
+ def get_available_resource(self, nodename):
+ resources = super().get_available_resource(nodename)
+ resources['uuid'] = nova.virt.node.get_local_node_uuid()
+ return resources
+
+ def get_nodenames_by_uuid(self, refresh=False):
+ return {
+ nova.virt.node.get_local_node_uuid(): self.get_available_nodes()[0]
+ }