flowey_lib_hvlite/
build_nextest_unit_tests.rs1use crate::init_openvmm_magicpath_openhcl_sysroot::OpenvmmSysrootArch;
11use crate::run_cargo_build::common::CommonArch;
12use crate::run_cargo_build::common::CommonPlatform;
13use crate::run_cargo_build::common::CommonProfile;
14use crate::run_cargo_build::common::CommonTriple;
15use crate::run_cargo_nextest_run::NextestProfile;
16use flowey::node::prelude::*;
17use flowey_lib_common::run_cargo_build::CargoBuildProfile;
18use flowey_lib_common::run_cargo_build::CargoFeatureSet;
19use flowey_lib_common::run_cargo_nextest_run::TestResults;
20use flowey_lib_common::run_cargo_nextest_run::build_params::PanicAbortTests;
21use flowey_lib_common::run_cargo_nextest_run::build_params::TestPackages;
22
23#[derive(Serialize, Deserialize)]
25pub struct NextestUnitTestArchive {
26 #[serde(rename = "unit_tests.tar.zst")]
27 pub archive_file: PathBuf,
28}
29
30#[derive(Serialize, Deserialize)]
32pub enum BuildNextestUnitTestMode {
33 ImmediatelyRun {
36 nextest_profile: NextestProfile,
37 results: WriteVar<TestResults>,
38 },
39 Archive(WriteVar<NextestUnitTestArchive>),
42}
43
44flowey_request! {
45 pub struct Request {
46 pub target: target_lexicon::Triple,
48 pub profile: CommonProfile,
50 pub unstable_panic_abort_tests: Option<PanicAbortTests>,
52 pub build_mode: BuildNextestUnitTestMode,
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::build_xtask::Node>();
64 ctx.import::<crate::git_checkout_openvmm_repo::Node>();
65 ctx.import::<crate::init_openvmm_magicpath_openhcl_sysroot::Node>();
66 ctx.import::<crate::install_openvmm_rust_build_essential::Node>();
67 ctx.import::<crate::run_cargo_nextest_run::Node>();
68 ctx.import::<crate::init_cross_build::Node>();
69 ctx.import::<flowey_lib_common::run_cargo_nextest_archive::Node>();
70 }
71
72 fn emit(requests: Vec<Self::Request>, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
73 let flowey_platform = ctx.platform();
74 let flowey_arch = ctx.arch();
75
76 let xtask_target = CommonTriple::Common {
77 arch: match flowey_arch {
78 FlowArch::X86_64 => CommonArch::X86_64,
79 FlowArch::Aarch64 => CommonArch::Aarch64,
80 arch => anyhow::bail!("unsupported arch {arch}"),
81 },
82 platform: match flowey_platform {
83 FlowPlatform::Windows => CommonPlatform::WindowsMsvc,
84 FlowPlatform::Linux(_) => CommonPlatform::LinuxGnu,
85 FlowPlatform::MacOs => CommonPlatform::MacOs,
86 platform => anyhow::bail!("unsupported platform {platform}"),
87 },
88 };
89 let xtask = ctx.reqv(|v| crate::build_xtask::Request {
90 target: xtask_target,
91 xtask: v,
92 });
93
94 let openvmm_repo_path = ctx.reqv(crate::git_checkout_openvmm_repo::req::GetRepoDir);
95
96 let ambient_deps = vec![ctx.reqv(crate::install_openvmm_rust_build_essential::Request)];
99
100 let test_packages = ctx.emit_rust_stepv("determine unit test exclusions", |ctx| {
101 let xtask = xtask.claim(ctx);
102 let openvmm_repo_path = openvmm_repo_path.clone().claim(ctx);
103 move |rt| {
104 let xtask = rt.read(xtask);
105 let openvmm_repo_path = rt.read(openvmm_repo_path);
106
107 let mut exclude = [
108 "whp",
111 "kvm",
112 "openvmm",
113 "vmm_tests",
115 "guest_test_uefi",
117 "inspect_derive",
124 "mesh_derive",
125 "save_restore_derive",
126 "test_with_tracing_macro",
127 "pal_async_test",
128 "vmm_test_macros",
129 ]
130 .map(|x| x.to_string())
131 .to_vec();
132
133 {
136 let xtask_bin = match xtask {
137 crate::build_xtask::XtaskOutput::LinuxBin { bin, dbg: _ } => bin,
138 crate::build_xtask::XtaskOutput::WindowsBin { exe, pdb: _ } => exe,
139 };
140
141 let sh = xshell::Shell::new()?;
142 sh.change_dir(openvmm_repo_path);
143 let output = xshell::cmd!(sh, "{xtask_bin} fuzz list --crates").output()?;
144 let output = String::from_utf8(output.stdout)?;
145
146 let fuzz_crates = output.trim().split('\n').map(|s| s.to_owned());
147 exclude.extend(fuzz_crates);
148 }
149
150 Ok(TestPackages::Workspace { exclude })
151 }
152 });
153
154 for Request {
155 target,
156 profile,
157 unstable_panic_abort_tests,
158 build_mode,
159 } in requests
160 {
161 let mut pre_run_deps = ambient_deps.clone();
162
163 let sysroot_arch = match target.architecture {
164 target_lexicon::Architecture::X86_64 => OpenvmmSysrootArch::X64,
165 target_lexicon::Architecture::Aarch64(_) => OpenvmmSysrootArch::Aarch64,
166 arch => anyhow::bail!("unsupported arch {arch}"),
167 };
168
169 if matches!(target.environment, target_lexicon::Environment::Musl) {
173 pre_run_deps.push(
174 ctx.reqv(|v| crate::init_openvmm_magicpath_openhcl_sysroot::Request {
175 arch: sysroot_arch,
176 path: v,
177 })
178 .into_side_effect(),
179 );
180 }
181
182 let features = if matches!(
192 target.operating_system,
193 target_lexicon::OperatingSystem::Windows
194 ) {
195 CargoFeatureSet::Specific(vec!["ci".into()])
196 } else {
197 CargoFeatureSet::All
198 };
199
200 let injected_env = ctx.reqv(|v| crate::init_cross_build::Request {
201 target: target.clone(),
202 injected_env: v,
203 });
204
205 let build_params =
206 flowey_lib_common::run_cargo_nextest_run::build_params::NextestBuildParams {
207 packages: test_packages.clone(),
208 features,
209 no_default_features: false,
210 unstable_panic_abort_tests,
211 target: target.clone(),
212 profile: match profile {
213 CommonProfile::Release => CargoBuildProfile::Release,
214 CommonProfile::Debug => CargoBuildProfile::Debug,
215 },
216 extra_env: injected_env,
217 };
218
219 match build_mode {
220 BuildNextestUnitTestMode::ImmediatelyRun {
221 nextest_profile,
222 results,
223 } => ctx.req(crate::run_cargo_nextest_run::Request {
224 friendly_name: "unit-tests".into(),
225 run_kind: flowey_lib_common::run_cargo_nextest_run::NextestRunKind::BuildAndRun(
226 build_params,
227 ),
228 nextest_profile,
229 nextest_filter_expr: None,
230 nextest_working_dir: None,
231 nextest_config_file: None,
232 run_ignored: false,
233 extra_env: None,
234 pre_run_deps,
235 results,
236 }),
237 BuildNextestUnitTestMode::Archive(unit_tests_archive) => {
238 let archive_file =
239 ctx.reqv(|v| flowey_lib_common::run_cargo_nextest_archive::Request {
240 friendly_label: "unit-tests".into(),
241 working_dir: openvmm_repo_path.clone(),
242 build_params,
243 pre_run_deps,
244 archive_file: v,
245 });
246
247 ctx.emit_minor_rust_step("report built unit tests", |ctx| {
248 let archive_file = archive_file.claim(ctx);
249 let unit_tests = unit_tests_archive.claim(ctx);
250 |rt| {
251 let archive_file = rt.read(archive_file);
252 rt.write(unit_tests, &NextestUnitTestArchive { archive_file });
253 }
254 });
255 }
256 }
257 }
258
259 Ok(())
260 }
261}