New test case: "test_connection_limit"
Traffic based test, that is planned to validate "connection_limit" functionality. Once set, LB should limit clients' connections (parallel sessions) to the set value. Change-Id: I3cf49f6281529058b86b88501872292771812c6c
This commit is contained in:
parent
c50539cc07
commit
b6d71a7d12
|
@ -19,6 +19,8 @@ import socket
|
|||
import testtools
|
||||
import time
|
||||
|
||||
from threading import Thread
|
||||
|
||||
from oslo_log import log as logging
|
||||
from oslo_utils import uuidutils
|
||||
from tempest import config
|
||||
|
@ -1391,3 +1393,65 @@ class TrafficOperationsScenarioTest(test_base.LoadBalancerBaseTestWithCompute):
|
|||
listener_port), const.X_FORWARDED_PROTO: const.HTTP.lower()}
|
||||
received_headers = _data_parser(data, expected_headers)
|
||||
self.assertEqual(expected_headers, received_headers)
|
||||
|
||||
@decorators.idempotent_id('45f5f018-1073-11eb-be7b-74e5f9e2a801')
|
||||
def test_connection_limit(self):
|
||||
"""Test scenario:
|
||||
|
||||
* Create LB, HTTP listener, pool, 2 members and validate traffic.
|
||||
* Update listener's "connection_limit" to "X", wait till
|
||||
* configuration is done.
|
||||
* Start HTTP traffic - parallel TCP connections that are doubled
|
||||
* than configured "connection_limit", it means (X*2)
|
||||
* Assertion - test fails if the amount of "Failed TCP connections"
|
||||
* is less than total TCP connections ("X/2")sent in parallel.
|
||||
"""
|
||||
listener_port = 104
|
||||
listener_id, pool_id = self._listener_pool_create(
|
||||
const.HTTP, listener_port)
|
||||
self._test_basic_traffic(
|
||||
const.HTTP, listener_port, pool_id, persistent=False)
|
||||
|
||||
# Update listener's "connection_limit" to: <connection_limit> value.
|
||||
connection_limit = 5
|
||||
listener_kwargs = {
|
||||
const.LISTENER_ID: listener_id,
|
||||
const.CONNECTION_LIMIT: connection_limit}
|
||||
self.mem_listener_client.update_listener(**listener_kwargs)
|
||||
waiters.wait_for_status(self.mem_lb_client.show_loadbalancer,
|
||||
self.lb_id, const.PROVISIONING_STATUS,
|
||||
const.ACTIVE,
|
||||
CONF.load_balancer.build_interval,
|
||||
CONF.load_balancer.build_timeout)
|
||||
|
||||
# Start the traffic, using parallel TCP connections.
|
||||
# The number of TCP connection is "doubled" than the amount of
|
||||
# configured connection limit set.
|
||||
connections_number = connection_limit * 2
|
||||
http_gets_per_connection = 10
|
||||
delay_between_http_gets = 0.1
|
||||
threads = [None] * connections_number
|
||||
traffic_result_limited = [None] * connections_number
|
||||
for i in range(len(threads)):
|
||||
threads[i] = Thread(
|
||||
target=self._http_requests_single_connection,
|
||||
args=(self.lb_vip_address, listener_port,
|
||||
http_gets_per_connection, delay_between_http_gets,
|
||||
traffic_result_limited, i))
|
||||
threads[i].start()
|
||||
for i in range(len(threads)):
|
||||
threads[i].join()
|
||||
LOG.info('test_connection_limit traffic_result_limited: '
|
||||
+ str(traffic_result_limited))
|
||||
|
||||
# Assertion - test fails if the amount of "Failed Connections"
|
||||
# is less than "total TCP connections sent"/2
|
||||
failed_connections_limited = len(
|
||||
[item for item in traffic_result_limited
|
||||
if item['ConnectionStatus'] is False])
|
||||
LOG.info('test_connection_limit failed_connections_limited: '
|
||||
+ str(failed_connections_limited))
|
||||
self.assertGreaterEqual(
|
||||
failed_connections_limited,
|
||||
connections_number/2,
|
||||
'Failed - the number of failed connections is less than expected!')
|
||||
|
|
|
@ -421,3 +421,41 @@ class ValidatorsMixin(test.BaseTestCase):
|
|||
protocol_port))
|
||||
LOG.error(message)
|
||||
raise Exception(message)
|
||||
|
||||
@staticmethod
|
||||
def _http_requests_single_connection(
|
||||
dst_ip, dst_port, request_number,
|
||||
delay, result, index, tcp_timeout=1):
|
||||
"""This function is used as a thread target function.
|
||||
|
||||
:param dst_ip: Destination HTTP server IP.
|
||||
:param dst_port: Destination HTTP server port.
|
||||
:param request_number: A number of subsequent GET requests to be sent
|
||||
on the same TCP connection/session.
|
||||
:param delay: Delay in [sec] between the GET requests.
|
||||
:param result: A list of Nones: [None, None..., None] as a number of
|
||||
threads to be started. Each thread will then update appropriate
|
||||
item in this list with its own retrieved data.
|
||||
:param index: Indexing the threads.
|
||||
:param tcp_timeout: Python Requests module TCP timeout.
|
||||
:return: Updated by threads "result" list, for example 1 threads
|
||||
with a single GET may look like this:
|
||||
[{'ConnectionStatus': True,
|
||||
'RespondData': [{'RequestNumber': 0,'ResponseCode': 200,
|
||||
'ResponseContentSize': 1}]
|
||||
|
||||
"""
|
||||
try:
|
||||
s = requests.Session()
|
||||
responses = []
|
||||
for req in range(0, request_number):
|
||||
r = s.get('http://'+dst_ip+':'+str(dst_port),
|
||||
timeout=tcp_timeout)
|
||||
responses.append({
|
||||
'RequestNumber': req, 'ResponseCode': r.status_code,
|
||||
'ResponseContentSize': len(r.content)})
|
||||
time.sleep(delay)
|
||||
result[index] = {
|
||||
'ConnectionStatus': True, 'RespondData': responses}
|
||||
except Exception as e:
|
||||
result[index] = {'ConnectionStatus': False, 'RespondData': e}
|
||||
|
|
Loading…
Reference in New Issue