New test case: "test_insert_headers"
This test covers LB "insert HTTP headers" functionality. It’s a traffic based scenario and validation is done using real HTTP headers being received on backend side. Change-Id: I97efd6bcc793e1378356c18209d5345597f39a00
This commit is contained in:
parent
3497f6cb70
commit
1ea1a2bd37
|
@ -15,6 +15,7 @@
|
||||||
import datetime
|
import datetime
|
||||||
import ipaddress
|
import ipaddress
|
||||||
import shlex
|
import shlex
|
||||||
|
import socket
|
||||||
import testtools
|
import testtools
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
@ -90,7 +91,8 @@ class TrafficOperationsScenarioTest(test_base.LoadBalancerBaseTestWithCompute):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _listener_pool_create(cls, protocol, protocol_port,
|
def _listener_pool_create(cls, protocol, protocol_port,
|
||||||
pool_algorithm=const.LB_ALGORITHM_ROUND_ROBIN):
|
pool_algorithm=const.LB_ALGORITHM_ROUND_ROBIN,
|
||||||
|
insert_headers_dic=None):
|
||||||
if (protocol == const.UDP and
|
if (protocol == const.UDP and
|
||||||
not cls.mem_listener_client.is_version_supported(
|
not cls.mem_listener_client.is_version_supported(
|
||||||
cls.api_version, '2.1')):
|
cls.api_version, '2.1')):
|
||||||
|
@ -112,6 +114,10 @@ class TrafficOperationsScenarioTest(test_base.LoadBalancerBaseTestWithCompute):
|
||||||
# haproxy process and use haproxy>=1.8:
|
# haproxy process and use haproxy>=1.8:
|
||||||
const.CONNECTION_LIMIT: 200,
|
const.CONNECTION_LIMIT: 200,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if insert_headers_dic:
|
||||||
|
listener_kwargs[const.INSERT_HEADERS] = insert_headers_dic
|
||||||
|
|
||||||
listener = cls.mem_listener_client.create_listener(**listener_kwargs)
|
listener = cls.mem_listener_client.create_listener(**listener_kwargs)
|
||||||
|
|
||||||
waiters.wait_for_status(cls.mem_lb_client.show_loadbalancer,
|
waiters.wait_for_status(cls.mem_lb_client.show_loadbalancer,
|
||||||
|
@ -1322,3 +1328,70 @@ class TrafficOperationsScenarioTest(test_base.LoadBalancerBaseTestWithCompute):
|
||||||
protocol_port)
|
protocol_port)
|
||||||
self.assertConsistentResponse(
|
self.assertConsistentResponse(
|
||||||
(None, None), url_for_vip, repeat=3, expect_connection_error=True)
|
(None, None), url_for_vip, repeat=3, expect_connection_error=True)
|
||||||
|
|
||||||
|
@decorators.idempotent_id('d3a28e76-76bc-11eb-a7c3-74e5f9e2a801')
|
||||||
|
def test_insert_headers(self):
|
||||||
|
# Create listener, enable insert of "X_FORWARDED_FOR" HTTP header
|
||||||
|
listener_port = 102
|
||||||
|
listener_id, pool_id = self._listener_pool_create(
|
||||||
|
const.HTTP, listener_port, insert_headers_dic={
|
||||||
|
const.X_FORWARDED_FOR: "true"})
|
||||||
|
self._test_basic_traffic(
|
||||||
|
const.HTTP, listener_port, listener_id, pool_id)
|
||||||
|
|
||||||
|
# Initiate HTTP traffic
|
||||||
|
test_url = 'http://{}:{}/request'.format(
|
||||||
|
self.lb_vip_address, listener_port)
|
||||||
|
data = self.validate_URL_response(test_url)
|
||||||
|
LOG.info('Received payload is: {}'.format(data))
|
||||||
|
|
||||||
|
# Detect source IP that is used to create TCP socket toward LB_VIP.
|
||||||
|
try:
|
||||||
|
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
s.connect((self.lb_vip_address, listener_port))
|
||||||
|
client_source_ip = s.getsockname()[0]
|
||||||
|
s.close()
|
||||||
|
except Exception:
|
||||||
|
LOG.exception('Failed to initiate TCP socket toward LB_VIP')
|
||||||
|
raise Exception('LB_VIP is not available')
|
||||||
|
|
||||||
|
# Function needed to parse the received payload from backend.
|
||||||
|
# Returns dictionary of relevant headers if found.
|
||||||
|
def _data_parser(payload, relevant_headers):
|
||||||
|
retrieved_headers = {}
|
||||||
|
for line in payload.split('\n'):
|
||||||
|
try:
|
||||||
|
key, value = line.split(': ', 1)
|
||||||
|
except ValueError:
|
||||||
|
continue
|
||||||
|
if key in relevant_headers:
|
||||||
|
retrieved_headers[key] = value.lower()
|
||||||
|
return retrieved_headers
|
||||||
|
|
||||||
|
# Make sure that "X_FORWARDED_FOR" header was inserted with
|
||||||
|
# expected IP (client_source_ip). Should present in data.
|
||||||
|
expected_headers = {const.X_FORWARDED_FOR: client_source_ip}
|
||||||
|
received_headers = _data_parser(data, expected_headers)
|
||||||
|
self.assertEqual(expected_headers, received_headers)
|
||||||
|
|
||||||
|
# Update listener to insert: "X_FORWARDED_PORT" and
|
||||||
|
# "X_FORWARDED_PROTO"type headers.
|
||||||
|
listener_kwargs = {
|
||||||
|
const.LISTENER_ID: listener_id,
|
||||||
|
const.INSERT_HEADERS: {
|
||||||
|
const.X_FORWARDED_PORT: "true",
|
||||||
|
const.X_FORWARDED_PROTO: "true"}}
|
||||||
|
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.check_interval,
|
||||||
|
CONF.load_balancer.check_timeout)
|
||||||
|
|
||||||
|
# Initiate HTTP traffic
|
||||||
|
data = self.validate_URL_response(test_url)
|
||||||
|
LOG.info('Received payload is: {}'.format(data))
|
||||||
|
expected_headers = {const.X_FORWARDED_PORT: '{}'.format(
|
||||||
|
listener_port), const.X_FORWARDED_PROTO: const.HTTP.lower()}
|
||||||
|
received_headers = _data_parser(data, expected_headers)
|
||||||
|
self.assertEqual(expected_headers, received_headers)
|
||||||
|
|
Loading…
Reference in New Issue