#![allow( clippy::assertions_on_constants, clippy::assertions_on_result_states, clippy::clone_on_copy, clippy::decimal_literal_representation, clippy::doc_markdown, clippy::empty_line_after_doc_comments, clippy::field_reassign_with_default, clippy::get_unwrap, clippy::identity_op, clippy::inconsistent_digit_grouping, clippy::indexing_slicing, clippy::integer_division, clippy::len_zero, clippy::let_underscore_must_use, clippy::manual_div_ceil, clippy::manual_let_else, clippy::manual_range_contains, clippy::modulo_arithmetic, clippy::needless_range_loop, clippy::non_ascii_literal, clippy::redundant_clone, clippy::shadow_reuse, clippy::shadow_same, clippy::shadow_unrelated, clippy::single_match_else, clippy::str_to_string, clippy::string_slice, clippy::tests_outside_test_module, clippy::too_many_lines, clippy::unnecessary_wraps, clippy::unseparated_literal_suffix, clippy::use_debug, clippy::useless_vec, clippy::wildcard_enum_match_arm, clippy::else_if_without_else, clippy::expect_used, clippy::missing_const_for_fn, clippy::similar_names, clippy::type_complexity, clippy::collapsible_else_if, clippy::doc_lazy_continuation, clippy::items_after_test_module, clippy::map_clone, clippy::multiple_unsafe_ops_per_block, clippy::unwrap_or_default, clippy::assign_op_pattern, clippy::needless_borrow, clippy::println_empty_string, clippy::unnecessary_cast, clippy::used_underscore_binding, clippy::create_dir, clippy::implicit_saturating_sub, clippy::exit, clippy::expect_fun_call, clippy::too_many_arguments, clippy::unnecessary_map_or, clippy::unwrap_used, dead_code, unused_imports, unused_variables, clippy::cloned_ref_to_slice_refs, clippy::neg_multiply, clippy::while_let_loop, clippy::bool_assert_comparison, clippy::excessive_precision, clippy::trivially_copy_pass_by_ref, clippy::op_ref, clippy::redundant_closure, clippy::unnecessary_lazy_evaluations, clippy::if_then_some_else_none, clippy::unnecessary_to_owned, clippy::single_component_path_imports, )] //! Unit tests for DQN Rainbow Configuration //! //! Tests configuration defaults, serialization, and validation for Rainbow DQN. use ml::dqn::rainbow_config::RainbowAgentConfig; #[test] fn test_rainbow_config_default() { let config = RainbowAgentConfig::default(); // Verify device defaults assert_eq!(config.device, "cpu"); // Verify replay buffer settings assert_eq!(config.min_replay_size, 10000); assert_eq!(config.replay_buffer_size, 100000); assert_eq!(config.batch_size, 32); // Verify learning parameters assert_eq!(config.learning_rate, 0.0001); assert!(config.gamma > 0.0 && config.gamma <= 1.0); // Verify update frequencies assert!(config.target_update_freq > 0); assert!(config.train_freq > 0); assert!(config.noise_reset_freq > 0); // Verify priority replay parameters assert!(config.priority_alpha >= 0.0); assert!(config.priority_beta >= 0.0 && config.priority_beta <= 1.0); assert!(config.priority_beta_increment >= 0.0); } #[test] fn test_rainbow_config_serialization() { let config = RainbowAgentConfig::default(); // Test JSON serialization let json = serde_json::to_string(&config).expect("Should serialize to JSON"); assert!(json.contains("device")); assert!(json.contains("batch_size")); assert!(json.contains("learning_rate")); // Test deserialization let deserialized: RainbowAgentConfig = serde_json::from_str(&json).expect("Should deserialize from JSON"); assert_eq!(deserialized.device, config.device); assert_eq!(deserialized.batch_size, config.batch_size); assert_eq!(deserialized.learning_rate, config.learning_rate); } #[test] fn test_rainbow_config_custom_values() { let mut config = RainbowAgentConfig::default(); // Modify configuration config.device = "cuda".to_string(); config.batch_size = 64; config.learning_rate = 0.001; config.gamma = 0.95; // Verify changes assert_eq!(config.device, "cuda"); assert_eq!(config.batch_size, 64); assert_eq!(config.learning_rate, 0.001); assert_eq!(config.gamma, 0.95); } #[test] fn test_rainbow_config_priority_replay_params() { let config = RainbowAgentConfig::default(); // Verify priority replay parameters are valid assert!( config.priority_alpha >= 0.0 && config.priority_alpha <= 1.0, "priority_alpha should be in [0, 1]" ); assert!( config.priority_beta >= 0.0 && config.priority_beta <= 1.0, "priority_beta should be in [0, 1]" ); assert!( config.priority_beta_increment >= 0.0 && config.priority_beta_increment <= 0.01, "priority_beta_increment should be small positive value" ); } #[test] fn test_rainbow_config_network_settings() { let config = RainbowAgentConfig::default(); // Verify network config exists let _network = &config.network_config; } #[test] fn test_rainbow_config_cloneable() { let config = RainbowAgentConfig::default(); let cloned = config.clone(); assert_eq!(cloned.device, config.device); assert_eq!(cloned.batch_size, config.batch_size); assert_eq!(cloned.learning_rate, config.learning_rate); } #[test] fn test_rainbow_config_debuggable() { let config = RainbowAgentConfig::default(); let debug_str = format!("{:?}", config); assert!(debug_str.contains("RainbowAgentConfig")); assert!(debug_str.contains("device")); }