diff --git a/framework/deproxy/deproxy_client.py b/framework/deproxy/deproxy_client.py index fd625486e..b74420ec4 100644 --- a/framework/deproxy/deproxy_client.py +++ b/framework/deproxy/deproxy_client.py @@ -608,6 +608,11 @@ def make_request( self.stream_id += 2 self._valid_req_num += 1 + def send_ping(self, data: bytes = b"\x00\x01\x02\x03\x04\x05\x06\x07") -> None: + self.h2_connection.ping(opaque_data=data) + self.send_bytes(self.h2_connection.data_to_send()) + self.h2_connection.clear_outbound_data_buffer() + @staticmethod def create_request( method, diff --git a/framework/test_suite/tester.py b/framework/test_suite/tester.py index 55acde763..bae1bbe7f 100644 --- a/framework/test_suite/tester.py +++ b/framework/test_suite/tester.py @@ -7,6 +7,7 @@ import re import signal import subprocess +import threading import typing import unittest from unittest.util import strclass @@ -375,6 +376,23 @@ def start_all_clients(self): if not client.is_running(): raise Exception("Can not start client %s" % cid) + def create_task(self, func): + stop_event = threading.Event() + + task = threading.Thread(target=func, args=(stop_event,)) + self.__tasks.append((task, stop_event)) + + return task + + async def __cleanup_tasks(self): + for task, stop_event in self.__tasks: + stop_event.set() + + await asyncio.gather( + *[asyncio.to_thread(task.join) for task, _ in self.__tasks if task.ident is not None] + ) + self.__tasks.clear() + async def asyncSetUp(self): # `unittest.TestLoader.discover` returns initialized objects, we can't # raise `SkipTest` inside of `TempestaTest.__init__` because we are unable @@ -386,6 +404,7 @@ async def asyncSetUp(self): test_logger.info(f"setUp '{self.id()}'") if not await remote.wait_available(): raise Exception("Tempesta node is unavailable") + self.__tasks = [] self.__exceptions = dict() self.__servers = {} self.__clients = {} @@ -412,6 +431,7 @@ async def asyncSetUp(self): self.addAsyncCleanup(self.cleanup_interfaces) self.addAsyncCleanup(self.cleanup_deproxy) self.addAsyncCleanup(self.cleanup_services) + self.addAsyncCleanup(self.__cleanup_tasks) test_logger.info(f"setUp completed '{self.id()}'") async def cleanup_services(self): diff --git a/tests/client_mem/__init__.py b/tests/client_mem/__init__.py new file mode 100644 index 000000000..4bb358bfd --- /dev/null +++ b/tests/client_mem/__init__.py @@ -0,0 +1,3 @@ +__all__ = ["test_client_mem"] + +# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 diff --git a/tests/client_mem/test_client_mem.py b/tests/client_mem/test_client_mem.py new file mode 100644 index 000000000..22bf996e5 --- /dev/null +++ b/tests/client_mem/test_client_mem.py @@ -0,0 +1,378 @@ +"""Tests for client mem configuration.""" + +__author__ = "Tempesta Technologies, Inc." +__copyright__ = "Copyright (C) 2025 Tempesta Technologies, Inc." +__license__ = "GPL2" + +import asyncio +import time +import run_config +from framework.helpers import error +from framework.test_suite import marks, tester + +DEPROXY_CLIENT = { + "id": "deproxy", + "type": "deproxy", + "addr": "${tempesta_ip}", + "port": "80", +} + +DEPROXY_CLIENT_SSL = { + "id": "deproxy", + "type": "deproxy", + "addr": "${tempesta_ip}", + "port": "443", + "ssl": True, +} + +DEPROXY_CLIENT_H2 = { + "id": "deproxy", + "type": "deproxy_h2", + "addr": "${tempesta_ip}", + "port": "443", + "ssl": True, +} + +DEPROXY_SERVER = { + "id": "deproxy", + "type": "deproxy", + "port": "8000", + "response": "static", + "response_content": "HTTP/1.1 200 OK\r\nConnection: keep-alive\r\nContent-Length: 0\r\n\r\n", +} + + +class TestClientMemBase(tester.TempestaTest): + def update_tempesta_config(self, client_mem_config: str): + new_config = self.get_tempesta().config.defconfig + self.get_tempesta().config.defconfig = new_config + client_mem_config + + +class TestClientMemConfig(TestClientMemBase): + """ + This class contains tests for 'client_mem' directives. + """ + + tempesta = { + "config": """ +listen 80; +""" + } + + @marks.Parameterize.expand( + [ + marks.Param(name="not_present", client_mem_config="client_mem;\n"), + marks.Param(name="to_many_args", client_mem_config="client_mem 1 3 5;\n"), + marks.Param(name="no_attrs", client_mem_config="client_mem 1 b=3;\n"), + marks.Param(name="value_1", client_mem_config="client_mem 11aa;\n"), + marks.Param(name="soft_is_greater_then_hard", client_mem_config="client_mem 10 1;\n"), + ] + ) + async def test_invalid(self, name, client_mem_config): + """ + This test checks that Tempesta FW doesn't start with wrong `client_mem` + option. + """ + tempesta = self.get_tempesta() + self.update_tempesta_config(client_mem_config) + self.oops_ignore = ["ERROR"] + with self.assertRaises(error.ProcessBadExitStatusException): + tempesta.start() + + +class TestBlockByMemExceededBase(TestClientMemBase): + tempesta = { + "config": """ +listen 80; +listen 443 proto=h2,https; + +server ${server_ip}:8000; + +block_action attack reply; +block_action error reply; + +tls_certificate ${tempesta_workdir}/tempesta.crt; +tls_certificate_key ${tempesta_workdir}/tempesta.key; +tls_match_any_server_name; +""", + } + + backends = [DEPROXY_SERVER] + + async def send_request_and_check_conn_close(self, client, request): + client.make_request(request) + """ + For http2 connection Tempesta FW adjust memory on + frame level, so connection will be closed with + TCP RST without any response + """ + await client.wait_for_connection_close(strict=True) + + +@marks.parameterize_class( + [ + { + "name": "Http", + "clients": [DEPROXY_CLIENT], + "client_mem": "client_mem 5000 10000;\n", + }, + { + "name": "Https", + "clients": [DEPROXY_CLIENT_SSL], + "client_mem": "client_mem 5000 10000;\n", + }, + { + "name": "H2", + "clients": [DEPROXY_CLIENT_H2], + "client_mem": "client_mem 20000 40000;\n", + }, + ] +) +class TestBlockByMemExceeded(TestBlockByMemExceededBase): + async def test_request(self): + """ + This test checks that Tempesta FW drop client connection + if request exceeded `client_mem` limit. + """ + self.update_tempesta_config(self.client_mem) + await self.start_all_services() + + client = self.get_client("deproxy") + request = client.create_request( + method="POST", uri="/", headers=[("Content-Length", "30000")], body="a" * 30000 + ) + + await self.send_request_and_check_conn_close(client, request) + + async def test_response(self): + """ + This test checks that Tempesta FW drop client connection + if response exceeded `client_mem` limit. Check that + client received 403 error response before connection + will be closed. + """ + self.update_tempesta_config(self.client_mem) + await self.start_all_services() + + srv: StaticDeproxyServer = self.get_server("deproxy") + srv.set_response( + "HTTP/1.1 200 OK\r\n" + + "Content-Length: 10000\r\n" + + "Content-Type: text/html\r\n" + + "\r\n" + + "a" * 10000 + ) + + client = self.get_client("deproxy") + request = client.create_request( + method="GET", + uri="/", + headers=[], + ) + + await client.send_request(request, "403") + await client.wait_for_connection_close(strict=True) + + +class TestReconfigClientMemStress(tester.TempestaTest): + tempesta = { + "config": """ +listen 80; +listen 443 proto=h2,https; + +server ${server_ip}:8000; + +block_action attack reply; +block_action error reply; + +tls_certificate ${tempesta_workdir}/tempesta.crt; +tls_certificate_key ${tempesta_workdir}/tempesta.key; +tls_match_any_server_name; +""", + } + + backends = [DEPROXY_SERVER] + + clients = [ + { + "id": "gflood", + "type": "external", + "binary": "gflood", + "ssl": True, + "cmd_args": "-address ${tempesta_ip}:443 -host tempesta-tech.com -threads 4 -connections 100 -streams 100", + }, + ] + + def __do_reload_impl(self, base_config, i): + config = base_config + "client_mem 10000 20000;\n" if i % 2 == 0 else base_config + self.get_tempesta().config.defconfig = config + self.get_tempesta().reload() + time.sleep(0.1) + + def __do_reload(self, stop_event): + base_config = self.get_tempesta().config.defconfig + while not stop_event.is_set(): + self.__do_reload_impl(base_config, 0) + self.__do_reload_impl(base_config, 1) + + async def test_under_load(self): + """ + This test checks that there is no crashes if we reload + Tempesta FW with `client_mem` options under heavy load. + (Tempesta FW deletes special data structure used for + client memory accounting in very sofisticated way). + """ + await self.start_all_services(client=False) + client = self.get_client("gflood") + task = self.create_task(self.__do_reload) + task.start() + client.start() + await self.wait_while_busy(client) + client.stop() + + +@marks.parameterize_class( + [ + { + "name": "Http", + "clients": [DEPROXY_CLIENT], + }, + { + "name": "Https", + "clients": [DEPROXY_CLIENT_SSL], + }, + { + "name": "H2", + "clients": [DEPROXY_CLIENT_H2], + }, + ] +) +class TestReconfigClientMem(TestBlockByMemExceededBase): + tempesta = { + "config": """ +listen 80; +listen 443 proto=h2,https; + +server ${server_ip}:8000; + +block_action attack reply; +block_action error reply; + +tls_certificate ${tempesta_workdir}/tempesta.crt; +tls_certificate_key ${tempesta_workdir}/tempesta.key; +tls_match_any_server_name; +""", + } + + backends = [DEPROXY_SERVER] + + async def test(self): + """ + This test check that `client_mem` option is reconfigurable. + First of all start Tempesta FW without `client_mem` option, + send request with long body and check that we successfully + receive response. Reload Tempesta FW with strong `client_mem` + limit and check that we close client connection, because + `client_mem` limit is exceeded. + """ + await self.start_all_services() + client = self.get_client("deproxy") + request = client.create_request( + method="POST", uri="/", headers=[("Content-Length", "10000")], body="a" * 10000 + ) + + await client.send_request(request, "200") + self.update_tempesta_config("client_mem 10000 20000;\n") + self.get_tempesta().reload() + await self.send_request_and_check_conn_close(client, request) + + +class TestBlockByMemExceededByPing(tester.TempestaTest): + tempesta = { + "config": """ +listen 443 proto=h2; + +server ${server_ip}:8000; + +client_mem 500 1000; +block_action attack reply; +block_action error reply; + +tls_certificate ${tempesta_workdir}/tempesta.crt; +tls_certificate_key ${tempesta_workdir}/tempesta.key; +tls_match_any_server_name; +""", + } + + clients = [DEPROXY_CLIENT_H2] + + backends = [DEPROXY_SERVER] + + async def test(self): + """ + This test check that Tempesta FW drops client connection under ping + flood, if client_mem is exceeded hard limit. + """ + await self.start_all_services() + + ping_count = 10000 + + client = self.get_client("deproxy") + for _ in range(0, ping_count): + client.send_ping() + + await client.wait_for_connection_close(strict=True) + + +class TestSeveralClientsWithSmallLrusize(tester.TempestaTest): + tempesta = { + "config": """ +listen 443 proto=h2,https; + +server ${server_ip}:8000; + +client_lru_size 1; + +tls_certificate ${tempesta_workdir}/tempesta.crt; +tls_certificate_key ${tempesta_workdir}/tempesta.key; +tls_match_any_server_name; +""", + } + + clients = [ + { + "id": f"deproxy-interface-{id_}", + "type": "deproxy", + "addr": "${tempesta_ip}", + "port": "443", + "interface": True, + "ssl": True, + } + for id_ in range(3) + ] + + backends = [DEPROXY_SERVER] + + @staticmethod + def make_resp(body): + return f"HTTP/1.1 200 OK\r\nContent-Length: {len(body)}\r\n\r\n{body}" + + async def test_all_clients_active(self): + """ + This test checks Tempesta FW behaviour, when count of clients + exceeded LRU size. In this case Tempesta FW remove old clients + and delete structure, which is used for memory accounting. + """ + await self.start_all_services() + server = self.get_server("deproxy") + + server.set_response(self.make_resp("x" * 10000)) + + i = 0 + for client in self.get_clients(): + client.start() + request = client.create_request(method="GET", uri="/", headers=[]) + client.make_requests([request] * 10) + await server.wait_for_requests((i + 1) * 10, strict=True) + await client.wait_for_response() + self.assertTrue(len(client.responses), 10) diff --git a/tests/fault_injection/test_fault_injection_base.py b/tests/fault_injection/test_fault_injection_base.py index cd0da4557..728b0e2f4 100644 --- a/tests/fault_injection/test_fault_injection_base.py +++ b/tests/fault_injection/test_fault_injection_base.py @@ -883,6 +883,70 @@ async def test(self, name, func_name, extra_config, space, retval): module_name_preload=None, retval=0, ), + marks.Param( + name="tfw_alloc_percpu_gfp", + func_name="tfw__alloc_percpu_gfp", + config=f""" +listen 80; +listen 443 proto=h2,https; +client_lru_size 5; +client_mem 500000 1000000; +tls_certificate {TEMPESTA_WORKDIR}/tempesta.crt; +tls_certificate_key {TEMPESTA_WORKDIR}/tempesta.key; +server {SERVER_IP}:8000 conns_n=10; +""", + module_path="lib", + module_name_preload="tempesta_lib", + retval=0, + ), + marks.Param( + name="tfw_percpu_ref_init", + func_name="tfw_percpu_ref_init", + config=f""" +listen 80; +listen 443 proto=h2,https; +client_lru_size 5; +client_mem 500000 1000000; +tls_certificate {TEMPESTA_WORKDIR}/tempesta.crt; +tls_certificate_key {TEMPESTA_WORKDIR}/tempesta.key; +server {SERVER_IP}:8000 conns_n=10; +""", + module_path="lib", + module_name_preload="tempesta_lib", + retval=-12, + ), + marks.Param( + name="tfw_get_free_pages", + func_name="tfw__get_free_pages", + config=f""" +listen 80; +listen 443 proto=h2,https; +client_lru_size 5; +client_mem 500000 1000000; +tls_certificate {TEMPESTA_WORKDIR}/tempesta.crt; +tls_certificate_key {TEMPESTA_WORKDIR}/tempesta.key; +server {SERVER_IP}:8000 conns_n=10; + +health_check h_monitor1 {{ + request "GET / HTTP/1.1\r\n\r\n"; + request_url "/"; + resp_code 200; + resp_crc32 auto; + timeout 1; +}} + +srv_group test {{ + sched hash; + server {SERVER_IP}:8001 conns_n=10; + + health h_monitor1; +}} + +""", + module_path="lib", + module_name_preload="tempesta_lib", + retval=0, + ), ] ) async def test_init_modules( diff --git a/tests/http2_general/test_h2_frame.py b/tests/http2_general/test_h2_frame.py index 81dc21f43..81f51229a 100644 --- a/tests/http2_general/test_h2_frame.py +++ b/tests/http2_general/test_h2_frame.py @@ -803,11 +803,6 @@ class TestPostponedFrames(H2Base): This class checks that Tempesta FW doesn't violate this rule. """ - def _ping(self, client): - client.h2_connection.ping(opaque_data=b"\x00\x01\x02\x03\x04\x05\x06\x07") - client.send_bytes(client.h2_connection.data_to_send()) - client.h2_connection.clear_outbound_data_buffer() - @marks.Parameterize.expand( [ marks.Param(name="headers", header="a" * 30000, token="value"), @@ -841,7 +836,7 @@ async def test(self, name, header, token): stream_id = client.stream_id client.make_request(self.get_request) for _ in range(0, ping_count): - self._ping(client) + client.send_ping() self.assertTrue(await client.wait_for_headers_frame(stream_id)) self.assertTrue(await client.wait_for_ping_frames(ping_count)) @@ -850,7 +845,7 @@ async def test(self, name, header, token): self.assertTrue(await client.wait_for_ack_settings()) for _ in range(0, ping_count): - self._ping(client) + client.send_ping() self.assertTrue(await client.wait_for_headers_frame(stream_id)) self.assertTrue(await client.wait_for_ping_frames(2 * ping_count)) diff --git a/tests/multiple_clients/test_multiple_clients.py b/tests/multiple_clients/test_multiple_clients.py index c88156fa7..c137dac4e 100755 --- a/tests/multiple_clients/test_multiple_clients.py +++ b/tests/multiple_clients/test_multiple_clients.py @@ -99,3 +99,20 @@ async def test_tcp_fin_timeout(self): self.assertTrue( client.is_rst_received, "Client don't receive TCP RST when Tempesta FW closes." ) + + async def test_client_memory(self): + """ + This test checks Tempesta FW behaviour, when count of clients + exceeded LRU size. In this case Tempesta FW remove old clients + and delete structure, which is used for memory accounting in very + sofisticated way. + """ + config = self.get_tempesta().config.defconfig + self.get_tempesta().config.defconfig = config + "client_mem 500000 1000000;\n" + await self.start_all_services(client=False) + request = self.get_client("deproxy-0").create_request(method="GET", headers=[]) + + for client in self.get_clients(): + client.start() + await client.send_request(request, "200") + client.stop() diff --git a/tests/reconf/test_reconf_base.py b/tests/reconf/test_reconf_base.py index 075fc052f..b4374f776 100644 --- a/tests/reconf/test_reconf_base.py +++ b/tests/reconf/test_reconf_base.py @@ -3,7 +3,8 @@ __license__ = "GPL2" import asyncio -import threading +import time + from framework.helpers import analyzer, dmesg, error, port_checks, remote from framework.helpers.analyzer import PSH, TCP @@ -294,24 +295,16 @@ class TestListenStartFail(tester.TempestaTest): }, ] - stop = False - - async def __heavy_load(self): + def __heavy_load(self, stop_event): curl = self.get_client("curl") - while not self.stop: + + while not stop_event.is_set(): curl.start() - await self.wait_while_busy(curl) + time.sleep(0.1) curl.stop() - async def __finish_heavy_load(self): - self.stop = True - for task in self.tasks: - await task - async def asyncSetUp(self): await super().asyncSetUp() - self.tasks = [] - self.addAsyncCleanup(self.__finish_heavy_load) async def test_start_failed_under_heavy_load(self): """ @@ -327,7 +320,8 @@ async def test_start_failed_under_heavy_load(self): server.start() self.deproxy_manager.start() - self.tasks.append(asyncio.create_task(self.__heavy_load())) + task = self.create_task(self.__heavy_load) + task.start() self.get_tempesta().config.set_defconfig( f""" @@ -698,9 +692,6 @@ class TestServerOptionsReconf(tester.TempestaTest): async def asyncSetUp(self): await super().asyncSetUp() self.dmesg = dmesg.DmesgFinder(disable_ratelimit=True) - self.sniffer = analyzer.Sniffer( - node=remote.tempesta, host="Tempesta", timeout=self.sniffer_timeout, ports=[8000] - ) def _set_tempesta_config_with_server_retry_nonidempotent(self): self.get_tempesta().config.set_defconfig( @@ -946,7 +937,9 @@ async def test_reconf_server_forward_retries(self, name, old_srv_forward_retries client = self.get_client("deproxy") tempesta = self.get_tempesta() - self.get_server("deproxy").drop_conn_when_request_received = True + server = self.get_server("deproxy") + + server.drop_conn_when_request_received = True tempesta.config.set_defconfig( f""" @@ -978,10 +971,8 @@ async def test_reconf_server_forward_retries(self, name, old_srv_forward_retries """ ) - await self.sniffer.start() tempesta.reload() await client.send_request(client.create_request(method="GET", headers=[]), "504") - self.sniffer.stop() self.assertTrue( await self.dmesg.find( @@ -990,10 +981,9 @@ async def test_reconf_server_forward_retries(self, name, old_srv_forward_retries DMESG_WARNING, ) - forward_tries = len([p for p in self.sniffer.packets if p[TCP].flags & PSH]) self.assertEqual( server_forward_retries + 1, - forward_tries, + len(server.requests), "Tempesta made forward attempts not equal to `server_forward_retries` after reload.", ) @@ -2030,11 +2020,6 @@ async def test(self, name, config): with self.assertRaises(error.ProcessBadExitStatusException): tempesta.reload() - def _ping(self, client): - client.h2_connection.ping(opaque_data=b"\x00\x01\x02\x03\x04\x05\x06\x07") - client.send_bytes(client.h2_connection.data_to_send()) - client.h2_connection.clear_outbound_data_buffer() - async def test_decrease(self): tempesta = self.get_tempesta() old_config = tempesta.config.defconfig @@ -2048,7 +2033,7 @@ async def test_decrease(self): self.assertTrue(await client.wait_for_ack_settings()) for _ in range(0, 10000): - self._ping(client) + client.send_ping() tempesta.config.set_defconfig(old_config) tempesta.reload() diff --git a/tests/stress/test_stress.py b/tests/stress/test_stress.py index ae61290cb..1baad6915 100644 --- a/tests/stress/test_stress.py +++ b/tests/stress/test_stress.py @@ -829,6 +829,8 @@ class TestContinuationFlood(tester.TempestaTest): server ${server_ip}:8000; + client_mem 10000 20000; + tls_certificate ${tempesta_workdir}/tempesta.crt; tls_certificate_key ${tempesta_workdir}/tempesta.key; tls_match_any_server_name; diff --git a/tests/tests_disabled.json b/tests/tests_disabled.json index 64ab2cdf2..cd7ebfb65 100644 --- a/tests/tests_disabled.json +++ b/tests/tests_disabled.json @@ -189,10 +189,6 @@ "name": "tests.clickhouse.test_clickhouse_logs.TestClickHouseLogsDelay", "reason": "The response time varies each time, and it is not possible to predict it exactly." }, - { - "name": "tests.stress.test_stress.TestContinuationFlood", - "reason": "Disabled by test issue #817" - }, { "name": "tests.stress.test_stress.TestStressNoCacheMTU80", "reason": "Disabled by test issue #817" diff --git a/tests/tests_disabled_remote.json b/tests/tests_disabled_remote.json index 2430ed5b1..9340509f2 100644 --- a/tests/tests_disabled_remote.json +++ b/tests/tests_disabled_remote.json @@ -104,10 +104,6 @@ { "name": "tests.frang.test_concurrent_connections.TestConcurrentConnectionsNonTempesta", "reason": "Is not intended to run on remote setup. Local only." - }, - { - "name": "tests.stress.test_stress.TestContinuationFlood", - "reason": "Disabled by test issue #817" }, { "name": "tests.stress.test_stress.H2LoadStressMTU80", diff --git a/tests/tests_disabled_tcpseg.json b/tests/tests_disabled_tcpseg.json index 3cb925dda..2680d6a70 100644 --- a/tests/tests_disabled_tcpseg.json +++ b/tests/tests_disabled_tcpseg.json @@ -161,10 +161,6 @@ "name": "tests.http2_general.test_h2_hpack.TestHpackBomb", "reason": "These tests should not be run with TCP segmentation. We have separate tests for `http_max_header_list_size`." }, - { - "name": "tests.stress.test_ddos", - "reason": "These tests should not be run with TCP segmentation. These tests does not use deproxy." - }, { "name": "tests.frang.test_config", "reason": "These tests should not be run with TCP segmentation." @@ -197,6 +193,18 @@ "name": "tests.server_connections", "reason": "These tests should not be run with TCP segmentation. These tests check a connection level." }, + { + "name": "tests.client_mem.test_client_mem.TestBlockByMemExceededHttp.test_response", + "reason": "These tests should not be run with TCP segmentation. In case of segmentation we drop request, not response." + }, + { + "name": "tests.client_mem.test_client_mem.TestBlockByMemExceededHttps.test_response", + "reason": "These tests should not be run with TCP segmentation. In case of segmentation we drop request, not response." + }, + { + "name": "tests.client_mem.test_client_mem.TestBlockByMemExceededH2.test_response", + "reason": "These tests should not be run with TCP segmentation. In case of segmentation we drop request, not response." + }, { "name": "tests.tls.test_tls_integrity.ProxyH2", "reason": "Disabled by issue #1714" @@ -256,22 +264,6 @@ { "name": "tests.frang.test_concurrent_connections.TestConcurrentConnectionsNonTempesta", "reason": "Is not intended to run with segmentation." - }, - { - "name": "tests.stress.test_stress.TestContinuationFlood", - "reason": "Disabled by test issue #817" - }, - { - "name": "tests.stress.test_stress.H2LoadStressMTU80", - "reason": "Disabled by test issue #817" - }, - { - "name": "tests.stress.test_stress.TlsWrkStressMTU80", - "reason": "Disabled by test issue #817" - }, - { - "name": "tests.stress.test_stress.WrkStressMTU80", - "reason": "Disabled by test issue #817" } ] } diff --git a/tests/tls/test_tls_limits.py b/tests/tls/test_tls_limits.py index fc2b5fe96..3134563ad 100644 --- a/tests/tls/test_tls_limits.py +++ b/tests/tls/test_tls_limits.py @@ -66,6 +66,7 @@ class TLSMatchHostSni(tester.TempestaTest): TLS_WARN = "Warning: frang: vhost by SNI doesn't match vhost by authority" + @dmesg.unlimited_rate_on_tempesta_node async def test_host_sni_mismatch(self): """With the `http_strict_host_checking` limit, the host header and SNI name must be identical. Otherwise request will be filtered. After client