Verify Image attributes through Nova V2 GET API

This patch adds the JSON Schema for response of Nova V2 GET Image API
and validate the response with added JSON Schema to block the backward
incompatibility change in the future.

The response body of V2 GET Image API is below:

{
    "image": {
        "id": "70a599e0-31e7-49b7-b260-868f441e862b",
        "status": "ACTIVE",
        "updated": "2011-01-01T01:02:03Z",
        "links": [
            {
                "href": "http://openstack.example.com/v2/openstack/
                        images/70a599e0-31e7-49b7-b260-868f441e862b",
                "rel": "self"
            },
            {
                "href": "http://openstack.example.com/openstack/
                        images/70a599e0-31e7-49b7-b260-868f441e862b",
                "rel": "bookmark"
            },
            {
                "href": "http://glance.openstack.example.com/openstack/
                        images/70a599e0-31e7-49b7-b260-868f441e862b",
                "rel": "alternate",
                "type": "application/vnd.openstack.image"
            }
        ],
        "name": "fakeimage7",
        "created": "2011-01-01T01:02:03Z",
        "OS-EXT-IMG-SIZE:size": 25165824,
        "minDisk": 0,
        "minRam": 0,
        "progress": 100,
        "metadata": {
            "architecture": "x86_64",
            "auto_disk_config": "True",
            "kernel_id": "nokernel",
            "ramdisk_id": "nokernel"
        },
        "server": {
            "id": "65802d04-c684-4900-b645-a6a15f78add4",
            "links": [
                {
                    "href": "http://10.21.43.120:8774/v2/
                            f0468e49de7b4f74b6359a6dd3a72481/servers/
                            65802d04-c684-4900-b645-a6a15f78add4",
                    "rel": "self"
                }
            ]
        }
    }
}

Partially implements blueprint nova-api-attribute-test

Change-Id: I3f09f5857ad35bc9f703a0482c761ae2ec2418f1
diff --git a/tempest/api_schema/compute/v2/images.py b/tempest/api_schema/compute/v2/images.py
new file mode 100644
index 0000000..fb4804d
--- /dev/null
+++ b/tempest/api_schema/compute/v2/images.py
@@ -0,0 +1,81 @@
+# Copyright 2014 NEC Corporation.  All rights reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+get_image = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'image': {
+                'type': 'object',
+                'properties': {
+                    'id': {'type': 'string'},
+                    'status': {'type': 'string'},
+                    'updated': {'type': 'string'},
+                    'links': {
+                        'type': 'array',
+                        'items': {
+                            'type': 'object',
+                            'properties': {
+                                'href': {
+                                    'type': 'string',
+                                    'format': 'uri'
+                                },
+                                'rel': {'type': 'string'}
+                            },
+                            'required': ['href', 'rel']
+                        }
+                    },
+                    'name': {'type': 'string'},
+                    'created': {'type': 'string'},
+                    'OS-EXT-IMG-SIZE:size': {'type': 'integer'},
+                    'minDisk': {'type': 'integer'},
+                    'minRam': {'type': 'integer'},
+                    'progress': {'type': 'integer'},
+                    'metadata': {'type': 'object'},
+                    'server': {
+                        'type': 'object',
+                        'properties': {
+                            # NOTE: Now the type of 'id' is integer, but here
+                            # allows 'string' also because we will be able to
+                            # change it to 'uuid' in the future.
+                            'id': {'type': ['integer', 'string']},
+                            'links': {
+                                'type': 'array',
+                                'items': {
+                                    'type': 'object',
+                                    'properties': {
+                                        'href': {
+                                            'type': 'string',
+                                            'format': 'uri'
+                                        },
+                                        'rel': {'type': 'string'}
+                                    },
+                                    'required': ['href', 'rel']
+                                }
+                            }
+                        },
+                        'required': ['id', 'links']
+                    }
+                },
+                # 'server' attributes only comes in response body if image is
+                # associated with any server. So it is not 'required'
+                'required': ['id', 'status', 'updated', 'links', 'name',
+                             'created', 'OS-EXT-IMG-SIZE:size', 'minDisk',
+                             'minRam', 'progress', 'metadata']
+            }
+        },
+        'required': ['image']
+    }
+}
diff --git a/tempest/services/compute/json/images_client.py b/tempest/services/compute/json/images_client.py
index 5a79a29..deb9c93 100644
--- a/tempest/services/compute/json/images_client.py
+++ b/tempest/services/compute/json/images_client.py
@@ -16,6 +16,7 @@
 import json
 import urllib
 
+from tempest.api_schema.compute.v2 import images as schema
 from tempest.common import rest_client
 from tempest.common import waiters
 from tempest import config
@@ -74,6 +75,7 @@
         resp, body = self.get("images/%s" % str(image_id))
         self.expected_success(200, resp)
         body = json.loads(body)
+        self.validate_response(schema.get_image, resp, body)
         return resp, body['image']
 
     def delete_image(self, image_id):