feature: Add no rate limit shaping case.

This commit is contained in:
fumingwei
2024-06-04 19:47:25 +08:00
parent f41e709db3
commit fa72c50f99
10 changed files with 112 additions and 53 deletions

View File

@@ -279,7 +279,7 @@ class TcpPacketsCaptureAssertion:
return False, f"Error: Failed to verify DSCP value. Actual DSCP: {actual_dscp}, expected DSCP: {expected_dscp}."
class URLTransferBuilder:
def __init__(self, url: str, request_resolve: list, conn_timeout: int, max_recv_speed: int):
def __init__(self, url: str, request_resolve: list, conn_timeout: int, max_recv_speed):
self._url = url
self._request_resolve = request_resolve
self._conn_timeout = conn_timeout
@@ -293,24 +293,27 @@ class URLTransferBuilder:
self._local_port = None
self._remote_ip = None
self._remote_port = None
self._connection_time_ms = None
def _setup_connection(self):
self._response_buffer = BytesIO()
self._conn = pycurl.Curl()
self._conn.setopt(self._conn.WRITEFUNCTION, self._response_buffer.write)
self._conn.setopt(self._conn.RESOLVE, self._request_resolve)
self._conn.setopt(self._conn.URL, self._url)
self._conn.setopt(self._conn.TIMEOUT, self._conn_timeout)
self._conn.setopt(self._conn.MAX_RECV_SPEED_LARGE, self._max_recv_speed)
self._conn.setopt(pycurl.WRITEFUNCTION, self._response_buffer.write)
self._conn.setopt(pycurl.RESOLVE, self._request_resolve)
self._conn.setopt(pycurl.URL, self._url)
self._conn.setopt(pycurl.TIMEOUT, self._conn_timeout)
if self._max_recv_speed is not None:
self._conn.setopt(pycurl.MAX_RECV_SPEED_LARGE, self._max_recv_speed)
def _perform_connection(self):
self._conn.perform()
self._response_code = self._conn.getinfo(self._conn.RESPONSE_CODE)
self._response_code = self._conn.getinfo(pycurl.RESPONSE_CODE)
self._size_download = self._conn.getinfo(pycurl.SIZE_DOWNLOAD)
self._local_ip = self._conn.getinfo(pycurl.LOCAL_IP)
self._local_port = self._conn.getinfo(pycurl.LOCAL_PORT)
self._remote_ip = self._conn.getinfo(pycurl.PRIMARY_IP)
self._remote_port = self._conn.getinfo(pycurl.PRIMARY_PORT)
self._connection_time_ms = self._conn.getinfo(pycurl.CONNECT_TIME)
def _close_connection(self):
self._conn.close()
@@ -344,6 +347,12 @@ class URLTransferBuilder:
def quadruple(self):
return f"{self._local_ip}:{self._local_port},{self._remote_ip}:{self._remote_port}"
@property
def connect_time_s(self):
if self._close_connection is None:
return None
return self._connection_time_ms/1000000
class HttpURLTransferBuilder(URLTransferBuilder):
def _perform_connection(self):
super()._perform_connection()
@@ -496,6 +505,12 @@ class URLTransferResponseAssertion:
else:
return False, f"Error: The pycurl error is not None. Actual error info: {error_info}."
@staticmethod
def is_connect_time_less_than(actual_time_s, expected_time_s):
if actual_time_s < expected_time_s:
return True, None
return False, f"Error: The actual time is less than expected. Actual time:{actual_time_s}s, Expected time: {expected_time_s}s."
class DNSResponseAssertion:
@staticmethod
def is_error_info_none(error_info):
@@ -885,6 +900,39 @@ class ProxyCasesRunner:
return True, None
class ShapingCaseRunner:
@staticmethod
def no_rate_limit_protocol_http(url, resolves, conn_timeout, max_recv_speed):
conn = HttpURLTransferBuilder(url, resolves, conn_timeout, max_recv_speed)
conn.connect()
status, info = URLTransferResponseAssertion.is_pycurl_error_none(conn.error_info)
if not status:
return False, info
status, info = URLTransferResponseAssertion.is_response_code_equal(conn.response_code, 200)
if not status:
return False, info
status, info = URLTransferResponseAssertion.is_connect_time_less_than(conn.connect_time_s, 5)
if not status:
return False, info
return True, f"The connect time in seconds is: {conn.connect_time_s}."
@staticmethod
def no_rate_limit_protocol_https(url, resolves, conn_timeout, max_recv_speed):
conn = HttpsURLTransferBuilder(url, resolves, conn_timeout, max_recv_speed)
conn.connect()
status, info = URLTransferResponseAssertion.is_pycurl_error_none(conn.error_info)
if not status:
return False, info
status, info = URLTransferResponseAssertion.is_response_code_equal(conn.response_code, 200)
if not status:
return False, info
status, info = URLTransferResponseAssertion.is_cert_issuer_matched(conn.cert_issuer, r'\bCN[\s]*=[\s]*BadSSL\b')
if not status:
return False, info
status, info = URLTransferResponseAssertion.is_connect_time_less_than(conn.connect_time_s, 5)
if not status:
return False, info
return True, f"The connect time in seconds is: {conn.connect_time_s}."
@staticmethod
def rate_limit_0bps_protocol_http(url, resolves, conn_timeout, max_recv_speed):
conn = HttpURLTransferBuilder(url, resolves, conn_timeout, max_recv_speed)
@@ -1516,36 +1564,52 @@ class DiagnoseCasesRunner:
"conn_timeout": 1,
"max_recv_speed": 6553600
},
{
"name": "Shaping_NoRateLimit_HTTP",
"protocol_type": "http",
"test_function": ShapingCaseRunner.no_rate_limit_protocol_http,
"request_content": "http://testing-no-rate-limit.badssl.selftest.gdnt-cloud.website/resources/64M",
"conn_timeout": 12,
"max_recv_speed": None
},
{
"name": "Shaping_NoRateLimit_HTTPS",
"protocol_type": "http",
"test_function": ShapingCaseRunner.no_rate_limit_protocol_https,
"request_content": "http://testing-no-rate-limit.badssl.selftest.gdnt-cloud.website/resources/64M",
"conn_timeout": 12,
"max_recv_speed": None
},
{
"name": "Shaping_RateLimit0bps_HTTP",
"protocol_type": "http",
"test_function": ShapingCaseRunner.rate_limit_0bps_protocol_http,
"request_content": "http://testing-rate-limit-0bps.badssl.selftest.gdnt-cloud.website/resources/16M",
"conn_timeout": 4,
"request_content": "http://testing-rate-limit-0bps.badssl.selftest.gdnt-cloud.website/resources/64M",
"conn_timeout": 12,
"max_recv_speed": 6553600
},
{
"name": "Shaping_RateLimit0bps_HTTPS",
"protocol_type": "https",
"test_function": ShapingCaseRunner.rate_limit_0bps_protocol_https,
"request_content": "https://testing-rate-limit-0bps.badssl.selftest.gdnt-cloud.website/resources/16M",
"conn_timeout": 4,
"request_content": "https://testing-rate-limit-0bps.badssl.selftest.gdnt-cloud.website/resources/64M",
"conn_timeout": 12,
"max_recv_speed": 6553600
},
{
"name": "Shaping_RateLimit1000gbps_HTTP",
"protocol_type": "http",
"test_function": ShapingCaseRunner.rate_limit_1000gbps_protocol_http,
"request_content": "http://testing-rate-limit-1000gbps.badssl.selftest.gdnt-cloud.website/resources/16M",
"conn_timeout": 4,
"request_content": "http://testing-rate-limit-1000gbps.badssl.selftest.gdnt-cloud.website/resources/64M",
"conn_timeout": 12,
"max_recv_speed": 6553600
},
{
"name": "Shaping_RateLimit1000gbps_HTTPS",
"protocol_type": "https",
"test_function": ShapingCaseRunner.rate_limit_1000gbps_protocol_https,
"request_content": "https://testing-rate-limit-1000gbps.badssl.selftest.gdnt-cloud.website/resources/16M",
"conn_timeout": 4,
"request_content": "https://testing-rate-limit-1000gbps.badssl.selftest.gdnt-cloud.website/resources/64M",
"conn_timeout": 12,
"max_recv_speed": 6553600
}
]

