Add os-migration tests for Nova v2 API

v2 os-migration API returns a body which includes the info like:

  {
    "migrations": [
      {
        "id": 1,
        "status": "finished",
        "instance_uuid": "e9e4fdd7-f956-44ff-bfeb-d654a96ab3a2",
        "source_node": "localhost-dev",
        "source_compute": "localhost-dev",
        "dest_node": "localhost-dev",
        "dest_compute": "localhost-dev",
        "dest_host": "192.168.11.100",
        "old_instance_type_id": 6,
        "new_instance_type_id": 2,
        "created_at": "2014-03-18T00:14:49.000000",
        "updated_at": "2014-03-18T00:15:15.000000"
      }
    ]
  }

This patch adds this API tests.

This patch adds tests for JSON format only without XML format because
the XML support has been marked as deprecated in Nova with the commit
I4acc15ce5f487738bb34a95c2261a5d05d827d8d and it will be removed in
Juno cycle.

Change-Id: I0e19b776313eff98d157e1249333174908061798
diff --git a/tempest/api/compute/admin/test_migrations.py b/tempest/api/compute/admin/test_migrations.py
new file mode 100644
index 0000000..514f1fa
--- /dev/null
+++ b/tempest/api/compute/admin/test_migrations.py
@@ -0,0 +1,55 @@
+# 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.
+
+import testtools
+
+from tempest.api.compute import base
+from tempest import config
+from tempest import test
+
+CONF = config.CONF
+
+
+class MigrationsAdminTest(base.BaseV2ComputeAdminTest):
+
+    @classmethod
+    def setUpClass(cls):
+        super(MigrationsAdminTest, cls).setUpClass()
+        cls.client = cls.os_adm.migrations_client
+
+    @test.attr(type='gate')
+    def test_list_migrations(self):
+        # Admin can get the migrations list
+        resp, _ = self.client.list_migrations()
+        self.assertEqual(200, resp.status)
+
+    @testtools.skipUnless(CONF.compute_feature_enabled.resize,
+                          'Resize not available.')
+    @test.attr(type='gate')
+    def test_list_migrations_in_flavor_resize_situation(self):
+        # Admin can get the migrations list which contains the resized server
+        resp, server = self.create_test_server(wait_until="ACTIVE")
+        server_id = server['id']
+
+        resp, _ = self.servers_client.resize(server_id, self.flavor_ref_alt)
+        self.assertEqual(202, resp.status)
+        self.servers_client.wait_for_server_status(server_id, 'VERIFY_RESIZE')
+        self.servers_client.confirm_resize(server_id)
+        self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
+
+        resp, body = self.client.list_migrations()
+        self.assertEqual(200, resp.status)
+
+        instance_uuids = [x['instance_uuid'] for x in body]
+        self.assertIn(server_id, instance_uuids)
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index abd36a6..b1614b8 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -233,6 +233,7 @@
             cls.os.instance_usages_audit_log_client
         cls.hypervisor_client = cls.os.hypervisor_client
         cls.certificates_client = cls.os.certificates_client
+        cls.migrations_client = cls.os.migrations_client
 
     @classmethod
     def create_image_from_server(cls, server_id, **kwargs):
diff --git a/tempest/clients.py b/tempest/clients.py
index 7ebd983..1c10176 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -52,6 +52,8 @@
     InterfacesClientJSON
 from tempest.services.compute.json.keypairs_client import KeyPairsClientJSON
 from tempest.services.compute.json.limits_client import LimitsClientJSON
+from tempest.services.compute.json.migrations_client import \
+    MigrationsClientJSON
 from tempest.services.compute.json.quotas_client import QuotasClientJSON
 from tempest.services.compute.json.security_groups_client import \
     SecurityGroupsClientJSON
@@ -381,6 +383,7 @@
             AccountClientCustomizedHeader(self.auth_provider)
         self.data_processing_client = DataProcessingClient(
             self.auth_provider)
+        self.migrations_client = MigrationsClientJSON(self.auth_provider)
 
 
 class AltManager(Manager):
diff --git a/tempest/services/compute/json/migrations_client.py b/tempest/services/compute/json/migrations_client.py
new file mode 100644
index 0000000..a13349e
--- /dev/null
+++ b/tempest/services/compute/json/migrations_client.py
@@ -0,0 +1,39 @@
+# Copyright 2014 NEC Corporation.
+#
+#    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.
+
+import json
+import urllib
+
+from tempest.common import rest_client
+from tempest import config
+
+CONF = config.CONF
+
+
+class MigrationsClientJSON(rest_client.RestClient):
+
+    def __init__(self, auth_provider):
+        super(MigrationsClientJSON, self).__init__(auth_provider)
+        self.service = CONF.compute.catalog_type
+
+    def list_migrations(self, params=None):
+        """Lists all migrations."""
+
+        url = 'os-migrations'
+        if params:
+            url += '?%s' % urllib.urlencode(params)
+
+        resp, body = self.get(url)
+        body = json.loads(body)
+        return resp, body['migrations']