Adds status check for FloatingIP in network scenarios

Verifies FloatingIP changes status correctly on association and dis-association

Scenarios:
test_network_basic_op
test_network_advanced_server_ops

Status is verified after connectivity check and without a waiter in order to
not mask unknown races in Neutron

Changes show() to refresh() to keep consistency

Partially Implements: blueprint fip-op-status (this is a Neutron bp:
https://blueprints.launchpad.net/neutron/+spec/fip-op-status)
Partially Implements: blueprint neutron-advanced-scenarios

Change-Id: Ibd45f3092cebc8f9fd0d16a3a543c2ef72156409
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 79207cd..4cde415 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -622,6 +622,23 @@
         self.assertIsNone(floating_ip.port_id)
         return floating_ip
 
+    def check_floating_ip_status(self, floating_ip, status):
+        """Verifies floatingip has reached given status. without waiting
+
+        :param floating_ip: net_resources.DeletableFloatingIp floating IP to
+        to check status
+        :param status: target status
+        :raises: AssertionError if status doesn't match
+        """
+        floating_ip.refresh()
+        self.assertEqual(status, floating_ip.status,
+                         message="FloatingIP: {fp} is at status: {cst}. "
+                                 "failed  to reach status: {st}"
+                         .format(fp=floating_ip, cst=floating_ip.status,
+                                 st=status))
+        LOG.info("FloatingIP: {fp} is at status: {st}"
+                 .format(fp=floating_ip, st=status))
+
     def _check_vm_connectivity(self, ip_address,
                                username=None,
                                private_key=None,
diff --git a/tempest/scenario/test_network_advanced_server_ops.py b/tempest/scenario/test_network_advanced_server_ops.py
index 58a028f..0c48334 100644
--- a/tempest/scenario/test_network_advanced_server_ops.py
+++ b/tempest/scenario/test_network_advanced_server_ops.py
@@ -87,6 +87,7 @@
         self._check_public_network_connectivity(floating_ip, username,
                                                 private_key, should_connect,
                                                 servers=[self.server])
+        self.check_floating_ip_status(self.floating_ip, 'ACTIVE')
 
     def _wait_server_status_and_check_network_connectivity(self):
         self.servers_client.wait_for_server_status(self.server['id'], 'ACTIVE')
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index de60745..5d75b64 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -176,16 +176,31 @@
 
     def _check_public_network_connectivity(self, should_connect=True,
                                            msg=None):
+        """Verifies connectivty to a VM via public network and floating IP,
+        and verifies floating IP has resource status is correct.
+
+        Floating IP status is verified after connectivity test in order to
+        not add extra waiting and mask racing conditions.
+
+        :param should_connect: bool. determines if connectivity check is
+        negative or positive.
+        :param msg: Failure message to add to Error message. Should describe
+        the place in the test scenario where the method was called,
+        to indicate the context of the failure
+        """
         ssh_login = CONF.compute.image_ssh_user
         floating_ip, server = self.floating_ip_tuple
         ip_address = floating_ip.floating_ip_address
         private_key = None
+        floatingip_status = 'DOWN'
         if should_connect:
             private_key = self._get_server_key(server)
+            floatingip_status = 'ACTIVE'
         # call the common method in the parent class
         super(TestNetworkBasicOps, self)._check_public_network_connectivity(
             ip_address, ssh_login, private_key, should_connect, msg,
             self.servers)
+        self.check_floating_ip_status(floating_ip, floatingip_status)
 
     def _disassociate_floating_ips(self):
         floating_ip, server = self.floating_ip_tuple
@@ -350,6 +365,8 @@
         VMs are created with unique keypair so connectivity also asserts that
         floating IP is associated with the new VM instead of the old one
 
+        Verifies that floating IP status is updated correctly after each change
+
 
         """
         self._setup_network_and_servers()
diff --git a/tempest/services/network/resources.py b/tempest/services/network/resources.py
index 2b182d0..a84b4d5 100644
--- a/tempest/services/network/resources.py
+++ b/tempest/services/network/resources.py
@@ -52,7 +52,7 @@
         return
 
     @abc.abstractmethod
-    def show(self):
+    def refresh(self):
         return
 
     def __hash__(self):
@@ -62,7 +62,11 @@
         if not hasattr(self, 'status'):
             return
 
-        return self.client.wait_for_resource_status(self.show, status)
+        def helper_get():
+            self.refresh()
+            return self
+
+        return self.client.wait_for_resource_status(helper_get, status)
 
 
 class DeletableNetwork(DeletableResource):
@@ -116,6 +120,12 @@
 
 class DeletableFloatingIp(DeletableResource):
 
+    def refresh(self, *args, **kwargs):
+        _, result = self.client.show_floatingip(self.id,
+                                                *args,
+                                                **kwargs)
+        super(DeletableFloatingIp, self).update(**result['floatingip'])
+
     def update(self, *args, **kwargs):
         _, result = self.client.update_floatingip(self.id,
                                                   *args,
@@ -172,7 +182,6 @@
     def delete(self):
         self.client.delete_vip(self.id)
 
-    def show(self):
+    def refresh(self):
         _, result = self.client.show_vip(self.id)
-        super(DeletableVip, self).update(**result['vip'])
-        return self
+        super(DeletableVip, self).update(**result['vip'])
\ No newline at end of file