Skip to content

Commit

Permalink
Replace RPC topic-based service queries with binary-based in scheduler
Browse files Browse the repository at this point in the history
This makes the nova/scheduler subtree query for compute services by
binary name instead of RPC topic.

Change-Id: I2633aff583f3036bd4d0b71edd547f46f29039e1
  • Loading branch information
kk7ds committed Mar 9, 2015
1 parent 9802c9b commit 3a28a18
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 66 deletions.
10 changes: 4 additions & 6 deletions nova/scheduler/host_manager.py
Expand Up @@ -64,7 +64,6 @@

CONF = cfg.CONF
CONF.register_opts(host_manager_opts)
CONF.import_opt('compute_topic', 'nova.compute.rpcapi')

LOG = logging.getLogger(__name__)

Expand Down Expand Up @@ -463,8 +462,8 @@ def get_all_host_states(self, context):
"""

service_refs = {service.host: service
for service in objects.ServiceList.get_by_topic(
context, CONF.compute_topic)}
for service in objects.ServiceList.get_by_binary(
context, 'nova-compute')}
# Get resource usage across the available compute nodes:
compute_nodes = objects.ComputeNodeList.get_all(context)
seen_nodes = set()
Expand All @@ -473,9 +472,8 @@ def get_all_host_states(self, context):

if not service:
LOG.warning(_LW(
"No service record found for host %(host)s "
"on %(topic)s topic"),
{'host': compute.host, 'topic': CONF.compute_topic})
"No compute service record found for host %(host)s"),
{'host': compute.host})
continue
host = compute.host
node = compute.hypervisor_hostname
Expand Down
20 changes: 10 additions & 10 deletions nova/tests/unit/scheduler/test_filter_scheduler.py
Expand Up @@ -36,15 +36,15 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase):

driver_cls = filter_scheduler.FilterScheduler

@mock.patch('nova.objects.ServiceList.get_by_topic',
@mock.patch('nova.objects.ServiceList.get_by_binary',
return_value=fakes.SERVICES)
@mock.patch('nova.objects.ComputeNodeList.get_all',
return_value=fakes.COMPUTE_NODES)
@mock.patch('nova.db.instance_extra_get_by_instance_uuid',
return_value={'numa_topology': None,
'pci_requests': None})
def test_schedule_happy_day(self, mock_get_extra, mock_get_all,
mock_get_by_topic):
mock_get_by_binary):
"""Make sure there's nothing glaringly wrong with _schedule()
by doing a happy day pass through.
"""
Expand Down Expand Up @@ -114,15 +114,15 @@ def test_post_select_populate(self):

self.assertEqual({'vcpus': 5}, host_state.limits)

@mock.patch('nova.objects.ServiceList.get_by_topic',
@mock.patch('nova.objects.ServiceList.get_by_binary',
return_value=fakes.SERVICES)
@mock.patch('nova.objects.ComputeNodeList.get_all',
return_value=fakes.COMPUTE_NODES)
@mock.patch('nova.db.instance_extra_get_by_instance_uuid',
return_value={'numa_topology': None,
'pci_requests': None})
def test_schedule_host_pool(self, mock_get_extra, mock_get_all,
mock_get_by_topic):
mock_get_by_binary):
"""Make sure the scheduler_host_subset_size property works properly."""

self.flags(scheduler_host_subset_size=2)
Expand All @@ -147,15 +147,15 @@ def test_schedule_host_pool(self, mock_get_extra, mock_get_all,
# one host should be chosen
self.assertEqual(len(hosts), 1)

@mock.patch('nova.objects.ServiceList.get_by_topic',
@mock.patch('nova.objects.ServiceList.get_by_binary',
return_value=fakes.SERVICES)
@mock.patch('nova.objects.ComputeNodeList.get_all',
return_value=fakes.COMPUTE_NODES)
@mock.patch('nova.db.instance_extra_get_by_instance_uuid',
return_value={'numa_topology': None,
'pci_requests': None})
def test_schedule_large_host_pool(self, mock_get_extra, mock_get_all,
mock_get_by_topic):
mock_get_by_binary):
"""Hosts should still be chosen if pool size
is larger than number of filtered hosts.
"""
Expand All @@ -181,15 +181,15 @@ def test_schedule_large_host_pool(self, mock_get_extra, mock_get_all,
# one host should be chose
self.assertEqual(len(hosts), 1)

@mock.patch('nova.objects.ServiceList.get_by_topic',
@mock.patch('nova.objects.ServiceList.get_by_binary',
return_value=fakes.SERVICES)
@mock.patch('nova.objects.ComputeNodeList.get_all',
return_value=fakes.COMPUTE_NODES)
@mock.patch('nova.db.instance_extra_get_by_instance_uuid',
return_value={'numa_topology': None,
'pci_requests': None})
def test_schedule_chooses_best_host(self, mock_get_extra, mock_get_all,
mock_get_by_topic):
mock_get_by_binary):
"""If scheduler_host_subset_size is 1, the largest host with greatest
weight should be returned.
"""
Expand Down Expand Up @@ -230,15 +230,15 @@ def _fake_weigh_objects(_self, functions, hosts, options):

self.assertEqual(50, hosts[0].weight)

@mock.patch('nova.objects.ServiceList.get_by_topic',
@mock.patch('nova.objects.ServiceList.get_by_binary',
return_value=fakes.SERVICES)
@mock.patch('nova.objects.ComputeNodeList.get_all',
return_value=fakes.COMPUTE_NODES)
@mock.patch('nova.db.instance_extra_get_by_instance_uuid',
return_value={'numa_topology': None,
'pci_requests': None})
def test_select_destinations(self, mock_get_extra, mock_get_all,
mock_get_by_topic):
mock_get_by_binary):
"""select_destinations is basically a wrapper around _schedule().
Similar to the _schedule tests, this just does a happy path test to
Expand Down
63 changes: 30 additions & 33 deletions nova/tests/unit/scheduler/test_host_manager.py
Expand Up @@ -19,7 +19,6 @@
import collections

