113
115
mox.IsA(exception.NoValidHost), mox.IgnoreArg())
114
116
self.mox.ReplayAll()
115
117
sched.schedule_run_instance(
116
fake_context, request_spec, None, None, None, None, {})
118
fake_context, request_spec, None, None, None, None, {}, False)
117
119
self.assertTrue(self.was_admin)
119
121
def test_scheduler_includes_launch_index(self):
145
147
fake_context, 'host1',
146
148
mox.Func(_has_launch_index(0)), {},
147
149
None, None, None, None,
148
instance_uuid='fake-uuid1').AndReturn(instance1)
150
instance_uuid='fake-uuid1',
151
legacy_bdm_in_spec=False).AndReturn(instance1)
150
153
self.driver._provision_resource(
151
154
fake_context, 'host2',
152
155
mox.Func(_has_launch_index(1)), {},
153
156
None, None, None, None,
154
instance_uuid='fake-uuid2').AndReturn(instance2)
157
instance_uuid='fake-uuid2',
158
legacy_bdm_in_spec=False).AndReturn(instance2)
155
159
self.mox.ReplayAll()
157
161
self.driver.schedule_run_instance(fake_context, request_spec,
158
None, None, None, None, {})
162
None, None, None, None, {}, False)
160
164
def test_schedule_happy_day(self):
161
165
"""Make sure there's nothing glaringly wrong with _schedule()
195
199
for weighed_host in weighed_hosts:
196
200
self.assertTrue(weighed_host.obj is not None)
198
def test_schedule_prep_resize_doesnt_update_host(self):
199
fake_context = context.RequestContext('user', 'project',
202
sched = fakes.FakeFilterScheduler()
204
def _return_hosts(*args, **kwargs):
205
host_state = host_manager.HostState('host2', 'node2')
206
return [weights.WeighedHost(host_state, 1.0)]
208
self.stubs.Set(sched, '_schedule', _return_hosts)
212
def _fake_instance_update_db(*args, **kwargs):
213
# This should not be called
216
self.stubs.Set(driver, 'instance_update_db',
217
_fake_instance_update_db)
219
instance = {'uuid': 'fake-uuid', 'host': 'host1'}
221
sched.schedule_prep_resize(fake_context, {}, {}, {},
223
self.assertEqual(info['called'], 0)
225
202
def test_max_attempts(self):
226
203
self.flags(scheduler_max_attempts=4)
253
231
# should not have retry info in the populated filter properties:
254
232
self.assertFalse("retry" in filter_properties)
234
def test_retry_force_hosts(self):
235
# Retry info should not get populated when re-scheduling is off.
236
self.flags(scheduler_max_attempts=2)
237
sched = fakes.FakeFilterScheduler()
239
instance_properties = {'project_id': '12345', 'os_type': 'Linux'}
240
request_spec = dict(instance_properties=instance_properties)
241
filter_properties = dict(force_hosts=['force_host'])
243
self.mox.StubOutWithMock(db, 'compute_node_get_all')
244
db.compute_node_get_all(mox.IgnoreArg()).AndReturn([])
247
sched._schedule(self.context, request_spec,
248
filter_properties=filter_properties)
250
# should not have retry info in the populated filter properties:
251
self.assertFalse("retry" in filter_properties)
253
def test_retry_force_nodes(self):
254
# Retry info should not get populated when re-scheduling is off.
255
self.flags(scheduler_max_attempts=2)
256
sched = fakes.FakeFilterScheduler()
258
instance_properties = {'project_id': '12345', 'os_type': 'Linux'}
259
request_spec = dict(instance_properties=instance_properties)
260
filter_properties = dict(force_nodes=['force_node'])
262
self.mox.StubOutWithMock(db, 'compute_node_get_all')
263
db.compute_node_get_all(mox.IgnoreArg()).AndReturn([])
266
sched._schedule(self.context, request_spec,
267
filter_properties=filter_properties)
269
# should not have retry info in the populated filter properties:
270
self.assertFalse("retry" in filter_properties)
256
272
def test_retry_attempt_one(self):
257
273
# Test retry logic on initial scheduling attempt.
258
274
self.flags(scheduler_max_attempts=2)
259
275
sched = fakes.FakeFilterScheduler()
261
277
instance_properties = {'project_id': '12345', 'os_type': 'Linux'}
262
request_spec = dict(instance_properties=instance_properties)
278
request_spec = dict(instance_properties=instance_properties,
263
280
filter_properties = {}
265
282
self.mox.StubOutWithMock(db, 'compute_node_get_all')
312
330
self.context, request_spec, admin_password=None,
313
331
injected_files=None, requested_networks=None,
314
332
is_first_time=False,
315
filter_properties=filter_properties)
333
filter_properties=filter_properties,
334
legacy_bdm_in_spec=False)
316
335
uuids = request_spec.get('instance_uuids')
317
336
self.assertEqual(uuids, instance_uuids)
344
363
self.assertEqual({'vcpus': 5}, host_state.limits)
346
def test_prep_resize_post_populates_retry(self):
347
# Prep resize should add a ('host', 'node') entry to the retry dict.
348
sched = fakes.FakeFilterScheduler()
351
instance = {'disable_terminate': False,
353
'deleted': 0, 'info_cache': {},
355
'system_metadata': [], 'shutdown_terminate': False,
356
'id': 1, 'security_groups': [], 'metadata': []}
358
instance_properties = {'project_id': 'fake', 'os_type': 'Linux'}
360
'memory_mb': 1024, 'root_gb': 40, 'deleted_at': None,
361
'name': u'm1.medium', 'deleted': 0, 'created_at': None,
362
'ephemeral_gb': 0, 'updated_at': None, 'disabled': False,
363
'vcpus': 2, 'extra_specs': {}, 'swap': 0,
364
'rxtx_factor': 1.0, 'is_public': True, 'flavorid': u'3',
365
'vcpu_weight': None, 'id': 1}
367
request_spec = {'instance_properties': instance_properties,
368
'instance_type': instance_type}
369
retry = {'hosts': [], 'num_attempts': 1}
370
filter_properties = {'retry': retry}
373
host = fakes.FakeHostState('host', 'node', {})
374
weighed_host = weights.WeighedHost(host, 1)
375
weighed_hosts = [weighed_host]
377
self.mox.StubOutWithMock(sched, '_schedule')
378
self.mox.StubOutWithMock(sched.compute_rpcapi, 'prep_resize')
380
sched._schedule(self.context, request_spec, filter_properties,
381
[instance['uuid']]).AndReturn(weighed_hosts)
382
sched.compute_rpcapi.prep_resize(self.context, image, instance,
383
instance_type, 'host', reservations, request_spec=request_spec,
384
filter_properties=filter_properties, node='node')
387
sched.schedule_prep_resize(self.context, image, request_spec,
388
filter_properties, instance, instance_type, reservations)
390
self.assertEqual([['host', 'node']],
391
filter_properties['retry']['hosts'])
393
365
def test_basic_schedule_run_instances_anti_affinity(self):
394
366
filter_properties = {'scheduler_hints':
395
367
{'group': 'cats'}}
442
414
instance=instance1_1, requested_networks=None,
443
415
injected_files=None, admin_password=None, is_first_time=None,
444
416
request_spec=request_spec1, filter_properties=mox.IgnoreArg(),
417
node='node3', legacy_bdm_in_spec=False)
447
419
driver.instance_update_db(fake_context, instance1_2['uuid'],
448
420
extra_values=expected_metadata).WithSideEffects(
451
423
instance=instance1_2, requested_networks=None,
452
424
injected_files=None, admin_password=None, is_first_time=None,
453
425
request_spec=request_spec1, filter_properties=mox.IgnoreArg(),
426
node='node4', legacy_bdm_in_spec=False)
455
427
self.mox.ReplayAll()
456
428
sched.schedule_run_instance(fake_context, request_spec1,
457
None, None, None, None, filter_properties)
429
None, None, None, None, filter_properties, False)
459
431
def test_schedule_host_pool(self):
460
432
"""Make sure the scheduler_host_subset_size property works properly."""
663
638
self.assertRaises(exception.NoValidHost,
664
639
self.driver.select_destinations, self.context,
665
640
{'num_instances': 1}, {})
642
def test_handles_deleted_instance(self):
643
"""Test instance deletion while being scheduled."""
645
def _raise_instance_not_found(*args, **kwargs):
646
raise exception.InstanceNotFound(instance_id='123')
648
self.stubs.Set(driver, 'instance_update_db',
649
_raise_instance_not_found)
651
sched = fakes.FakeFilterScheduler()
653
fake_context = context.RequestContext('user', 'project')
654
host_state = host_manager.HostState('host2', 'node2')
655
weighted_host = weights.WeighedHost(host_state, 1.42)
656
filter_properties = {}
659
instance_properties = {'project_id': 1, 'os_type': 'Linux'}
660
request_spec = {'instance_type': {'memory_mb': 1, 'local_gb': 1},
661
'instance_properties': instance_properties,
662
'instance_uuids': [uuid]}
663
sched._provision_resource(fake_context, weighted_host,
664
request_spec, filter_properties,
665
None, None, None, None)
667
def test_pci_request_in_filter_properties(self):
669
request_spec = {'instance_type': instance_type,
670
'instance_properties': {'project_id': 1,
672
filter_properties = {}
673
requests = [{'count': 1, 'spec': [{'vendor_id': '8086'}]}]
674
self.mox.StubOutWithMock(pci_request, 'get_pci_requests_from_flavor')
675
pci_request.get_pci_requests_from_flavor(
676
instance_type).AndReturn(requests)
678
self.driver.populate_filter_properties(
679
request_spec, filter_properties)
680
self.assertEqual(filter_properties.get('pci_requests'),