vdev/commands/compose_tests/
show.rs1use anyhow::Result;
2use std::collections::HashSet;
3
4use crate::{testing::config::ComposeTestConfig, utils::environment::Environment};
5
6use super::active_projects::{find_active_environment, load_active_projects};
7
8pub fn exec(integration: Option<&String>, path: &str) -> Result<()> {
9 let show = Show::new(path)?;
10 match integration {
11 None => show.show_all(),
12 Some(integration) => show.show_one(integration),
13 }
14}
15
16pub fn exec_environments_only(integration: &str, path: &str) -> Result<()> {
18 let (_test_dir, config) = ComposeTestConfig::load(path, integration)?;
19 for environment in config.environments().keys() {
20 println!("{environment}");
21 }
22 Ok(())
23}
24
25struct Show {
26 path: String,
27 active_projects: HashSet<String>,
28}
29
30impl Show {
31 fn new(path: &str) -> Result<Self> {
32 Ok(Self {
33 path: path.to_string(),
34 active_projects: load_active_projects()?,
35 })
36 }
37
38 fn show_all(&self) -> Result<()> {
39 let entries = ComposeTestConfig::collect_all(&self.path)?;
40
41 let width = entries
42 .keys()
43 .fold(16, |width, entry| width.max(entry.len()));
44 println!("{:width$} Environment Name(s)", "Integration Name");
45 println!("{:width$} -------------------", "----------------");
46 for (integration, config) in entries {
47 let prefix = format!("vector-{}-{integration}-", self.path);
48 let active_env = find_active_environment(&self.active_projects, &prefix, &config);
49 let environments = config
50 .environments()
51 .keys()
52 .map(|environment| format_env(active_env.as_ref(), environment))
53 .collect::<Vec<_>>()
54 .join(" ");
55 println!("{integration:width$} {environments}");
56 }
57 Ok(())
58 }
59
60 fn show_one(&self, integration: &str) -> Result<()> {
61 let (_test_dir, config) = ComposeTestConfig::load(&self.path, integration)?;
62 let prefix = format!("vector-{}-{integration}-", self.path);
63 let active_env = find_active_environment(&self.active_projects, &prefix, &config);
64
65 if let Some(args) = &config.args {
66 println!("Test args: {}", args.join(" "));
67 } else {
68 println!("Test args: N/A");
69 }
70
71 if config.features.is_empty() {
72 println!("Features: N/A");
73 } else {
74 println!("Features: {}", config.features.join(","));
75 }
76
77 println!(
78 "Test filter: {}",
79 config.test_filter.as_deref().unwrap_or("N/A")
80 );
81
82 println!("Environment:");
83 print_env(" ", &config.env);
84 println!("Runner:");
85 println!(" Environment:");
86 print_env(" ", &config.runner.env);
87 println!(" Volumes:");
88 if config.runner.volumes.is_empty() {
89 println!(" N/A");
90 } else {
91 for (target, mount) in &config.runner.volumes {
92 println!(" {target} => {mount}");
93 }
94 }
95 println!(
96 " Needs docker socket: {}",
97 config.runner.needs_docker_socket
98 );
99
100 println!("Environments:");
101 for environment in config.environments().keys() {
102 println!(" {}", format_env(active_env.as_ref(), environment));
103 }
104
105 Ok(())
106 }
107}
108
109fn print_env(prefix: &str, environment: &Environment) {
110 if environment.is_empty() {
111 println!("{prefix} N/A");
112 } else {
113 for (key, value) in environment {
114 match value {
115 Some(value) => println!("{prefix}{key}={value:?}"),
116 None => println!("{prefix}{key} (passthrough)"),
117 }
118 }
119 }
120}
121
122fn format_env(active_env: Option<&String>, environment: &str) -> String {
123 match active_env {
124 Some(active) if active == environment => format!("{environment} (active)"),
125 _ => environment.into(),
126 }
127}