Verify Server Actions attributes of Nova APIs
Below listed Server Actions does not return response body. They only
return the response code.
This patch adds the JSON schema for the response code 202 & 204
and validate the Server Actions response code with added schema.
Server Action Nova v2 Nova v3
addFixedIp 202 202
addSecurityGroup 202 N/A
changePassword 202 204
confirmResize 204 202
createBackup 202 202
forceDelete 202 202
injectNetworkInfo 202 202
lock 202 202
migrate 202 202
os-migrateLive 202 202
os-resetState 202 202
os-start 202 202
os-stop 202 202
pause 202 202
reboot 202 202
removeFixedIp 202 202
removeSecurityGroup 202 N/A
resetNetwork 202 202
resize 202 202
restore 202 202
resume 202 202
revertResize 202 202
shelve 202 202
shelveOffload 202 202
suspend 202 202
unlock 202 202
unpause 202 202
unrescue 202 202
unshelve 202 202
Partially implements blueprint nova-api-attribute-test
Change-Id: Ie078186527e53c8990a6058056f908e61dc2da8a
diff --git a/tempest/api_schema/compute/servers.py b/tempest/api_schema/compute/servers.py
index e11f047..fb39087 100644
--- a/tempest/api_schema/compute/servers.py
+++ b/tempest/api_schema/compute/servers.py
@@ -139,3 +139,11 @@
'required': ['servers']
}
}
+
+server_actions_common_schema = {
+ 'status_code': [202]
+}
+
+server_actions_delete_password = {
+ 'status_code': [204]
+}
diff --git a/tempest/api_schema/compute/v2/servers.py b/tempest/api_schema/compute/v2/servers.py
index e90f436..3da3276 100644
--- a/tempest/api_schema/compute/v2/servers.py
+++ b/tempest/api_schema/compute/v2/servers.py
@@ -128,3 +128,6 @@
'status_code': [200],
'response_body': parameter_types.addresses
}
+
+server_actions_confirm_resize = copy.deepcopy(
+ servers.server_actions_delete_password)
diff --git a/tempest/api_schema/compute/v3/servers.py b/tempest/api_schema/compute/v3/servers.py
index 956b5ad..8f694f7 100644
--- a/tempest/api_schema/compute/v3/servers.py
+++ b/tempest/api_schema/compute/v3/servers.py
@@ -81,3 +81,6 @@
'status_code': [200],
'response_body': addresses_v3
}
+
+server_actions_change_password = copy.deepcopy(
+ servers.server_actions_delete_password)
diff --git a/tempest/services/compute/json/interfaces_client.py b/tempest/services/compute/json/interfaces_client.py
index 8d51123..cdac8b7 100644
--- a/tempest/services/compute/json/interfaces_client.py
+++ b/tempest/services/compute/json/interfaces_client.py
@@ -17,6 +17,7 @@
import time
from tempest.api_schema.compute import interfaces as common_schema
+from tempest.api_schema.compute import servers as servers_schema
from tempest.api_schema.compute.v2 import interfaces as schema
from tempest.common import rest_client
from tempest import config
@@ -94,6 +95,8 @@
})
resp, body = self.post('servers/%s/action' % str(server_id),
post_body)
+ self.validate_response(servers_schema.server_actions_common_schema,
+ resp, body)
return resp, body
def remove_fixed_ip(self, server_id, ip_address):
@@ -105,4 +108,6 @@
})
resp, body = self.post('servers/%s/action' % str(server_id),
post_body)
+ self.validate_response(servers_schema.server_actions_common_schema,
+ resp, body)
return resp, body
diff --git a/tempest/services/compute/json/servers_client.py b/tempest/services/compute/json/servers_client.py
index 5204cd0..9c7eec6 100644
--- a/tempest/services/compute/json/servers_client.py
+++ b/tempest/services/compute/json/servers_client.py
@@ -204,7 +204,7 @@
return resp, body
def action(self, server_id, action_name, response_key,
- schema=None, **kwargs):
+ schema=common_schema.server_actions_common_schema, **kwargs):
post_body = json.dumps({action_name: kwargs})
resp, body = self.post('servers/%s/action' % str(server_id),
post_body)
@@ -218,6 +218,8 @@
if schema is not None:
self.validate_response(schema, resp, body)
body = body[response_key]
+ else:
+ self.validate_response(schema, resp, body)
return resp, body
def create_backup(self, server_id, backup_type, rotation, name):
@@ -245,8 +247,11 @@
Note that this does not actually change the instance server
password.
"""
- return self.delete("servers/%s/os-server-password" %
- str(server_id))
+ resp, body = self.delete("servers/%s/os-server-password" %
+ str(server_id))
+ self.validate_response(common_schema.server_actions_delete_password,
+ resp, body)
+ return resp, body
def reboot(self, server_id, reboot_type):
"""Reboots a server."""
@@ -258,7 +263,7 @@
if 'disk_config' in kwargs:
kwargs['OS-DCF:diskConfig'] = kwargs['disk_config']
del kwargs['disk_config']
- return self.action(server_id, 'rebuild', 'server', **kwargs)
+ return self.action(server_id, 'rebuild', 'server', None, **kwargs)
def resize(self, server_id, flavor_ref, **kwargs):
"""Changes the flavor of a server."""
@@ -270,7 +275,9 @@
def confirm_resize(self, server_id, **kwargs):
"""Confirms the flavor change for a server."""
- return self.action(server_id, 'confirmResize', None, **kwargs)
+ return self.action(server_id, 'confirmResize',
+ None, schema.server_actions_confirm_resize,
+ **kwargs)
def revert_resize(self, server_id, **kwargs):
"""Reverts a server back to its original flavor."""
@@ -370,6 +377,8 @@
req_body = json.dumps({'os-migrateLive': migrate_params})
resp, body = self.post("servers/%s/action" % str(server_id), req_body)
+ self.validate_response(common_schema.server_actions_common_schema,
+ resp, body)
return resp, body
def migrate_server(self, server_id, **kwargs):
@@ -418,7 +427,7 @@
def get_console_output(self, server_id, length):
return self.action(server_id, 'os-getConsoleOutput', 'output',
- length=length)
+ None, length=length)
def list_virtual_interfaces(self, server_id):
"""
@@ -432,7 +441,7 @@
def rescue_server(self, server_id, **kwargs):
"""Rescue the provided server."""
- return self.action(server_id, 'rescue', None, **kwargs)
+ return self.action(server_id, 'rescue', 'adminPass', None, **kwargs)
def unrescue_server(self, server_id):
"""Unrescue the provided server."""
diff --git a/tempest/services/compute/v3/json/interfaces_client.py b/tempest/services/compute/v3/json/interfaces_client.py
index 77b3179..e66ccaa 100644
--- a/tempest/services/compute/v3/json/interfaces_client.py
+++ b/tempest/services/compute/v3/json/interfaces_client.py
@@ -17,6 +17,7 @@
import time
from tempest.api_schema.compute import interfaces as common_schema
+from tempest.api_schema.compute import servers as servers_schema
from tempest.api_schema.compute.v3 import interfaces as schema
from tempest.common import rest_client
from tempest import config
@@ -95,6 +96,8 @@
})
resp, body = self.post('servers/%s/action' % str(server_id),
post_body)
+ self.validate_response(servers_schema.server_actions_common_schema,
+ resp, body)
return resp, body
def remove_fixed_ip(self, server_id, ip_address):
@@ -106,4 +109,6 @@
})
resp, body = self.post('servers/%s/action' % str(server_id),
post_body)
+ self.validate_response(servers_schema.server_actions_common_schema,
+ resp, body)
return resp, body
diff --git a/tempest/services/compute/v3/json/servers_client.py b/tempest/services/compute/v3/json/servers_client.py
index 1990d39..caa0a1d 100644
--- a/tempest/services/compute/v3/json/servers_client.py
+++ b/tempest/services/compute/v3/json/servers_client.py
@@ -203,12 +203,15 @@
self.validate_response(schema.list_addresses_by_network, resp, body)
return resp, body
- def action(self, server_id, action_name, response_key, **kwargs):
+ def action(self, server_id, action_name, response_key,
+ schema=common_schema.server_actions_common_schema, **kwargs):
post_body = json.dumps({action_name: kwargs})
resp, body = self.post('servers/%s/action' % str(server_id),
post_body)
if response_key is not None:
body = json.loads(body)[response_key]
+ else:
+ self.validate_response(schema, resp, body)
return resp, body
def create_backup(self, server_id, backup_type, rotation, name):
@@ -220,7 +223,8 @@
def change_password(self, server_id, admin_password):
"""Changes the root password for the server."""
- return self.action(server_id, 'change_password', None,
+ return self.action(server_id, 'change_password',
+ None, schema.server_actions_change_password,
admin_password=admin_password)
def get_password(self, server_id):
@@ -236,8 +240,11 @@
Note that this does not actually change the instance server
password.
"""
- return self.delete("servers/%s/os-server-password" %
- str(server_id))
+ resp, body = self.delete("servers/%s/os-server-password" %
+ str(server_id))
+ self.validate_response(common_schema.server_actions_delete_password,
+ resp, body)
+ return resp, body
def reboot(self, server_id, reboot_type):
"""Reboots a server."""
@@ -364,6 +371,8 @@
resp, body = self.post("servers/%s/action" % str(server_id),
req_body)
+ self.validate_response(common_schema.server_actions_common_schema,
+ resp, body)
return resp, body
def migrate_server(self, server_id, **kwargs):
@@ -416,7 +425,7 @@
def rescue_server(self, server_id, **kwargs):
"""Rescue the provided server."""
- return self.action(server_id, 'rescue', None, **kwargs)
+ return self.action(server_id, 'rescue', 'admin_password', **kwargs)
def unrescue_server(self, server_id):
"""Unrescue the provided server."""