vdev/commands/
test.rs

1use anyhow::Result;
2use clap::Args;
3use std::collections::BTreeMap;
4
5use crate::platform;
6use crate::testing::runner::get_agent_test_runner;
7
8/// Execute tests
9#[derive(Args, Debug)]
10#[command()]
11pub struct Cli {
12    /// Extra test command arguments
13    args: Option<Vec<String>>,
14
15    /// Whether to run tests in a container
16    #[arg(short = 'C', long)]
17    container: bool,
18
19    /// Reuse existing test runner image instead of rebuilding (useful in CI)
20    #[arg(long)]
21    reuse_image: bool,
22
23    /// Environment variables in the form KEY[=VALUE]
24    #[arg(short, long)]
25    env: Option<Vec<String>>,
26}
27
28fn parse_env(env: Vec<String>) -> BTreeMap<String, Option<String>> {
29    env.into_iter()
30        .map(|entry| {
31            #[allow(clippy::map_unwrap_or)] // Can't use map_or due to borrowing entry
32            entry
33                .split_once('=')
34                .map(|(k, v)| (k.to_owned(), Some(v.to_owned())))
35                .unwrap_or_else(|| (entry, None))
36        })
37        .collect()
38}
39
40impl Cli {
41    pub fn exec(self) -> Result<()> {
42        let runner = get_agent_test_runner(self.container)?;
43
44        let mut args = vec!["--workspace".to_string()];
45
46        if let Some(mut extra_args) = self.args {
47            args.append(&mut extra_args);
48        }
49
50        if !args.contains(&"--features".to_string()) {
51            let features = platform::default_features();
52            args.extend(["--features".to_string(), features.to_string()]);
53        }
54
55        runner.test(
56            &parse_env(self.env.unwrap_or_default()),
57            &BTreeMap::default(),
58            None,
59            &args,
60            self.reuse_image,
61            false, // Don't pre-build Vector for direct test runs
62        )
63    }
64}