1use crate::build_flowey_hvlite::FloweyHvliteOutput;
7use crate::build_guest_test_uefi::GuestTestUefiOutput;
8use crate::build_nextest_vmm_tests::NextestVmmTestsArchive;
9use crate::build_openhcl_igvm_from_recipe::OpenhclIgvmOutput;
10use crate::build_openvmm::OpenvmmOutput;
11use crate::build_openvmm_vhost::OpenvmmVhostOutput;
12use crate::build_pipette::PipetteOutput;
13use crate::build_prep_steps::PrepStepsOutput;
14use crate::build_snp_linux_direct_igvm::SnpLinuxDirectIgvmOutput;
15use crate::build_test_igvm_agent_rpc_server::TestIgvmAgentRpcServerOutput;
16use crate::build_tmk_vmm::TmkVmmOutput;
17use crate::build_tmks::TmksOutput;
18use crate::build_tpm_guest_tests::TpmGuestTestsOutput;
19use crate::build_vmfirmwareigvm_dll::VmfirmwareigvmDllOutput;
20use crate::build_vmgstool::VmgstoolOutput;
21use crate::common::CommonArch;
22use crate::download_release_igvm_files_from_gh::OpenhclReleaseVersion;
23use flowey::node::prelude::*;
24use petri_artifacts_common::artifacts::*;
25use petri_artifacts_core::ArtifactId;
26use petri_artifacts_core::ArtifactTarget;
27use petri_artifacts_vmm_test::artifacts::*;
28
29macro_rules! define_vmm_tests_built_artifacts {
30 (
31 $name:ident,
32 $($artifact:ident(
33 $($variant:ident(
34 ($output_let_expr:expr, $member:ident $(, $none_member:ident)*),
35 $artifact_ty:ty
36 )),* $(,)?
37 ) => $output:ty),* $(,)?
38 ) => {
39 ::paste::paste! {
40 #[derive(Serialize, Deserialize)]
41 pub struct $name<C = VarNotClaimed> {$($(
42 pub [<$artifact _ $variant>]: Option<::flowey::node::prelude::ReadVar<$output, C>>,
43 )*)*}
44
45 impl Default for $name<VarNotClaimed> {
46 fn default() -> Self {
47 Self {$($(
48 [<$artifact _ $variant>]: None,
49 )*)*}
50 }
51 }
52
53 impl $name<VarNotClaimed> {
54 pub fn claim(self, ctx: &mut StepCtx<'_>) -> $name<VarClaimed> {
55 let Self {$($(
56 [<$artifact _ $variant>],
57 )*)*} = self;
58 $name {$($(
59 [<$artifact _ $variant>]: [<$artifact _ $variant>].claim(ctx),
60 )*)*}
61 }
62
63 $(pub fn $artifact(&mut self, target: ArtifactTarget) -> ::anyhow::Result<&mut Option<::flowey::node::prelude::ReadVar<$output>>> {
64 match &target {
65 $($artifact_ty::TARGET => Ok(&mut self.[<$artifact _ $variant>]),)*
66 _ if let Some(target) = retry_as_musl(target.clone()) => {
67 return self.$artifact(target);
68 }
69 _ => Err(anyhow::anyhow!("{} {}", target, concat!("does not exist for ", stringify!($artifact)))),
70 }
71 })*
72
73 $($(pub fn [<$artifact _ $variant _target>]() -> ::target_lexicon::Triple {
74 $artifact_ty::TARGET.target_triple().expect("no target triple for artifact")
75 })*)*
76 }
77
78 impl $name<VarClaimed> {
79 pub fn write(self, rt: &mut RustRuntimeServices<'_>, test_content_dir: impl AsRef<Path>) -> ::anyhow::Result<()> {
80 let Self {$($(
81 [<$artifact _ $variant>],
82 )*)*} = self;
83
84
85 $($(if let Some(artifact) = [<$artifact _ $variant>] {
86 let dst = test_content_dir
87 .as_ref()
88 .join($artifact_ty::relative_path());
89
90 #[expect(clippy::allow_attributes)]
91 #[allow(irrefutable_let_patterns, unused_variables)]
92 let $output_let_expr = rt.read(artifact) else {
93 ::anyhow::bail!(concat!(
94 "unexpected variant of ",
95 stringify!($output),
96 " for ",
97 stringify!([<$artifact _ $variant>])
98 ));
99 };
100
101 fs_err::create_dir_all(dst.parent().unwrap())?;
102 fs_err::copy($member, &dst)?;
103 dst.make_executable()?;
104 })*)*
105
106 Ok(())
107 }
108 }
109
110 #[derive(Serialize, Deserialize)]
111 pub struct [<$name Write>]<C = VarNotClaimed> {$($(
112 pub [<$artifact _ $variant>]: Option<::flowey::node::prelude::WriteVar<$output, C>>,
113 )*)*}
114
115 impl Default for [<$name Write>]<VarNotClaimed> {
116 fn default() -> Self {
117 Self {$($(
118 [<$artifact _ $variant>]: None,
119 )*)*}
120 }
121 }
122
123 impl [<$name Write>]<VarNotClaimed> {
124 pub fn claim(self, ctx: &mut StepCtx<'_>) -> [<$name Write>]<VarClaimed> {
125 let Self {$($(
126 [<$artifact _ $variant>],
127 )*)*} = self;
128 [<$name Write>] {$($(
129 [<$artifact _ $variant>]: [<$artifact _ $variant>].claim(ctx),
130 )*)*}
131 }
132 }
133
134 impl [<$name Write>]<VarClaimed> {
135 pub fn resolve(self, rt: &mut RustRuntimeServices<'_>, test_content_dir: impl AsRef<Path>) -> ::anyhow::Result<()> {
136 let Self {$($(
137 [<$artifact _ $variant>],
138 )*)*} = self;
139
140
141 $($(if let Some(artifact) = [<$artifact _ $variant>] {
142 let $member = test_content_dir
143 .as_ref()
144 .join($artifact_ty::relative_path());
145
146 if $member.exists() {
147 $(let $none_member = None;)*
148 rt.write(
149 artifact,
150 &$output_let_expr,
151 )
152 } else {
153 anyhow::bail!("{} not found", $member.display());
154 }
155 })*)*
156
157 Ok(())
158 }
159 }
160
161 #[derive(Serialize, Deserialize, Default, Debug, Clone)]
162 pub struct [<$name Selections>] {$($(
163 pub [<$artifact _ $variant>]: bool,
164 )*)*}
165
166 impl [<$name Selections>] {
167 pub fn resolve_artifact(&mut self, id: &str) -> bool {
168 match id {
169 $($($artifact_ty::GLOBAL_UNIQUE_ID => {
170 self.[<$artifact _ $variant>] = true;
171 true
172 })*)*
173 _ => false
174 }
175 }
176
177 $(pub fn [<$artifact _for>](&self, target: ArtifactTarget) -> ::anyhow::Result<bool>{
178 match &target {
179 $($artifact_ty::TARGET => {
180 Ok(self.[<$artifact _ $variant>])
181 })*
182 _ => Err(anyhow::anyhow!("{} {}", target, concat!("does not exist for ", stringify!($artifact)))),
183 }
184 }
185
186 pub fn [<require_ $artifact _for>](&mut self, target: ArtifactTarget) -> ::anyhow::Result<PathBuf>{
187 match &target {
188 $($artifact_ty::TARGET => {
189 self.[<$artifact _ $variant>] = true;
190 Ok($artifact_ty::relative_path())
191 })*
192 _ if let Some(target) = retry_as_musl(target.clone()) => {
193 self.[<require_ $artifact _for>](target)
194 }
195 _ => Err(anyhow::anyhow!("{} {}", target, concat!("does not exist for ", stringify!($artifact)))),
196 }
197 })*
198
199 pub fn new_var_set(&self, ctx: &mut ::flowey::node::prelude::NodeCtx<'_>) -> (
200 $name,
201 [<$name Write>],
202 ) {
203 let mut built_artifacts_read = $name::default();
204 let mut built_artifacts_write = [<$name Write>]::default();
205
206 $($(if self.[<$artifact _ $variant>] {
207 let (read_var, write_var) = ctx.new_var();
208 built_artifacts_read.[<$artifact _ $variant>] = Some(read_var);
209 built_artifacts_write.[<$artifact _ $variant>] = Some(write_var);
210 })*)*
211
212 (built_artifacts_read, built_artifacts_write)
213 }
214
215 pub fn handles(&self) -> Vec<::petri_artifacts_core::ErasedArtifactHandle> {
216 let mut handles = Vec::new();
217
218 $($(if self.[<$artifact _ $variant>] {
219 handles.push($artifact_ty.erase())
220 })*)*
221
222 handles
223 }
224 }
225
226 }
227 };
228}
229
230fn retry_as_musl(target: ArtifactTarget) -> Option<ArtifactTarget> {
234 let ArtifactTarget::Triple(mut triple) = target else {
235 return None;
236 };
237
238 if matches!(
239 triple.operating_system,
240 target_lexicon::OperatingSystem::Linux
241 ) && !matches!(triple.environment, target_lexicon::Environment::Musl)
242 {
243 triple.environment = target_lexicon::Environment::Musl;
244 Some(ArtifactTarget::Triple(triple))
245 } else {
246 None
247 }
248}
249
250define_vmm_tests_built_artifacts!(
251 VmmTestsBuiltArtifacts,
252 flowey_hvlite(
254 windows_x64(
255 (FloweyHvliteOutput::WindowsBin { exe, pdb }, exe, pdb),
256 host_tools::FLOWEY_HVLITE_WINDOWS_X64
257 ),
258 windows_aarch64(
259 (FloweyHvliteOutput::WindowsBin { exe, pdb }, exe, pdb),
260 host_tools::FLOWEY_HVLITE_WINDOWS_AARCH64
261 ),
262 linux_x64(
263 (FloweyHvliteOutput::LinuxBin { bin, dbg }, bin, dbg),
264 host_tools::FLOWEY_HVLITE_LINUX_X64
265 ),
266 linux_musl_x64(
267 (FloweyHvliteOutput::LinuxBin { bin, dbg }, bin, dbg),
268 host_tools::FLOWEY_HVLITE_LINUX_X64_MUSL
269 ),
270 ) => FloweyHvliteOutput,
271 nextest_vmm_tests_archive(
272 windows_x64(
273 (NextestVmmTestsArchive { archive_file }, archive_file),
274 host_tools::NEXTEST_VMM_TESTS_ARCHIVE_WINDOWS_X64
275 ),
276 windows_aarch64(
277 (NextestVmmTestsArchive { archive_file }, archive_file),
278 host_tools::NEXTEST_VMM_TESTS_ARCHIVE_WINDOWS_AARCH64
279 ),
280 linux_x64(
281 (NextestVmmTestsArchive { archive_file }, archive_file),
282 host_tools::NEXTEST_VMM_TESTS_ARCHIVE_LINUX_X64
283 ),
284 linux_musl_x64(
285 (NextestVmmTestsArchive { archive_file }, archive_file),
286 host_tools::NEXTEST_VMM_TESTS_ARCHIVE_LINUX_X64_MUSL
287 ),
288 linux_musl_aarch64(
289 (NextestVmmTestsArchive { archive_file }, archive_file),
290 host_tools::NEXTEST_VMM_TESTS_ARCHIVE_LINUX_AARCH64_MUSL
291 ),
292 ) => NextestVmmTestsArchive,
293 prep_steps(
294 windows_x64(
295 (PrepStepsOutput::WindowsBin { exe, pdb }, exe, pdb),
296 host_tools::PREP_STEPS_WINDOWS_X64
297 ),
298 linux_musl_x64(
299 (PrepStepsOutput::LinuxBin { bin, dbg}, bin, dbg),
300 host_tools::PREP_STEPS_LINUX_X64_MUSL
301 ),
302 ) => PrepStepsOutput,
303 test_igvm_agent_rpc_server(
304 windows_x64(
305 (TestIgvmAgentRpcServerOutput { exe, pdb }, exe, pdb),
306 host_tools::TEST_IGVM_AGENT_RPC_SERVER_WINDOWS_X64
307 ),
308 ) => TestIgvmAgentRpcServerOutput,
309
310 openvmm(
312 windows_x64(
313 (OpenvmmOutput::WindowsBin { exe, pdb }, exe, pdb),
314 OPENVMM_WINDOWS_X64
315 ),
316 windows_aarch64(
317 (OpenvmmOutput::WindowsBin { exe, pdb }, exe, pdb),
318 OPENVMM_WINDOWS_AARCH64
319 ),
320 linux_x64(
321 (OpenvmmOutput::LinuxBin { bin, dbg}, bin, dbg),
322 OPENVMM_LINUX_X64
323 ),
324 linux_aarch64(
325 (OpenvmmOutput::LinuxBin { bin, dbg}, bin, dbg),
326 OPENVMM_LINUX_AARCH64
327 ),
328 linux_musl_x64(
329 (OpenvmmOutput::LinuxBin { bin, dbg}, bin, dbg),
330 OPENVMM_LINUX_X64_MUSL
331 ),
332 linux_musl_aarch64(
333 (OpenvmmOutput::LinuxBin { bin, dbg}, bin, dbg),
334 OPENVMM_LINUX_AARCH64_MUSL
335 ),
336 ) => OpenvmmOutput,
337 openvmm_vhost(
338 linux_x64(
339 (OpenvmmVhostOutput { bin, dbg}, bin, dbg),
340 OPENVMM_VHOST_LINUX_X64
341 ),
342 linux_aarch64(
343 (OpenvmmVhostOutput { bin, dbg}, bin, dbg),
344 OPENVMM_VHOST_LINUX_AARCH64
345 ),
346 linux_musl_x64(
347 (OpenvmmVhostOutput { bin, dbg}, bin, dbg),
348 OPENVMM_VHOST_LINUX_X64_MUSL
349 ),
350 linux_musl_aarch64(
351 (OpenvmmVhostOutput { bin, dbg}, bin, dbg),
352 OPENVMM_VHOST_LINUX_AARCH64_MUSL
353 ),
354 ) => OpenvmmVhostOutput,
355 pipette(
356 windows_x64(
357 (PipetteOutput::WindowsBin { exe, pdb }, exe, pdb),
358 PIPETTE_WINDOWS_X64
359 ),
360 windows_aarch64(
361 (PipetteOutput::WindowsBin { exe, pdb }, exe, pdb),
362 PIPETTE_WINDOWS_AARCH64
363 ),
364 linux_musl_x64(
365 (PipetteOutput::LinuxBin { bin, dbg}, bin, dbg),
366 PIPETTE_LINUX_X64_MUSL
367 ),
368 linux_musl_aarch64(
369 (PipetteOutput::LinuxBin { bin, dbg}, bin, dbg),
370 PIPETTE_LINUX_AARCH64_MUSL
371 ),
372 ) => PipetteOutput,
373 guest_test_uefi(
374 x64(
375 (GuestTestUefiOutput { img, efi, pdb }, img, efi, pdb),
376 test_vhd::GUEST_TEST_UEFI_X64
377 ),
378 aarch64(
379 (GuestTestUefiOutput { img, efi, pdb }, img, efi, pdb),
380 test_vhd::GUEST_TEST_UEFI_AARCH64
381 ),
382 ) => GuestTestUefiOutput,
383 openhcl_standard(
384 x64(
385 (OpenhclIgvmOutput::X64 { igvm_bin }, igvm_bin),
386 openhcl_igvm::LATEST_STANDARD_X64
387 ),
388 aarch64(
389 (OpenhclIgvmOutput::Aarch64 { igvm_bin }, igvm_bin),
390 openhcl_igvm::LATEST_STANDARD_AARCH64
391 ),
392 ) => OpenhclIgvmOutput,
393 openhcl_standard_dev(
394 x64(
395 (OpenhclIgvmOutput::X64Devkern { igvm_bin }, igvm_bin),
396 openhcl_igvm::LATEST_STANDARD_DEV_KERNEL_X64
397 ),
398 aarch64(
399 (OpenhclIgvmOutput::Aarch64Devkern { igvm_bin }, igvm_bin),
400 openhcl_igvm::LATEST_STANDARD_DEV_KERNEL_AARCH64
401 ),
402 ) => OpenhclIgvmOutput,
403 openhcl_cvm(
404 x64(
405 (OpenhclIgvmOutput::X64Cvm { igvm_bin, endorsements }, igvm_bin, endorsements),
406 openhcl_igvm::LATEST_CVM_X64
407 ),
408 ) => OpenhclIgvmOutput,
409 vmfirmwareigvm_cvm(
410 x64(
411 (VmfirmwareigvmDllOutput { dll }, dll),
412 vmfw_dll::LATEST_CVM_X64
413 ),
414 ) => VmfirmwareigvmDllOutput,
415 openhcl_linux_direct(
416 x64(
417 (OpenhclIgvmOutput::X64TestLinuxDirect { igvm_bin }, igvm_bin),
418 openhcl_igvm::LATEST_LINUX_DIRECT_TEST_X64
419 ),
420 ) => OpenhclIgvmOutput,
421 openhcl_sivm(
422 x64(
423 (OpenhclIgvmOutput::X64TestSivm { igvm_bin }, igvm_bin),
424 openhcl_igvm::LATEST_SIVM_TEST_X64
425 ),
426 ) => OpenhclIgvmOutput,
427 snp_linux_direct_igvm(
428 x64(
429 (SnpLinuxDirectIgvmOutput { igvm_bin, igvm_map }, igvm_bin, igvm_map),
430 snp_igvm::SNP_LINUX_DIRECT_IGVM_X64
431 ),
432 ) => SnpLinuxDirectIgvmOutput,
433 tmks(
434 x64(
435 (TmksOutput { bin, dbg}, bin, dbg),
436 tmks::SIMPLE_TMK_X64
437 ),
438 aarch64(
439 (TmksOutput { bin, dbg}, bin, dbg),
440 tmks::SIMPLE_TMK_AARCH64
441 ),
442 ) => TmksOutput,
443 tmk_vmm(
444 windows_x64(
445 (TmkVmmOutput::WindowsBin { exe, pdb }, exe, pdb),
446 tmks::TMK_VMM_WINDOWS_X64
447 ),
448 windows_aarch64(
449 (TmkVmmOutput::WindowsBin { exe, pdb }, exe, pdb),
450 tmks::TMK_VMM_WINDOWS_AARCH64
451 ),
452 linux_musl_x64(
453 (TmkVmmOutput::LinuxBin { bin, dbg}, bin, dbg),
454 tmks::TMK_VMM_LINUX_X64_MUSL
455 ),
456 linux_musl_aarch64(
457 (TmkVmmOutput::LinuxBin { bin, dbg}, bin, dbg),
458 tmks::TMK_VMM_LINUX_AARCH64_MUSL
459 ),
460 ) => TmkVmmOutput,
461 vmgstool(
462 windows_x64(
463 (VmgstoolOutput::WindowsBin { exe, pdb }, exe, pdb),
464 vmgstool::VMGSTOOL_WINDOWS_X64
465 ),
466 windows_aarch64(
467 (VmgstoolOutput::WindowsBin { exe, pdb }, exe, pdb),
468 vmgstool::VMGSTOOL_WINDOWS_AARCH64
469 ),
470 linux_x64(
471 (VmgstoolOutput::LinuxBin { bin, dbg}, bin, dbg),
472 vmgstool::VMGSTOOL_LINUX_X64
473 ),
474 ) => VmgstoolOutput,
475 vmgstool_dev(
476 windows_x64(
477 (VmgstoolOutput::WindowsBin { exe, pdb }, exe, pdb),
478 vmgstool::VMGSTOOL_DEV_WINDOWS_X64
479 ),
480 windows_aarch64(
481 (VmgstoolOutput::WindowsBin { exe, pdb }, exe, pdb),
482 vmgstool::VMGSTOOL_DEV_WINDOWS_AARCH64
483 ),
484 linux_x64(
485 (VmgstoolOutput::LinuxBin { bin, dbg}, bin, dbg),
486 vmgstool::VMGSTOOL_DEV_LINUX_X64
487 ),
488 ) => VmgstoolOutput,
489 tpm_guest_tests(
490 windows_x64(
491 (TpmGuestTestsOutput::WindowsBin { exe, pdb }, exe, pdb),
492 guest_tools::TPM_GUEST_TESTS_WINDOWS_X64
493 ),
494 linux_x64(
495 (TpmGuestTestsOutput::LinuxBin { bin, dbg}, bin, dbg),
496 guest_tools::TPM_GUEST_TESTS_LINUX_X64
497 ),
498 ) => TpmGuestTestsOutput,
499);
500
501pub type ResolveVmmTestsBuiltArtifacts =
502 Box<dyn Fn(&mut flowey::pipeline::prelude::PipelineJobCtx<'_>) -> VmmTestsBuiltArtifacts>;
503
504#[macro_export]
505macro_rules! vmm_tests_built_artifacts_builder {
506 (
507 $name:ty,
508 (
509 $($artifact:ident => $output:ty),* $(,)?
510 )
511 ) => {
512 ::paste::paste! {
513 #[derive(Default, Clone)]
514 pub struct $name {
515 $(pub [<use_ $artifact>]: Option<::flowey::pipeline::prelude::UseTypedArtifact<$output>>,)*
516 }
517
518 impl $name {
519 pub fn finish(self) -> Result<$crate::init_vmm_tests_content_dir::ResolveVmmTestsBuiltArtifacts, &'static str> {
520 let $name {
521 $([<use_ $artifact>],)*
522 } = self;
523
524 $(let [<use_ $artifact>] = [<use_ $artifact>].ok_or(stringify!($artifact))?;)*
525
526 Ok(Box::new(move |ctx| $crate::init_vmm_tests_content_dir::VmmTestsBuiltArtifacts {
527 $($artifact: Some(ctx.use_typed_artifact(&[<use_ $artifact>])),)*
528 .. Default::default()
529 }))
530 }
531
532 pub fn selections() -> $crate::init_vmm_tests_content_dir::VmmTestsBuiltArtifactsSelections {
533 let mut selections = $crate::init_vmm_tests_content_dir::VmmTestsBuiltArtifactsSelections::default();
534 $(selections.$artifact = true;)*
535 selections
536 }
537 }
538 }
539 };
540}
541
542define_vmm_tests_built_artifacts!(
543 VmmTestsPreBuiltArtifacts,
544 test_linux_kernel(
545 x64(
546 (src, src),
547 loadable::LINUX_DIRECT_TEST_KERNEL_X64
548 ),
549 aarch64(
550 (src, src),
551 loadable::LINUX_DIRECT_TEST_KERNEL_AARCH64
552 ),
553 ) => PathBuf,
554 test_linux_kernel_cca(
555 aarch64(
556 (src, src),
557 loadable::LINUX_DIRECT_TEST_KERNEL_CCA_AARCH64
558 ),
559 ) => PathBuf,
560 test_linux_initrd(
561 x64(
562 (src, src),
563 loadable::LINUX_DIRECT_TEST_INITRD_X64
564 ),
565 aarch64(
566 (src, src),
567 loadable::LINUX_DIRECT_TEST_INITRD_AARCH64
568 ),
569 ) => PathBuf,
570 test_linux_bzimage(
571 x64(
572 (src, src),
573 loadable::LINUX_DIRECT_TEST_BZIMAGE_X64
574 ),
575 ) => PathBuf,
576 uefi(
577 x64(
578 (src, src),
579 loadable::UEFI_FIRMWARE_X64
580 ),
581 aarch64(
582 (src, src),
583 loadable::UEFI_FIRMWARE_AARCH64
584 ),
585 ) => PathBuf,
586 qemu_system_aarch64(
587 linux_x64(
588 (src, src),
589 QEMU_SYSTEM_AARCH64_LINUX_X64
590 ),
591 ) => PathBuf,
592);
593
594flowey_request! {
595 pub struct Request {
596 pub test_content_dir: ReadVar<PathBuf>,
599 pub vmm_tests_target: target_lexicon::Triple,
604 pub built_artifacts: VmmTestsBuiltArtifacts,
606 pub prebuilt_artifacts: VmmTestsPreBuiltArtifactsSelections,
608 pub uefi_firmware_flavor: Option<crate::download_uefi_mu_msvm::FirmwareFlavor>,
610 pub is_repo_root: bool,
614
615 pub needs_virtio_win_drivers: bool,
618 pub needs_release_igvm: bool,
619
620 pub done: WriteVar<SideEffect>
621 }
622}
623
624new_simple_flow_node!(struct Node);
625
626impl SimpleFlowNode for Node {
627 type Request = Request;
628
629 fn imports(ctx: &mut ImportCtx<'_>) {
630 ctx.import::<crate::resolve_openvmm_test_initrd::Node>();
631 ctx.import::<crate::resolve_openvmm_test_linux_kernel::Node>();
632 ctx.import::<crate::resolve_openvmm_test_virtio_win::Node>();
633 ctx.import::<crate::git_checkout_openvmm_repo::Node>();
634 ctx.import::<crate::download_uefi_mu_msvm::Node>();
635 ctx.import::<crate::download_release_igvm_files_from_gh::resolve::Node>();
636 ctx.import::<crate::resolve_openvmm_qemu::Node>();
637 }
638
639 fn process_request(request: Self::Request, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
640 let Request {
641 test_content_dir,
642 vmm_tests_target,
643 built_artifacts,
644 prebuilt_artifacts,
645 uefi_firmware_flavor,
646 is_repo_root,
647 needs_virtio_win_drivers,
648 needs_release_igvm,
649 done,
650 } = request;
651
652 let openvmm_repo_path =
653 is_repo_root.then(|| ctx.reqv(crate::git_checkout_openvmm_repo::req::GetRepoDir));
654
655 let arch = CommonArch::from_architecture(vmm_tests_target.architecture)?;
656
657 let test_linux_initrd_x64 = prebuilt_artifacts.test_linux_initrd_x64.then(|| {
658 ctx.reqv(|v| crate::resolve_openvmm_test_initrd::Request::Get(CommonArch::X86_64, v))
659 });
660 let test_linux_initrd_aarch64 = prebuilt_artifacts.test_linux_initrd_aarch64.then(|| {
661 ctx.reqv(|v| crate::resolve_openvmm_test_initrd::Request::Get(CommonArch::Aarch64, v))
662 });
663 let test_linux_kernel_x64 = prebuilt_artifacts.test_linux_kernel_x64.then(|| {
664 ctx.reqv(|v| {
665 crate::resolve_openvmm_test_linux_kernel::Request::Get(
666 crate::resolve_openvmm_test_linux_kernel::OpenvmmTestKernelFile::Kernel,
667 CommonArch::X86_64,
668 crate::resolve_openvmm_test_linux_kernel::DEFAULT_LINUX_TEST_KERNEL_VERSION,
669 v,
670 )
671 })
672 });
673 let test_linux_kernel_aarch64 = prebuilt_artifacts.test_linux_kernel_aarch64.then(|| {
674 ctx.reqv(|v| {
675 crate::resolve_openvmm_test_linux_kernel::Request::Get(
676 crate::resolve_openvmm_test_linux_kernel::OpenvmmTestKernelFile::Kernel,
677 CommonArch::Aarch64,
678 crate::resolve_openvmm_test_linux_kernel::DEFAULT_LINUX_TEST_KERNEL_VERSION,
679 v,
680 )
681 })
682 });
683 let test_linux_kernel_cca_aarch64 =
684 prebuilt_artifacts.test_linux_kernel_cca_aarch64.then(|| {
685 ctx.reqv(|v| {
686 crate::resolve_openvmm_test_linux_kernel::Request::Get(
687 crate::resolve_openvmm_test_linux_kernel::OpenvmmTestKernelFile::Kernel,
688 CommonArch::Aarch64,
689 crate::resolve_openvmm_test_linux_kernel::CCA_LINUX_TEST_KERNEL_VERSION,
690 v,
691 )
692 })
693 });
694 let test_linux_bzimage_x64 = prebuilt_artifacts.test_linux_bzimage_x64.then(|| {
695 ctx.reqv(|v| {
696 crate::resolve_openvmm_test_linux_kernel::Request::Get(
697 crate::resolve_openvmm_test_linux_kernel::OpenvmmTestKernelFile::BzImage,
698 CommonArch::X86_64,
699 crate::resolve_openvmm_test_linux_kernel::DEFAULT_LINUX_TEST_KERNEL_VERSION,
700 v,
701 )
702 })
703 });
704
705 let uefi_x64 = prebuilt_artifacts.uefi_x64.then(|| {
706 ctx.reqv(|msvm_fd| crate::download_uefi_mu_msvm::Request::GetMsvmFd {
707 arch: CommonArch::X86_64,
708 flavor: uefi_firmware_flavor,
709 msvm_fd,
710 })
711 });
712 let uefi_aarch64 = prebuilt_artifacts.uefi_aarch64.then(|| {
713 ctx.reqv(|msvm_fd| crate::download_uefi_mu_msvm::Request::GetMsvmFd {
714 arch: CommonArch::Aarch64,
715 flavor: uefi_firmware_flavor,
716 msvm_fd,
717 })
718 });
719
720 let qemu_system_aarch64_linux_x64 =
721 prebuilt_artifacts.qemu_system_aarch64_linux_x64.then(|| {
722 ctx.reqv(|v| {
723 crate::resolve_openvmm_qemu::Request::Get(
724 crate::resolve_openvmm_qemu::QemuFile::SystemAarch64,
725 CommonArch::X86_64,
726 v,
727 )
728 })
729 });
730
731 let prebuilt_artifacts = VmmTestsPreBuiltArtifacts {
732 test_linux_kernel_x64,
733 test_linux_kernel_aarch64,
734 test_linux_kernel_cca_aarch64,
735 test_linux_initrd_x64,
736 test_linux_initrd_aarch64,
737 test_linux_bzimage_x64,
738 uefi_x64,
739 uefi_aarch64,
740 qemu_system_aarch64_linux_x64,
741 };
742
743 let virtio_win_dir = needs_virtio_win_drivers
744 .then(|| ctx.reqv(crate::resolve_openvmm_test_virtio_win::Request::Get));
745
746 let release_igvm_files = needs_release_igvm.then(|| {
747 ctx.reqv(
748 |v| crate::download_release_igvm_files_from_gh::resolve::Request {
749 arch,
750 release_igvm_files: v,
751 release_version: OpenhclReleaseVersion::latest(),
752 },
753 )
754 });
755
756 ctx.emit_rust_step("setting up vmm_tests content dir", |ctx| {
757 claim_vars!(
758 ctx,
759 (
760 test_content_dir,
761 openvmm_repo_path,
762 built_artifacts,
764 prebuilt_artifacts,
766 virtio_win_dir,
767 release_igvm_files,
768 )
769 );
770
771 done.claim(ctx);
772
773 move |rt| {
774 read_vars!(rt, (release_igvm_files, test_content_dir));
775
776 if !test_content_dir.exists() {
777 fs_err::create_dir_all(&test_content_dir)?
778 };
779
780 if let Some(openvmm_repo_path) = openvmm_repo_path {
781 let openvmm_repo_path = rt.read(openvmm_repo_path);
782
783 let nextest_config_file = PathBuf::new().join(".config").join("nextest.toml");
784 fs_err::create_dir_all(
785 test_content_dir
786 .join(&nextest_config_file)
787 .parent()
788 .context("no parent")?,
789 )?;
790 fs_err::copy(
791 openvmm_repo_path.join(&nextest_config_file),
792 test_content_dir.join(&nextest_config_file),
793 )?;
794
795 let repo_cargo_toml_file = Path::new("Cargo.toml");
796 fs_err::copy(
797 openvmm_repo_path.join(repo_cargo_toml_file),
798 test_content_dir.join(repo_cargo_toml_file),
799 )?;
800
801 let crate_cargo_toml_file = PathBuf::new()
802 .join("vmm_tests")
803 .join("vmm_tests")
804 .join("Cargo.toml");
805 fs_err::create_dir_all(
806 test_content_dir
807 .join(&crate_cargo_toml_file)
808 .parent()
809 .context("no parent")?,
810 )?;
811 fs_err::copy(
812 openvmm_repo_path.join(&crate_cargo_toml_file),
813 test_content_dir.join(&crate_cargo_toml_file),
814 )?;
815 }
816
817 built_artifacts.write(rt, &test_content_dir)?;
818
819 prebuilt_artifacts.write(rt, &test_content_dir)?;
820
821 if let Some(release_igvm_files) = release_igvm_files {
822 if let Some(src) = &release_igvm_files.openhcl {
823 fs_err::copy(
824 src,
825 test_content_dir
826 .join(openhcl_igvm::LATEST_RELEASE_STANDARD_X64::relative_path()),
827 )?;
828 }
829
830 if let Some(src) = &release_igvm_files.openhcl_aarch64 {
831 fs_err::copy(
832 src,
833 test_content_dir.join(
834 openhcl_igvm::LATEST_RELEASE_STANDARD_AARCH64::relative_path(),
835 ),
836 )?;
837 }
838
839 if let Some(src) = &release_igvm_files.openhcl_direct {
840 fs_err::copy(
841 src,
842 test_content_dir.join(
843 openhcl_igvm::LATEST_RELEASE_LINUX_DIRECT_X64::relative_path(),
844 ),
845 )?;
846 }
847 }
848
849 if let Some(virtio_win_dir) = virtio_win_dir {
850 let src = rt.read(virtio_win_dir);
851 let dst =
852 test_content_dir.join(virtio_win::VIRTIO_WINDOWS_DRIVERS::relative_path());
853 let _ = fs_err::remove_dir_all(&dst);
854 flowey_lib_common::_util::copy_dir_all(&src, &dst)?;
855 }
856
857 log::info!("final folder content: {}", test_content_dir.display());
859 fn list_dir(dir: PathBuf, layer: usize) -> anyhow::Result<()> {
860 if layer > 2
861 || dir
862 .file_name()
863 .and_then(|n| n.to_str())
864 .is_some_and(|n| ["temp", "test_results"].contains(&n))
865 {
866 log::info!("{}- ...", " ".repeat(layer * 2));
867 return Ok(());
868 }
869 for entry in dir.read_dir()? {
870 let entry = entry?;
871 log::info!("{}- {}", " ".repeat(layer * 2), entry.file_name().display());
872 let subdir = entry.path();
873 if subdir.is_dir() {
874 list_dir(subdir, layer + 1)?;
875 }
876 }
877 Ok(())
878 }
879 list_dir(test_content_dir, 0)?;
880
881 Ok(())
882 }
883 });
884
885 Ok(())
886 }
887}
888
889pub mod vmm_tests_artifact_builders {
894 use super::*;
895
896 vmm_tests_built_artifacts_builder!(
897 VmmTestsArtifactsBuilderLinuxX86,
898 (
899 pipette_windows_x64 => PipetteOutput,
901 nextest_vmm_tests_archive_linux_x64 => NextestVmmTestsArchive,
903 nextest_vmm_tests_archive_linux_musl_x64 => NextestVmmTestsArchive,
904 openvmm_linux_x64 => OpenvmmOutput,
905 openvmm_linux_musl_x64 => OpenvmmOutput,
906 openvmm_vhost_linux_x64 => OpenvmmVhostOutput,
907 pipette_linux_musl_x64 => PipetteOutput,
908 prep_steps_linux_musl_x64 => PrepStepsOutput,
909 snp_linux_direct_igvm_x64 => SnpLinuxDirectIgvmOutput,
910 tmk_vmm_linux_musl_x64 => TmkVmmOutput,
911 guest_test_uefi_x64 => GuestTestUefiOutput,
913 tmks_x64 => TmksOutput,
914 nextest_vmm_tests_archive_linux_musl_aarch64 => NextestVmmTestsArchive,
916 openvmm_linux_musl_aarch64 => OpenvmmOutput,
917 pipette_linux_musl_aarch64 => PipetteOutput,
918 )
919 );
920
921 vmm_tests_built_artifacts_builder!(
922 VmmTestsArtifactsBuilderLinuxMuslX86,
923 (
924 pipette_windows_x64 => PipetteOutput,
926 nextest_vmm_tests_archive_linux_musl_x64 => NextestVmmTestsArchive,
928 openvmm_linux_musl_x64 => OpenvmmOutput,
929 openvmm_vhost_linux_musl_x64 => OpenvmmVhostOutput,
930 pipette_linux_musl_x64 => PipetteOutput,
931 prep_steps_linux_musl_x64 => PrepStepsOutput,
932 snp_linux_direct_igvm_x64 => SnpLinuxDirectIgvmOutput,
933 tmk_vmm_linux_musl_x64 => TmkVmmOutput,
934 guest_test_uefi_x64 => GuestTestUefiOutput,
936 tmks_x64 => TmksOutput,
937 )
938 );
939
940 vmm_tests_built_artifacts_builder!(
941 VmmTestsArtifactsBuilderWindowsX86,
942 (
943 nextest_vmm_tests_archive_windows_x64 => NextestVmmTestsArchive,
945 openvmm_windows_x64 => OpenvmmOutput,
946 pipette_windows_x64 => PipetteOutput,
947 tmk_vmm_windows_x64 => TmkVmmOutput,
948 prep_steps_windows_x64 => PrepStepsOutput,
949 vmgstool_windows_x64 => VmgstoolOutput,
950 vmgstool_dev_windows_x64 => VmgstoolOutput,
951 tpm_guest_tests_windows_x64 => TpmGuestTestsOutput,
952 test_igvm_agent_rpc_server_windows_x64 => TestIgvmAgentRpcServerOutput,
953 vmfirmwareigvm_cvm_x64 => VmfirmwareigvmDllOutput,
954 openhcl_standard_x64 => OpenhclIgvmOutput,
956 openhcl_cvm_x64 => OpenhclIgvmOutput,
957 openhcl_linux_direct_x64 => OpenhclIgvmOutput,
958 openhcl_sivm_x64 => OpenhclIgvmOutput,
959 pipette_linux_musl_x64 => PipetteOutput,
960 tmk_vmm_linux_musl_x64 => TmkVmmOutput,
961 tpm_guest_tests_linux_x64 => TpmGuestTestsOutput,
962 guest_test_uefi_x64 => GuestTestUefiOutput,
964 tmks_x64 => TmksOutput,
965 )
966 );
967
968 vmm_tests_built_artifacts_builder!(
969 VmmTestsArtifactsBuilderWindowsAarch64,
970 (
971 nextest_vmm_tests_archive_windows_aarch64 => NextestVmmTestsArchive,
973 openvmm_windows_aarch64 => OpenvmmOutput,
974 pipette_windows_aarch64 => PipetteOutput,
975 tmk_vmm_windows_aarch64 => TmkVmmOutput,
976 vmgstool_windows_aarch64 => VmgstoolOutput,
977 vmgstool_dev_windows_aarch64 => VmgstoolOutput,
978 openhcl_standard_aarch64 => OpenhclIgvmOutput,
980 pipette_linux_musl_aarch64 => PipetteOutput,
981 tmk_vmm_linux_musl_aarch64 => TmkVmmOutput,
982 guest_test_uefi_aarch64 => GuestTestUefiOutput,
984 tmks_aarch64 => TmksOutput,
985 )
986 );
987}