#[cfg(test)]
mod tests {
use crate::{
create_backoff_strategy, BackoffConfig, ConsumerConfig, ConsumerStartSequence,
HealthStatus, WorkQueue,
};
use std::time::Duration;
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq)]
struct TestMessage {
id: String,
content: String,
timestamp: chrono::DateTime<chrono::Utc>,
}
impl TestMessage {
fn new(id: &str, content: &str) -> Self {
Self {
id: id.to_string(),
content: content.to_string(),
timestamp: chrono::Utc::now(),
}
}
}
#[test]
fn test_test_message_constructor() {
let msg = TestMessage::new("id-123", "payload");
assert_eq!(msg.id, "id-123");
assert_eq!(msg.content, "payload");
assert!(msg.timestamp <= chrono::Utc::now());
}
#[test]
fn test_health_status_comprehensive() {
let healthy = HealthStatus {
nats_connected: true,
jetstream_available: true,
};
assert!(healthy.is_healthy());
let nats_only = HealthStatus {
nats_connected: true,
jetstream_available: false,
};
assert!(!nats_only.is_healthy());
let jetstream_only = HealthStatus {
nats_connected: false,
jetstream_available: true,
};
assert!(!jetstream_only.is_healthy());
let disconnected = HealthStatus {
nats_connected: false,
jetstream_available: false,
};
assert!(!disconnected.is_healthy());
}
#[test]
fn test_health_status_serialization() {
let status = HealthStatus {
nats_connected: true,
jetstream_available: false,
};
let json = serde_json::to_string(&status).expect("Should serialize");
assert!(json.contains("nats_connected"));
assert!(json.contains("jetstream_available"));
assert!(json.contains("true"));
assert!(json.contains("false"));
let deserialized: HealthStatus = serde_json::from_str(&json).expect("Should deserialize");
assert_eq!(deserialized.nats_connected, status.nats_connected);
assert_eq!(deserialized.jetstream_available, status.jetstream_available);
assert!(!deserialized.is_healthy());
}
#[test]
fn test_consumer_config_comprehensive() {
let default_config = ConsumerConfig::default();
assert!(!default_config.name.is_empty());
assert!(default_config.name.starts_with("consumer-"));
assert_eq!(default_config.max_deliver, 3);
assert_eq!(default_config.ack_wait, Duration::from_secs(30));
assert_eq!(
default_config.max_age,
Some(Duration::from_secs(24 * 60 * 60))
); assert_eq!(default_config.worker_count, 1);
assert!(default_config.consumer_group.is_none());
assert!(matches!(
default_config.start_sequence,
ConsumerStartSequence::Latest
));
let custom_config = ConsumerConfig {
name: "test-consumer".to_string(),
consumer_group: Some("test-group".to_string()),
max_deliver: 5,
ack_wait: Duration::from_secs(60),
max_age: Some(Duration::from_secs(3600)), start_sequence: ConsumerStartSequence::First,
worker_count: 4,
};
assert_eq!(custom_config.name, "test-consumer");
assert_eq!(custom_config.consumer_group, Some("test-group".to_string()));
assert_eq!(custom_config.max_deliver, 5);
assert_eq!(custom_config.ack_wait, Duration::from_secs(60));
assert_eq!(custom_config.max_age, Some(Duration::from_secs(3600)));
assert_eq!(custom_config.worker_count, 4);
assert!(matches!(
custom_config.start_sequence,
ConsumerStartSequence::First
));
}
#[test]
fn test_consumer_start_sequence() {
let first = ConsumerStartSequence::First;
let latest = ConsumerStartSequence::Latest;
let sequence = ConsumerStartSequence::Sequence(12345);
let time = ConsumerStartSequence::Time(chrono::Utc::now());
match first {
ConsumerStartSequence::First => {}
_ => panic!("Expected First variant"),
}
match latest {
ConsumerStartSequence::Latest => {}
_ => panic!("Expected Latest variant"),
}
match sequence {
ConsumerStartSequence::Sequence(seq) => assert_eq!(seq, 12345),
_ => panic!("Expected Sequence variant"),
}
match time {
ConsumerStartSequence::Time(_) => {}
_ => panic!("Expected Time variant"),
}
}
#[test]
fn test_backoff_config_comprehensive() {
let default_config = BackoffConfig::default();
assert_eq!(default_config.initial_delay, Duration::from_millis(100));
assert_eq!(default_config.max_delay, Duration::from_secs(30));
assert_eq!(default_config.max_retries, 5);
assert_eq!(default_config.multiplier, 2.0);
assert_eq!(default_config.jitter, 0.1);
let custom_config = BackoffConfig {
initial_delay: Duration::from_millis(50),
max_delay: Duration::from_secs(60),
max_retries: 10,
multiplier: 1.5,
jitter: 0.2,
};
assert_eq!(custom_config.initial_delay, Duration::from_millis(50));
assert_eq!(custom_config.max_delay, Duration::from_secs(60));
assert_eq!(custom_config.max_retries, 10);
assert_eq!(custom_config.multiplier, 1.5);
assert_eq!(custom_config.jitter, 0.2);
let strategy = create_backoff_strategy(&custom_config);
let delays: Vec<Duration> = strategy.collect();
assert_eq!(delays.len(), custom_config.max_retries);
assert_eq!(delays[0], custom_config.initial_delay);
for i in 1..delays.len() {
assert!(delays[i] >= delays[i - 1]);
}
}
#[test]
fn test_backoff_config_edge_cases() {
let zero_config = BackoffConfig {
initial_delay: Duration::from_millis(0),
max_delay: Duration::from_millis(0),
max_retries: 0,
multiplier: 0.0,
jitter: 0.0,
};
let strategy = create_backoff_strategy(&zero_config);
let delays: Vec<Duration> = strategy.collect();
assert_eq!(delays.len(), 0);
let large_config = BackoffConfig {
initial_delay: Duration::from_secs(300),
max_delay: Duration::from_secs(3600),
max_retries: 1000,
multiplier: 10.0,
jitter: 1.0,
};
let strategy = create_backoff_strategy(&large_config);
let delays: Vec<Duration> = strategy.collect();
assert_eq!(delays.len(), large_config.max_retries);
for delay in delays {
assert!(delay <= large_config.max_delay);
}
}
#[test]
fn test_work_queue_creation() {
let _batch_size = 50;
let _timeout = Duration::from_secs(5);
let strategy = WorkQueue::create_batch_retry_strategy();
let delays: Vec<Duration> = strategy.collect();
assert_eq!(delays.len(), 3); assert_eq!(delays[0], Duration::from_millis(100));
for i in 1..delays.len() {
assert!(delays[i] >= delays[i - 1]); }
assert!(delays.iter().all(|&d| d <= Duration::from_secs(5)));
}
#[test]
fn test_work_queue_single_retry_strategy() {
let strategy = WorkQueue::create_single_retry_strategy();
let delays: Vec<Duration> = strategy.collect();
assert_eq!(delays.len(), 3); assert_eq!(delays[0], Duration::from_millis(50));
for i in 1..delays.len() {
assert!(delays[i] >= delays[i - 1]); }
assert!(delays.iter().all(|&d| d <= Duration::from_secs(2)));
}
#[test]
fn test_work_queue_batch_vs_single_strategies() {
let batch_strategy = WorkQueue::create_batch_retry_strategy();
let batch_delays: Vec<Duration> = batch_strategy.collect();
let single_strategy = WorkQueue::create_single_retry_strategy();
let single_delays: Vec<Duration> = single_strategy.collect();
assert_eq!(batch_delays.len(), single_delays.len());
assert!(batch_delays[0] > single_delays[0]);
let batch_max = batch_delays.iter().max().unwrap();
let single_max = single_delays.iter().max().unwrap();
assert!(batch_max >= single_max);
}
#[test]
fn test_consumer_config_unique_names() {
let config1 = ConsumerConfig::default();
let config2 = ConsumerConfig::default();
assert_ne!(config1.name, config2.name);
assert!(config1.name.starts_with("consumer-"));
assert!(config2.name.starts_with("consumer-"));
assert!(config1.name.contains('-'));
assert!(config2.name.contains('-'));
}
#[test]
fn test_consumer_config_worker_count_scenarios() {
let single_worker = ConsumerConfig::default();
assert_eq!(single_worker.worker_count, 1);
let multi_worker = ConsumerConfig {
worker_count: 8,
..Default::default()
};
assert_eq!(multi_worker.worker_count, 8);
let zero_worker = ConsumerConfig {
worker_count: 0,
..Default::default()
};
assert_eq!(zero_worker.worker_count, 0);
}
#[test]
fn test_consumer_config_timing_configurations() {
let short_ack = ConsumerConfig {
ack_wait: Duration::from_millis(100),
..Default::default()
};
assert_eq!(short_ack.ack_wait, Duration::from_millis(100));
let long_ack = ConsumerConfig {
ack_wait: Duration::from_secs(600), ..Default::default()
};
assert_eq!(long_ack.ack_wait, Duration::from_secs(600));
let unlimited_age = ConsumerConfig {
max_age: None,
..Default::default()
};
assert!(unlimited_age.max_age.is_none());
let short_age = ConsumerConfig {
max_age: Some(Duration::from_secs(60)), ..Default::default()
};
assert_eq!(short_age.max_age, Some(Duration::from_secs(60)));
}
#[test]
fn test_consumer_config_delivery_configurations() {
let single_delivery = ConsumerConfig {
max_deliver: 1,
..Default::default()
};
assert_eq!(single_delivery.max_deliver, 1);
let many_retries = ConsumerConfig {
max_deliver: 100,
..Default::default()
};
assert_eq!(many_retries.max_deliver, 100);
let zero_delivery = ConsumerConfig {
max_deliver: 0,
..Default::default()
};
assert_eq!(zero_delivery.max_deliver, 0);
}
#[test]
fn test_health_status_debug_and_clone() {
let status = HealthStatus {
nats_connected: true,
jetstream_available: false,
};
let debug_str = format!("{:?}", status);
assert!(debug_str.contains("nats_connected"));
assert!(debug_str.contains("jetstream_available"));
assert!(debug_str.contains("true"));
assert!(debug_str.contains("false"));
let cloned_status = status.clone();
assert_eq!(status.nats_connected, cloned_status.nats_connected);
assert_eq!(
status.jetstream_available,
cloned_status.jetstream_available
);
assert_eq!(status.is_healthy(), cloned_status.is_healthy());
}
#[test]
fn test_backoff_config_debug_and_clone() {
let config = BackoffConfig {
initial_delay: Duration::from_millis(200),
max_delay: Duration::from_secs(45),
max_retries: 7,
multiplier: 1.8,
jitter: 0.15,
};
let debug_str = format!("{:?}", config);
assert!(debug_str.contains("initial_delay"));
assert!(debug_str.contains("max_delay"));
assert!(debug_str.contains("max_retries"));
assert!(debug_str.contains("multiplier"));
assert!(debug_str.contains("jitter"));
let cloned_config = config.clone();
assert_eq!(config.initial_delay, cloned_config.initial_delay);
assert_eq!(config.max_delay, cloned_config.max_delay);
assert_eq!(config.max_retries, cloned_config.max_retries);
assert_eq!(config.multiplier, cloned_config.multiplier);
assert_eq!(config.jitter, cloned_config.jitter);
}
#[test]
fn test_consumer_config_debug_and_clone() {
let config = ConsumerConfig {
name: "debug-test-consumer".to_string(),
consumer_group: Some("debug-group".to_string()),
max_deliver: 4,
ack_wait: Duration::from_secs(45),
max_age: Some(Duration::from_secs(7200)),
start_sequence: ConsumerStartSequence::Sequence(999),
worker_count: 3,
};
let debug_str = format!("{:?}", config);
assert!(debug_str.contains("debug-test-consumer"));
assert!(debug_str.contains("debug-group"));
assert!(debug_str.contains("max_deliver"));
assert!(debug_str.contains("worker_count"));
let cloned_config = config.clone();
assert_eq!(config.name, cloned_config.name);
assert_eq!(config.consumer_group, cloned_config.consumer_group);
assert_eq!(config.max_deliver, cloned_config.max_deliver);
assert_eq!(config.ack_wait, cloned_config.ack_wait);
assert_eq!(config.max_age, cloned_config.max_age);
assert_eq!(config.worker_count, cloned_config.worker_count);
}
#[test]
fn test_consumer_start_sequence_comprehensive() {
let timestamp = chrono::Utc::now();
let first = ConsumerStartSequence::First;
let first_debug = format!("{:?}", first);
assert!(first_debug.contains("First"));
let latest = ConsumerStartSequence::Latest;
let latest_debug = format!("{:?}", latest);
assert!(latest_debug.contains("Latest"));
let sequence = ConsumerStartSequence::Sequence(54321);
let sequence_debug = format!("{:?}", sequence);
assert!(sequence_debug.contains("Sequence"));
assert!(sequence_debug.contains("54321"));
let time = ConsumerStartSequence::Time(timestamp);
let time_debug = format!("{:?}", time);
assert!(time_debug.contains("Time"));
let cloned_first = first.clone();
assert!(matches!(cloned_first, ConsumerStartSequence::First));
let cloned_latest = latest.clone();
assert!(matches!(cloned_latest, ConsumerStartSequence::Latest));
let cloned_sequence = sequence.clone();
if let ConsumerStartSequence::Sequence(seq) = cloned_sequence {
assert_eq!(seq, 54321);
} else {
panic!("Expected Sequence variant");
}
let cloned_time = time.clone();
if let ConsumerStartSequence::Time(t) = cloned_time {
assert_eq!(t, timestamp);
} else {
panic!("Expected Time variant");
}
}
#[test]
fn test_message_delivery_tracking() {
let delivery_counts = vec![1, 2, 3, 5, 10];
for count in delivery_counts {
let is_redelivery = count > 1;
if count == 1 {
assert!(!is_redelivery, "First delivery should not be redelivery");
} else {
assert!(is_redelivery, "Delivery count > 1 should be redelivery");
}
}
}
#[test]
fn test_timing_edge_cases() {
let zero_duration = Duration::from_nanos(0);
let _max_duration = Duration::from_secs(u64::MAX / 1000);
let config_zero = ConsumerConfig {
ack_wait: zero_duration,
max_age: Some(zero_duration),
..Default::default()
};
assert_eq!(config_zero.ack_wait, zero_duration);
assert_eq!(config_zero.max_age, Some(zero_duration));
let config_large = ConsumerConfig {
ack_wait: Duration::from_secs(86400), max_age: Some(Duration::from_secs(604800)), ..Default::default()
};
assert_eq!(config_large.ack_wait, Duration::from_secs(86400));
assert_eq!(config_large.max_age, Some(Duration::from_secs(604800)));
}
#[test]
fn test_backoff_strategy_limits() {
let extreme_config = BackoffConfig {
initial_delay: Duration::from_nanos(1),
max_delay: Duration::from_nanos(100),
max_retries: 1000,
multiplier: 100.0,
jitter: 0.0,
};
let strategy = create_backoff_strategy(&extreme_config);
let delays: Vec<Duration> = strategy.collect();
assert_eq!(delays.len(), extreme_config.max_retries);
for delay in delays {
assert!(delay <= extreme_config.max_delay);
}
}
#[test]
fn test_uuid_generation_uniqueness() {
let mut names = std::collections::HashSet::new();
for _ in 0..100 {
let config = ConsumerConfig::default();
let inserted = names.insert(config.name.clone());
assert!(inserted, "UUID should be unique: {}", config.name);
}
assert_eq!(names.len(), 100);
}
#[test]
fn test_message_acknowledgment_conceptual() {
let scenarios = vec![
(1, false, "First delivery"),
(2, true, "Second delivery (redelivery)"),
(3, true, "Third delivery (redelivery)"),
(10, true, "Tenth delivery (redelivery)"),
];
for (count, expected_redelivery, scenario) in scenarios {
let is_redelivery = count > 1;
assert_eq!(
is_redelivery, expected_redelivery,
"Failed for scenario: {}",
scenario
);
}
}
#[test]
fn test_message_subject_handling() {
let subjects = vec![
"smith.intents.raw.fs.read.v1",
"smith.intents.vetted.http.fetch.v1",
"smith.results.fs.read.v1",
"smith.audit.security.v1",
"",
"invalid.subject",
"smith.intents.raw.",
"very.long.subject.with.many.parts.that.could.cause.issues",
];
for subject in subjects {
if subject.starts_with("smith.") {
assert!(
subject.len() > 6,
"Smith subject should have content after prefix"
);
}
if subject.is_empty() {
assert_eq!(subject, "", "Empty subject should be empty string");
}
let parts: Vec<&str> = subject.split('.').collect();
if !subject.is_empty() {
assert!(!parts.is_empty(), "Subject should have at least one part");
}
}
}
#[test]
fn test_work_queue_timeout_configurations() {
let timeouts = vec![
Duration::from_millis(0),
Duration::from_millis(1),
Duration::from_millis(100),
Duration::from_secs(1),
Duration::from_secs(30),
Duration::from_secs(300),
];
for timeout in timeouts {
let millis = timeout.as_millis();
let reconstructed = Duration::from_millis(millis as u64);
assert_eq!(reconstructed.as_millis(), millis);
}
}
#[test]
fn test_work_queue_batch_size_scenarios() {
let batch_sizes = vec![0, 1, 10, 50, 100, 1000, 10000];
for batch_size in batch_sizes {
if batch_size == 0 {
assert_eq!(batch_size, 0);
} else {
assert!(
batch_size > 0,
"Positive batch size should be greater than 0"
);
}
assert!(
batch_size <= 10000,
"Batch size should have reasonable upper limit"
);
}
}
#[test]
fn test_work_queue_retry_strategy_comparison() {
let batch_strategy = WorkQueue::create_batch_retry_strategy();
let batch_delays: Vec<Duration> = batch_strategy.collect();
let single_strategy = WorkQueue::create_single_retry_strategy();
let single_delays: Vec<Duration> = single_strategy.collect();
assert_eq!(batch_delays.len(), single_delays.len());
assert_eq!(batch_delays.len(), 3);
assert_eq!(batch_delays[0], Duration::from_millis(100));
assert!(batch_delays.iter().all(|&d| d <= Duration::from_secs(5)));
assert_eq!(single_delays[0], Duration::from_millis(50));
assert!(single_delays.iter().all(|&d| d <= Duration::from_secs(2)));
for i in 1..batch_delays.len() {
assert!(batch_delays[i] >= batch_delays[i - 1]);
assert!(single_delays[i] >= single_delays[i - 1]);
}
}
#[test]
fn test_backoff_config_mathematical_properties() {
let config = BackoffConfig {
initial_delay: Duration::from_millis(100),
max_delay: Duration::from_secs(10),
max_retries: 5,
multiplier: 2.0,
jitter: 0.1,
};
assert!(config.multiplier > 0.0, "Multiplier should be positive");
assert!(
config.multiplier <= 100.0,
"Multiplier should have reasonable upper bound"
);
assert!(config.jitter >= 0.0, "Jitter should be non-negative");
assert!(config.jitter <= 1.0, "Jitter should not exceed 100%");
assert!(
config.initial_delay <= config.max_delay,
"Initial delay should not exceed max delay"
);
assert!(
config.max_retries <= 1000,
"Max retries should have reasonable upper bound"
);
}
#[test]
fn test_health_status_edge_cases() {
let test_cases = vec![
(true, true, true, "Both connected and available"),
(
true,
false,
false,
"NATS connected but JetStream unavailable",
),
(
false,
true,
false,
"NATS disconnected but JetStream available",
),
(false, false, false, "Both disconnected and unavailable"),
];
for (nats, jetstream, expected_healthy, description) in test_cases {
let status = HealthStatus {
nats_connected: nats,
jetstream_available: jetstream,
};
assert_eq!(
status.is_healthy(),
expected_healthy,
"Failed for: {}",
description
);
let json = serde_json::to_string(&status).expect("Should serialize");
let deserialized: HealthStatus =
serde_json::from_str(&json).expect("Should deserialize");
assert_eq!(status.nats_connected, deserialized.nats_connected);
assert_eq!(status.jetstream_available, deserialized.jetstream_available);
assert_eq!(status.is_healthy(), deserialized.is_healthy());
}
}
#[test]
fn test_consumer_config_consumer_group_scenarios() {
let test_cases = vec![
None,
Some("".to_string()),
Some("simple-group".to_string()),
Some("complex-group-with-hyphens".to_string()),
Some("group_with_underscores".to_string()),
Some("groupWithCamelCase".to_string()),
Some("group.with.dots".to_string()),
Some("a".repeat(100)), ];
for group in test_cases {
let config = ConsumerConfig {
consumer_group: group.clone(),
..Default::default()
};
assert_eq!(config.consumer_group, group);
let cloned = config.clone();
assert_eq!(cloned.consumer_group, group);
}
}
#[test]
fn test_consumer_start_sequence_edge_cases() {
let sequences = vec![0, 1, u64::MAX / 2, u64::MAX - 1];
for seq in sequences {
let start_seq = ConsumerStartSequence::Sequence(seq);
match start_seq {
ConsumerStartSequence::Sequence(s) => assert_eq!(s, seq),
_ => panic!("Expected Sequence variant"),
}
}
let now = chrono::Utc::now();
let past = now - chrono::Duration::seconds(3600);
let future = now + chrono::Duration::seconds(3600);
let time_sequences = vec![past, now, future];
for time in time_sequences {
let start_seq = ConsumerStartSequence::Time(time);
match start_seq {
ConsumerStartSequence::Time(t) => assert_eq!(t, time),
_ => panic!("Expected Time variant"),
}
}
}
#[test]
fn test_backoff_strategy_extreme_configurations() {
let configs = vec![
BackoffConfig {
initial_delay: Duration::from_millis(1),
max_delay: Duration::from_secs(1),
max_retries: 100,
multiplier: 1.1,
jitter: 0.01,
},
BackoffConfig {
initial_delay: Duration::from_secs(1),
max_delay: Duration::from_secs(60),
max_retries: 10,
multiplier: 3.0,
jitter: 0.5,
},
];
for config in configs {
let strategy = create_backoff_strategy(&config);
let delays: Vec<Duration> = strategy.collect();
assert_eq!(delays.len(), config.max_retries);
for delay in &delays {
assert!(*delay >= Duration::from_nanos(0));
}
if !delays.is_empty() {
if config.jitter == 0.0 || config.jitter < 0.1 {
assert_eq!(delays[0], config.initial_delay);
} else {
assert!(delays[0] <= config.max_delay);
}
}
}
}
#[test]
fn test_consumer_config_max_deliver_edge_cases() {
let max_deliver_values = vec![0, 1, 2, 3, 10, 100, i64::MAX];
for max_deliver in max_deliver_values {
let config = ConsumerConfig {
max_deliver,
..Default::default()
};
assert_eq!(config.max_deliver, max_deliver);
let cloned = config.clone();
assert_eq!(cloned.max_deliver, max_deliver);
}
}
#[test]
fn test_duration_arithmetic_safety() {
let durations = vec![
Duration::from_nanos(0),
Duration::from_nanos(1),
Duration::from_millis(1),
Duration::from_secs(1),
Duration::from_secs(3600),
];
for dur1 in &durations {
for dur2 in &durations {
if let Some(sum) = dur1.checked_add(*dur2) {
assert!(sum >= *dur1);
assert!(sum >= *dur2);
}
if *dur1 >= *dur2 {
let diff = *dur1 - *dur2;
assert!(diff <= *dur1);
}
for factor in [1, 2, 3] {
if let Some(product) = dur1.checked_mul(factor) {
assert!(product >= *dur1);
}
}
}
}
}
#[test]
fn test_work_queue_log_batch_result_coverage() {
let batch_sizes = vec![0, 1, 5, 10, 50];
for size in batch_sizes {
if size == 0 {
assert_eq!(size, 0);
} else {
assert!(size > 0);
}
}
}
#[test]
fn test_message_timeout_scenarios() {
let timeout = Duration::from_millis(100);
assert!(timeout >= Duration::from_millis(1));
assert!(timeout <= Duration::from_secs(1));
let half_timeout = timeout / 2;
assert_eq!(half_timeout, Duration::from_millis(50));
let double_timeout = timeout * 2;
assert_eq!(double_timeout, Duration::from_millis(200));
}
#[test]
fn test_consumer_config_comprehensive_validation() {
let comprehensive_config = ConsumerConfig {
name: "comprehensive-test-consumer".to_string(),
consumer_group: Some("comprehensive-group".to_string()),
max_deliver: 7,
ack_wait: Duration::from_secs(45),
max_age: Some(Duration::from_secs(86400)), start_sequence: ConsumerStartSequence::Sequence(12345),
worker_count: 8,
};
assert_eq!(comprehensive_config.name, "comprehensive-test-consumer");
assert_eq!(
comprehensive_config.consumer_group,
Some("comprehensive-group".to_string())
);
assert_eq!(comprehensive_config.max_deliver, 7);
assert_eq!(comprehensive_config.ack_wait, Duration::from_secs(45));
assert_eq!(
comprehensive_config.max_age,
Some(Duration::from_secs(86400))
);
assert_eq!(comprehensive_config.worker_count, 8);
match comprehensive_config.start_sequence {
ConsumerStartSequence::Sequence(seq) => assert_eq!(seq, 12345),
_ => panic!("Expected Sequence variant"),
}
assert!(comprehensive_config.max_deliver > 0);
assert!(comprehensive_config.ack_wait > Duration::from_secs(0));
assert!(comprehensive_config.worker_count > 0);
if let Some(age) = comprehensive_config.max_age {
assert!(age > Duration::from_secs(0));
}
}
#[test]
fn test_connection_state_conceptual() {
let connection_states = vec![
("Connected", true),
("Disconnected", false),
("Connecting", false),
("Reconnecting", false),
("Closed", false),
];
for (state_name, expected_connected) in connection_states {
let is_connected = state_name == "Connected";
assert_eq!(
is_connected, expected_connected,
"Failed for state: {}",
state_name
);
}
}
#[test]
fn test_jetstream_availability_timeout() {
let timeout = Duration::from_secs(1);
assert!(timeout >= Duration::from_millis(100));
assert!(timeout <= Duration::from_secs(10));
assert_eq!(timeout, Duration::from_secs(1));
let half_timeout = timeout / 2;
assert_eq!(half_timeout, Duration::from_millis(500));
let double_timeout = timeout * 2;
assert_eq!(double_timeout, Duration::from_secs(2));
}
}