use blvm_node::config::*;
use std::collections::HashMap;
#[test]
fn test_config_with_all_transport_preferences() {
let mut preferences = vec![TransportPreferenceConfig::TcpOnly];
#[cfg(feature = "quinn")]
preferences.push(TransportPreferenceConfig::QuinnOnly);
#[cfg(feature = "iroh")]
{
preferences.push(TransportPreferenceConfig::IrohOnly);
preferences.push(TransportPreferenceConfig::Hybrid);
}
#[cfg(all(feature = "quinn", feature = "iroh"))]
preferences.push(TransportPreferenceConfig::All);
for preference in preferences {
let mut config = NodeConfig::default();
config.transport_preference = preference;
let json = serde_json::to_string(&config).unwrap();
let deserialized: NodeConfig = serde_json::from_str(&json).unwrap();
let deserialized_pref: blvm_node::network::transport::TransportPreference =
deserialized.transport_preference.into();
let expected_pref: blvm_node::network::transport::TransportPreference = preference.into();
assert_eq!(deserialized_pref, expected_pref);
}
}
#[test]
fn test_config_with_extreme_values() {
let mut config = NodeConfig::default();
let mut network_timing = NetworkTimingConfig::default();
network_timing.target_outbound_peers = 1000; network_timing.peer_connection_delay_seconds = 3600; config.network_timing = Some(network_timing);
let storage = StorageConfig::default();
config.storage = Some(storage);
let json = serde_json::to_string(&config).unwrap();
let deserialized: NodeConfig = serde_json::from_str(&json).unwrap();
assert_eq!(
deserialized
.network_timing
.as_ref()
.unwrap()
.target_outbound_peers,
1000
);
assert!(deserialized.storage.is_some());
}
#[test]
fn test_config_with_minimal_values() {
let mut config = NodeConfig::default();
let mut network_timing = NetworkTimingConfig::default();
network_timing.target_outbound_peers = 1;
network_timing.peer_connection_delay_seconds = 0;
config.network_timing = Some(network_timing);
let storage = StorageConfig::default();
config.storage = Some(storage);
let json = serde_json::to_string(&config).unwrap();
let deserialized: NodeConfig = serde_json::from_str(&json).unwrap();
assert_eq!(
deserialized
.network_timing
.as_ref()
.unwrap()
.target_outbound_peers,
1
);
assert_eq!(
deserialized
.network_timing
.as_ref()
.unwrap()
.peer_connection_delay_seconds,
0
);
}
#[test]
fn test_config_with_all_pruning_modes() {
let test_cases = vec![
(PruningMode::Disabled, None),
(
PruningMode::Normal {
keep_from_height: 0,
min_recent_blocks: 100,
},
Some(100),
),
(
PruningMode::Normal {
keep_from_height: 0,
min_recent_blocks: 1000,
},
Some(1000),
),
];
for (mode, expected_min) in test_cases {
let pruning_config = PruningConfig {
mode: match mode {
PruningMode::Disabled => PruningMode::Disabled,
PruningMode::Normal {
keep_from_height,
min_recent_blocks,
} => PruningMode::Normal {
keep_from_height,
min_recent_blocks,
},
_ => continue,
},
prune_on_startup: true,
..Default::default()
};
let json = serde_json::to_string(&pruning_config).unwrap();
let deserialized: PruningConfig = serde_json::from_str(&json).unwrap();
match (deserialized.mode, expected_min) {
(PruningMode::Disabled, None) => {}
(
PruningMode::Normal {
min_recent_blocks: d_min,
..
},
Some(e_min),
) => {
assert_eq!(d_min, e_min);
}
_ => panic!("Modes don't match"),
}
}
}
#[test]
fn test_config_with_complex_indexing_config() {
let mut indexing_config = IndexingConfig::default();
indexing_config.enable_address_index = true;
indexing_config.enable_value_index = true;
indexing_config.strategy = IndexingStrategy::Lazy;
let json = serde_json::to_string(&indexing_config).unwrap();
let deserialized: IndexingConfig = serde_json::from_str(&json).unwrap();
assert_eq!(deserialized.enable_address_index, true);
assert_eq!(deserialized.enable_value_index, true);
match (deserialized.strategy, IndexingStrategy::Lazy) {
(IndexingStrategy::Lazy, IndexingStrategy::Lazy) => {}
_ => panic!("Strategy doesn't match"),
}
}
#[test]
fn test_config_with_module_overrides() {
let mut config = NodeConfig::default();
let mut module_config = HashMap::new();
module_config.insert("key1".to_string(), "value1".to_string());
module_config.insert("key2".to_string(), "value2".to_string());
if let Some(ref mut modules) = config.modules {
modules
.module_configs
.insert("test-module".to_string(), module_config);
}
let json = serde_json::to_string(&config).unwrap();
let deserialized: NodeConfig = serde_json::from_str(&json).unwrap();
assert!(deserialized
.modules
.as_ref()
.unwrap()
.module_configs
.contains_key("test-module"));
let module_config = deserialized
.modules
.as_ref()
.unwrap()
.module_configs
.get("test-module")
.unwrap();
assert_eq!(module_config.get("key1"), Some(&"value1".to_string()));
}
#[test]
fn test_config_with_empty_strings() {
let mut config = NodeConfig::default();
if let Some(ref mut modules) = config.modules {
modules.modules_dir = String::new();
modules.data_dir = String::new();
}
let json = serde_json::to_string(&config).unwrap();
let deserialized: NodeConfig = serde_json::from_str(&json).unwrap();
assert_eq!(deserialized.modules.as_ref().unwrap().modules_dir, "");
assert_eq!(deserialized.modules.as_ref().unwrap().data_dir, "");
}
#[test]
fn test_config_with_all_indexing_strategies() {
let strategies = vec![IndexingStrategy::Eager, IndexingStrategy::Lazy];
for strategy in &strategies {
let mut storage = StorageConfig::default();
if let Some(ref mut indexing) = storage.indexing {
indexing.strategy = match strategy {
IndexingStrategy::Eager => IndexingStrategy::Eager,
IndexingStrategy::Lazy => IndexingStrategy::Lazy,
};
}
let mut config = NodeConfig::default();
config.storage = Some(storage);
let json = serde_json::to_string(&config).unwrap();
let deserialized: NodeConfig = serde_json::from_str(&json).unwrap();
if let Some(ref storage) = deserialized.storage {
if let Some(ref indexing) = storage.indexing {
match (indexing.strategy, strategy) {
(IndexingStrategy::Eager, IndexingStrategy::Eager) => {}
(IndexingStrategy::Lazy, IndexingStrategy::Lazy) => {}
_ => panic!("Strategy doesn't match"),
}
}
}
}
}
#[test]
fn test_config_roundtrip_complex_scenario() {
let mut config = NodeConfig::default();
config.transport_preference = TransportPreferenceConfig::TcpOnly;
let mut network_timing = NetworkTimingConfig::default();
network_timing.target_outbound_peers = 50;
config.network_timing = Some(network_timing);
let mut storage = StorageConfig::default();
let mut pruning = PruningConfig::default();
pruning.mode = PruningMode::Normal {
keep_from_height: 0,
min_recent_blocks: 5000,
};
storage.pruning = Some(pruning);
if let Some(ref mut indexing) = storage.indexing {
indexing.enable_address_index = true;
indexing.strategy = IndexingStrategy::Eager;
}
config.storage = Some(storage);
if let Some(ref mut modules) = config.modules {
modules.enabled_modules = vec!["module1".to_string(), "module2".to_string()];
}
let json = serde_json::to_string(&config).unwrap();
let deserialized: NodeConfig = serde_json::from_str(&json).unwrap();
let deserialized_pref: blvm_node::network::transport::TransportPreference =
deserialized.transport_preference.into();
let expected: blvm_node::network::transport::TransportPreference =
TransportPreferenceConfig::TcpOnly.into();
assert_eq!(deserialized_pref, expected);
assert_eq!(
deserialized
.network_timing
.as_ref()
.unwrap()
.target_outbound_peers,
50
);
if let Some(ref storage) = deserialized.storage {
if let Some(ref pruning) = storage.pruning {
match &pruning.mode {
PruningMode::Normal {
min_recent_blocks, ..
} => assert_eq!(*min_recent_blocks, 5000),
_ => panic!("Expected Normal pruning mode"),
}
}
if let Some(ref indexing) = storage.indexing {
assert_eq!(indexing.enable_address_index, true);
match indexing.strategy {
IndexingStrategy::Eager => {}
_ => panic!("Expected Eager strategy"),
}
}
}
assert_eq!(
deserialized.modules.as_ref().unwrap().enabled_modules.len(),
2
);
}
#[test]
fn test_config_with_malformed_json_handling() {
let malformed_json = r#"{
"transport_preference": "invalid_value"
}"#;
let result: Result<NodeConfig, _> = serde_json::from_str(malformed_json);
assert!(result.is_err());
}
#[test]
fn test_config_defaults_after_partial_deserialization() {
let partial_json = r#"{
"transport_preference": "tcponly"
}"#;
let config: NodeConfig = serde_json::from_str(partial_json).unwrap();
let pref: blvm_node::network::transport::TransportPreference =
config.transport_preference.into();
assert!(pref.allows_tcp());
if let Some(ref modules) = config.modules {
assert_eq!(modules.enabled, true); }
}