Microversion v2.20 tests: nova volume operations when shelved

Compute microversion v2.20 allows the volume attachment operations
while server in shelved and shelved_offloaded state.

Ref- http://docs.openstack.org/developer/nova/api_microversion_history.html#id18

This commit adds tests for that behavior and verify the attaching and detaching
volumes from a shelved or shelved_offloaded server.

NOTE- In addition to tests, this also does some schema versioning.
Tempest strictly validate the response and does not allow additional elements
in response.
As v2.20 microversion request will respond as latest behavior of Nova till V2.20,
response schema needs to be version for older microversion if response is changed in between.
Adding schema versioning for v2.9 and 2.19 where server response has been changed.

Co-Authored-By: ghanshyam <ghanshyam.mann@nectechnologies.in>

Change-Id: I5ececf58f7ccda5521ace456f017795f14f11def
diff --git a/tempest/lib/services/compute/servers_client.py b/tempest/lib/services/compute/servers_client.py
index a37f167..0472eda 100644
--- a/tempest/lib/services/compute/servers_client.py
+++ b/tempest/lib/services/compute/servers_client.py
@@ -20,11 +20,17 @@
 from six.moves.urllib import parse as urllib
 
 from tempest.lib.api_schema.response.compute.v2_1 import servers as schema
+from tempest.lib.api_schema.response.compute.v2_19 import servers as schemav219
+from tempest.lib.api_schema.response.compute.v2_9 import servers as schemav29
 from tempest.lib.common import rest_client
 from tempest.lib.services.compute import base_compute_client
 
 
 class ServersClient(base_compute_client.BaseComputeClient):
+    schema_versions_info = [
+        {'min': None, 'max': '2.8', 'schema': schema},
+        {'min': '2.9', 'max': '2.18', 'schema': schemav29},
+        {'min': '2.19', 'max': None, 'schema': schemav219}]
 
     def __init__(self, auth_provider, service, region,
                  enable_instance_password=True, **kwargs):
@@ -88,6 +94,7 @@
         post_body = json.dumps({'server': kwargs})
         resp, body = self.put("servers/%s" % server_id, post_body)
         body = json.loads(body)
+        schema = self.get_schema(self.schema_versions_info)
         self.validate_response(schema.update_server, resp, body)
         return rest_client.ResponseBody(resp, body)
 
@@ -95,6 +102,7 @@
         """Get server details."""
         resp, body = self.get("servers/%s" % server_id)
         body = json.loads(body)
+        schema = self.get_schema(self.schema_versions_info)
         self.validate_response(schema.get_server, resp, body)
         return rest_client.ResponseBody(resp, body)
 
@@ -114,6 +122,7 @@
         """
 
         url = 'servers'
+        schema = self.get_schema(self.schema_versions_info)
         _schema = schema.list_servers
 
         if detail:
@@ -209,6 +218,7 @@
         kwargs['imageRef'] = image_ref
         if 'disk_config' in kwargs:
             kwargs['OS-DCF:diskConfig'] = kwargs.pop('disk_config')
+        schema = self.get_schema(self.schema_versions_info)
         if self.enable_instance_password:
             rebuild_schema = schema.rebuild_server_with_admin_pass
         else: