|
|
|
@ -370,22 +370,20 @@ class CPUThreadPolicyTest(BasePinningTest):
|
|
|
|
|
"host have HyperThreading enabled?")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class EmulatorExtraCPUTest(BasePinningTest):
|
|
|
|
|
class EmulatorThreadTest(BasePinningTest, numa_helper.NUMAHelperMixin):
|
|
|
|
|
|
|
|
|
|
vcpus = 1
|
|
|
|
|
min_microversion = '2.74'
|
|
|
|
|
|
|
|
|
|
def setUp(self):
|
|
|
|
|
super(EmulatorExtraCPUTest, self).setUp()
|
|
|
|
|
# Iterate over cpu_topology and find the NUMA Node with the most
|
|
|
|
|
# pCPUs and set that as the NUMA Node to use throughout the test
|
|
|
|
|
largest_numa_node = max(CONF.whitebox_hardware.cpu_topology.items(),
|
|
|
|
|
key=lambda k: len(k[1]))
|
|
|
|
|
self.numa_to_use = largest_numa_node[0]
|
|
|
|
|
super(EmulatorThreadTest, self).setUp()
|
|
|
|
|
self.dedicated_cpus_per_numa = \
|
|
|
|
|
CONF.whitebox_hardware.dedicated_cpus_per_numa
|
|
|
|
|
self.shared_cpus_per_numa = \
|
|
|
|
|
CONF.whitebox_hardware.shared_cpus_per_numa
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
def skip_checks(cls):
|
|
|
|
|
super(EmulatorExtraCPUTest, cls).skip_checks()
|
|
|
|
|
super(EmulatorThreadTest, cls).skip_checks()
|
|
|
|
|
if not utils.is_extension_enabled('OS-FLV-EXT-DATA', 'compute'):
|
|
|
|
|
msg = "OS-FLV-EXT-DATA extension not enabled."
|
|
|
|
|
raise cls.skipException(msg)
|
|
|
|
@ -394,7 +392,7 @@ class EmulatorExtraCPUTest(BasePinningTest):
|
|
|
|
|
raise cls.skipException(msg)
|
|
|
|
|
|
|
|
|
|
def create_flavor(self, threads_policy, vcpus):
|
|
|
|
|
flavor = super(EmulatorExtraCPUTest,
|
|
|
|
|
flavor = super(EmulatorThreadTest,
|
|
|
|
|
self).create_flavor(vcpus=vcpus, disk=1)
|
|
|
|
|
|
|
|
|
|
specs = {
|
|
|
|
@ -404,133 +402,63 @@ class EmulatorExtraCPUTest(BasePinningTest):
|
|
|
|
|
self.flavors_client.set_flavor_extra_spec(flavor['id'], **specs)
|
|
|
|
|
return flavor
|
|
|
|
|
|
|
|
|
|
def get_server_emulator_threads(self, server_id):
|
|
|
|
|
"""Get the host CPU numbers to which the server's emulator threads are
|
|
|
|
|
pinned.
|
|
|
|
|
|
|
|
|
|
:param server_id: The instance UUID to look up.
|
|
|
|
|
:return emulator_threads: A set of host CPU numbers.
|
|
|
|
|
"""
|
|
|
|
|
root = self.get_server_xml(server_id)
|
|
|
|
|
|
|
|
|
|
emulatorpins = root.findall('./cputune/emulatorpin')
|
|
|
|
|
emulator_threads = set()
|
|
|
|
|
for pin in emulatorpins:
|
|
|
|
|
emulator_threads |= hardware.parse_cpu_spec(
|
|
|
|
|
pin.get('cpuset'))
|
|
|
|
|
|
|
|
|
|
return emulator_threads
|
|
|
|
|
|
|
|
|
|
def policy_share_cpu_shared_set(self, section, pin_set_mode):
|
|
|
|
|
def test_policy_share_cpu_shared_set(self):
|
|
|
|
|
"""With policy set to share and cpu_share_set set, emulator threads
|
|
|
|
|
should be pinned to cpu_share_set.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
:param section: The nova.conf section to apply the pin_set
|
|
|
|
|
configuration
|
|
|
|
|
:param pin_set_mode: Which pCPU list mode to use when exposing
|
|
|
|
|
dedicated pCPU's to the guest, either vcpu_pin_set or cpu_dedicated_set
|
|
|
|
|
:param single_shared_cpu bool, wheter to use a single pCPU for the
|
|
|
|
|
shared set or a range of pCPUs for the shared_set range.
|
|
|
|
|
"""
|
|
|
|
|
# NOTE: this scenario is based around upstream BP:
|
|
|
|
|
# https://blueprints.launchpad.net/nova/+spec/overhead-pin-set and
|
|
|
|
|
# downstream BZ https://bugzilla.redhat.com/show_bug.cgi?id=1468004#c0
|
|
|
|
|
# which allows for multiple guest's emulator threads to share the same
|
|
|
|
|
# cpu_shared_set range
|
|
|
|
|
if len(CONF.whitebox_hardware.cpu_topology[self.numa_to_use]) < 3:
|
|
|
|
|
raise self.skipException('Test requires NUMA Node with 3 or more '
|
|
|
|
|
'CPUs to run')
|
|
|
|
|
dedicated_set = hardware.format_cpu_spec(
|
|
|
|
|
CONF.whitebox_hardware.cpu_topology[self.numa_to_use][:2])
|
|
|
|
|
if self.shared_cpus_per_numa == 0:
|
|
|
|
|
raise self.skipException('Test requires cpu_shared_set to be '
|
|
|
|
|
'configured on the compute hosts')
|
|
|
|
|
|
|
|
|
|
cpu_shared_set_str = hardware.format_cpu_spec(
|
|
|
|
|
CONF.whitebox_hardware.cpu_topology[self.numa_to_use][2:])
|
|
|
|
|
# Create a flavor using the shared threads_policy and create an
|
|
|
|
|
# instance
|
|
|
|
|
flavor = self.create_flavor(threads_policy='share',
|
|
|
|
|
vcpus=self.shared_cpus_per_numa)
|
|
|
|
|
|
|
|
|
|
hostname = self.list_compute_hosts()[0]
|
|
|
|
|
host_sm = clients.NovaServiceManager(
|
|
|
|
|
hostname, 'nova-compute', self.os_admin.services_client)
|
|
|
|
|
server = self.create_test_server(flavor=flavor['id'])
|
|
|
|
|
|
|
|
|
|
# Update the compute node's cpu_shared_set to cpu_shared_set_str and
|
|
|
|
|
# dedicated CPUs to the range found for dedicated_set
|
|
|
|
|
with host_sm.config_options((section, pin_set_mode, dedicated_set),
|
|
|
|
|
('compute', 'cpu_shared_set',
|
|
|
|
|
cpu_shared_set_str)):
|
|
|
|
|
# Determine the compute host the guest was scheduled to and gather
|
|
|
|
|
# the cpu shared set from the host
|
|
|
|
|
host = self.get_host_for_server(server['id'])
|
|
|
|
|
host_sm = clients.NovaServiceManager(host, 'nova-compute',
|
|
|
|
|
self.os_admin.services_client)
|
|
|
|
|
cpu_shared_set = host_sm.get_cpu_shared_set()
|
|
|
|
|
|
|
|
|
|
# Create a flavor using the shared threads_policy and two instances
|
|
|
|
|
# on the same host
|
|
|
|
|
flavor = self.create_flavor(threads_policy='share',
|
|
|
|
|
vcpus=self.vcpus)
|
|
|
|
|
server_a = self.create_test_server(
|
|
|
|
|
clients=self.os_admin,
|
|
|
|
|
flavor=flavor['id'],
|
|
|
|
|
host=hostname
|
|
|
|
|
)
|
|
|
|
|
server_b = self.create_test_server(
|
|
|
|
|
clients=self.os_admin,
|
|
|
|
|
flavor=flavor['id'],
|
|
|
|
|
host=hostname
|
|
|
|
|
)
|
|
|
|
|
# Gather the emulator threads from the server
|
|
|
|
|
emulator_threads = \
|
|
|
|
|
self.get_server_emulator_threads(server['id'])
|
|
|
|
|
|
|
|
|
|
# Gather the emulator threads from both servers
|
|
|
|
|
emulator_threads_a = \
|
|
|
|
|
self.get_server_emulator_threads(server_a['id'])
|
|
|
|
|
emulator_threads_b = \
|
|
|
|
|
self.get_server_emulator_threads(server_b['id'])
|
|
|
|
|
# Confirm the emulator threads from the server is equal to the host's
|
|
|
|
|
# cpu_shared_set
|
|
|
|
|
self.assertEqual(
|
|
|
|
|
cpu_shared_set, emulator_threads,
|
|
|
|
|
'Emulator threads for server %s is not the same as CPU set '
|
|
|
|
|
'%s' % (emulator_threads, cpu_shared_set))
|
|
|
|
|
|
|
|
|
|
# Confirm the emulator threads from server's A and B are both equal
|
|
|
|
|
# to cpu_shared_set
|
|
|
|
|
cpu_shared_set = hardware.parse_cpu_spec(cpu_shared_set_str)
|
|
|
|
|
self.assertEqual(
|
|
|
|
|
emulator_threads_a, cpu_shared_set,
|
|
|
|
|
'Emulator threads for server A %s are not the same as CPU set '
|
|
|
|
|
'%s' % (emulator_threads_a, cpu_shared_set))
|
|
|
|
|
self.delete_server(server['id'])
|
|
|
|
|
|
|
|
|
|
self.assertEqual(
|
|
|
|
|
emulator_threads_b, cpu_shared_set,
|
|
|
|
|
'Emulator threads for server B %s are not the same as CPU set '
|
|
|
|
|
'%s' % (emulator_threads_b, cpu_shared_set))
|
|
|
|
|
|
|
|
|
|
self.delete_server(server_a['id'])
|
|
|
|
|
self.delete_server(server_b['id'])
|
|
|
|
|
|
|
|
|
|
def policy_share_cpu_shared_unset(self, section, pin_set_mode):
|
|
|
|
|
def test_policy_share_cpu_shared_unset(self):
|
|
|
|
|
"""With policy set to share and cpu_share_set unset, emulator threads
|
|
|
|
|
should float over the instance's pCPUs.
|
|
|
|
|
|
|
|
|
|
:param section: The nova.conf section to apply the pin_set
|
|
|
|
|
configuration
|
|
|
|
|
:param pin_set_mode: Which pCPU list mode to use when exposing
|
|
|
|
|
dedicated pCPU's to the guest, either vcpu_pin_set or cpu_dedicated_set
|
|
|
|
|
"""
|
|
|
|
|
if len(CONF.whitebox_hardware.cpu_topology[self.numa_to_use]) < 2:
|
|
|
|
|
raise self.skipException('Test requires NUMA Node with 2 or more '
|
|
|
|
|
'CPUs to run')
|
|
|
|
|
if self.dedicated_cpus_per_numa < 2:
|
|
|
|
|
raise self.skipException(
|
|
|
|
|
'Need at least 2 or more pCPUs per NUMA allocated to the '
|
|
|
|
|
'cpu_dedicated_set of the compute host')
|
|
|
|
|
|
|
|
|
|
dedicated_set = hardware.format_cpu_spec(
|
|
|
|
|
CONF.whitebox_hardware.cpu_topology[self.numa_to_use][:2])
|
|
|
|
|
hostname = self.list_compute_hosts()[0]
|
|
|
|
|
host_sm = clients.NovaServiceManager(
|
|
|
|
|
hostname, 'nova-compute', self.os_admin.services_client)
|
|
|
|
|
|
|
|
|
|
# Update the compute node's cpu_shared_set to None and dedicated CPUs
|
|
|
|
|
# to the range found for dedicated_set
|
|
|
|
|
with host_sm.config_options((section, pin_set_mode, dedicated_set),
|
|
|
|
|
('compute', 'cpu_shared_set', None)):
|
|
|
|
|
with self.config_all_computes(('compute', 'cpu_shared_set', None)):
|
|
|
|
|
|
|
|
|
|
# Create a flavor using the shared threads_policy and two instances
|
|
|
|
|
# on the same host
|
|
|
|
|
flavor = self.create_flavor(threads_policy='share',
|
|
|
|
|
vcpus=self.vcpus)
|
|
|
|
|
server_a = self.create_test_server(
|
|
|
|
|
clients=self.os_admin,
|
|
|
|
|
flavor=flavor['id'],
|
|
|
|
|
host=hostname
|
|
|
|
|
)
|
|
|
|
|
flavor = self.create_flavor(
|
|
|
|
|
threads_policy='share',
|
|
|
|
|
vcpus=int(self.dedicated_cpus_per_numa / 2))
|
|
|
|
|
|
|
|
|
|
server_a = self.create_test_server(flavor=flavor['id'])
|
|
|
|
|
server_b = self.create_test_server(
|
|
|
|
|
clients=self.os_admin,
|
|
|
|
|
flavor=flavor['id'],
|
|
|
|
|
host=hostname
|
|
|
|
|
scheduler_hints={'same_host': server_a['id']}
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# Gather the emulator threads from server A and B. Then gather the
|
|
|
|
@ -555,212 +483,84 @@ class EmulatorExtraCPUTest(BasePinningTest):
|
|
|
|
|
'Threads %s not the same as CPU pins %s' % (emulator_threads_b,
|
|
|
|
|
cpu_pins_b))
|
|
|
|
|
|
|
|
|
|
# Confirm the pinned cpus from server a to do no intersect with
|
|
|
|
|
# server b
|
|
|
|
|
# Confirm the pinned pCPUs from server A do not intersect with
|
|
|
|
|
# the pinned pCPUs of server B
|
|
|
|
|
self.assertTrue(
|
|
|
|
|
cpu_pins_a.isdisjoint(cpu_pins_b),
|
|
|
|
|
'Different server pins overlap: %s and %s' % (cpu_pins_a,
|
|
|
|
|
cpu_pins_b))
|
|
|
|
|
|
|
|
|
|
self.delete_server(server_a['id'])
|
|
|
|
|
self.delete_server(server_b['id'])
|
|
|
|
|
|
|
|
|
|
def policy_isolate(self, section, pin_set_mode):
|
|
|
|
|
def test_policy_isolate(self):
|
|
|
|
|
"""With policy isolate, cpu_shared_set is ignored, and emulator threads
|
|
|
|
|
should be pinned to a pCPU distinct from the instance's pCPUs.
|
|
|
|
|
|
|
|
|
|
:param section: The nova.conf section to apply the pin_set
|
|
|
|
|
configuration
|
|
|
|
|
:param pin_set_mode: Which pCPU list mode to use when exposing
|
|
|
|
|
dedicated pCPU's to the guest, either vcpu_pin_set or cpu_dedicated_set
|
|
|
|
|
"""
|
|
|
|
|
if len(CONF.whitebox_hardware.cpu_topology[self.numa_to_use]) < 4:
|
|
|
|
|
raise self.skipException('Test requires NUMA Node with 4 or more '
|
|
|
|
|
'CPUs to run')
|
|
|
|
|
dedicated_set = \
|
|
|
|
|
set(CONF.whitebox_hardware.cpu_topology[self.numa_to_use])
|
|
|
|
|
dedicated_set_str = hardware.format_cpu_spec(dedicated_set)
|
|
|
|
|
if self.dedicated_cpus_per_numa < 2:
|
|
|
|
|
raise self.skipException(
|
|
|
|
|
'Need at least 2 or more pCPUs per NUMA allocated to the '
|
|
|
|
|
'cpu_dedicated_set of the compute host')
|
|
|
|
|
|
|
|
|
|
hostname = self.list_compute_hosts()[0]
|
|
|
|
|
host_sm = clients.NovaServiceManager(
|
|
|
|
|
hostname, 'nova-compute', self.os_admin.services_client)
|
|
|
|
|
# Create a flavor using the isolate threads_policy and then launch
|
|
|
|
|
# an instance with the flavor
|
|
|
|
|
flavor = self.create_flavor(threads_policy='isolate',
|
|
|
|
|
vcpus=(self.dedicated_cpus_per_numa - 1))
|
|
|
|
|
|
|
|
|
|
# Update the compute node's cpu_shared_set to None and dedicated CPUs
|
|
|
|
|
# to the range found for dedicated_set_str
|
|
|
|
|
with host_sm.config_options((section, pin_set_mode, dedicated_set_str),
|
|
|
|
|
('compute', 'cpu_shared_set', None)):
|
|
|
|
|
server = self.create_test_server(flavor=flavor['id'])
|
|
|
|
|
|
|
|
|
|
# Create a flavor using the isolate threads_policy and two
|
|
|
|
|
# instances on the same host
|
|
|
|
|
flavor = self.create_flavor(threads_policy='isolate',
|
|
|
|
|
vcpus=self.vcpus)
|
|
|
|
|
server_a = self.create_test_server(
|
|
|
|
|
clients=self.os_admin,
|
|
|
|
|
flavor=flavor['id'],
|
|
|
|
|
host=hostname
|
|
|
|
|
)
|
|
|
|
|
server_b = self.create_test_server(
|
|
|
|
|
clients=self.os_admin,
|
|
|
|
|
flavor=flavor['id'],
|
|
|
|
|
host=hostname
|
|
|
|
|
)
|
|
|
|
|
# Gather the emulator threads and the pinned PCPUs from the guest
|
|
|
|
|
emulator_threads = \
|
|
|
|
|
self.get_server_emulator_threads(server['id'])
|
|
|
|
|
cpu_pins = self.get_pinning_as_set(server['id'])
|
|
|
|
|
|
|
|
|
|
# Gather the emulator threads from server A and B. Then gather the
|
|
|
|
|
# pinned PCPUs from server A and B.
|
|
|
|
|
emulator_threads_a = \
|
|
|
|
|
self.get_server_emulator_threads(server_a['id'])
|
|
|
|
|
emulator_threads_b = \
|
|
|
|
|
self.get_server_emulator_threads(server_b['id'])
|
|
|
|
|
# Determine the compute host the guest was scheduled to and gather
|
|
|
|
|
# the cpu dedicated set from the host
|
|
|
|
|
host = self.get_host_for_server(server['id'])
|
|
|
|
|
host_sm = clients.NovaServiceManager(host, 'nova-compute',
|
|
|
|
|
self.os_admin.services_client)
|
|
|
|
|
cpu_dedicated_set = host_sm.get_cpu_dedicated_set()
|
|
|
|
|
|
|
|
|
|
cpu_pins_a = self.get_pinning_as_set(server_a['id'])
|
|
|
|
|
cpu_pins_b = self.get_pinning_as_set(server_b['id'])
|
|
|
|
|
# Confirm the pinned cpus from the guest are part of the dedicated
|
|
|
|
|
# range of the compute host it is scheduled to
|
|
|
|
|
self.assertTrue(
|
|
|
|
|
cpu_pins.issubset(cpu_dedicated_set), 'Pin set value %s is not '
|
|
|
|
|
'a subset of %s' % (cpu_pins, cpu_dedicated_set))
|
|
|
|
|
|
|
|
|
|
# Check that every value gathered is a subset of the
|
|
|
|
|
# cpu_dedicate_set configured for the host
|
|
|
|
|
for pin_set in [emulator_threads_a, emulator_threads_b, cpu_pins_a,
|
|
|
|
|
cpu_pins_b]:
|
|
|
|
|
self.assertTrue(
|
|
|
|
|
pin_set.issubset(dedicated_set), 'Pin set value %s is not '
|
|
|
|
|
'a subset of %s' % (pin_set, dedicated_set))
|
|
|
|
|
# Validate the emulator thread is disjoined from the pinned CPUs of the
|
|
|
|
|
# guest.
|
|
|
|
|
self.assertTrue(
|
|
|
|
|
cpu_pins.isdisjoint(emulator_threads),
|
|
|
|
|
'Threads %s overlap with CPUs %s' % (emulator_threads,
|
|
|
|
|
cpu_pins))
|
|
|
|
|
|
|
|
|
|
# Validate that all emulator thread and guest pinned CPUs are all
|
|
|
|
|
# disjointed from each other
|
|
|
|
|
self.assertTrue(
|
|
|
|
|
cpu_pins_a.isdisjoint(emulator_threads_a),
|
|
|
|
|
'Threads %s overlap with CPUs %s' % (emulator_threads_a,
|
|
|
|
|
cpu_pins_a))
|
|
|
|
|
self.assertTrue(
|
|
|
|
|
cpu_pins_b.isdisjoint(emulator_threads_b),
|
|
|
|
|
'Threads %s overlap with CPUs %s' % (emulator_threads_b,
|
|
|
|
|
cpu_pins_b))
|
|
|
|
|
self.assertTrue(
|
|
|
|
|
cpu_pins_a.isdisjoint(cpu_pins_b),
|
|
|
|
|
'Different server pins overlap: %s and %s' % (cpu_pins_a,
|
|
|
|
|
cpu_pins_b))
|
|
|
|
|
self.assertTrue(
|
|
|
|
|
emulator_threads_a.isdisjoint(emulator_threads_b),
|
|
|
|
|
'Different threads overlap: %s and %s' % (emulator_threads_a,
|
|
|
|
|
emulator_threads_b))
|
|
|
|
|
self.delete_server(server_a['id'])
|
|
|
|
|
self.delete_server(server_b['id'])
|
|
|
|
|
# Confirm the emulator thread is a subset of the compute host's cpu
|
|
|
|
|
# dedicated set
|
|
|
|
|
self.assertTrue(
|
|
|
|
|
emulator_threads.issubset(cpu_dedicated_set), 'Emulator thread '
|
|
|
|
|
'value %s is not a subset of cpu dedicated set %s' %
|
|
|
|
|
(emulator_threads, cpu_dedicated_set))
|
|
|
|
|
|
|
|
|
|
def emulator_no_extra_cpu(self, section, pin_set_mode):
|
|
|
|
|
self.delete_server(server['id'])
|
|
|
|
|
|
|
|
|
|
def test_emulator_no_extra_cpu(self):
|
|
|
|
|
"""Create a flavor that consumes all available pCPUs for the guest.
|
|
|
|
|
The flavor should also be set to isolate emulator pinning. Instance
|
|
|
|
|
should fail to build, since there are no distinct pCPUs available for
|
|
|
|
|
the emulator thread.
|
|
|
|
|
|
|
|
|
|
:param pin_set_mode: Which pCPU list mode to use when exposing
|
|
|
|
|
dedicated pCPU's to the guest, either vcpu_pin_set or cpu_dedicated_set
|
|
|
|
|
"""
|
|
|
|
|
if len(CONF.whitebox_hardware.cpu_topology[self.numa_to_use]) < 2:
|
|
|
|
|
raise self.skipException('Test requires NUMA Node with 2 or more '
|
|
|
|
|
'CPUs to run')
|
|
|
|
|
dedicated_set = hardware.format_cpu_spec(
|
|
|
|
|
CONF.whitebox_hardware.cpu_topology[self.numa_to_use][:2])
|
|
|
|
|
|
|
|
|
|
hostname = self.list_compute_hosts()[0]
|
|
|
|
|
host_sm = clients.NovaServiceManager(
|
|
|
|
|
hostname, 'nova-compute', self.os_admin.services_client)
|
|
|
|
|
# Create a dedicated flavor with a vcpu size equal to the number
|
|
|
|
|
# of available pCPUs in the dedicated set. With threads_policy
|
|
|
|
|
# being set to isolate, the build should fail since no more
|
|
|
|
|
# pCPUs will be available.
|
|
|
|
|
flavor = self.create_flavor(threads_policy='isolate',
|
|
|
|
|
vcpus=self.dedicated_cpus_per_numa)
|
|
|
|
|
|
|
|
|
|
with host_sm.config_options((section, pin_set_mode, dedicated_set),
|
|
|
|
|
('compute', 'cpu_shared_set', None)):
|
|
|
|
|
|
|
|
|
|
# Create a dedicated flavor with a vcpu size equal to the number
|
|
|
|
|
# of available pCPUs in the dedicated set. With threads_policy
|
|
|
|
|
# being set to isolate, the build should fail since no more
|
|
|
|
|
# pCPUs will be available.
|
|
|
|
|
flavor = self.create_flavor(threads_policy='isolate',
|
|
|
|
|
vcpus=len(dedicated_set))
|
|
|
|
|
|
|
|
|
|
# Confirm the instance cannot be built
|
|
|
|
|
self.assertRaises(BuildErrorException,
|
|
|
|
|
self.create_test_server,
|
|
|
|
|
clients=self.os_admin,
|
|
|
|
|
flavor=flavor['id'],
|
|
|
|
|
host=hostname)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VCPUPinSetEmulatorThreads(EmulatorExtraCPUTest):
|
|
|
|
|
|
|
|
|
|
max_microversion = '2.79'
|
|
|
|
|
pin_set_mode = 'vcpu_pin_set'
|
|
|
|
|
pin_section = 'DEFAULT'
|
|
|
|
|
|
|
|
|
|
def test_policy_share_cpu_shared_set(self):
|
|
|
|
|
"""With policy set to share and cpu_share_set set, emulator threads
|
|
|
|
|
should be pinned to cpu_share_set.
|
|
|
|
|
"""
|
|
|
|
|
super(VCPUPinSetEmulatorThreads,
|
|
|
|
|
self).policy_share_cpu_shared_set(
|
|
|
|
|
section=self.pin_section, pin_set_mode=self.pin_set_mode)
|
|
|
|
|
|
|
|
|
|
def test_policy_share_cpu_shared_unset(self):
|
|
|
|
|
"""With policy set to share and cpu_share_set unset, emulator threads
|
|
|
|
|
should float over the instance's pCPUs.
|
|
|
|
|
"""
|
|
|
|
|
super(VCPUPinSetEmulatorThreads,
|
|
|
|
|
self).policy_share_cpu_shared_unset(
|
|
|
|
|
section=self.pin_section, pin_set_mode=self.pin_set_mode)
|
|
|
|
|
|
|
|
|
|
def test_policy_isolate(self):
|
|
|
|
|
"""With policy isolate, cpu_shared_set is ignored, and emulator threads
|
|
|
|
|
sould be pinned to a pCPU distinct from the instance's pCPUs. pCPU's
|
|
|
|
|
are exposed to the guest via vcpu_pin_set.
|
|
|
|
|
"""
|
|
|
|
|
super(VCPUPinSetEmulatorThreads,
|
|
|
|
|
self).policy_isolate(
|
|
|
|
|
section=self.pin_section, pin_set_mode=self.pin_set_mode)
|
|
|
|
|
|
|
|
|
|
def test_emulator_no_extra_cpu(self):
|
|
|
|
|
"""With policy isolate and an instance's vCPU's consuming all available
|
|
|
|
|
pCPU's from the vcpu_pin_set, build should fail since there are no
|
|
|
|
|
pCPU's available for the emulator thread
|
|
|
|
|
"""
|
|
|
|
|
super(VCPUPinSetEmulatorThreads,
|
|
|
|
|
self).emulator_no_extra_cpu(
|
|
|
|
|
section=self.pin_section, pin_set_mode=self.pin_set_mode)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class CPUDedicatedEmulatorThreads(EmulatorExtraCPUTest):
|
|
|
|
|
|
|
|
|
|
compute_min_microversion = '2.79'
|
|
|
|
|
compute_max_microversion = 'latest'
|
|
|
|
|
pin_set_mode = 'cpu_dedicated_set'
|
|
|
|
|
pin_section = 'compute'
|
|
|
|
|
|
|
|
|
|
def test_policy_share_cpu_shared_set(self):
|
|
|
|
|
"""With policy set to share and cpu_share_set set, emulator threads
|
|
|
|
|
should be pinned to cpu_share_set.
|
|
|
|
|
"""
|
|
|
|
|
super(CPUDedicatedEmulatorThreads,
|
|
|
|
|
self).policy_share_cpu_shared_set(
|
|
|
|
|
section=self.pin_section, pin_set_mode=self.pin_set_mode)
|
|
|
|
|
|
|
|
|
|
def test_policy_share_cpu_shared_unset(self):
|
|
|
|
|
"""With policy set to share and cpu_share_set unset, emulator threads
|
|
|
|
|
should float over the instance's pCPUs.
|
|
|
|
|
"""
|
|
|
|
|
super(CPUDedicatedEmulatorThreads,
|
|
|
|
|
self).policy_share_cpu_shared_unset(
|
|
|
|
|
section=self.pin_section, pin_set_mode=self.pin_set_mode)
|
|
|
|
|
|
|
|
|
|
def test_policy_isolate(self):
|
|
|
|
|
"""With policy isolate, cpu_shared_set is ignored, and emulator threads
|
|
|
|
|
sould be pinned to a pCPU distinct from the instance's pCPUs. pCPU's
|
|
|
|
|
are exposed to the guest via cpu_dedicated_set.
|
|
|
|
|
"""
|
|
|
|
|
super(CPUDedicatedEmulatorThreads,
|
|
|
|
|
self).policy_isolate(
|
|
|
|
|
section=self.pin_section, pin_set_mode=self.pin_set_mode)
|
|
|
|
|
|
|
|
|
|
def test_emulator_no_extra_cpu(self):
|
|
|
|
|
"""With policy isolate and an instance's vCPU's consuming all available
|
|
|
|
|
pCPU's from the cpu_dedicated_set, build should fail since there are no
|
|
|
|
|
pCPU's available for the emulator thread
|
|
|
|
|
"""
|
|
|
|
|
super(CPUDedicatedEmulatorThreads,
|
|
|
|
|
self).emulator_no_extra_cpu(
|
|
|
|
|
section=self.pin_section, pin_set_mode=self.pin_set_mode)
|
|
|
|
|
# Confirm the instance cannot be built
|
|
|
|
|
self.assertRaises(BuildErrorException,
|
|
|
|
|
self.create_test_server,
|
|
|
|
|
flavor=flavor['id'])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class NUMALiveMigrationBase(BasePinningTest):
|
|
|
|
|