#![allow(clippy::unreadable_literal)] #![allow(clippy::cast_sign_loss)] #![allow(clippy::cast_precision_loss)] #![allow(clippy::cast_possible_truncation)]
use fraiseql_wire::metrics;
use fraiseql_wire::stream::StreamStats;
#[test]
fn test_metrics_module_exports() {
metrics::counters::query_submitted("test", true, false, false);
metrics::counters::auth_attempted("cleartext");
metrics::counters::json_parse_error("test");
metrics::counters::query_completed("success", "test");
metrics::counters::rows_processed("test", 100, "ok");
metrics::counters::rows_filtered("test", 10);
metrics::counters::deserialization_success("test", "TestType");
metrics::counters::deserialization_failure("test", "TestType", "missing_field");
metrics::histograms::query_startup_duration("test", 100);
metrics::histograms::query_total_duration("test", 500);
metrics::histograms::chunk_processing_duration("test", 50);
metrics::histograms::chunk_size("test", 256);
metrics::histograms::filter_duration("test", 10);
metrics::histograms::deserialization_duration("test", "TestType", 25);
metrics::histograms::auth_duration("cleartext", 50);
metrics::histograms::channel_occupancy("test", 100);
let _ = metrics::labels::ENTITY;
let _ = metrics::labels::MECHANISM_SCRAM;
let _ = metrics::labels::STATUS_OK;
}
#[test]
fn test_counters_basic_operation() {
for i in 0..10 {
metrics::counters::query_submitted(
&format!("entity_{}", i),
i % 2 == 0,
i % 3 == 0,
i % 4 == 0,
);
}
metrics::counters::auth_attempted(metrics::labels::MECHANISM_SCRAM);
metrics::counters::auth_attempted(metrics::labels::MECHANISM_CLEARTEXT);
metrics::counters::auth_successful(metrics::labels::MECHANISM_SCRAM);
metrics::counters::auth_failed(metrics::labels::MECHANISM_CLEARTEXT, "invalid_password");
for entity in &["users", "projects", "tasks"] {
metrics::counters::query_completed("success", entity);
metrics::counters::query_completed("error", entity);
metrics::counters::query_completed("cancelled", entity);
}
}
#[test]
fn test_histograms_basic_operation() {
for duration_ms in &[10, 50, 100, 250, 500, 1000] {
metrics::histograms::query_startup_duration("users", *duration_ms);
metrics::histograms::query_total_duration("projects", *duration_ms);
metrics::histograms::auth_duration(metrics::labels::MECHANISM_SCRAM, *duration_ms);
}
for chunk_size in &[1, 64, 128, 256, 512, 1024] {
metrics::histograms::chunk_size("data", *chunk_size);
metrics::histograms::chunk_processing_duration("data", *chunk_size / 4);
}
for i in 0..100 {
metrics::histograms::filter_duration("items", i as u64 % 100);
}
}
#[test]
fn test_deserialization_metrics_with_types() {
let types = [
"String",
"i32",
"bool",
"serde_json::Value",
"MyCustomType",
"Vec<String>",
];
for type_name in types {
metrics::counters::deserialization_success("users", type_name);
metrics::histograms::deserialization_duration("users", type_name, 15);
metrics::counters::deserialization_failure("users", type_name, "missing_field");
metrics::counters::deserialization_failure("users", type_name, "type_mismatch");
metrics::counters::deserialization_failure("users", type_name, "invalid_value");
}
}
#[test]
fn test_label_constants() {
assert_eq!(metrics::labels::ENTITY, "entity");
assert_eq!(metrics::labels::MECHANISM_SCRAM, "scram");
assert_eq!(metrics::labels::MECHANISM_CLEARTEXT, "cleartext");
assert_eq!(metrics::labels::STATUS_OK, "ok");
assert_eq!(metrics::labels::STATUS_ERROR, "error");
assert_eq!(metrics::labels::STATUS_CANCELLED, "cancelled");
assert_eq!(metrics::labels::STATUS_FILTERED, "filtered");
assert_eq!(metrics::labels::PHASE_AUTH, "auth");
assert_eq!(metrics::labels::PHASE_STARTUP, "startup");
assert_eq!(metrics::labels::PHASE_QUERY, "query");
assert_eq!(metrics::labels::PHASE_STREAMING, "streaming");
}
#[test]
fn test_query_error_categories() {
let error_categories = [
"server_error",
"protocol_error",
"connection_error",
"json_parse_error",
];
for entity in &["users", "projects", "tasks"] {
for error_category in &error_categories {
metrics::counters::query_error(entity, error_category);
}
}
}
#[test]
fn test_row_processing_metrics() {
let entities = ["users", "projects", "tasks", "events"];
let row_counts = [1, 10, 100, 1000, 10000];
for entity in entities {
for count in &row_counts {
metrics::counters::rows_processed(entity, *count, "ok");
metrics::counters::rows_processed(entity, count / 2, "error");
}
}
}
#[test]
fn test_filtering_metrics_distribution() {
for i in 0..1000 {
let filter_duration = (i % 100) as u64;
metrics::histograms::filter_duration("large_dataset", filter_duration);
if i % 7 == 0 {
metrics::counters::rows_filtered("large_dataset", 1);
}
}
}
#[test]
fn test_chunk_processing_metrics() {
for chunk_num in 0..10 {
let chunk_size = 256 - (chunk_num as u64 % 100);
let processing_duration = 10 + (chunk_num as u64 % 20);
metrics::histograms::chunk_size("items", chunk_size);
metrics::histograms::chunk_processing_duration("items", processing_duration);
}
}
#[test]
fn test_auth_metrics_both_mechanisms() {
metrics::counters::auth_attempted(metrics::labels::MECHANISM_SCRAM);
metrics::histograms::auth_duration(metrics::labels::MECHANISM_SCRAM, 150);
metrics::counters::auth_successful(metrics::labels::MECHANISM_SCRAM);
metrics::counters::auth_attempted(metrics::labels::MECHANISM_CLEARTEXT);
metrics::histograms::auth_duration(metrics::labels::MECHANISM_CLEARTEXT, 10);
metrics::counters::auth_successful(metrics::labels::MECHANISM_CLEARTEXT);
metrics::counters::auth_failed(metrics::labels::MECHANISM_SCRAM, "invalid_password");
metrics::counters::auth_failed(metrics::labels::MECHANISM_CLEARTEXT, "server_error");
}
#[test]
fn test_comprehensive_query_lifecycle() {
let entity = "users";
metrics::counters::query_submitted(entity, true, false, false);
metrics::counters::auth_attempted(metrics::labels::MECHANISM_SCRAM);
metrics::histograms::auth_duration(metrics::labels::MECHANISM_SCRAM, 100);
metrics::counters::auth_successful(metrics::labels::MECHANISM_SCRAM);
metrics::histograms::query_startup_duration(entity, 50);
for _chunk in 0..5 {
let chunk_size = 256u64;
metrics::histograms::chunk_size(entity, chunk_size);
metrics::histograms::chunk_processing_duration(entity, 20);
for row in 0..chunk_size {
metrics::histograms::filter_duration(entity, 5);
if row % 10 == 0 {
metrics::counters::rows_filtered(entity, 1);
}
}
metrics::counters::deserialization_success(entity, "User");
metrics::histograms::deserialization_duration(entity, "User", 8);
}
metrics::counters::rows_processed(entity, 1280, "ok");
metrics::histograms::query_total_duration(entity, 150);
metrics::counters::query_completed("success", entity);
}
#[test]
fn test_error_scenario_metrics() {
let entity = "projects";
metrics::counters::query_submitted(entity, false, true, true);
metrics::counters::auth_attempted(metrics::labels::MECHANISM_SCRAM);
metrics::counters::auth_successful(metrics::labels::MECHANISM_SCRAM);
metrics::histograms::query_startup_duration(entity, 75);
metrics::histograms::chunk_size(entity, 256);
metrics::histograms::chunk_processing_duration(entity, 25);
metrics::counters::json_parse_error(entity);
metrics::counters::query_error(entity, "json_parse_error");
metrics::counters::rows_processed(entity, 256, "error");
metrics::histograms::query_total_duration(entity, 100);
metrics::counters::query_completed("error", entity);
}
#[test]
fn test_cancellation_scenario_metrics() {
let entity = "tasks";
metrics::counters::query_submitted(entity, false, false, false);
metrics::histograms::query_startup_duration(entity, 30);
metrics::histograms::chunk_size(entity, 256);
metrics::histograms::chunk_processing_duration(entity, 15);
metrics::counters::rows_processed(entity, 256, "ok");
metrics::histograms::query_total_duration(entity, 50);
metrics::counters::query_completed("cancelled", entity);
}
#[test]
fn test_deserialization_error_scenarios() {
let entity = "data";
let type_name = "MyType";
for i in 0..100 {
if i % 10 == 0 {
metrics::counters::deserialization_failure(entity, type_name, "missing_field");
} else if i % 5 == 0 {
metrics::counters::deserialization_failure(entity, type_name, "type_mismatch");
} else {
metrics::counters::deserialization_success(entity, type_name);
metrics::histograms::deserialization_duration(entity, type_name, 10 + (i as u64 % 20));
}
}
}
#[test]
fn test_various_entity_names() {
let entities = [
"users",
"projects",
"tasks",
"events",
"logs",
"metrics_test_entity",
"very_long_entity_name_that_is_still_valid",
];
for entity in entities {
metrics::counters::query_submitted(entity, true, true, true);
metrics::histograms::query_startup_duration(entity, 100);
metrics::histograms::query_total_duration(entity, 500);
metrics::counters::rows_processed(entity, 1000, "ok");
metrics::counters::query_completed("success", entity);
}
}
#[test]
fn test_channel_occupancy_metrics() {
let entity = "backpressure_test";
for i in 0..10 {
metrics::histograms::channel_occupancy(entity, i as u64);
}
for i in 50..200 {
metrics::histograms::channel_occupancy(entity, i as u64);
}
for i in 200..256 {
metrics::histograms::channel_occupancy(entity, i as u64);
}
metrics::histograms::channel_occupancy(entity, 255);
metrics::histograms::channel_occupancy(entity, 256);
}
#[test]
fn test_channel_occupancy_multiple_entities() {
let entities = ["fast_entity", "slow_entity", "mixed_entity"];
for entity in entities {
for step in 0..100 {
let occupancy = (step % 256) as u64;
metrics::histograms::channel_occupancy(entity, occupancy);
}
}
}
#[test]
fn test_stream_stats_creation_and_properties() {
let stats = StreamStats {
items_buffered: 100,
estimated_memory: 204800, total_rows_yielded: 1000,
total_rows_filtered: 100,
};
assert_eq!(stats.items_buffered, 100);
assert_eq!(stats.estimated_memory, 204800);
assert_eq!(stats.total_rows_yielded, 1000);
assert_eq!(stats.total_rows_filtered, 100);
}
#[test]
fn test_stream_stats_memory_estimation_various_sizes() {
let buffer_sizes = [0, 1, 10, 50, 128, 256];
let expected_kb = [0, 2, 20, 100, 256, 512];
for (size, kb) in buffer_sizes.iter().zip(expected_kb.iter()) {
let stats = StreamStats {
items_buffered: *size,
estimated_memory: size * 2048,
total_rows_yielded: *size as u64,
total_rows_filtered: 0,
};
assert_eq!(stats.estimated_memory, kb * 1024);
}
}
#[test]
fn test_stream_stats_row_tracking() {
let stats = StreamStats {
items_buffered: 50,
estimated_memory: 102400,
total_rows_yielded: 5000,
total_rows_filtered: 500,
};
assert_eq!(stats.total_rows_yielded, 5000);
assert_eq!(stats.total_rows_filtered, 500);
let filter_ratio = stats.total_rows_filtered as f64 / stats.total_rows_yielded as f64;
assert!((filter_ratio - 0.1).abs() < 0.01); }
#[test]
fn test_stream_stats_zero() {
let stats = StreamStats::zero();
assert_eq!(stats.items_buffered, 0);
assert_eq!(stats.estimated_memory, 0);
assert_eq!(stats.total_rows_yielded, 0);
assert_eq!(stats.total_rows_filtered, 0);
}
#[test]
fn test_memory_limit_exceeded_metric() {
metrics::counters::memory_limit_exceeded("test_entity");
metrics::counters::memory_limit_exceeded("another_entity");
}
#[test]
fn test_memory_limit_exceeded_error() {
use fraiseql_wire::WireError;
let err = WireError::MemoryLimitExceeded {
limit: 500_000_000,
estimated_memory: 750_000_000,
};
let msg = err.to_string();
assert!(msg.contains("750000000"));
assert!(msg.contains("500000000"));
assert!(msg.contains("memory limit exceeded"));
assert_eq!(err.category(), "memory_limit_exceeded");
assert!(!err.is_retriable());
}
#[test]
fn test_query_builder_max_memory_api() {
}
#[test]
fn test_memory_estimation_formula() {
let test_cases = [
(0, 0), (1, 2048), (100, 204_800), (256, 524_288), (512, 1_048_576), ];
for (items, expected_bytes) in test_cases {
let estimated = items * 2048;
assert_eq!(
estimated, expected_bytes,
"Memory estimation failed for {} items",
items
);
}
}
#[test]
fn test_memory_limit_error_properties() {
use fraiseql_wire::WireError;
let error = WireError::MemoryLimitExceeded {
limit: 100_000,
estimated_memory: 150_000,
};
assert!(!error.is_retriable());
assert_eq!(error.category(), "memory_limit_exceeded");
let msg = error.to_string();
assert!(msg.contains("memory limit exceeded"));
assert!(msg.contains("buffered"));
assert!(msg.contains("limit"));
}