Simplify the QoS bandwidth test to increase reliability

The initial implementation was measuring the bandwidth stability
over segments of time. But recent failures on high gate pressure
has shown that such stability can't be expected on the edge.

The test now checks the average bandwidth during the whole transmission.

Change-Id: Ic6a00f20ce76aba319ecdada79f68599c891cf29
Closes-Bug: #1662109
diff --git a/neutron/tests/tempest/scenario/test_qos.py b/neutron/tests/tempest/scenario/test_qos.py
index b558438..8b8e90a 100644
--- a/neutron/tests/tempest/scenario/test_qos.py
+++ b/neutron/tests/tempest/scenario/test_qos.py
@@ -38,7 +38,6 @@
         client_socket = socket.socket(socket.AF_INET,
                                       socket.SOCK_STREAM)
         client_socket.connect((host_ip, port))
-        client_socket.setblocking(0)
         return client_socket
     except socket.error as serr:
         if serr.errno == errno.ECONNREFUSED:
@@ -97,10 +96,6 @@
                 file=QoSTest.FILE_PATH)
 
     def _check_bw(self, ssh_client, host, port):
-        total_bytes_read = 0
-        cycle_start_time = time.time()
-        cycle_data_read = 0
-
         cmd = "killall -q nc"
         try:
             ssh_client.exec_command(cmd)
@@ -109,36 +104,26 @@
         cmd = ("(nc -ll -p %(port)d < %(file_path)s > /dev/null &)" % {
                 'port': port, 'file_path': QoSTest.FILE_PATH})
         ssh_client.exec_command(cmd)
+
+        start_time = time.time()
         client_socket = _connect_socket(host, port)
+        total_bytes_read = 0
 
         while total_bytes_read < QoSTest.FILE_SIZE:
-            try:
-                data = client_socket.recv(QoSTest.BUFFER_SIZE)
-            except socket.error as e:
-                if e.args[0] in [errno.EAGAIN, errno.EWOULDBLOCK]:
-                    continue
-                else:
-                    raise
+            data = client_socket.recv(QoSTest.BUFFER_SIZE)
             total_bytes_read += len(data)
-            cycle_data_read += len(data)
-            time_elapsed = time.time() - cycle_start_time
-            should_check = (time_elapsed >= 5 or
-                            total_bytes_read == QoSTest.FILE_SIZE)
-            if should_check:
-                LOG.debug("time_elapsed =  %(time_elapsed)d,"
-                          "total_bytes_read = %(bytes_read)d,"
-                          "cycle_data_read = %(cycle_data)d",
-                          {"time_elapsed": time_elapsed,
-                           "bytes_read": total_bytes_read,
-                           "cycle_data": cycle_data_read})
 
-                if cycle_data_read / time_elapsed > QoSTest.LIMIT_BYTES_SEC:
-                    # Limit reached
-                    return False
-                else:
-                    cycle_start_time = time.time()
-                    cycle_data_read = 0
-        return True
+        time_elapsed = time.time() - start_time
+        bytes_per_second = total_bytes_read / time_elapsed
+
+        LOG.debug("time_elapsed = %(time_elapsed)d, "
+                  "total_bytes_read = %(total_bytes_read)d, "
+                  "bytes_per_second = %(bytes_per_second)d",
+                  {'time_elapsed': time_elapsed,
+                   'total_bytes_read': total_bytes_read,
+                   'bytes_per_second': bytes_per_second})
+
+        return bytes_per_second <= QoSTest.LIMIT_BYTES_SEC
 
     @test.idempotent_id('1f7ed39b-428f-410a-bd2b-db9f465680df')
     def test_qos(self):