View File

@@ -26,22 +26,6 @@ enabled = 1
conn_timeout = 3
max_recv_speed_large = 6553600
#[test_dnsRequest_allow_rdtype_a]
#enabled = 1
#conn_timeout = 3
#max_recv_speed_large = 6553600
#[test_dnsRequest_allow_rdtype_aaaa]
#enabled = 1
#conn_timeout = 3
#max_recv_speed_large = 6553600
#[test_dnsRequest_allow_rdtype_cname]
#enabled = 1
#conn_timeout = 3
#max_recv_speed_large = 6553600
[Proxy_Intercept_HTTPS]
enabled = 1
conn_timeout = 1
@@ -214,20 +198,28 @@ max_recv_speed_large = 6553600
[Shaping_RateLimit0bps_HTTP]
enabled = 1
conn_timeout = 4
conn_timeout = 12
max_recv_speed_large = 6553600
[Shaping_RateLimit0bps_HTTPS]
enabled = 1
conn_timeout = 4
conn_timeout = 12
max_recv_speed_large = 6553600
[Shaping_RateLimit1000gbps_HTTP]
enabled = 1
conn_timeout = 4
conn_timeout = 12
max_recv_speed_large = 6553600
[Shaping_RateLimit1000gbps_HTTPS]
enabled = 1
conn_timeout = 4
conn_timeout = 12
max_recv_speed_large = 6553600
[Shaping_NoRateLimit_HTTP]
enabled = 1
conn_timeout = 12
[Shaping_NoRateLimit_HTTPS]
enabled = 1
conn_timeout = 12