import mock
from oslo_config import cfg
from oslo_serialization import jsonutils
import six

Expand All @@ -35,9 +34,6 @@
from nova.tests.unit.scheduler import fakes
from nova import utils

CONF = cfg.CONF
CONF.import_opt('compute_topic', 'nova.compute.rpcapi')


class FakeFilterClass1(filters.BaseHostFilter):
def host_passes(self, host_state, filter_properties):
Expand Down Expand Up @@ -313,12 +309,12 @@ def test_get_all_host_states(self):

context = 'fake_context'

self.mox.StubOutWithMock(objects.ServiceList, 'get_by_topic')
self.mox.StubOutWithMock(objects.ServiceList, 'get_by_binary')
self.mox.StubOutWithMock(objects.ComputeNodeList, 'get_all')
self.mox.StubOutWithMock(host_manager.LOG, 'warning')

objects.ServiceList.get_by_topic(
context, CONF.compute_topic).AndReturn(fakes.SERVICES)
objects.ServiceList.get_by_binary(
context, 'nova-compute').AndReturn(fakes.SERVICES)
objects.ComputeNodeList.get_all(context).AndReturn(fakes.COMPUTE_NODES)
# node 3 host physical disk space is greater than database
host_manager.LOG.warning("Host %(hostname)s has more disk space "
Expand All @@ -327,9 +323,9 @@ def test_get_all_host_states(self):
{'physical': 3333, 'database': 3072,
'hostname': 'node3'})
# Invalid service
host_manager.LOG.warning("No service record found for host %(host)s "
"on %(topic)s topic",
{'host': 'fake', 'topic': CONF.compute_topic})
host_manager.LOG.warning("No compute service record found for "
"host %(host)s",
{'host': 'fake'})
self.mox.ReplayAll()
self.host_manager.get_all_host_states(context)
host_states_map = self.host_manager.host_state_map
Expand Down Expand Up @@ -371,10 +367,10 @@ def test_get_all_host_states(self):

