def test_h3_quic_with_custom_upstream_bind_configuration( quic_test_server_fixture): """Test http3 quic with a custom upstream bind configuration. Runs the CLI configured to use HTTP/3 Quic against our test server, and sanity checks statistics from both client and server. Sets custom address to bind upstream requests to. """ address = quic_test_server_fixture.server_ip upstream_bind_config = f"{{source_address:{{address:\"{address}\",port_value:0}}}}" parsed_json, _ = quic_test_server_fixture.runNighthawkClient([ "--protocol http3", quic_test_server_fixture.getTestServerRootUri(), "--rps", "100", "--duration", "100", "--termination-predicate", "benchmark.http_2xx:24", "--max-active-requests", "1", # Envoy doesn't support disabling certificate verification on Quic # connections, so the host in our requests has to match the hostname in # the leaf certificate. "--request-header", "Host:www.lyft.com", "--upstream-bind-config %s" % upstream_bind_config ]) counters = quic_test_server_fixture.getNighthawkCounterMapFromJson( parsed_json) asserts.assertCounterEqual(counters, "benchmark.http_2xx", 25) asserts.assertCounterEqual(counters, "upstream_cx_http3_total", 1)
def test_https_h2_sni(https_test_server_fixture): """Tests that SNI indication works on https/h1.""" # Verify success when we set the right host parsed_json, _ = https_test_server_fixture.runNighthawkClient([ https_test_server_fixture.getTestServerRootUri(), "--rps", "100", "--duration", "100", "--termination-predicate", "benchmark.http_2xx:2", "--request-header", ":authority: sni.com", "--h2" ]) counters = https_test_server_fixture.getNighthawkCounterMapFromJson(parsed_json) asserts.assertCounterGreaterEqual(counters, "benchmark.http_2xx", 1) asserts.assertCounterGreaterEqual(counters, "upstream_cx_http2_total", 1) asserts.assertCounterEqual(counters, "ssl.handshake", 1) # Verify success when we set the right host parsed_json, _ = https_test_server_fixture.runNighthawkClient([ https_test_server_fixture.getTestServerRootUri(), "--rps", "100", "--duration", "100", "--termination-predicate", "benchmark.http_2xx:2", "--request-header", "host: sni.com", "--h2" ]) counters = https_test_server_fixture.getNighthawkCounterMapFromJson(parsed_json) asserts.assertCounterGreaterEqual(counters, "benchmark.http_2xx", 1) asserts.assertCounterGreaterEqual(counters, "upstream_cx_http2_total", 1) asserts.assertCounterEqual(counters, "ssl.handshake", 1) # Verify failure when we set no host (will get plain http) parsed_json, _ = https_test_server_fixture.runNighthawkClient([ https_test_server_fixture.getTestServerRootUri(), "--rps", "100", "--duration", "100", "--h2" ], expect_failure=True) # Verify failure when we provide both host and :authority: (will get plain http) parsed_json, _ = https_test_server_fixture.runNighthawkClient([ https_test_server_fixture.getTestServerRootUri(), "--rps", "100", "--duration", "100", "--h2", "--request-header", "host: sni.com", "--request-header", ":authority: sni.com" ], expect_failure=True)
def _run_with_number_of_connections(fixture, number_of_connections, expected_connections=-1, max_pending_requests=0, requests_per_connection=1024 * 1024, rps=100, run_test_expectation=True, h2=False): if expected_connections == -1: expected_connections = number_of_connections # We add a delay to responses to make sure connections are needed, as the pool creates connections on-demand. args = [ fixture.getTestServerRootUri(), "--rps", str(rps), "--duration", "2", "--request-header", "x-envoy-fault-delay-request:500", "--max-pending-requests", str(max_pending_requests), "--max-requests-per-connection", str(requests_per_connection), "--connections", str(number_of_connections) ] if h2: args.append("--h2") parsed_json, _ = fixture.runNighthawkClient(args) counters = fixture.getNighthawkCounterMapFromJson(parsed_json) if run_test_expectation: asserts.assertCounterEqual(counters, "upstream_cx_total", expected_connections) return counters
def test_http_request_release_timing(http_test_server_fixture, qps_parameterization_fixture, duration_parameterization_fixture): """Test latency-sample-, query- and reply- counts in various configurations.""" for concurrency in [1, 2]: parsed_json, _ = http_test_server_fixture.runNighthawkClient([ http_test_server_fixture.getTestServerRootUri(), "--duration", str(duration_parameterization_fixture), "--rps", str(qps_parameterization_fixture), "--concurrency", str(concurrency) ]) total_requests = qps_parameterization_fixture * concurrency * duration_parameterization_fixture global_histograms = http_test_server_fixture.getNighthawkGlobalHistogramsbyIdFromJson( parsed_json) counters = http_test_server_fixture.getNighthawkCounterMapFromJson( parsed_json) asserts.assertEqual( int(global_histograms["benchmark_http_client.request_to_response"] ["count"]), total_requests) asserts.assertEqual( int(global_histograms["benchmark_http_client.queue_to_connect"] ["count"]), total_requests) asserts.assertEqual( int(global_histograms["benchmark_http_client.latency_2xx"] ["count"]), total_requests) asserts.assertCounterEqual(counters, "benchmark.http_2xx", (total_requests))
def test_http_h1_mini_stress_test_without_client_side_queueing(http_test_server_fixture): """Run a max rps test with the h1 pool against our test server, with no client-side queueing.""" counters = _mini_stress_test(http_test_server_fixture, [ http_test_server_fixture.getTestServerRootUri(), "--rps", "999999", "--connections", "1", "--duration", "100", "--termination-predicate", "benchmark.http_2xx:99" ]) asserts.assertCounterEqual(counters, "upstream_rq_pending_total", 1) asserts.assertNotIn("upstream_cx_overflow", counters)
def test_http_h2_mini_stress_test_with_client_side_queueing(http_test_server_fixture): """Run a max rps test with the h2 pool against our test server, using a small client-side queue.""" counters = _mini_stress_test(http_test_server_fixture, [ http_test_server_fixture.getTestServerRootUri(), "--rps", "999999", "--max-pending-requests", "10", "--h2", "--max-active-requests", "1", "--connections", "1", "--duration", "100", "--termination-predicate", "benchmark.http_2xx:99", "--simple-warmup" ]) asserts.assertCounterEqual(counters, "upstream_rq_pending_total", 1) asserts.assertCounterGreaterEqual(counters, "upstream_rq_pending_overflow", 10)
def test_nighthawk_client_v2_api_explicitly_set(http_test_server_fixture): """Test that the v2 api works when requested to.""" parsed_json, _ = http_test_server_fixture.runNighthawkClient([ http_test_server_fixture.getTestServerRootUri(), "--duration", "100", "--termination-predicate", "benchmark.pool_connection_failure:0", "--failure-predicate", "foo:1", "--allow-envoy-deprecated-v2-api", "--transport-socket", "{name:\"envoy.transport_sockets.tls\",typed_config:{\"@type\":\"type.googleapis.com/envoy.api.v2.auth.UpstreamTlsContext\",\"common_tls_context\":{}}}" ]) counters = http_test_server_fixture.getNighthawkCounterMapFromJson(parsed_json) asserts.assertCounterEqual(counters, "benchmark.pool_connection_failure", 1)
def test_nighthawk_test_server_envoy_deprecated_v2_api( http_test_server_fixture_envoy_deprecated_v2_api): """Test that the v2 configuration works for the test server.""" parsed_json, _ = http_test_server_fixture_envoy_deprecated_v2_api.runNighthawkClient([ http_test_server_fixture_envoy_deprecated_v2_api.getTestServerRootUri(), "--duration", "100", "--termination-predicate", "benchmark.http_2xx:24" ]) counters = http_test_server_fixture_envoy_deprecated_v2_api.getNighthawkCounterMapFromJson( parsed_json) asserts.assertCounterEqual(counters, "benchmark.http_2xx", 25)
def test_http_h1_failure_predicate(http_test_server_fixture): """Test with a failure predicate. Should result in failing execution, with 10 successfull requests. """ parsed_json, _ = http_test_server_fixture.runNighthawkClient([ http_test_server_fixture.getTestServerRootUri(), "--duration", "5", "--rps", "500", "--connections", "1", "--failure-predicate", "benchmark.http_2xx:0" ], expect_failure=True) counters = http_test_server_fixture.getNighthawkCounterMapFromJson(parsed_json) asserts.assertCounterEqual(counters, "benchmark.http_2xx", 1)
def test_http_h1_termination_predicate(http_test_server_fixture): """Test with a termination predicate. Should result in successful execution, with 10 successful requests. We would expect 25 based on rps and duration. """ parsed_json, _ = http_test_server_fixture.runNighthawkClient([ http_test_server_fixture.getTestServerRootUri(), "--duration", "5", "--rps", "500", "--connections", "1", "--termination-predicate", "benchmark.http_2xx:9" ]) counters = http_test_server_fixture.getNighthawkCounterMapFromJson(parsed_json) asserts.assertCounterEqual(counters, "benchmark.http_2xx", 10)
def test_http_concurrency(http_test_server_fixture): """Test that concurrency acts like a multiplier.""" parsed_json, _ = http_test_server_fixture.runNighthawkClient([ "--concurrency 4 --rps 100 --connections 1", "--duration", "100", "--termination-predicate", "benchmark.http_2xx:24", http_test_server_fixture.getTestServerRootUri() ]) counters = http_test_server_fixture.getNighthawkCounterMapFromJson(parsed_json) # Quite a loose expectation, but this may fluctuate depending on server load. # Ideally we'd see 4 workers * 5 rps * 5s = 100 requests total asserts.assertCounterEqual(counters, "benchmark.http_2xx", 100) asserts.assertCounterEqual(counters, "upstream_cx_http1_total", 4)
def test_https_prefetching(https_test_server_fixture): """Test we prefetch connections. We test for 1 second at 1 rps, which should result in 1 connection max without prefetching. However, we specify 50 connections and the prefetching flag, so we ought to see 50 http1 connections created. """ parsed_json, _ = https_test_server_fixture.runNighthawkClient([ "--duration 1", "--rps 1", "--prefetch-connections", "--connections 50", https_test_server_fixture.getTestServerRootUri() ]) counters = https_test_server_fixture.getNighthawkCounterMapFromJson(parsed_json) asserts.assertCounterEqual(counters, "upstream_cx_http1_total", 50)
def test_http_h1(http_test_server_fixture): """Test http1 over plain http. Runs the CLI configured to use plain HTTP/1 against our test server, and sanity checks statistics from both client and server. """ parsed_json, _ = http_test_server_fixture.runNighthawkClient([ http_test_server_fixture.getTestServerRootUri(), "--duration", "100", "--termination-predicate", "benchmark.http_2xx:24" ]) counters = http_test_server_fixture.getNighthawkCounterMapFromJson( parsed_json) asserts.assertCounterEqual(counters, "benchmark.http_2xx", 25) asserts.assertCounterEqual(counters, "upstream_cx_rx_bytes_total", 3400) # It is possible that the # of upstream_cx > # of backend connections for H1 # as new connections will spawn if the existing clients cannot keep up with the RPS. asserts.assertCounterGreaterEqual(counters, "upstream_cx_http1_total", 1) asserts.assertCounterGreaterEqual(counters, "upstream_cx_total", 1) asserts.assertCounterGreaterEqual(counters, "upstream_cx_tx_bytes_total", 500) asserts.assertCounterGreaterEqual(counters, "upstream_rq_pending_total", 1) asserts.assertCounterEqual(counters, "upstream_rq_total", 25) asserts.assertCounterEqual(counters, "default.total_match_count", 1) global_histograms = http_test_server_fixture.getNighthawkGlobalHistogramsbyIdFromJson( parsed_json) asserts.assertEqual( int(global_histograms["benchmark_http_client.response_body_size"] ["count"]), 25) asserts.assertEqual( int(global_histograms["benchmark_http_client.response_header_size"] ["count"]), 25) asserts.assertEqual( int(global_histograms["benchmark_http_client.response_body_size"] ["raw_mean"]), 10) asserts.assertEqual( int(global_histograms["benchmark_http_client.response_header_size"] ["raw_mean"]), 97) asserts.assertEqual( int(global_histograms["benchmark_http_client.response_body_size"] ["raw_min"]), 10) asserts.assertEqual( int(global_histograms["benchmark_http_client.response_header_size"] ["raw_min"]), 97) asserts.assertEqual( int(global_histograms["benchmark_http_client.response_body_size"] ["raw_max"]), 10) asserts.assertEqual( int(global_histograms["benchmark_http_client.response_header_size"] ["raw_max"]), 97) asserts.assertEqual( int(global_histograms["benchmark_http_client.response_body_size"] ["raw_pstdev"]), 0) asserts.assertEqual( int(global_histograms["benchmark_http_client.response_header_size"] ["raw_pstdev"]), 0) asserts.assertGreaterEqual(len(counters), 12)
def test_cancellation_with_infinite_duration(http_test_server_fixture): """Test that we can use signals to cancel execution.""" args = [ http_test_server_fixture.nighthawk_client_path, "--concurrency", "2", http_test_server_fixture.getTestServerRootUri(), "--no-duration", "--output-format", "json" ] client_process = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) Thread(target=(lambda: _send_sigterm(client_process))).start() stdout, stderr = client_process.communicate() client_process.wait() output = stdout.decode('utf-8') asserts.assertEqual(client_process.returncode, 0) parsed_json = json.loads(output) counters = http_test_server_fixture.getNighthawkCounterMapFromJson(parsed_json) asserts.assertCounterEqual(counters, "graceful_stop_requested", 2) asserts.assertCounterGreaterEqual(counters, "benchmark.http_2xx", 1)
def test_http_concurrency(http_test_server_fixture): """Test that concurrency acts like a multiplier.""" parsed_json, _ = http_test_server_fixture.runNighthawkClient([ "--concurrency 4 --rps 100 --connections 1", "--duration", "100", "--termination-predicate", "benchmark.http_2xx:24", http_test_server_fixture.getTestServerRootUri() ]) counters = http_test_server_fixture.getNighthawkCounterMapFromJson(parsed_json) # Quite a loose expectation, but this may fluctuate depending on server load. # Ideally we'd see 4 workers * 5 rps * 5s = 100 requests total asserts.assertCounterEqual(counters, "benchmark.http_2xx", 100) # Assert that we at least have 1 connection for each event loop (1*4). It is possible that the # of # upstream_cx > # of backend connections for H1 as new connections will spawn if the existing clients # cannot keep up with the RPS. asserts.assertCounterGreaterEqual(counters, "upstream_cx_http1_total", 4)
def _mini_stress_test(fixture, args): # run a test with more rps then we can handle, and a very small client-side queue. # we should observe both lots of successfull requests as well as time spend in blocking mode., parsed_json, _ = fixture.runNighthawkClient(args) counters = fixture.getNighthawkCounterMapFromJson(parsed_json) # We set a reasonably low expectation of 100 requests. We set it low, because we want this # test to succeed on a reasonable share of setups (hopefully practically all). MIN_EXPECTED_REQUESTS = 100 asserts.assertCounterEqual(counters, "benchmark.http_2xx", MIN_EXPECTED_REQUESTS) if "--h2" in args: asserts.assertCounterEqual(counters, "upstream_cx_http2_total", 1) else: asserts.assertCounterEqual(counters, "upstream_cx_http1_total", 1) global_histograms = fixture.getNighthawkGlobalHistogramsbyIdFromJson( parsed_json) if "--open-loop" in args: asserts.assertEqual( int(global_histograms["sequencer.blocking"]["count"]), 0) else: asserts.assertGreaterEqual( int(global_histograms["sequencer.blocking"]["count"]), 1) asserts.assertGreaterEqual( int(global_histograms["benchmark_http_client.request_to_response"] ["count"]), 1) asserts.assertGreaterEqual( int(global_histograms["benchmark_http_client.latency_2xx"]["count"]), 1) return counters
def test_multiple_backends_https_h1(multi_https_test_server_fixture): """Test that we can load-test multiple backends on https. Runs the CLI configured to use HTTP/1 with TLS against multiple test servers, and sanity checks statistics from both client and server. """ nighthawk_client_args = [ "--multi-target-use-https", "--multi-target-path", "/", "--duration", "100", "--termination-predicate", "benchmark.http_2xx:24" ] for uri in multi_https_test_server_fixture.getAllTestServerRootUris(): nighthawk_client_args.append("--multi-target-endpoint") nighthawk_client_args.append(uri.replace("https://", "").replace("/", "")) parsed_json, stderr = multi_https_test_server_fixture.runNighthawkClient(nighthawk_client_args) counters = multi_https_test_server_fixture.getNighthawkCounterMapFromJson(parsed_json) asserts.assertCounterEqual(counters, "benchmark.http_2xx", 25) asserts.assertCounterGreater(counters, "upstream_cx_rx_bytes_total", 0) # Assert that we at least have 1 connection per backend. It is possible that # the # of upstream_cx > # of backend connections for H1 as new connections # will spawn if the existing clients cannot keep up with the RPS. asserts.assertCounterGreaterEqual(counters, "upstream_cx_http1_total", 3) asserts.assertCounterGreaterEqual(counters, "upstream_cx_total", 3) asserts.assertCounterGreaterEqual(counters, "upstream_rq_pending_total", 3) asserts.assertCounterGreater(counters, "upstream_cx_tx_bytes_total", 0) asserts.assertCounterEqual(counters, "upstream_rq_total", 25) asserts.assertCounterEqual(counters, "default.total_match_count", 3) for parsed_server_json in multi_https_test_server_fixture.getAllTestServerStatisticsJsons(): single_2xx = multi_https_test_server_fixture.getServerStatFromJson( parsed_server_json, "http.ingress_http.downstream_rq_2xx") # Confirm that each backend receives some traffic asserts.assertGreaterEqual(single_2xx, 1)
def _run_benchmark(fixture, rps=1000, duration=30, max_connections=1, max_active_requests=100, request_body_size=0, response_size=1024, concurrency=1): if hasattr(fixture, "proxy_server"): assert (fixture.proxy_server.enableCpuProfiler()) assert (fixture.test_server.enableCpuProfiler()) args = [ fixture.getTestServerRootUri(), "--rps", str(rps), "--duration", str(duration), "--connections", str(max_connections), "--max-active-requests", str(max_active_requests), "--concurrency", str(concurrency), "--request-header", "x-nighthawk-test-server-config:{response_body_size:%s}" % response_size, "--experimental-h1-connection-reuse-strategy", "lru", "--prefetch-connections" ] if request_body_size > 0: args.append("--request-body-size") args.append(str(request_body_size)) parsed_json, _ = fixture.runNighthawkClient(args) counters = fixture.getNighthawkCounterMapFromJson(parsed_json) response_count = counters["benchmark.http_2xx"] request_count = counters["upstream_rq_total"] connection_counter = "upstream_cx_http1_total" # Some arbitrary sanity checks asserts.assertCounterGreaterEqual(counters, "benchmark.http_2xx", (concurrency * rps * duration) * 0.99) asserts.assertGreater(counters["upstream_cx_rx_bytes_total"], response_count * response_size) asserts.assertGreater(counters["upstream_cx_tx_bytes_total"], request_count * request_body_size) asserts.assertCounterEqual(counters, connection_counter, concurrency * max_connections) # Could potentially set thresholds on acceptable latency here. # dump human readable output to logs json_as_string = json.dumps(parsed_json) human_output = fixture.transformNighthawkJson(json_as_string, "human") logging.info(human_output) with open(os.path.join(fixture.test_server.tmpdir, "nighthawk-human.txt"), "w") as f: f.write(human_output) with open(os.path.join(fixture.test_server.tmpdir, "nighthawk.json"), "w") as f: f.write(json_as_string) with open(os.path.join(fixture.test_server.tmpdir, "nighthawk.yaml"), "w") as f: f.write(fixture.transformNighthawkJson(json_as_string, "yaml")) with open(os.path.join(fixture.test_server.tmpdir, "fortio.json"), "w") as f: f.write(fixture.transformNighthawkJson(json_as_string, "fortio")) with open(os.path.join(fixture.test_server.tmpdir, "server_version.txt"), "w") as f: f.write(fixture.test_server.getCliVersionString()) if hasattr(fixture, "proxy_server"): with open( os.path.join(fixture.test_server.tmpdir, "proxy_version.txt"), "w") as f: f.write(fixture.proxy_server.getCliVersionString()) r = runfiles.Create() copyfile( r.Rlocation("nighthawk/benchmarks/test/templates/simple_plot.html"), os.path.join(fixture.test_server.tmpdir, "simple_plot.html"))
def test_multiple_backends_https_h1(multi_https_test_server_fixture): """Test that we can load-test multiple backends on https. Runs the CLI configured to use HTTP/1 with TLS against multiple test servers, and sanity checks statistics from both client and server. """ nighthawk_client_args = [ "--multi-target-use-https", "--multi-target-path", "/", "--duration", "100", "--termination-predicate", "benchmark.http_2xx:24" ] for uri in multi_https_test_server_fixture.getAllTestServerRootUris(): nighthawk_client_args.append("--multi-target-endpoint") nighthawk_client_args.append( uri.replace("https://", "").replace("/", "")) parsed_json, stderr = multi_https_test_server_fixture.runNighthawkClient( nighthawk_client_args) counters = multi_https_test_server_fixture.getNighthawkCounterMapFromJson( parsed_json) asserts.assertCounterEqual(counters, "benchmark.http_2xx", 25) asserts.assertCounterEqual(counters, "upstream_cx_http1_total", 3) asserts.assertCounterGreater(counters, "upstream_cx_rx_bytes_total", 0) asserts.assertCounterEqual(counters, "upstream_cx_total", 3) asserts.assertCounterGreater(counters, "upstream_cx_tx_bytes_total", 0) asserts.assertCounterEqual(counters, "upstream_rq_pending_total", 3) asserts.assertCounterEqual(counters, "upstream_rq_total", 25) asserts.assertCounterEqual(counters, "default.total_match_count", 3) total_2xx = 0 for parsed_server_json in multi_https_test_server_fixture.getAllTestServerStatisticsJsons( ): single_2xx = multi_https_test_server_fixture.getServerStatFromJson( parsed_server_json, "http.ingress_http.downstream_rq_2xx") asserts.assertBetweenInclusive(single_2xx, 8, 9) total_2xx += single_2xx asserts.assertBetweenInclusive(total_2xx, 24, 25)
def test_https_h2(https_test_server_fixture): """Test http2 over https. Runs the CLI configured to use HTTP/2 (using https) against our test server, and sanity checks statistics from both client and server. """ parsed_json, _ = https_test_server_fixture.runNighthawkClient([ "--h2", https_test_server_fixture.getTestServerRootUri(), "--rps", "100", "--duration", "100", "--termination-predicate", "benchmark.http_2xx:24", "--max-active-requests", "1" ]) counters = https_test_server_fixture.getNighthawkCounterMapFromJson( parsed_json) asserts.assertCounterEqual(counters, "benchmark.http_2xx", 25) asserts.assertCounterEqual(counters, "upstream_cx_http2_total", 1) # Through emperical observation, 1030 has been determined to be the minimum of bytes # we can expect to have received when execution has stopped. asserts.assertCounterGreaterEqual(counters, "upstream_cx_rx_bytes_total", 1030) asserts.assertCounterEqual(counters, "upstream_cx_total", 1) asserts.assertCounterGreaterEqual(counters, "upstream_cx_tx_bytes_total", 403) asserts.assertCounterEqual(counters, "upstream_rq_pending_total", 1) asserts.assertCounterEqual(counters, "upstream_rq_total", 25) asserts.assertCounterEqual(counters, "ssl.ciphers.ECDHE-RSA-AES128-GCM-SHA256", 1) asserts.assertCounterEqual(counters, "ssl.curves.X25519", 1) asserts.assertCounterEqual(counters, "ssl.handshake", 1) asserts.assertCounterEqual(counters, "ssl.sigalgs.rsa_pss_rsae_sha256", 1) asserts.assertCounterEqual(counters, "ssl.versions.TLSv1.2", 1) asserts.assertCounterEqual(counters, "default.total_match_count", 1) asserts.assertEqual(len(counters), 17)
def test_https_h1(https_test_server_fixture): """Test h1 over https. Runs the CLI configured to use HTTP/1 over https against our test server, and sanity checks statistics from both client and server. """ parsed_json, _ = https_test_server_fixture.runNighthawkClient([ https_test_server_fixture.getTestServerRootUri(), "--connections", "1", "--rps", "100", "--duration", "100", "--termination-predicate", "benchmark.http_2xx:24" ]) counters = https_test_server_fixture.getNighthawkCounterMapFromJson( parsed_json) asserts.assertCounterEqual(counters, "benchmark.http_2xx", 25) asserts.assertCounterEqual(counters, "upstream_cx_http1_total", 1) asserts.assertCounterEqual(counters, "upstream_cx_rx_bytes_total", 3400) asserts.assertCounterEqual(counters, "upstream_cx_total", 1) asserts.assertCounterEqual( counters, "upstream_cx_tx_bytes_total", 1375 if https_test_server_fixture.ip_version == IpVersion.IPV6 else 1450) asserts.assertCounterEqual(counters, "upstream_rq_pending_total", 1) asserts.assertCounterEqual(counters, "upstream_rq_total", 25) asserts.assertCounterEqual(counters, "ssl.ciphers.ECDHE-RSA-AES128-GCM-SHA256", 1) asserts.assertCounterEqual(counters, "ssl.curves.X25519", 1) asserts.assertCounterEqual(counters, "ssl.handshake", 1) asserts.assertCounterEqual(counters, "ssl.sigalgs.rsa_pss_rsae_sha256", 1) asserts.assertCounterEqual(counters, "ssl.versions.TLSv1.2", 1) asserts.assertCounterEqual(counters, "default.total_match_count", 1) asserts.assertEqual(len(counters), 17) server_stats = https_test_server_fixture.getTestServerStatisticsJson() asserts.assertEqual( https_test_server_fixture.getServerStatFromJson( server_stats, "http.ingress_http.downstream_rq_2xx"), 25)
def test_http_h2(http_test_server_fixture): """Test h2 over plain http. Runs the CLI configured to use h2c against our test server, and sanity checks statistics from both client and server. """ parsed_json, _ = http_test_server_fixture.runNighthawkClient([ "--h2", http_test_server_fixture.getTestServerRootUri(), "--max-active-requests", "1", "--duration", "100", "--termination-predicate", "benchmark.http_2xx:24", "--rps", "100" ]) counters = http_test_server_fixture.getNighthawkCounterMapFromJson( parsed_json) asserts.assertCounterEqual(counters, "benchmark.http_2xx", 25) asserts.assertCounterEqual(counters, "upstream_cx_http2_total", 1) asserts.assertCounterGreaterEqual(counters, "upstream_cx_rx_bytes_total", 1030) asserts.assertCounterEqual(counters, "upstream_cx_total", 1) asserts.assertCounterGreaterEqual(counters, "upstream_cx_tx_bytes_total", 403) asserts.assertCounterEqual(counters, "upstream_rq_pending_total", 1) asserts.assertCounterEqual(counters, "upstream_rq_total", 25) asserts.assertCounterEqual(counters, "default.total_match_count", 1) asserts.assertEqual(len(counters), 12)
def test_http_h1(http_test_server_fixture): """Test http1 over plain http. Runs the CLI configured to use plain HTTP/1 against our test server, and sanity checks statistics from both client and server. """ parsed_json, _ = http_test_server_fixture.runNighthawkClient([ http_test_server_fixture.getTestServerRootUri(), "--duration", "100", "--termination-predicate", "benchmark.http_2xx:24" ]) counters = http_test_server_fixture.getNighthawkCounterMapFromJson( parsed_json) asserts.assertCounterEqual(counters, "benchmark.http_2xx", 25) asserts.assertCounterEqual(counters, "upstream_cx_http1_total", 1) asserts.assertCounterEqual(counters, "upstream_cx_rx_bytes_total", 3400) asserts.assertCounterEqual(counters, "upstream_cx_total", 1) asserts.assertCounterEqual( counters, "upstream_cx_tx_bytes_total", 1375 if http_test_server_fixture.ip_version == IpVersion.IPV6 else 1450) asserts.assertCounterEqual(counters, "upstream_rq_pending_total", 1) asserts.assertCounterEqual(counters, "upstream_rq_total", 25) asserts.assertCounterEqual(counters, "default.total_match_count", 1) global_histograms = http_test_server_fixture.getNighthawkGlobalHistogramsbyIdFromJson( parsed_json) asserts.assertEqual( int(global_histograms["benchmark_http_client.response_body_size"] ["count"]), 25) asserts.assertEqual( int(global_histograms["benchmark_http_client.response_header_size"] ["count"]), 25) asserts.assertEqual( int(global_histograms["benchmark_http_client.response_body_size"] ["raw_mean"]), 10) asserts.assertEqual( int(global_histograms["benchmark_http_client.response_header_size"] ["raw_mean"]), 97) asserts.assertEqual( int(global_histograms["benchmark_http_client.response_body_size"] ["raw_min"]), 10) asserts.assertEqual( int(global_histograms["benchmark_http_client.response_header_size"] ["raw_min"]), 97) asserts.assertEqual( int(global_histograms["benchmark_http_client.response_body_size"] ["raw_max"]), 10) asserts.assertEqual( int(global_histograms["benchmark_http_client.response_header_size"] ["raw_max"]), 97) asserts.assertEqual( int(global_histograms["benchmark_http_client.response_body_size"] ["raw_pstdev"]), 0) asserts.assertEqual( int(global_histograms["benchmark_http_client.response_header_size"] ["raw_pstdev"]), 0) asserts.assertEqual(len(counters), 12)
def test_h3_quic(quic_test_server_fixture): """Test http3 quic. Runs the CLI configured to use HTTP/3 Quic against our test server, and sanity checks statistics from both client and server. """ parsed_json, _ = quic_test_server_fixture.runNighthawkClient([ "--protocol http3", quic_test_server_fixture.getTestServerRootUri(), "--rps", "100", "--duration", "100", "--termination-predicate", "benchmark.http_2xx:24", "--max-active-requests", "1", # Envoy doesn't support disabling certificate verification on Quic # connections, so the host in our requests has to match the hostname in # the leaf certificate. "--request-header", "Host:www.lyft.com" ]) counters = quic_test_server_fixture.getNighthawkCounterMapFromJson(parsed_json) asserts.assertCounterEqual(counters, "benchmark.http_2xx", 25) asserts.assertCounterEqual(counters, "upstream_cx_http3_total", 1) asserts.assertCounterEqual(counters, "upstream_cx_total", 1) asserts.assertCounterEqual(counters, "upstream_rq_pending_total", 1) asserts.assertCounterEqual(counters, "upstream_rq_total", 25) asserts.assertCounterEqual(counters, "default.total_match_count", 1)