Skip to main content

perfgate_app/
baseline_resolve.rs

1//! Baseline path resolution logic.
2
3use perfgate_types::ConfigFile;
4use std::path::PathBuf;
5
6/// Resolve the baseline path from CLI args or config defaults.
7pub fn resolve_baseline_path(
8    cli_baseline: &Option<PathBuf>,
9    bench_name: &str,
10    config: &ConfigFile,
11) -> PathBuf {
12    // 1. CLI takes precedence
13    if let Some(path) = cli_baseline {
14        return path.clone();
15    }
16
17    // 2. Fall back to baseline_pattern from config defaults.
18    if let Some(pattern) = &config.defaults.baseline_pattern {
19        return render_baseline_pattern(pattern, bench_name);
20    }
21
22    // 3. Fall back to baseline_dir from config defaults
23    if let Some(baseline_dir) = &config.defaults.baseline_dir {
24        if is_remote_storage_uri(baseline_dir) {
25            return PathBuf::from(format!(
26                "{}/{}.json",
27                baseline_dir.trim_end_matches('/'),
28                bench_name
29            ));
30        }
31        return PathBuf::from(baseline_dir).join(format!("{}.json", bench_name));
32    }
33
34    // 4. Default convention: baselines/{bench_name}.json
35    PathBuf::from("baselines").join(format!("{}.json", bench_name))
36}
37
38/// Render a baseline pattern by replacing {bench} placeholder.
39pub fn render_baseline_pattern(pattern: &str, bench_name: &str) -> PathBuf {
40    PathBuf::from(pattern.replace("{bench}", bench_name))
41}
42
43/// Check if a path is a remote storage URI (s3:// or gs://).
44pub fn is_remote_storage_uri(path: &str) -> bool {
45    path.starts_with("s3://") || path.starts_with("gs://")
46}
47
48#[cfg(test)]
49mod tests {
50    use super::*;
51    use perfgate_types::{BaselineServerConfig, ConfigFile, DefaultsConfig};
52
53    #[test]
54    fn test_resolve_baseline_path_uses_cli_over_config() {
55        let config = ConfigFile {
56            defaults: DefaultsConfig {
57                noise_threshold: None,
58                baseline_pattern: Some("pattern/{bench}.receipt.json".to_string()),
59                baseline_dir: Some("bases".to_string()),
60                ..Default::default()
61            },
62            baseline_server: BaselineServerConfig::default(),
63            benches: Vec::new(),
64        };
65
66        let cli = Some(PathBuf::from("cli.json"));
67        assert_eq!(
68            resolve_baseline_path(&cli, "bench", &config),
69            PathBuf::from("cli.json")
70        );
71
72        let no_cli = None;
73        assert_eq!(
74            resolve_baseline_path(&no_cli, "bench", &config),
75            PathBuf::from("pattern").join("bench.receipt.json")
76        );
77    }
78
79    #[test]
80    fn test_is_remote_storage_uri() {
81        assert!(is_remote_storage_uri("s3://bucket/key"));
82        assert!(is_remote_storage_uri("gs://bucket/key"));
83        assert!(!is_remote_storage_uri("local/path"));
84    }
85}