vdev/commands/compose_tests/
active_projects.rs

1use anyhow::{Context, Result};
2use std::{collections::HashSet, process::Command};
3
4use crate::testing::{config::ComposeTestConfig, docker::CONTAINER_TOOL};
5
6/// Query Docker Compose for active projects
7pub(super) fn load_active_projects() -> Result<HashSet<String>> {
8    let output = Command::new(CONTAINER_TOOL.clone())
9        .args(["compose", "ls", "--format", "json"])
10        .output()
11        .with_context(|| "Failed to list compose projects")?;
12
13    if !output.status.success() {
14        return Ok(HashSet::new());
15    }
16
17    let projects: Vec<serde_json::Value> = serde_json::from_slice(&output.stdout)
18        .with_context(|| "Failed to parse docker compose ls output")?;
19
20    Ok(projects
21        .iter()
22        .filter_map(|project| {
23            project
24                .get("Name")
25                .and_then(|n| n.as_str())
26                .map(String::from)
27        })
28        .collect())
29}
30
31/// Find the active environment for a given integration by matching Docker Compose project names
32pub(super) fn find_active_environment(
33    active_projects: &HashSet<String>,
34    prefix: &str,
35    config: &ComposeTestConfig,
36) -> Option<String> {
37    for project_name in active_projects {
38        if let Some(sanitized_env_name) = project_name.strip_prefix(prefix) {
39            // The project name has dots replaced with hyphens, so we need to check
40            // all environments to find a match after applying the same sanitization
41            for env_name in config.environments().keys() {
42                if env_name.replace('.', "-") == sanitized_env_name {
43                    return Some(env_name.clone());
44                }
45            }
46        }
47    }
48    None
49}
50
51/// Find the active environment for a given integration by querying Docker Compose
52pub(super) fn find_active_environment_for_integration(
53    directory: &str,
54    integration: &str,
55    config: &ComposeTestConfig,
56) -> Result<Option<String>> {
57    let active_projects = load_active_projects()?;
58    let prefix = format!("vector-{directory}-{integration}-");
59    Ok(find_active_environment(&active_projects, &prefix, config))
60}