@mock.patch.object(host_manager.HostState, 'update_from_compute_node')
@mock.patch.object(objects.ComputeNodeList, 'get_all')
@mock.patch.object(objects.ServiceList, 'get_by_topic')
def test_get_all_host_states_with_no_aggs(self, svc_get_by_topic,
@mock.patch.object(objects.ServiceList, 'get_by_binary')
def test_get_all_host_states_with_no_aggs(self, svc_get_by_binary,
cn_get_all, update_from_cn):
svc_get_by_topic.return_value = [objects.Service(host='fake')]
svc_get_by_binary.return_value = [objects.Service(host='fake')]
cn_get_all.return_value = [
objects.ComputeNode(host='fake', hypervisor_hostname='fake')]

Expand All @@ -386,11 +382,11 @@ def test_get_all_host_states_with_no_aggs(self, svc_get_by_topic,

@mock.patch.object(host_manager.HostState, 'update_from_compute_node')
@mock.patch.object(objects.ComputeNodeList, 'get_all')
@mock.patch.object(objects.ServiceList, 'get_by_topic')
def test_get_all_host_states_with_matching_aggs(self, svc_get_by_topic,
@mock.patch.object(objects.ServiceList, 'get_by_binary')
def test_get_all_host_states_with_matching_aggs(self, svc_get_by_binary,
cn_get_all,
update_from_cn):
svc_get_by_topic.return_value = [objects.Service(host='fake')]
svc_get_by_binary.return_value = [objects.Service(host='fake')]
cn_get_all.return_value = [
objects.ComputeNode(host='fake', hypervisor_hostname='fake')]
fake_agg = objects.Aggregate(id=1)
Expand All @@ -404,12 +400,13 @@ def test_get_all_host_states_with_matching_aggs(self, svc_get_by_topic,

@mock.patch.object(host_manager.HostState, 'update_from_compute_node')
@mock.patch.object(objects.ComputeNodeList, 'get_all')
@mock.patch.object(objects.ServiceList, 'get_by_topic')
def test_get_all_host_states_with_not_matching_aggs(self, svc_get_by_topic,
@mock.patch.object(objects.ServiceList, 'get_by_binary')
def test_get_all_host_states_with_not_matching_aggs(self,
svc_get_by_binary,
cn_get_all,
update_from_cn):
svc_get_by_topic.return_value = [objects.Service(host='fake'),
objects.Service(host='other')]
svc_get_by_binary.return_value = [objects.Service(host='fake'),
objects.Service(host='other')]
cn_get_all.return_value = [
objects.ComputeNode(host='fake', hypervisor_hostname='fake'),
objects.ComputeNode(host='other', hypervisor_hostname='other')]
Expand Down Expand Up @@ -440,10 +437,10 @@ def setUp(self):
def test_get_all_host_states(self):
context = 'fake_context'

self.mox.StubOutWithMock(objects.ServiceList, 'get_by_topic')
self.mox.StubOutWithMock(objects.ServiceList, 'get_by_binary')
self.mox.StubOutWithMock(objects.ComputeNodeList, 'get_all')
objects.ServiceList.get_by_topic(
context, CONF.compute_topic).AndReturn(fakes.SERVICES)
objects.ServiceList.get_by_binary(
context, 'nova-compute').AndReturn(fakes.SERVICES)
objects.ComputeNodeList.get_all(context).AndReturn(fakes.COMPUTE_NODES)
self.mox.ReplayAll()

Expand All @@ -454,17 +451,17 @@ def test_get_all_host_states(self):
def test_get_all_host_states_after_delete_one(self):
context = 'fake_context'

self.mox.StubOutWithMock(objects.ServiceList, 'get_by_topic')
self.mox.StubOutWithMock(objects.ServiceList, 'get_by_binary')
self.mox.StubOutWithMock(objects.ComputeNodeList, 'get_all')
# all nodes active for first call
objects.ServiceList.get_by_topic(
context, CONF.compute_topic).AndReturn(fakes.SERVICES)
objects.ServiceList.get_by_binary(
context, 'nova-compute').AndReturn(fakes.SERVICES)
objects.ComputeNodeList.get_all(context).AndReturn(fakes.COMPUTE_NODES)
# remove node4 for second call
running_nodes = [n for n in fakes.COMPUTE_NODES
if n.get('hypervisor_hostname') != 'node4']
objects.ServiceList.get_by_topic(
context, CONF.compute_topic).AndReturn(fakes.SERVICES)
objects.ServiceList.get_by_binary(
context, 'nova-compute').AndReturn(fakes.SERVICES)
objects.ComputeNodeList.get_all(context).AndReturn(running_nodes)
self.mox.ReplayAll()

Expand All @@ -476,15 +473,15 @@ def test_get_all_host_states_after_delete_one(self):
def test_get_all_host_states_after_delete_all(self):
context = 'fake_context'

self.mox.StubOutWithMock(objects.ServiceList, 'get_by_topic')
self.mox.StubOutWithMock(objects.ServiceList, 'get_by_binary')
self.mox.StubOutWithMock(objects.ComputeNodeList, 'get_all')
# all nodes active for first call
objects.ServiceList.get_by_topic(
context, CONF.compute_topic).AndReturn(fakes.SERVICES)
objects.ServiceList.get_by_binary(
context, 'nova-compute').AndReturn(fakes.SERVICES)
objects.ComputeNodeList.get_all(context).AndReturn(fakes.COMPUTE_NODES)
# remove all nodes for second call
objects.ServiceList.get_by_topic(
context, CONF.compute_topic).AndReturn(fakes.SERVICES)
objects.ServiceList.get_by_binary(
context, 'nova-compute').AndReturn(fakes.SERVICES)
objects.ComputeNodeList.get_all(context).AndReturn([])
self.mox.ReplayAll()

Expand Down
30 changes: 13 additions & 17 deletions nova/tests/unit/scheduler/test_ironic_host_manager.py
Expand Up @@ -18,7 +18,6 @@
"""

import mock
from oslo_config import cfg

from nova import exception
from nova import objects
Expand All @@ -29,9 +28,6 @@
from nova import test
from nova.tests.unit.scheduler import ironic_fakes

CONF = cfg.CONF
CONF.import_opt('compute_topic', 'nova.compute.rpcapi')


class FakeFilterClass1(filters.BaseHostFilter):
def host_passes(self, host_state, filter_properties):
Expand Down Expand Up @@ -68,10 +64,10 @@ def test_get_all_host_states(self):
# Ensure .service is set and we have the values we expect to.
context = 'fake_context'

self.mox.StubOutWithMock(objects.ServiceList, 'get_by_topic')
self.mox.StubOutWithMock(objects.ServiceList, 'get_by_binary')
self.mox.StubOutWithMock(objects.ComputeNodeList, 'get_all')
objects.ServiceList.get_by_topic(
context, CONF.compute_topic).AndReturn(ironic_fakes.SERVICES)
objects.ServiceList.get_by_binary(
context, 'nova-compute').AndReturn(ironic_fakes.SERVICES)
objects.ComputeNodeList.get_all(context).AndReturn(
ironic_fakes.COMPUTE_NODES)
self.mox.ReplayAll()
Expand Down Expand Up @@ -138,18 +134,18 @@ def test_create_non_ironic_host_state(self, init_mock):
def test_get_all_host_states_after_delete_one(self):
context = 'fake_context'

self.mox.StubOutWithMock(objects.ServiceList, 'get_by_topic')
self.mox.StubOutWithMock(objects.ServiceList, 'get_by_binary')
self.mox.StubOutWithMock(objects.ComputeNodeList, 'get_all')
# all nodes active for first call
objects.ServiceList.get_by_topic(
context, CONF.compute_topic).AndReturn(ironic_fakes.SERVICES)
objects.ServiceList.get_by_binary(
context, 'nova-compute').AndReturn(ironic_fakes.SERVICES)
objects.ComputeNodeList.get_all(context).AndReturn(
ironic_fakes.COMPUTE_NODES)
# remove node4 for second call
running_nodes = [n for n in ironic_fakes.COMPUTE_NODES
if n.get('hypervisor_hostname') != 'node4uuid']
objects.ServiceList.get_by_topic(
context, CONF.compute_topic).AndReturn(ironic_fakes.SERVICES)
objects.ServiceList.get_by_binary(
context, 'nova-compute').AndReturn(ironic_fakes.SERVICES)
objects.ComputeNodeList.get_all(context).AndReturn(running_nodes)
self.mox.ReplayAll()

Expand All @@ -161,16 +157,16 @@ def test_get_all_host_states_after_delete_one(self):
def test_get_all_host_states_after_delete_all(self):
context = 'fake_context'

self.mox.StubOutWithMock(objects.ServiceList, 'get_by_topic')
self.mox.StubOutWithMock(objects.ServiceList, 'get_by_binary')
self.mox.StubOutWithMock(objects.ComputeNodeList, 'get_all')
# all nodes active for first call
objects.ServiceList.get_by_topic(
context, CONF.compute_topic).AndReturn(ironic_fakes.SERVICES)
objects.ServiceList.get_by_binary(
context, 'nova-compute').AndReturn(ironic_fakes.SERVICES)
objects.ComputeNodeList.get_all(context).AndReturn(
ironic_fakes.COMPUTE_NODES)
# remove all nodes for second call
objects.ServiceList.get_by_topic(
context, CONF.compute_topic).AndReturn(ironic_fakes.SERVICES)
objects.ServiceList.get_by_binary(
context, 'nova-compute').AndReturn(ironic_fakes.SERVICES)
objects.ComputeNodeList.get_all(context).AndReturn([])
self.mox.ReplayAll()

Expand Down

0 comments on commit 3a28a18

Please sign in to comment.