Merge "Add Nova lock and unlock scenario"
This commit is contained in:
commit
80adff3633
@ -1278,6 +1278,25 @@
|
|||||||
failure_rate:
|
failure_rate:
|
||||||
max: 0
|
max: 0
|
||||||
|
|
||||||
|
NovaServers.boot_lock_unlock_and_delete:
|
||||||
|
-
|
||||||
|
args:
|
||||||
|
flavor:
|
||||||
|
name: "m1.tiny"
|
||||||
|
image:
|
||||||
|
name: {{image_name}}
|
||||||
|
runner:
|
||||||
|
type: "constant"
|
||||||
|
times: 4
|
||||||
|
concurrency: 4
|
||||||
|
context:
|
||||||
|
users:
|
||||||
|
tenants: 2
|
||||||
|
users_per_tenant: 1
|
||||||
|
sla:
|
||||||
|
failure_rate:
|
||||||
|
max: 0
|
||||||
|
|
||||||
NovaServers.boot_server_from_volume_and_delete:
|
NovaServers.boot_server_from_volume_and_delete:
|
||||||
-
|
-
|
||||||
args:
|
args:
|
||||||
|
@ -62,7 +62,10 @@ _nova_order = get_order(200)
|
|||||||
|
|
||||||
@base.resource("nova", "servers", order=next(_nova_order))
|
@base.resource("nova", "servers", order=next(_nova_order))
|
||||||
class NovaServer(base.ResourceManager):
|
class NovaServer(base.ResourceManager):
|
||||||
pass
|
def delete(self):
|
||||||
|
if getattr(self.raw_resource, "OS-EXT-STS:locked", False):
|
||||||
|
self.raw_resource.unlock()
|
||||||
|
super(NovaServer, self).delete()
|
||||||
|
|
||||||
|
|
||||||
@base.resource("nova", "keypairs", order=next(_nova_order))
|
@base.resource("nova", "keypairs", order=next(_nova_order))
|
||||||
|
@ -173,6 +173,37 @@ class NovaServers(utils.NovaScenario,
|
|||||||
action()
|
action()
|
||||||
self._delete_server(server, force=force_delete)
|
self._delete_server(server, force=force_delete)
|
||||||
|
|
||||||
|
@types.set(image=types.ImageResourceType,
|
||||||
|
flavor=types.FlavorResourceType)
|
||||||
|
@validation.image_valid_on_flavor("flavor", "image")
|
||||||
|
@validation.required_services(consts.Service.NOVA)
|
||||||
|
@validation.required_openstack(users=True)
|
||||||
|
@base.scenario(context={"cleanup": ["nova"]})
|
||||||
|
def boot_lock_unlock_and_delete(self, image, flavor,
|
||||||
|
min_sleep=0, max_sleep=0,
|
||||||
|
force_delete=False,
|
||||||
|
**kwargs):
|
||||||
|
"""Boot a server, lock it, then unlock and delete it.
|
||||||
|
|
||||||
|
Optional 'min_sleep' and 'max_sleep' parameters allow the
|
||||||
|
scenario to simulate a pause between locking and unlocking the
|
||||||
|
server (of random duration from min_sleep to max_sleep).
|
||||||
|
|
||||||
|
:param image: image to be used to boot an instance
|
||||||
|
:param flavor: flavor to be used to boot an instance
|
||||||
|
:param min_sleep: Minimum sleep time between locking and unlocking
|
||||||
|
in seconds
|
||||||
|
:param max_sleep: Maximum sleep time between locking and unlocking
|
||||||
|
in seconds
|
||||||
|
:param force_delete: True if force_delete should be used
|
||||||
|
:param kwargs: Optional additional arguments for server creation
|
||||||
|
"""
|
||||||
|
server = self._boot_server(image, flavor, **kwargs)
|
||||||
|
self._lock_server(server)
|
||||||
|
self.sleep_between(min_sleep, max_sleep)
|
||||||
|
self._unlock_server(server)
|
||||||
|
self._delete_server(server, force=force_delete)
|
||||||
|
|
||||||
@types.set(image=types.ImageResourceType,
|
@types.set(image=types.ImageResourceType,
|
||||||
flavor=types.FlavorResourceType)
|
flavor=types.FlavorResourceType)
|
||||||
@validation.image_valid_on_flavor("flavor", "image")
|
@validation.image_valid_on_flavor("flavor", "image")
|
||||||
|
@ -747,3 +747,19 @@ class NovaScenario(base.Scenario):
|
|||||||
def _list_hypervisors(self, detailed=True):
|
def _list_hypervisors(self, detailed=True):
|
||||||
"""List hypervisors."""
|
"""List hypervisors."""
|
||||||
return self.admin_clients("nova").hypervisors.list(detailed)
|
return self.admin_clients("nova").hypervisors.list(detailed)
|
||||||
|
|
||||||
|
@base.atomic_action_timer("nova.lock_server")
|
||||||
|
def _lock_server(self, server):
|
||||||
|
"""Lock the given server.
|
||||||
|
|
||||||
|
:param server: Server to lock
|
||||||
|
"""
|
||||||
|
server.lock()
|
||||||
|
|
||||||
|
@base.atomic_action_timer("nova.unlock_server")
|
||||||
|
def _unlock_server(self, server):
|
||||||
|
"""Unlock the given server.
|
||||||
|
|
||||||
|
:param server: Server to unlock
|
||||||
|
"""
|
||||||
|
server.unlock()
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"NovaServers.boot_lock_unlock_and_delete": [
|
||||||
|
{
|
||||||
|
"args": {
|
||||||
|
"flavor": {
|
||||||
|
"name": "m1.tiny"
|
||||||
|
},
|
||||||
|
"image": {
|
||||||
|
"name": "cirros-0.3.2-x86_64-uec"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runner": {
|
||||||
|
"type": "constant",
|
||||||
|
"times": 10,
|
||||||
|
"concurrency": 2
|
||||||
|
},
|
||||||
|
"context": {
|
||||||
|
"users": {
|
||||||
|
"tenants": 1,
|
||||||
|
"users_per_tenant": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
---
|
||||||
|
NovaServers.boot_lock_unlock_and_delete:
|
||||||
|
-
|
||||||
|
args:
|
||||||
|
flavor:
|
||||||
|
name: "m1.tiny"
|
||||||
|
image:
|
||||||
|
name: "cirros-0.3.2-x86_64-uec"
|
||||||
|
runner:
|
||||||
|
type: "constant"
|
||||||
|
times: 10
|
||||||
|
concurrency: 2
|
||||||
|
context:
|
||||||
|
users:
|
||||||
|
tenants: 1
|
||||||
|
users_per_tenant: 1
|
@ -82,6 +82,29 @@ class QuotaMixinTestCase(test.TestCase):
|
|||||||
self.assertEqual([quota.tenant_uuid], quota.list())
|
self.assertEqual([quota.tenant_uuid], quota.list())
|
||||||
|
|
||||||
|
|
||||||
|
class NovaServerTestCase(test.TestCase):
|
||||||
|
|
||||||
|
def test_delete(self):
|
||||||
|
server = resources.NovaServer()
|
||||||
|
server.raw_resource = mock.Mock()
|
||||||
|
server._manager = mock.Mock()
|
||||||
|
server.delete()
|
||||||
|
|
||||||
|
server._manager.return_value.delete.assert_called_once_with(
|
||||||
|
server.raw_resource.id)
|
||||||
|
|
||||||
|
def test_delete_locked(self):
|
||||||
|
server = resources.NovaServer()
|
||||||
|
server.raw_resource = mock.Mock()
|
||||||
|
setattr(server.raw_resource, "OS-EXT-STS:locked", True)
|
||||||
|
server._manager = mock.Mock()
|
||||||
|
server.delete()
|
||||||
|
|
||||||
|
server.raw_resource.unlock.assert_called_once_with()
|
||||||
|
server._manager.return_value.delete.assert_called_once_with(
|
||||||
|
server.raw_resource.id)
|
||||||
|
|
||||||
|
|
||||||
class NovaSecurityGroupTestCase(test.TestCase):
|
class NovaSecurityGroupTestCase(test.TestCase):
|
||||||
|
|
||||||
@mock.patch("%s.base.ResourceManager._manager" % BASE)
|
@mock.patch("%s.base.ResourceManager._manager" % BASE)
|
||||||
|
@ -106,6 +106,27 @@ class NovaServersTestCase(test.TestCase):
|
|||||||
scenario._delete_server.assert_called_once_with(fake_server,
|
scenario._delete_server.assert_called_once_with(fake_server,
|
||||||
force=False)
|
force=False)
|
||||||
|
|
||||||
|
def test_boot_lock_unlock_and_delete(self):
|
||||||
|
server = fakes.FakeServer()
|
||||||
|
image = fakes.FakeImage()
|
||||||
|
flavor = fakes.FakeFlavor()
|
||||||
|
|
||||||
|
scenario = servers.NovaServers()
|
||||||
|
scenario._boot_server = mock.Mock(return_value=server)
|
||||||
|
scenario._lock_server = mock.Mock(side_effect=lambda s: s.lock())
|
||||||
|
scenario._unlock_server = mock.Mock(side_effect=lambda s: s.unlock())
|
||||||
|
scenario._delete_server = mock.Mock(
|
||||||
|
side_effect=lambda s, **kwargs:
|
||||||
|
self.assertFalse(getattr(s, "OS-EXT-STS:locked", False)))
|
||||||
|
|
||||||
|
scenario.boot_lock_unlock_and_delete(image, flavor, fakearg="fakearg")
|
||||||
|
|
||||||
|
scenario._boot_server.assert_called_once_with(image, flavor,
|
||||||
|
fakearg="fakearg")
|
||||||
|
scenario._lock_server.assert_called_once_with(server)
|
||||||
|
scenario._unlock_server.assert_called_once_with(server)
|
||||||
|
scenario._delete_server.assert_called_once_with(server, force=False)
|
||||||
|
|
||||||
def test_validate_actions(self):
|
def test_validate_actions(self):
|
||||||
actions = [{"hardd_reboot": 6}]
|
actions = [{"hardd_reboot": 6}]
|
||||||
scenario = servers.NovaServers()
|
scenario = servers.NovaServers()
|
||||||
|
@ -757,3 +757,19 @@ class NovaScenarioTestCase(test.TestCase):
|
|||||||
mock_clients("nova").hypervisors.list.assert_called_once_with(False)
|
mock_clients("nova").hypervisors.list.assert_called_once_with(False)
|
||||||
self._test_atomic_action_timer(nova_scenario.atomic_actions(),
|
self._test_atomic_action_timer(nova_scenario.atomic_actions(),
|
||||||
"nova.list_hypervisors")
|
"nova.list_hypervisors")
|
||||||
|
|
||||||
|
def test__lock_server(self):
|
||||||
|
server = mock.Mock()
|
||||||
|
nova_scenario = utils.NovaScenario()
|
||||||
|
nova_scenario._lock_server(server)
|
||||||
|
server.lock.assert_called_once_with()
|
||||||
|
self._test_atomic_action_timer(nova_scenario.atomic_actions(),
|
||||||
|
"nova.lock_server")
|
||||||
|
|
||||||
|
def test__unlock_server(self):
|
||||||
|
server = mock.Mock()
|
||||||
|
nova_scenario = utils.NovaScenario()
|
||||||
|
nova_scenario._unlock_server(server)
|
||||||
|
server.unlock.assert_called_once_with()
|
||||||
|
self._test_atomic_action_timer(nova_scenario.atomic_actions(),
|
||||||
|
"nova.unlock_server")
|
||||||
|
@ -105,10 +105,15 @@ class FakeResource(object):
|
|||||||
|
|
||||||
|
|
||||||
class FakeServer(FakeResource):
|
class FakeServer(FakeResource):
|
||||||
|
|
||||||
def suspend(self):
|
def suspend(self):
|
||||||
self.status = "SUSPENDED"
|
self.status = "SUSPENDED"
|
||||||
|
|
||||||
|
def lock(self):
|
||||||
|
setattr(self, "OS-EXT-STS:locked", True)
|
||||||
|
|
||||||
|
def unlock(self):
|
||||||
|
setattr(self, "OS-EXT-STS:locked", False)
|
||||||
|
|
||||||
|
|
||||||
class FakeFailedServer(FakeResource):
|
class FakeFailedServer(FakeResource):
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user