View File

@@ -0,0 +1,16 @@
---
---
server {
listen 80;
server_name no-rate-limit.{{ site.domain }};
include {{ site.serving-path }}/common/common.conf;
root {{ site.serving-path }}/domains/testing-rate-limit/root;
}
server {
listen 443;
server_name no-rate-limit.{{ site.domain }};
include {{ site.serving-path }}/nginx-includes/wildcard-normal.conf;
include {{ site.serving-path }}/nginx-includes/tls-defaults.conf;
root {{ site.serving-path }}/domains/testing-rate-limit/root;
}

View File

@@ -4,7 +4,7 @@ server {
listen 80;
server_name testing-rate-limit-0bps.{{ site.domain }};
include {{ site.serving-path }}/common/common.conf;
root {{ site.serving-path }}/domains/testing-rate-limit/rate-limit-0bps;
root {{ site.serving-path }}/domains/testing-rate-limit/root;
}
server {
@@ -12,5 +12,5 @@ server {
server_name testing-rate-limit-0bps.{{ site.domain }};
include {{ site.serving-path }}/nginx-includes/wildcard-normal.conf;
include {{ site.serving-path }}/nginx-includes/tls-defaults.conf;
root {{ site.serving-path }}/domains/testing-rate-limit/rate-limit-0bps;
root {{ site.serving-path }}/domains/testing-rate-limit/root;
}

View File

@@ -5,7 +5,7 @@ server {
server_name testing-rate-limit-1000gbps.{{ site.domain }};
include {{ site.serving-path }}/common/common.conf;
root {{ site.serving-path }}/domains/testing-rate-limit/rate-limit-1000gbps;
root {{ site.serving-path }}/domains/testing-rate-limit/root;
}
server {
@@ -14,5 +14,5 @@ server {
include {{ site.serving-path }}/nginx-includes/wildcard-normal.conf;
include {{ site.serving-path }}/nginx-includes/tls-defaults.conf;
root {{ site.serving-path }}/domains/testing-rate-limit/rate-limit-1000gbps;
root {{ site.serving-path }}/domains/testing-rate-limit/root;
}

View File

@@ -1,12 +0,0 @@
---
subdomain: testing-rate-limit-1000gbps
layout: page
favicon: green
background: green
---
<div id="content">
<h1 style="font-size: 12vw;">
{{ page.subdomain }}.<br>{{ site.domain }}
</h1>
</div>

View File

@@ -1,5 +1,4 @@
---
subdomain: testing-rate-limit-0bps
layout: page
favicon: green
background: green
@@ -7,6 +6,6 @@ background: green
<div id="content">
<h1 style="font-size: 12vw;">
{{ page.subdomain }}.<br>{{ site.domain }}
TEST for rate limit.
</h1>
</div>