upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorDanConwayDev <DanConwayDev@protonmail.com>2025-12-11 08:47:08 +0000
committerDanConwayDev <DanConwayDev@protonmail.com>2025-12-11 08:47:08 +0000
commit61d4796d84960ec9f25392635afceea3a3bd0916 (patch)
tree98bd7c10d34decc2f7c96f50ddead8e8dc63f473 /tests
parentffcf8a7bc679f0aff9135063d343be3161b3b439 (diff)
refactor: move metrics tests to tests/sync/ structure (Phase 7)
Diffstat (limited to 'tests')
-rw-r--r--tests/common/sync_helpers.rs31
-rw-r--r--tests/sync.rs2
-rw-r--r--tests/sync/metrics.rs (renamed from tests/proactive_sync_metrics.rs)72
-rw-r--r--tests/sync/mod.rs4
4 files changed, 58 insertions, 51 deletions
diff --git a/tests/common/sync_helpers.rs b/tests/common/sync_helpers.rs
index 50d0d7a..7788783 100644
--- a/tests/common/sync_helpers.rs
+++ b/tests/common/sync_helpers.rs
@@ -561,6 +561,37 @@ pub fn repo_coord(keys: &Keys, identifier: &str) -> String {
561 ) 561 )
562} 562}
563 563
564// ============================================================================
565// Metrics Helpers
566// ============================================================================
567
568/// Fetch Prometheus metrics from a relay's `/metrics` endpoint.
569///
570/// Converts the WebSocket URL to HTTP and fetches the metrics endpoint.
571/// Useful for verifying sync-related metrics in tests.
572///
573/// # Arguments
574/// * `relay_url` - WebSocket URL of the relay (e.g., "ws://127.0.0.1:8080")
575///
576/// # Returns
577/// * `Ok(String)` - The metrics text in Prometheus format
578/// * `Err(reqwest::Error)` - If the request fails
579///
580/// # Example
581/// ```ignore
582/// let metrics = fetch_metrics("ws://127.0.0.1:8080").await?;
583/// assert!(metrics.contains("ngit_sync_"));
584/// ```
585pub async fn fetch_metrics(relay_url: &str) -> Result<String, reqwest::Error> {
586 // Convert ws:// URL to http:// for metrics endpoint
587 let http_url = relay_url
588 .replace("ws://", "http://")
589 .replace("/", "")
590 + "/metrics";
591
592 reqwest::get(&http_url).await?.text().await
593}
594
564#[cfg(test)] 595#[cfg(test)]
565mod tests { 596mod tests {
566 use super::*; 597 use super::*;
diff --git a/tests/sync.rs b/tests/sync.rs
index 2836d8d..5b6b752 100644
--- a/tests/sync.rs
+++ b/tests/sync.rs
@@ -8,6 +8,7 @@
8//! - `live_sync` - Tests for real-time sync after connection established 8//! - `live_sync` - Tests for real-time sync after connection established
9//! - `tag_variations` - Tests for different Layer 2/3 tag types 9//! - `tag_variations` - Tests for different Layer 2/3 tag types
10//! - `catchup` - Tests for catchup sync after disconnect (not yet implemented) 10//! - `catchup` - Tests for catchup sync after disconnect (not yet implemented)
11//! - `metrics` - Tests for Prometheus metrics integration
11//! 12//!
12//! # Running Tests 13//! # Running Tests
13//! 14//!
@@ -34,5 +35,6 @@ mod sync {
34 pub mod catchup; 35 pub mod catchup;
35 pub mod discovery; 36 pub mod discovery;
36 pub mod live_sync; 37 pub mod live_sync;
38 pub mod metrics;
37 pub mod tag_variations; 39 pub mod tag_variations;
38} \ No newline at end of file 40} \ No newline at end of file
diff --git a/tests/proactive_sync_metrics.rs b/tests/sync/metrics.rs
index 32abe74..dbb9dc0 100644
--- a/tests/proactive_sync_metrics.rs
+++ b/tests/sync/metrics.rs
@@ -1,6 +1,6 @@
1//! GRASP-02 Phase 6: Proactive Sync Metrics Integration Tests 1//! Proactive Sync Metrics Tests
2//! 2//!
3//! Tests the Prometheus metrics integration for proactive sync: 3//! Tests for Prometheus metrics integration with proactive sync:
4//! - All sync metrics exposed at `/metrics` endpoint 4//! - All sync metrics exposed at `/metrics` endpoint
5//! - Connection metrics update correctly 5//! - Connection metrics update correctly
6//! - Health state metrics reflect actual state 6//! - Health state metrics reflect actual state
@@ -10,45 +10,15 @@
10//! # Running Tests 10//! # Running Tests
11//! 11//!
12//! ```bash 12//! ```bash
13//! cargo test --test proactive_sync_metrics 13//! cargo test --test sync metrics
14//! cargo test --test proactive_sync_metrics -- --nocapture 14//! cargo test --test sync metrics -- --nocapture
15//! ``` 15//! ```
16 16
17mod common;
18
19use std::time::Duration; 17use std::time::Duration;
20 18
21use common::TestRelay;
22use nostr_sdk::prelude::*; 19use nostr_sdk::prelude::*;
23 20
24/// Kind 30617 - Repository State (NIP-34) 21use crate::common::{sync_helpers::*, TestRelay};
25const KIND_REPOSITORY_STATE: u16 = 30617;
26
27/// Create a valid repository announcement event for testing
28fn create_valid_repo_announcement(keys: &Keys, domain: &str, identifier: &str) -> Event {
29 let tags = vec![
30 Tag::identifier(identifier),
31 Tag::custom(
32 TagKind::custom("clone"),
33 vec![format!("http://{}/{}", domain, identifier)],
34 ),
35 Tag::custom(TagKind::custom("relays"), vec![format!("ws://{}", domain)]),
36 ];
37
38 EventBuilder::new(Kind::Custom(KIND_REPOSITORY_STATE), "Repository state")
39 .tags(tags)
40 .sign_with_keys(keys)
41 .expect("Failed to sign event")
42}
43
44/// Helper to fetch metrics from a relay's HTTP endpoint
45async fn fetch_metrics(relay: &TestRelay) -> Result<String, reqwest::Error> {
46 // Extract host:port from ws:// URL
47 let ws_url = relay.url();
48 let http_url = ws_url.replace("ws://", "http://").replace("/", "") + "/metrics";
49
50 reqwest::get(&http_url).await?.text().await
51}
52 22
53/// Test that sync metrics are exposed at /metrics endpoint 23/// Test that sync metrics are exposed at /metrics endpoint
54#[tokio::test] 24#[tokio::test]
@@ -58,8 +28,8 @@ async fn test_sync_metrics_exposed() {
58 // Give time for relay to start 28 // Give time for relay to start
59 tokio::time::sleep(Duration::from_millis(500)).await; 29 tokio::time::sleep(Duration::from_millis(500)).await;
60 30
61 // Fetch metrics 31 // Fetch metrics using the shared helper
62 let metrics_result = fetch_metrics(&relay).await; 32 let metrics_result = fetch_metrics(&relay.url()).await;
63 33
64 relay.stop().await; 34 relay.stop().await;
65 35
@@ -84,7 +54,7 @@ async fn test_sync_metric_names_present() {
84 tokio::time::sleep(Duration::from_secs(2)).await; 54 tokio::time::sleep(Duration::from_secs(2)).await;
85 55
86 // Fetch metrics from the syncing relay 56 // Fetch metrics from the syncing relay
87 let metrics = fetch_metrics(&sync_relay) 57 let metrics = fetch_metrics(&sync_relay.url())
88 .await 58 .await
89 .expect("Failed to fetch metrics"); 59 .expect("Failed to fetch metrics");
90 60
@@ -113,7 +83,7 @@ async fn test_connection_metrics_on_success() {
113 tokio::time::sleep(Duration::from_secs(2)).await; 83 tokio::time::sleep(Duration::from_secs(2)).await;
114 84
115 // Fetch metrics - we can verify the relay started and metrics endpoint works 85 // Fetch metrics - we can verify the relay started and metrics endpoint works
116 let metrics = fetch_metrics(&sync_relay) 86 let metrics = fetch_metrics(&sync_relay.url())
117 .await 87 .await
118 .expect("Failed to fetch metrics"); 88 .expect("Failed to fetch metrics");
119 89
@@ -139,7 +109,7 @@ async fn test_event_sync_metrics() {
139 109
140 // Create and submit an event to source relay 110 // Create and submit an event to source relay
141 let keys = Keys::generate(); 111 let keys = Keys::generate();
142 let event = create_valid_repo_announcement(&keys, &source_relay.domain(), "metrics-test-repo"); 112 let event = create_repo_announcement(&keys, &[&source_relay.domain()], "metrics-test-repo");
143 113
144 let client = Client::default(); 114 let client = Client::default();
145 client 115 client
@@ -154,7 +124,7 @@ async fn test_event_sync_metrics() {
154 tokio::time::sleep(Duration::from_secs(2)).await; 124 tokio::time::sleep(Duration::from_secs(2)).await;
155 125
156 // Fetch metrics from sync relay 126 // Fetch metrics from sync relay
157 let metrics = fetch_metrics(&sync_relay) 127 let metrics = fetch_metrics(&sync_relay.url())
158 .await 128 .await
159 .expect("Failed to fetch metrics"); 129 .expect("Failed to fetch metrics");
160 130
@@ -180,7 +150,7 @@ async fn test_health_state_metrics() {
180 tokio::time::sleep(Duration::from_secs(3)).await; 150 tokio::time::sleep(Duration::from_secs(3)).await;
181 151
182 // Fetch metrics 152 // Fetch metrics
183 let metrics = fetch_metrics(&sync_relay) 153 let metrics = fetch_metrics(&sync_relay.url())
184 .await 154 .await
185 .expect("Failed to fetch metrics"); 155 .expect("Failed to fetch metrics");
186 156
@@ -203,7 +173,7 @@ async fn test_gap_event_tracking() {
203 let keys = Keys::generate(); 173 let keys = Keys::generate();
204 174
205 // Submit event before sync relay starts 175 // Submit event before sync relay starts
206 let event = create_valid_repo_announcement(&keys, &source_relay.domain(), "pre-existing-repo"); 176 let event = create_repo_announcement(&keys, &[&source_relay.domain()], "pre-existing-repo");
207 177
208 let client = Client::default(); 178 let client = Client::default();
209 client 179 client
@@ -220,7 +190,7 @@ async fn test_gap_event_tracking() {
220 tokio::time::sleep(Duration::from_secs(3)).await; 190 tokio::time::sleep(Duration::from_secs(3)).await;
221 191
222 // Fetch metrics 192 // Fetch metrics
223 let metrics = fetch_metrics(&sync_relay) 193 let metrics = fetch_metrics(&sync_relay.url())
224 .await 194 .await
225 .expect("Failed to fetch metrics"); 195 .expect("Failed to fetch metrics");
226 196
@@ -256,9 +226,9 @@ async fn test_multi_relay_load() {
256 // Submit events to all source relays 226 // Submit events to all source relays
257 let keys = Keys::generate(); 227 let keys = Keys::generate();
258 228
259 let event1 = create_valid_repo_announcement(&keys, &source_relay_1.domain(), "repo-1"); 229 let event1 = create_repo_announcement(&keys, &[&source_relay_1.domain()], "repo-1");
260 let event2 = create_valid_repo_announcement(&keys, &source_relay_2.domain(), "repo-2"); 230 let event2 = create_repo_announcement(&keys, &[&source_relay_2.domain()], "repo-2");
261 let event3 = create_valid_repo_announcement(&keys, &source_relay_3.domain(), "repo-3"); 231 let event3 = create_repo_announcement(&keys, &[&source_relay_3.domain()], "repo-3");
262 232
263 // Submit events 233 // Submit events
264 let client1 = Client::default(); 234 let client1 = Client::default();
@@ -289,7 +259,7 @@ async fn test_multi_relay_load() {
289 tokio::time::sleep(Duration::from_secs(3)).await; 259 tokio::time::sleep(Duration::from_secs(3)).await;
290 260
291 // Fetch metrics from sync relay 261 // Fetch metrics from sync relay
292 let metrics = fetch_metrics(&sync_relay) 262 let metrics = fetch_metrics(&sync_relay.url())
293 .await 263 .await
294 .expect("Failed to fetch metrics"); 264 .expect("Failed to fetch metrics");
295 265
@@ -315,7 +285,7 @@ async fn test_prometheus_format_valid() {
315 let relay = TestRelay::start().await; 285 let relay = TestRelay::start().await;
316 tokio::time::sleep(Duration::from_millis(500)).await; 286 tokio::time::sleep(Duration::from_millis(500)).await;
317 287
318 let metrics = fetch_metrics(&relay) 288 let metrics = fetch_metrics(&relay.url())
319 .await 289 .await
320 .expect("Failed to fetch metrics"); 290 .expect("Failed to fetch metrics");
321 291
@@ -350,7 +320,7 @@ async fn test_metrics_availability_during_sync() {
350 320
351 // Make multiple metrics requests while sync is active 321 // Make multiple metrics requests while sync is active
352 for i in 0..3 { 322 for i in 0..3 {
353 let metrics = fetch_metrics(&sync_relay).await; 323 let metrics = fetch_metrics(&sync_relay.url()).await;
354 assert!( 324 assert!(
355 metrics.is_ok(), 325 metrics.is_ok(),
356 "Metrics request {} should succeed during sync", 326 "Metrics request {} should succeed during sync",
@@ -361,4 +331,4 @@ async fn test_metrics_availability_during_sync() {
361 331
362 sync_relay.stop().await; 332 sync_relay.stop().await;
363 source_relay.stop().await; 333 source_relay.stop().await;
364} 334} \ No newline at end of file
diff --git a/tests/sync/mod.rs b/tests/sync/mod.rs
index b0da8b8..cf8f599 100644
--- a/tests/sync/mod.rs
+++ b/tests/sync/mod.rs
@@ -8,6 +8,7 @@
8//! - Live sync (events sync in real-time after connection established) 8//! - Live sync (events sync in real-time after connection established)
9//! - Tag variations (testing different Layer 2/3 tag types: a/A/q, e/E/q) 9//! - Tag variations (testing different Layer 2/3 tag types: a/A/q, e/E/q)
10//! - Catchup sync (events from disconnected period sync on reconnect) 10//! - Catchup sync (events from disconnected period sync on reconnect)
11//! - Metrics (Prometheus metrics for sync operations)
11//! 12//!
12//! # Test Files 13//! # Test Files
13//! 14//!
@@ -16,6 +17,7 @@
16//! - `live_sync.rs` - Tests 5, 6, 7: real-time sync after connection 17//! - `live_sync.rs` - Tests 5, 6, 7: real-time sync after connection
17//! - `tag_variations.rs` - Tests 8, 9: Layer 2/3 tag type coverage 18//! - `tag_variations.rs` - Tests 8, 9: Layer 2/3 tag type coverage
18//! - `catchup.rs` - Test 0: catchup after disconnect (stub, `#[ignore]`) 19//! - `catchup.rs` - Test 0: catchup after disconnect (stub, `#[ignore]`)
20//! - `metrics.rs` - Prometheus metrics integration tests
19//! 21//!
20//! # Shared Imports 22//! # Shared Imports
21//! 23//!
@@ -23,10 +25,12 @@
23//! - `TestClient` - Client with retry logic 25//! - `TestClient` - Client with retry logic
24//! - Event builders for Layer 2/3 events 26//! - Event builders for Layer 2/3 events
25//! - `wait_for_event_on_relay()` - Non-panicking assertion helper 27//! - `wait_for_event_on_relay()` - Non-panicking assertion helper
28//! - `fetch_metrics()` - Prometheus metrics fetching
26 29
27// Test modules 30// Test modules
28pub mod bootstrap; 31pub mod bootstrap;
29pub mod catchup; 32pub mod catchup;
30pub mod discovery; 33pub mod discovery;
31pub mod live_sync; 34pub mod live_sync;
35pub mod metrics;
32pub mod tag_variations; \ No newline at end of file 36pub mod tag_variations; \ No newline at end of file