Skip to main content

flowey_lib_hvlite/
run_cargo_nextest_run.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Run cargo-nextest tests in the context of the HvLite repo.
5//!
6//! Uses the generic [`flowey_lib_common::run_cargo_nextest_run::Node`]
7//! under-the-hood.
8
9use flowey::node::prelude::*;
10use flowey_lib_common::run_cargo_nextest_run::NextestRunKind;
11use flowey_lib_common::run_cargo_nextest_run::TestResults;
12use std::collections::BTreeMap;
13
14/// Nextest profiles defined in HvLite's `.config/nextest.toml`
15#[derive(Serialize, Deserialize, Clone, Copy)]
16pub enum NextestProfile {
17    Default,
18    Ci,
19}
20
21impl NextestProfile {
22    pub fn as_str(&self) -> &'static str {
23        match self {
24            NextestProfile::Default => "default",
25            NextestProfile::Ci => "ci",
26        }
27    }
28}
29
30flowey_request! {
31    pub struct Request {
32        /// Friendly name for this test group that will be displayed in logs.
33        pub friendly_name: String,
34        /// What kind of test run this is (inline build vs. from nextest archive).
35        pub run_kind: NextestRunKind,
36        /// Nextest profile to use when running the source code
37        pub nextest_profile: NextestProfile,
38        /// Nextest test filter expression
39        pub nextest_filter_expr: Option<String>,
40        /// Nextest working directory (defaults to repo root)
41        pub nextest_working_dir: Option<ReadVar<PathBuf>>,
42        /// Nextest configuration file (defaults to config in repo)
43        pub nextest_config_file: Option<ReadVar<PathBuf>>,
44        /// Whether to run ignored test
45        pub run_ignored: bool,
46        /// Additional env vars set when executing the tests.
47        pub extra_env: Option<ReadVar<BTreeMap<String, String>>>,
48        /// Wait for specified side-effects to resolve before building / running any
49        /// tests. (e.g: to allow for some ambient packages / dependencies to
50        /// get installed).
51        pub pre_run_deps: Vec<ReadVar<SideEffect>>,
52        /// Results of running the tests
53        pub results: WriteVar<TestResults>,
54    }
55}
56
57new_flow_node!(struct Node);
58
59impl FlowNode for Node {
60    type Request = Request;
61
62    fn imports(ctx: &mut ImportCtx<'_>) {
63        ctx.import::<crate::git_checkout_openvmm_repo::Node>();
64        ctx.import::<flowey_lib_common::run_cargo_nextest_run::Node>();
65    }
66
67    fn emit(requests: Vec<Self::Request>, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
68        let base_env = [
69            // Used by the test_with_tracing macro in test runners
70            ("RUST_LOG", "trace"),
71        ]
72        .into_iter()
73        .map(|(a, b)| (a.to_owned(), b.to_owned()))
74        .collect::<BTreeMap<_, _>>();
75
76        for Request {
77            friendly_name,
78            run_kind,
79            nextest_profile,
80            nextest_filter_expr,
81            nextest_working_dir,
82            nextest_config_file,
83            run_ignored,
84            pre_run_deps,
85            results,
86            extra_env,
87        } in requests
88        {
89            let extra_env = if let Some(with_env) = extra_env {
90                let base_env = base_env.clone();
91                with_env.map(ctx, move |mut m| {
92                    for (key, value) in base_env {
93                        m.entry(key).or_insert(value);
94                    }
95                    m
96                })
97            } else {
98                ReadVar::from_static(base_env.clone())
99            };
100
101            let working_dir = nextest_working_dir
102                .unwrap_or_else(|| ctx.reqv(crate::git_checkout_openvmm_repo::req::GetRepoDir));
103
104            let config_file = nextest_config_file.unwrap_or_else(|| {
105                ctx.reqv(crate::git_checkout_openvmm_repo::req::GetRepoDir)
106                    .map(ctx, |p| p.join(".config").join("nextest.toml"))
107            });
108
109            ctx.req(flowey_lib_common::run_cargo_nextest_run::Request::Run(
110                flowey_lib_common::run_cargo_nextest_run::Run {
111                    friendly_name,
112                    run_kind,
113                    working_dir,
114                    config_file,
115                    tool_config_files: Vec::new(),
116                    nextest_profile: nextest_profile.as_str().to_owned(),
117                    extra_env: Some(extra_env),
118                    with_rlimit_unlimited_core_size: true,
119                    nextest_filter_expr,
120                    run_ignored,
121                    pre_run_deps,
122                    results,
123                },
124            ));
125        }
126
127        Ok(())
128    }
129}