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