Skip to content

Commit 710116f

Browse files
committed
Reproducer for bug 2003991 unshelving offloaded instance
This adds test coverage for: * Shelve/unshelve offloaded with legacy quota usage * Shelve/unshelve offloaded with quota usage from placement * Shelve/unshelve offloaded with unified limits * Shelve/unshelve with legacy quota usage * Shelve/unshelve with quota usage from placement * Shelve/unshelve with unified limits Related-Bug: #2003991 Change-Id: Icc9b6366aebba2f8468e2127da7b7e099098513a (cherry picked from commit 427b2cb) (cherry picked from commit 004a773)
1 parent 77db642 commit 710116f

File tree

1 file changed

+107
-0
lines changed

1 file changed

+107
-0
lines changed

nova/tests/functional/test_servers.py

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
from cinderclient import exceptions as cinder_exception
2424
from keystoneauth1 import adapter
2525
from oslo_config import cfg
26+
from oslo_limit import fixture as limit_fixture
2627
from oslo_log import log as logging
2728
from oslo_serialization import base64
2829
from oslo_serialization import jsonutils
@@ -377,6 +378,112 @@ def test_deferred_delete_force(self):
377378
# Wait for real deletion
378379
self._wait_until_deleted(found_server)
379380

381+
def test_unshelve_offloaded_overquota(self):
382+
# Use a quota limit of 3 vcpus.
383+
self.flags(cores=3, group='quota')
384+
385+
# Use flavor that has vcpus = 1.
386+
for i in range(0, 3):
387+
server = self._create_server(flavor_id=1)
388+
389+
# We should be at the quota limit now. Shelve an instance and wait for
390+
# it to become SHELVED_OFFLOADED.
391+
self._shelve_server(server, expected_state='SHELVED_OFFLOADED')
392+
393+
# Try to boot another instance. It should fail because shelved
394+
# offloaded instances still consume quota.
395+
ex = self.assertRaises(client.OpenStackApiException,
396+
self._create_server,
397+
flavor_id=1)
398+
self.assertEqual(403, ex.response.status_code)
399+
400+
# Unshelving the instance should also succeed.
401+
self._unshelve_server(server)
402+
403+
def _test_unshelve_offloaded_overquota_placement(self):
404+
# Use flavor that has vcpus = 1.
405+
for i in range(0, 3):
406+
server = self._create_server(flavor_id=1)
407+
408+
# We should be at the quota limit now. Shelve an instance and wait for
409+
# it to become SHELVED_OFFLOADED.
410+
self._shelve_server(server, expected_state='SHELVED_OFFLOADED')
411+
412+
# Try to boot another instance. It should succeed because with
413+
# placement, shelved offloaded instances do not consume cores/ram
414+
# quota.
415+
self._create_server(flavor_id=1)
416+
417+
# FIXME(melwitt): This is bug #2003991, the unshelve is supposed to
418+
# fail if we would be over quota after unshelving.
419+
# Now try to unshelve the earlier instance. It should fail because it
420+
# would put us over quota to have 4 running instances.
421+
# ex = self.assertRaises(client.OpenStackApiException,
422+
# self._unshelve_server,
423+
# server)
424+
# self.assertEqual(403, ex.response.status_code)
425+
self._unshelve_server(server)
426+
427+
def test_unshelve_offloaded_overquota_placement(self):
428+
# Count quota usage from placement.
429+
self.flags(count_usage_from_placement=True, group='quota')
430+
# Use a quota limit of 3 vcpus.
431+
self.flags(cores=3, group='quota')
432+
self._test_unshelve_offloaded_overquota_placement()
433+
434+
def test_unshelve_offloaded_overquota_ul(self):
435+
self.flags(driver='nova.quota.UnifiedLimitsDriver', group='quota')
436+
limits = {
437+
'servers': 5,
438+
'class:VCPU': 3,
439+
'class:MEMORY_MB': 2048,
440+
'class:DISK_GB': 5
441+
}
442+
self.useFixture(limit_fixture.LimitFixture(limits, {}))
443+
self._test_unshelve_offloaded_overquota_placement()
444+
445+
def test_unshelve_overquota(self):
446+
# Test for behavior where the shelved instance is not offloaded.
447+
self.flags(shelved_offload_time=3600)
448+
# Use a quota limit of 3 vcpus.
449+
self.flags(cores=3, group='quota')
450+
451+
# Use flavor that has vcpus = 1.
452+
for i in range(0, 3):
453+
server = self._create_server(flavor_id=1)
454+
455+
# We should be at the quota limit now. Shelve an instance.
456+
self._shelve_server(server, expected_state='SHELVED')
457+
458+
# Try to boot another instance. It should fail because shelved
459+
# instances still consume quota.
460+
ex = self.assertRaises(client.OpenStackApiException,
461+
self._create_server,
462+
flavor_id=1)
463+
self.assertEqual(403, ex.response.status_code)
464+
465+
# Verify that it's still SHELVED.
466+
self._wait_for_state_change(server, 'SHELVED')
467+
468+
# Unshelving the instance should also succeed.
469+
self._unshelve_server(server)
470+
471+
def test_unshelve_overquota_placement(self):
472+
# Count quota usage from placement, should behave the same as legacy.
473+
self.flags(count_usage_from_placement=True, group='quota')
474+
self.test_unshelve_overquota()
475+
476+
def test_unshelve_overquota_ul(self):
477+
self.flags(driver='nova.quota.UnifiedLimitsDriver', group='quota')
478+
limits = {
479+
'servers': 5,
480+
'class:VCPU': 3,
481+
'class:MEMORY_MB': 2048,
482+
'class:DISK_GB': 5
483+
}
484+
self.useFixture(limit_fixture.LimitFixture(limits, {}))
485+
self.test_unshelve_overquota_placement()
486+
380487
def test_create_server_with_metadata(self):
381488
# Creates a server with metadata.
382489

0 commit comments

Comments
 (0)