Skip to content

Commit 63476f9

Browse files
committed
tests: add tests to check user-agent in request headers
1 parent 100dc08 commit 63476f9

File tree

5 files changed

+67
-89
lines changed

5 files changed

+67
-89
lines changed

Cargo.lock

Lines changed: 0 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

common/eth2/Cargo.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,3 @@ zeroize = { workspace = true }
3838

3939
[dev-dependencies]
4040
tokio = { workspace = true }
41-
mockito = { workspace = true }
42-
regex = { workspace = true }

common/eth2/src/lighthouse_vc/http_client.rs

Lines changed: 4 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,10 @@ impl ValidatorClientHttpClient {
691691
let url = self.make_graffiti_url(pubkey)?;
692692
self.delete(url).await
693693
}
694+
695+
pub async fn create_request<U: IntoUrl>(&self, url: U) -> Result<Response, Error> {
696+
self.client.get(url).send().await.map_err(Error::from)
697+
}
694698
}
695699

696700
/// Returns `Ok(response)` if the response is a `200 OK` response or a
@@ -709,87 +713,3 @@ async fn ok_or_error(response: Response) -> Result<Response, Error> {
709713
Err(Error::StatusCode(status))
710714
}
711715
}
712-
713-
#[cfg(test)]
714-
mod tests {
715-
use super::*;
716-
use mockito::{Matcher, Server};
717-
use std::str::FromStr;
718-
719-
#[test]
720-
fn test_validator_client_creation_with_user_agent() {
721-
let server = SensitiveUrl::parse("http://localhost:5062").unwrap();
722-
let secret = "test-secret".to_string();
723-
724-
// Test authenticated client
725-
let client = ValidatorClientHttpClient::new(server.clone(), secret.clone()).unwrap();
726-
assert!(client.api_token().is_some());
727-
assert_eq!(client.authorization_header, AuthorizationHeader::Bearer);
728-
729-
// Test unauthenticated client
730-
let unauth_client = ValidatorClientHttpClient::new_unauthenticated(server).unwrap();
731-
assert!(unauth_client.api_token().is_none());
732-
assert_eq!(unauth_client.authorization_header, AuthorizationHeader::Omit);
733-
}
734-
735-
#[tokio::test]
736-
async fn test_validator_client_user_agent_in_requests() {
737-
// Create mock server
738-
let mut server = Server::new_async().await;
739-
let expected_user_agent = lighthouse_version::user_agent();
740-
741-
// Mock the auth endpoint with user agent verification
742-
let auth_mock = server
743-
.mock("GET", "/lighthouse/auth")
744-
.match_header("user-agent", expected_user_agent.as_str())
745-
.with_status(200)
746-
.with_body(r#"{"token_path":"/tmp/test","api_token":"test-token"}"#)
747-
.create_async()
748-
.await;
749-
750-
// Create client
751-
let server_url = SensitiveUrl::parse(&server.url()).unwrap();
752-
let client = ValidatorClientHttpClient::new_unauthenticated(server_url).unwrap();
753-
754-
// Make request - this should include the user agent header
755-
let _result = client.get_auth().await;
756-
757-
// Verify the mock was called with correct user agent
758-
auth_mock.assert_async().await;
759-
}
760-
761-
#[tokio::test]
762-
async fn test_validator_client_user_agent_with_auth_token() {
763-
// Create mock server
764-
let mut server = Server::new_async().await;
765-
let expected_user_agent = lighthouse_version::user_agent();
766-
let auth_token = "test-bearer-token";
767-
768-
// Mock the keystores endpoint with both user agent and authorization verification
769-
let keystores_mock = server
770-
.mock("GET", "/eth/v1/keystores")
771-
.match_header("user-agent", expected_user_agent.as_str())
772-
.match_header("authorization", format!("Bearer {}", auth_token).as_str())
773-
.with_status(200)
774-
.with_body(r#"{"data":[]}"#)
775-
.create_async()
776-
.await;
777-
778-
// Create authenticated client
779-
let server_url = SensitiveUrl::parse(&server.url()).unwrap();
780-
let client = ValidatorClientHttpClient::new(server_url, auth_token.to_string()).unwrap();
781-
782-
// Make request - this should include both user agent and authorization headers
783-
let _result = client.get_keystores().await;
784-
785-
// Verify the mock was called with correct headers
786-
keystores_mock.assert_async().await;
787-
}
788-
789-
#[test]
790-
fn test_authorization_header_display() {
791-
assert_eq!(AuthorizationHeader::Omit.to_string(), "Omit");
792-
assert_eq!(AuthorizationHeader::Basic.to_string(), "Basic");
793-
assert_eq!(AuthorizationHeader::Bearer.to_string(), "Bearer");
794-
}
795-
}

validator_client/http_api/src/test_utils.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,14 @@ use slot_clock::{SlotClock, TestingSlotClock};
2222
use std::future::Future;
2323
use std::net::{IpAddr, Ipv4Addr};
2424
use std::sync::Arc;
25+
use std::sync::Mutex;
2526
use std::time::Duration;
2627
use task_executor::test_utils::TestRuntime;
2728
use tempfile::{TempDir, tempdir};
2829
use tokio::sync::oneshot;
2930
use types::ChainSpec;
3031
use validator_services::block_service::BlockService;
32+
use warp::Filter;
3133
use zeroize::Zeroizing;
3234

3335
pub const PASSWORD_BYTES: &[u8] = &[42, 50, 37];
@@ -436,6 +438,33 @@ impl ApiTester {
436438
self
437439
}
438440

441+
pub async fn test_user_agent_is_set(self) -> Self {
442+
let captured: Arc<Mutex<Option<String>>> = Arc::new(Mutex::new(None));
443+
let captured_filter = captured.clone();
444+
445+
// Warp route: capture User-Agent header
446+
let route = warp::any()
447+
.and(warp::header::optional::<String>("user-agent"))
448+
.map(move |ua: Option<String>| {
449+
*captured_filter.lock().unwrap() = ua;
450+
warp::reply()
451+
});
452+
453+
// Start ephemeral server
454+
let (addr, server) = warp::serve(route).bind_ephemeral(([127, 0, 0, 1], 0));
455+
tokio::spawn(server);
456+
457+
// Make a request (simulate Lighthouse client)
458+
let url = format!("http://{}/", addr);
459+
let _client = self.client.create_request(&url).await;
460+
461+
// Check captured User-Agent
462+
let ua = captured.lock().unwrap().clone().unwrap();
463+
assert_eq!(ua, lighthouse_version::user_agent());
464+
465+
self
466+
}
467+
439468
pub async fn create_keystore_validators(self, s: KeystoreValidatorScenario) -> Self {
440469
let initial_vals = self.vals_total();
441470
let initial_enabled_vals = self.vals_enabled();

validator_client/http_api/src/tests.rs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
#![cfg(test)]
21
#![cfg(not(debug_assertions))]
32

43
mod keystores;
@@ -27,11 +26,13 @@ use std::future::Future;
2726
use std::net::{IpAddr, Ipv4Addr};
2827
use std::str::FromStr;
2928
use std::sync::Arc;
29+
use std::sync::Mutex;
3030
use std::time::Duration;
3131
use task_executor::test_utils::TestRuntime;
3232
use tempfile::{TempDir, tempdir};
3333
use types::graffiti::GraffitiString;
3434
use validator_store::ValidatorStore;
35+
use warp::Filter;
3536
use zeroize::Zeroizing;
3637

3738
const PASSWORD_BYTES: &[u8] = &[42, 50, 37];
@@ -401,6 +402,33 @@ impl ApiTester {
401402
self
402403
}
403404

405+
pub async fn test_user_agent_is_set(self) -> Self {
406+
let captured: Arc<Mutex<Option<String>>> = Arc::new(Mutex::new(None));
407+
let captured_filter = captured.clone();
408+
409+
// Warp route: capture User-Agent header
410+
let route = warp::any()
411+
.and(warp::header::optional::<String>("user-agent"))
412+
.map(move |ua: Option<String>| {
413+
*captured_filter.lock().unwrap() = ua;
414+
warp::reply()
415+
});
416+
417+
// Start ephemeral server
418+
let (addr, server) = warp::serve(route).bind_ephemeral(([127, 0, 0, 1], 0));
419+
tokio::spawn(server);
420+
421+
// Make a request (simulate Lighthouse client)
422+
let url = format!("http://{}/", addr);
423+
let _client = self.client.create_request(&url).await;
424+
425+
// Check captured User-Agent
426+
let ua = captured.lock().unwrap().clone().unwrap();
427+
assert_eq!(ua, lighthouse_version::user_agent());
428+
429+
self
430+
}
431+
404432
pub async fn create_keystore_validators(self, s: KeystoreValidatorScenario) -> Self {
405433
let initial_vals = self.vals_total();
406434
let initial_enabled_vals = self.vals_enabled();
@@ -1043,6 +1071,11 @@ async fn validator_exit() {
10431071
.await;
10441072
}
10451073

1074+
#[tokio::test]
1075+
async fn user_agent_is_set() {
1076+
ApiTester::new().await.test_user_agent_is_set().await;
1077+
}
1078+
10461079
#[tokio::test]
10471080
async fn validator_enabling() {
10481081
ApiTester::new()

0 commit comments

Comments
 (0)