From f983a626613f22d051a8a9c5dd41ff0923a8a10f Mon Sep 17 00:00:00 2001 From: Itay Tsabary Date: Wed, 25 Dec 2024 16:44:18 +0200 Subject: [PATCH] chore(starknet_http_server): add metric tests commit-id:839045c7 --- Cargo.lock | 4 + crates/starknet_http_server/Cargo.toml | 5 ++ .../starknet_http_server/src/http_server.rs | 1 - .../src/http_server_test.rs | 89 ++++++++++++++++++- crates/starknet_http_server/src/metrics.rs | 6 +- 5 files changed, 100 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bf2d5d7d57..0fcb86c63c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10490,16 +10490,20 @@ name = "starknet_http_server" version = "0.0.0" dependencies = [ "axum", + "blockifier", "hyper 0.14.30", "infra_utils", "jsonrpsee", + "mempool_test_utils", "metrics 0.21.1", + "metrics-exporter-prometheus", "papyrus_config", "reqwest 0.11.27", "serde", "serde_json", "starknet_api", "starknet_gateway_types", + "starknet_http_server", "starknet_sequencer_infra", "thiserror", "tokio", diff --git a/crates/starknet_http_server/Cargo.toml b/crates/starknet_http_server/Cargo.toml index c3b49c77ad..8d0aa7fc31 100644 --- a/crates/starknet_http_server/Cargo.toml +++ b/crates/starknet_http_server/Cargo.toml @@ -29,5 +29,10 @@ tracing.workspace = true validator.workspace = true [dev-dependencies] +blockifier = { workspace = true, features = ["testing"] } +mempool_test_utils.workspace = true +metrics-exporter-prometheus.workspace = true serde_json.workspace = true +starknet_gateway_types = { workspace = true, features = ["testing"] } +starknet_http_server = { workspace = true, features = ["testing"] } tokio = { workspace = true, features = ["rt"] } diff --git a/crates/starknet_http_server/src/http_server.rs b/crates/starknet_http_server/src/http_server.rs index 2063a6ae1e..38097aa994 100644 --- a/crates/starknet_http_server/src/http_server.rs +++ b/crates/starknet_http_server/src/http_server.rs @@ -72,7 +72,6 @@ async fn add_tx( HttpServerError::from(e) }); record_added_transaction_status(add_tx_result.is_ok()); - add_tx_result_as_json(add_tx_result) } diff --git a/crates/starknet_http_server/src/http_server_test.rs b/crates/starknet_http_server/src/http_server_test.rs index 787bed37f1..912f036866 100644 --- a/crates/starknet_http_server/src/http_server_test.rs +++ b/crates/starknet_http_server/src/http_server_test.rs @@ -1,9 +1,26 @@ +use std::net::SocketAddr; +use std::sync::Arc; + use axum::body::{Bytes, HttpBody}; use axum::http::StatusCode; use axum::response::{IntoResponse, Response}; +use blockifier::test_utils::CairoVersion; +use infra_utils::metrics::parse_numeric_metric; +use mempool_test_utils::starknet_api_test_utils::invoke_tx; +use metrics_exporter_prometheus::PrometheusBuilder; use starknet_api::transaction::TransactionHash; +use starknet_gateway_types::communication::{GatewayClientError, MockGatewayClient}; +use starknet_sequencer_infra::component_client::ClientError; +use tokio::task; -use crate::http_server::add_tx_result_as_json; +use crate::config::HttpServerConfig; +use crate::http_server::{add_tx_result_as_json, HttpServer}; +use crate::metrics::{ + ADDED_TRANSACTIONS_FAILURE, + ADDED_TRANSACTIONS_SUCCESS, + ADDED_TRANSACTIONS_TOTAL, +}; +use crate::test_utils::HttpTestClient; #[tokio::test] async fn test_tx_hash_json_conversion() { @@ -20,3 +37,73 @@ async fn test_tx_hash_json_conversion() { async fn to_bytes(res: Response) -> Bytes { res.into_body().collect().await.unwrap().to_bytes() } + +#[tokio::test] +async fn get_metrics_test() { + // Create a mock gateway client that returns a successful response and a failure response. + const SUCCESS_TXS_TO_SEND: usize = 1; + const FAILURE_TXS_TO_SEND: usize = 1; + + let mut mock_gateway_client = MockGatewayClient::new(); + // Set the successful response. + mock_gateway_client + .expect_add_tx() + .times(1) + .return_once(move |_| Ok(TransactionHash::default())); + // Set the failure response. + mock_gateway_client.expect_add_tx().times(1).return_once(move |_| { + Err(GatewayClientError::ClientError(ClientError::UnexpectedResponse( + "mock response".to_string(), + ))) + }); + + // Initialize the metrics directly instead of spawning a monitoring endpoint task. + let prometheus_handle = PrometheusBuilder::new() + .install_recorder() + .expect("should be able to build the recorder and install it globally"); + + // TODO(Tsabary): replace the const port with something that is not hardcoded. + // Create and run the server. + let http_server_config = HttpServerConfig { ip: "127.0.0.1".parse().unwrap(), port: 15123 }; + let mut http_server = + HttpServer::new(http_server_config.clone(), Arc::new(mock_gateway_client)); + tokio::spawn(async move { http_server.run().await }); + + let HttpServerConfig { ip, port } = http_server_config; + let add_tx_http_client = HttpTestClient::new(SocketAddr::from((ip, port))); + + // Ensure the server starts running. + task::yield_now().await; + + // Send transactions to the server. + for _ in std::iter::repeat(()).take(SUCCESS_TXS_TO_SEND + FAILURE_TXS_TO_SEND) { + let rpc_tx = invoke_tx(CairoVersion::default()); + add_tx_http_client.add_tx(rpc_tx).await; + } + + // Obtain and parse metrics. + let metrics = prometheus_handle.render(); + let added_transactions_total_count = + parse_numeric_metric::(&metrics, ADDED_TRANSACTIONS_TOTAL.0); + let added_transactions_success_count = + parse_numeric_metric::(&metrics, ADDED_TRANSACTIONS_SUCCESS.0); + let added_transactions_failure_count = + parse_numeric_metric::(&metrics, ADDED_TRANSACTIONS_FAILURE.0); + + // Ensure the metric values are as expected. + assert_eq!( + added_transactions_total_count.unwrap(), + SUCCESS_TXS_TO_SEND + FAILURE_TXS_TO_SEND, + "Total transaction count mismatch" + ); + assert_eq!( + added_transactions_success_count.unwrap(), + SUCCESS_TXS_TO_SEND, + "Successful transaction count mismatch" + ); + assert_eq!( + added_transactions_failure_count.unwrap(), + FAILURE_TXS_TO_SEND, + "Failing transaction count mismatch" + ); +} diff --git a/crates/starknet_http_server/src/metrics.rs b/crates/starknet_http_server/src/metrics.rs index 4db77daac9..b3a53b48de 100644 --- a/crates/starknet_http_server/src/metrics.rs +++ b/crates/starknet_http_server/src/metrics.rs @@ -1,11 +1,11 @@ use metrics::{absolute_counter, describe_counter, register_counter}; use tracing::info; -const ADDED_TRANSACTIONS_TOTAL: (&str, &str, u64) = +pub(crate) const ADDED_TRANSACTIONS_TOTAL: (&str, &str, u64) = ("ADDED_TRANSACTIONS_TOTAL", "Total number of transactions added", 0); -const ADDED_TRANSACTIONS_SUCCESS: (&str, &str, u64) = +pub(crate) const ADDED_TRANSACTIONS_SUCCESS: (&str, &str, u64) = ("ADDED_TRANSACTIONS_SUCCESS", "Number of successfully added transactions", 0); -const ADDED_TRANSACTIONS_FAILURE: (&str, &str, u64) = +pub(crate) const ADDED_TRANSACTIONS_FAILURE: (&str, &str, u64) = ("ADDED_TRANSACTIONS_FAILURE", "Number of faulty added transactions", 0); pub(crate) fn init_metrics() {