use super::*; use std::fs::File; use vrp_core::models::examples::create_example_problem; #[test] fn can_read_full_config() { let file = File::open("../examples/data/config/config.full.json").expect("cannot read config from file"); let config = read_config(BufReader::new(file)).unwrap(); let telemetry = config.telemetry.expect("no telemetry config"); let logging = telemetry.progress.expect("no logging config"); assert!(logging.enabled); assert_eq!(logging.log_best, Some(100)); assert_eq!(logging.log_population, Some(1000)); let metrics = telemetry.metrics.unwrap(); assert!(!metrics.enabled); assert_eq!(metrics.track_population, Some(1000)); let evolution_config = config.evolution.expect("no evolution config"); let initial = evolution_config.initial.expect("no initial population config"); match initial.method { RecreateMethod::Cheapest { weight: 1 } => {} _ => unreachable!(), } assert_eq!(initial.alternatives.methods.len(), 7); assert_eq!(initial.alternatives.max_size, 4); assert_eq!(initial.alternatives.quota, 0.05); match evolution_config.population.expect("no population config") { PopulationType::Rosomaxa { selection_size, max_elite_size, max_node_size, spread_factor, distribution_factor, rebalance_memory, exploration_ratio, } => { assert_eq!(selection_size, Some(8)); assert_eq!(max_elite_size, Some(2)); assert_eq!(max_node_size, Some(2)); assert_eq!(spread_factor, Some(0.75)); assert_eq!(distribution_factor, Some(0.75)); assert_eq!(rebalance_memory, Some(100)); assert_eq!(exploration_ratio, Some(0.9)); } _ => unreachable!(), } let hyper_config = config.hyper.expect("cannot get hyper"); match hyper_config { HyperType::StaticSelective { operators } => { let operators = operators.expect("cannot get operators"); assert_eq!(operators.len(), 4); match operators.first().unwrap() { SearchOperatorType::Decomposition { routes, repeat, probability } => { assert_eq!(*repeat, 4); assert_eq!(routes.min, 2); assert_eq!(routes.max, 4); match probability { OperatorProbabilityType::Context { threshold, phases } => { assert_eq!(threshold.jobs, 300); assert_eq!(threshold.routes, 10); assert_eq!(phases.len(), 2); } _ => unreachable!(), } } _ => unreachable!(), } match operators.get(1).unwrap() { SearchOperatorType::LocalSearch { probability, times, operators: inners } => { assert_eq!(as_scalar_probability(probability), 0.05); assert_eq!(*times, MinMaxConfig { min: 1, max: 2 }); assert_eq!(inners.len(), 4); } _ => unreachable!(), } match operators.get(2).unwrap() { SearchOperatorType::RuinRecreate { probability, ruins, recreates } => { assert_eq!(as_scalar_probability(probability), 1.); assert_eq!(ruins.len(), 7); assert_eq!(recreates.len(), 12); } _ => unreachable!(), } match operators.last().unwrap() { SearchOperatorType::LocalSearch { probability, times, operators: inners } => { assert_eq!(as_scalar_probability(probability), 0.01); assert_eq!(*times, MinMaxConfig { min: 1, max: 2 }); assert_eq!(inners.len(), 4); } _ => unreachable!(), } } HyperType::DynamicSelective => unreachable!(), } let termination = config.termination.expect("no termination config"); assert_eq!(termination.max_time, Some(300)); assert_eq!(termination.max_generations, Some(3000)); let environment = config.environment.expect("no environment config"); assert_eq!(environment.is_experimental, Some(false)); let parallelism = environment.parallelism.expect("no parallelism config"); assert_eq!(parallelism.num_thread_pools, 6); assert_eq!(parallelism.threads_per_pool, 8); let logging = environment.logging.expect("no logging config"); assert!(logging.enabled); assert_eq!(logging.prefix, Some("[config.full]".to_string())); let output_cfg = config.output.expect("cannot read output config"); assert_eq!(output_cfg.include_geojson, Some(true)); } #[test] fn can_create_default_config() { let config = Config::default(); assert!(config.evolution.is_none()); assert!(config.hyper.is_none()); assert!(config.termination.is_none()); assert!(config.telemetry.is_none()); } #[test] fn can_configure_telemetry_metrics() { let config = Config { evolution: None, hyper: None, termination: Some(TerminationConfig { max_time: None, max_generations: Some(100), variation: None }), environment: None, telemetry: Some(TelemetryConfig { progress: None, metrics: Some(MetricsConfig { enabled: true, track_population: Some(10) }), }), output: None, }; let solution = create_builder_from_config(create_example_problem(), Vec::default(), &config) .and_then(|config_builder| config_builder.build()) .map(|evolution_config| Solver::new(create_example_problem(), evolution_config)) .and_then(|solver| solver.solve()) .unwrap(); let metrics = solution.telemetry.expect("no metrics"); assert_eq!(metrics.generations, 100); assert_eq!(metrics.evolution.len(), 10 + 1); } fn as_scalar_probability(probability: &OperatorProbabilityType) -> Float { match probability { OperatorProbabilityType::Scalar { scalar } => *scalar, _ => unreachable!(), } }