Code Sync from neutron project to newly created neutron-tempest-plugin

* The following commit sync the code from following hash:
  start_hash: 7279aa35851110a4933a10b58b2758a2bc3933a3
  end_hash: 6e911a49a9e630878f4c46f61fde3964be550880

Change-Id: I371aa4d5f043f695df04b98b0f485c8f0548f2b3
diff --git a/neutron_tempest_plugin/scenario/test_migration.py b/neutron_tempest_plugin/scenario/test_migration.py
index 291611c..62c3642 100644
--- a/neutron_tempest_plugin/scenario/test_migration.py
+++ b/neutron_tempest_plugin/scenario/test_migration.py
@@ -13,9 +13,14 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.lib import decorators
-from tempest import test
+import functools
 
+from neutron_lib.api.definitions import portbindings as pb
+from neutron_lib import constants as const
+from tempest.common import utils
+from tempest.lib import decorators
+
+from neutron_tempest_plugin.common import utils as common_utils
 from neutron_tempest_plugin.scenario import base
 from neutron_tempest_plugin.scenario import test_dvr
 
@@ -26,8 +31,8 @@
     force_tenant_isolation = False
 
     @classmethod
-    @test.requires_ext(extension="dvr", service="network")
-    @test.requires_ext(extension="l3-ha", service="network")
+    @utils.requires_ext(extension="dvr", service="network")
+    @utils.requires_ext(extension="l3-ha", service="network")
     def skip_checks(cls):
         super(NetworkMigrationTestBase, cls).skip_checks()
 
@@ -36,12 +41,77 @@
         self.assertEqual(is_dvr, router['router']['distributed'])
         self.assertEqual(is_ha, router['router']['ha'])
 
+    def _wait_until_port_deleted(self, router_id, device_owner):
+        common_utils.wait_until_true(
+            functools.partial(
+                self._is_port_deleted,
+                router_id,
+                device_owner),
+            timeout=300, sleep=5)
+
+    def _is_port_deleted(self, router_id, device_owner):
+        ports = self.os_admin.network_client.list_ports(
+            device_id=router_id,
+            device_owner=device_owner)
+        return not ports.get('ports')
+
+    def _wait_until_port_ready(self, router_id, device_owner):
+        common_utils.wait_until_true(
+            functools.partial(
+                self._is_port_active,
+                router_id,
+                device_owner),
+            timeout=300, sleep=5)
+
+    def _is_port_active(self, router_id, device_owner):
+        ports = self.os_admin.network_client.list_ports(
+            device_id=router_id,
+            device_owner=device_owner,
+            status=const.ACTIVE).get('ports')
+        if ports:
+            if ports[0][pb.VIF_TYPE] not in [pb.VIF_TYPE_UNBOUND,
+                                             pb.VIF_TYPE_BINDING_FAILED]:
+                return True
+        return False
+
+    def _wait_until_router_ports_ready(self, router_id, dvr, ha):
+        if dvr:
+            self._wait_until_port_ready(
+                router_id, const.DEVICE_OWNER_DVR_INTERFACE)
+        if ha:
+            self._wait_until_port_ready(
+                router_id, const.DEVICE_OWNER_ROUTER_HA_INTF)
+            if dvr:
+                self._wait_until_port_ready(
+                    router_id, const.DEVICE_OWNER_ROUTER_SNAT)
+            else:
+                self._wait_until_port_ready(
+                    router_id, const.DEVICE_OWNER_HA_REPLICATED_INT)
+        self._wait_until_port_ready(
+            router_id, const.DEVICE_OWNER_ROUTER_GW)
+
+    def _wait_until_router_ports_migrated(
+            self, router_id, before_dvr, before_ha, after_dvr, after_ha):
+        if before_ha and not after_ha:
+            self._wait_until_port_deleted(
+                router_id, const.DEVICE_OWNER_ROUTER_HA_INTF)
+            self._wait_until_port_deleted(
+                    router_id, const.DEVICE_OWNER_HA_REPLICATED_INT)
+        if before_dvr and not after_dvr:
+            self._wait_until_port_deleted(
+                router_id, const.DEVICE_OWNER_DVR_INTERFACE)
+            self._wait_until_port_deleted(
+                router_id, const.DEVICE_OWNER_ROUTER_SNAT)
+        self._wait_until_router_ports_ready(router_id, after_dvr, after_ha)
+
     def _test_migration(self, before_dvr, before_ha, after_dvr, after_ha):
         router = self.create_router_by_client(
             distributed=before_dvr, ha=before_ha,
             tenant_id=self.client.tenant_id, is_admin=True)
 
         self.setup_network_and_server(router=router)
+        self._wait_until_router_ports_ready(
+            router['id'], before_dvr, before_ha)
         self._check_connectivity()
 
         self.os_admin.network_client.update_router(
@@ -52,6 +122,9 @@
 
         self.os_admin.network_client.update_router(
             router_id=router['id'], admin_state_up=True)
+
+        self._wait_until_router_ports_migrated(
+            router['id'], before_dvr, before_ha, after_dvr, after_ha)
         self._check_connectivity()