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)]
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 ) => FloweyHvliteOutput,
267 nextest_vmm_tests_archive(
268 windows_x64(
269 (NextestVmmTestsArchive { archive_file }, archive_file),
270 host_tools::NEXTEST_VMM_TESTS_ARCHIVE_WINDOWS_X64
271 ),
272 windows_aarch64(
273 (NextestVmmTestsArchive { archive_file }, archive_file),
274 host_tools::NEXTEST_VMM_TESTS_ARCHIVE_WINDOWS_AARCH64
275 ),
276 linux_x64(
277 (NextestVmmTestsArchive { archive_file }, archive_file),
278 host_tools::NEXTEST_VMM_TESTS_ARCHIVE_LINUX_X64
279 ),
280 linux_musl_x64(
281 (NextestVmmTestsArchive { archive_file }, archive_file),
282 host_tools::NEXTEST_VMM_TESTS_ARCHIVE_LINUX_X64_MUSL
283 ),
284 linux_musl_aarch64(
285 (NextestVmmTestsArchive { archive_file }, archive_file),
286 host_tools::NEXTEST_VMM_TESTS_ARCHIVE_LINUX_AARCH64_MUSL
287 ),
288 ) => NextestVmmTestsArchive,
289 prep_steps(
290 windows_x64(
291 (PrepStepsOutput::WindowsBin { exe, pdb }, exe, pdb),
292 host_tools::PREP_STEPS_WINDOWS_X64
293 ),
294 linux_musl_x64(
295 (PrepStepsOutput::LinuxBin { bin, dbg}, bin, dbg),
296 host_tools::PREP_STEPS_LINUX_X64_MUSL
297 ),
298 ) => PrepStepsOutput,
299 test_igvm_agent_rpc_server(
300 windows_x64(
301 (TestIgvmAgentRpcServerOutput { exe, pdb }, exe, pdb),
302 host_tools::TEST_IGVM_AGENT_RPC_SERVER_WINDOWS_X64
303 ),
304 ) => TestIgvmAgentRpcServerOutput,
305
306 openvmm(
308 windows_x64(
309 (OpenvmmOutput::WindowsBin { exe, pdb }, exe, pdb),
310 OPENVMM_WINDOWS_X64
311 ),
312 windows_aarch64(
313 (OpenvmmOutput::WindowsBin { exe, pdb }, exe, pdb),
314 OPENVMM_WINDOWS_AARCH64
315 ),
316 linux_x64(
317 (OpenvmmOutput::LinuxBin { bin, dbg}, bin, dbg),
318 OPENVMM_LINUX_X64
319 ),
320 linux_aarch64(
321 (OpenvmmOutput::LinuxBin { bin, dbg}, bin, dbg),
322 OPENVMM_LINUX_AARCH64
323 ),
324 linux_musl_x64(
325 (OpenvmmOutput::LinuxBin { bin, dbg}, bin, dbg),
326 OPENVMM_LINUX_X64_MUSL
327 ),
328 linux_musl_aarch64(
329 (OpenvmmOutput::LinuxBin { bin, dbg}, bin, dbg),
330 OPENVMM_LINUX_AARCH64_MUSL
331 ),
332 ) => OpenvmmOutput,
333 openvmm_vhost(
334 linux_x64(
335 (OpenvmmVhostOutput { bin, dbg}, bin, dbg),
336 OPENVMM_VHOST_LINUX_X64
337 ),
338 linux_aarch64(
339 (OpenvmmVhostOutput { bin, dbg}, bin, dbg),
340 OPENVMM_VHOST_LINUX_AARCH64
341 ),
342 linux_musl_x64(
343 (OpenvmmVhostOutput { bin, dbg}, bin, dbg),
344 OPENVMM_VHOST_LINUX_X64_MUSL
345 ),
346 linux_musl_aarch64(
347 (OpenvmmVhostOutput { bin, dbg}, bin, dbg),
348 OPENVMM_VHOST_LINUX_AARCH64_MUSL
349 ),
350 ) => OpenvmmVhostOutput,
351 pipette(
352 windows_x64(
353 (PipetteOutput::WindowsBin { exe, pdb }, exe, pdb),
354 PIPETTE_WINDOWS_X64
355 ),
356 windows_aarch64(
357 (PipetteOutput::WindowsBin { exe, pdb }, exe, pdb),
358 PIPETTE_WINDOWS_AARCH64
359 ),
360 linux_musl_x64(
361 (PipetteOutput::LinuxBin { bin, dbg}, bin, dbg),
362 PIPETTE_LINUX_X64_MUSL
363 ),
364 linux_musl_aarch64(
365 (PipetteOutput::LinuxBin { bin, dbg}, bin, dbg),
366 PIPETTE_LINUX_AARCH64_MUSL
367 ),
368 ) => PipetteOutput,
369 guest_test_uefi(
370 x64(
371 (GuestTestUefiOutput { img, efi, pdb }, img, efi, pdb),
372 test_vhd::GUEST_TEST_UEFI_X64
373 ),
374 aarch64(
375 (GuestTestUefiOutput { img, efi, pdb }, img, efi, pdb),
376 test_vhd::GUEST_TEST_UEFI_AARCH64
377 ),
378 ) => GuestTestUefiOutput,
379 openhcl_standard(
380 x64(
381 (OpenhclIgvmOutput::X64 { igvm_bin }, igvm_bin),
382 openhcl_igvm::LATEST_STANDARD_X64
383 ),
384 aarch64(
385 (OpenhclIgvmOutput::Aarch64 { igvm_bin }, igvm_bin),
386 openhcl_igvm::LATEST_STANDARD_AARCH64
387 ),
388 ) => OpenhclIgvmOutput,
389 openhcl_standard_dev(
390 x64(
391 (OpenhclIgvmOutput::X64Devkern { igvm_bin }, igvm_bin),
392 openhcl_igvm::LATEST_STANDARD_DEV_KERNEL_X64
393 ),
394 aarch64(
395 (OpenhclIgvmOutput::Aarch64Devkern { igvm_bin }, igvm_bin),
396 openhcl_igvm::LATEST_STANDARD_DEV_KERNEL_AARCH64
397 ),
398 ) => OpenhclIgvmOutput,
399 openhcl_cvm(
400 x64(
401 (OpenhclIgvmOutput::X64Cvm { igvm_bin, endorsements }, igvm_bin, endorsements),
402 openhcl_igvm::LATEST_CVM_X64
403 ),
404 ) => OpenhclIgvmOutput,
405 vmfirmwareigvm_cvm(
406 x64(
407 (VmfirmwareigvmDllOutput { dll }, dll),
408 vmfw_dll::LATEST_CVM_X64
409 ),
410 ) => VmfirmwareigvmDllOutput,
411 openhcl_linux_direct(
412 x64(
413 (OpenhclIgvmOutput::X64TestLinuxDirect { igvm_bin }, igvm_bin),
414 openhcl_igvm::LATEST_LINUX_DIRECT_TEST_X64
415 ),
416 ) => OpenhclIgvmOutput,
417 snp_linux_direct_igvm(
418 x64(
419 (SnpLinuxDirectIgvmOutput { igvm_bin, igvm_map }, igvm_bin, igvm_map),
420 snp_igvm::SNP_LINUX_DIRECT_IGVM_X64
421 ),
422 ) => SnpLinuxDirectIgvmOutput,
423 tmks(
424 x64(
425 (TmksOutput { bin, dbg}, bin, dbg),
426 tmks::SIMPLE_TMK_X64
427 ),
428 aarch64(
429 (TmksOutput { bin, dbg}, bin, dbg),
430 tmks::SIMPLE_TMK_AARCH64
431 ),
432 ) => TmksOutput,
433 tmk_vmm(
434 windows_x64(
435 (TmkVmmOutput::WindowsBin { exe, pdb }, exe, pdb),
436 tmks::TMK_VMM_WINDOWS_X64
437 ),
438 windows_aarch64(
439 (TmkVmmOutput::WindowsBin { exe, pdb }, exe, pdb),
440 tmks::TMK_VMM_WINDOWS_AARCH64
441 ),
442 linux_musl_x64(
443 (TmkVmmOutput::LinuxBin { bin, dbg}, bin, dbg),
444 tmks::TMK_VMM_LINUX_X64_MUSL
445 ),
446 linux_musl_aarch64(
447 (TmkVmmOutput::LinuxBin { bin, dbg}, bin, dbg),
448 tmks::TMK_VMM_LINUX_AARCH64_MUSL
449 ),
450 ) => TmkVmmOutput,
451 vmgstool(
452 windows_x64(
453 (VmgstoolOutput::WindowsBin { exe, pdb }, exe, pdb),
454 vmgstool::VMGSTOOL_WINDOWS_X64
455 ),
456 windows_aarch64(
457 (VmgstoolOutput::WindowsBin { exe, pdb }, exe, pdb),
458 vmgstool::VMGSTOOL_WINDOWS_AARCH64
459 ),
460 linux_x64(
461 (VmgstoolOutput::LinuxBin { bin, dbg}, bin, dbg),
462 vmgstool::VMGSTOOL_LINUX_X64
463 ),
464 ) => VmgstoolOutput,
465 vmgstool_dev(
466 windows_x64(
467 (VmgstoolOutput::WindowsBin { exe, pdb }, exe, pdb),
468 vmgstool::VMGSTOOL_DEV_WINDOWS_X64
469 ),
470 windows_aarch64(
471 (VmgstoolOutput::WindowsBin { exe, pdb }, exe, pdb),
472 vmgstool::VMGSTOOL_DEV_WINDOWS_AARCH64
473 ),
474 linux_x64(
475 (VmgstoolOutput::LinuxBin { bin, dbg}, bin, dbg),
476 vmgstool::VMGSTOOL_DEV_LINUX_X64
477 ),
478 ) => VmgstoolOutput,
479 tpm_guest_tests(
480 windows_x64(
481 (TpmGuestTestsOutput::WindowsBin { exe, pdb }, exe, pdb),
482 guest_tools::TPM_GUEST_TESTS_WINDOWS_X64
483 ),
484 linux_x64(
485 (TpmGuestTestsOutput::LinuxBin { bin, dbg}, bin, dbg),
486 guest_tools::TPM_GUEST_TESTS_LINUX_X64
487 ),
488 ) => TpmGuestTestsOutput,
489);
490
491pub type ResolveVmmTestsBuiltArtifacts =
492 Box<dyn Fn(&mut flowey::pipeline::prelude::PipelineJobCtx<'_>) -> VmmTestsBuiltArtifacts>;
493
494#[macro_export]
495macro_rules! vmm_tests_built_artifacts_builder {
496 (
497 $name:ty,
498 (
499 $($artifact:ident => $output:ty),* $(,)?
500 )
501 ) => {
502 ::paste::paste! {
503 #[derive(Default, Clone)]
504 pub struct $name {
505 $(pub [<use_ $artifact>]: Option<::flowey::pipeline::prelude::UseTypedArtifact<$output>>,)*
506 }
507
508 impl $name {
509 pub fn finish(self) -> Result<$crate::init_vmm_tests_content_dir::ResolveVmmTestsBuiltArtifacts, &'static str> {
510 let $name {
511 $([<use_ $artifact>],)*
512 } = self;
513
514 $(let [<use_ $artifact>] = [<use_ $artifact>].ok_or(stringify!($artifact))?;)*
515
516 Ok(Box::new(move |ctx| $crate::init_vmm_tests_content_dir::VmmTestsBuiltArtifacts {
517 $($artifact: Some(ctx.use_typed_artifact(&[<use_ $artifact>])),)*
518 .. Default::default()
519 }))
520 }
521
522 pub fn selections() -> $crate::init_vmm_tests_content_dir::VmmTestsBuiltArtifactsSelections {
523 let mut selections = $crate::init_vmm_tests_content_dir::VmmTestsBuiltArtifactsSelections::default();
524 $(selections.$artifact = true;)*
525 selections
526 }
527 }
528 }
529 };
530}
531
532define_vmm_tests_built_artifacts!(
533 VmmTestsPreBuiltArtifacts,
534 test_linux_kernel(
535 x64(
536 (src, src),
537 loadable::LINUX_DIRECT_TEST_KERNEL_X64
538 ),
539 aarch64(
540 (src, src),
541 loadable::LINUX_DIRECT_TEST_KERNEL_AARCH64
542 ),
543 ) => PathBuf,
544 test_linux_kernel_cca(
545 aarch64(
546 (src, src),
547 loadable::LINUX_DIRECT_TEST_KERNEL_CCA_AARCH64
548 ),
549 ) => PathBuf,
550 test_linux_initrd(
551 x64(
552 (src, src),
553 loadable::LINUX_DIRECT_TEST_INITRD_X64
554 ),
555 aarch64(
556 (src, src),
557 loadable::LINUX_DIRECT_TEST_INITRD_AARCH64
558 ),
559 ) => PathBuf,
560 test_linux_bzimage(
561 x64(
562 (src, src),
563 loadable::LINUX_DIRECT_TEST_BZIMAGE_X64
564 ),
565 ) => PathBuf,
566 uefi(
567 x64(
568 (src, src),
569 loadable::UEFI_FIRMWARE_X64
570 ),
571 aarch64(
572 (src, src),
573 loadable::UEFI_FIRMWARE_AARCH64
574 ),
575 ) => PathBuf,
576 qemu_system_aarch64(
577 linux_x64(
578 (src, src),
579 QEMU_SYSTEM_AARCH64_LINUX_X64
580 ),
581 ) => PathBuf,
582);
583
584flowey_request! {
585 pub struct Request {
586 pub test_content_dir: ReadVar<PathBuf>,
589 pub vmm_tests_target: target_lexicon::Triple,
594 pub built_artifacts: VmmTestsBuiltArtifacts,
596 pub prebuilt_artifacts: VmmTestsPreBuiltArtifactsSelections,
598 pub uefi_firmware_flavor: Option<crate::download_uefi_mu_msvm::FirmwareFlavor>,
600 pub is_repo_root: bool,
604
605 pub needs_virtio_win_drivers: bool,
608 pub needs_release_igvm: bool,
609
610 pub done: WriteVar<SideEffect>
611 }
612}
613
614new_simple_flow_node!(struct Node);
615
616impl SimpleFlowNode for Node {
617 type Request = Request;
618
619 fn imports(ctx: &mut ImportCtx<'_>) {
620 ctx.import::<crate::resolve_openvmm_test_initrd::Node>();
621 ctx.import::<crate::resolve_openvmm_test_linux_kernel::Node>();
622 ctx.import::<crate::resolve_openvmm_test_virtio_win::Node>();
623 ctx.import::<crate::git_checkout_openvmm_repo::Node>();
624 ctx.import::<crate::download_uefi_mu_msvm::Node>();
625 ctx.import::<crate::download_release_igvm_files_from_gh::resolve::Node>();
626 ctx.import::<crate::resolve_openvmm_qemu::Node>();
627 }
628
629 fn process_request(request: Self::Request, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
630 let Request {
631 test_content_dir,
632 vmm_tests_target,
633 built_artifacts,
634 prebuilt_artifacts,
635 uefi_firmware_flavor,
636 is_repo_root,
637 needs_virtio_win_drivers,
638 needs_release_igvm,
639 done,
640 } = request;
641
642 let openvmm_repo_path =
643 is_repo_root.then(|| ctx.reqv(crate::git_checkout_openvmm_repo::req::GetRepoDir));
644
645 let arch = CommonArch::from_architecture(vmm_tests_target.architecture)?;
646
647 let test_linux_initrd_x64 = prebuilt_artifacts.test_linux_initrd_x64.then(|| {
648 ctx.reqv(|v| crate::resolve_openvmm_test_initrd::Request::Get(CommonArch::X86_64, v))
649 });
650 let test_linux_initrd_aarch64 = prebuilt_artifacts.test_linux_initrd_aarch64.then(|| {
651 ctx.reqv(|v| crate::resolve_openvmm_test_initrd::Request::Get(CommonArch::Aarch64, v))
652 });
653 let test_linux_kernel_x64 = prebuilt_artifacts.test_linux_kernel_x64.then(|| {
654 ctx.reqv(|v| {
655 crate::resolve_openvmm_test_linux_kernel::Request::Get(
656 crate::resolve_openvmm_test_linux_kernel::OpenvmmTestKernelFile::Kernel,
657 CommonArch::X86_64,
658 crate::resolve_openvmm_test_linux_kernel::DEFAULT_LINUX_TEST_KERNEL_VERSION,
659 v,
660 )
661 })
662 });
663 let test_linux_kernel_aarch64 = prebuilt_artifacts.test_linux_kernel_aarch64.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::Aarch64,
668 crate::resolve_openvmm_test_linux_kernel::DEFAULT_LINUX_TEST_KERNEL_VERSION,
669 v,
670 )
671 })
672 });
673 let test_linux_kernel_cca_aarch64 =
674 prebuilt_artifacts.test_linux_kernel_cca_aarch64.then(|| {
675 ctx.reqv(|v| {
676 crate::resolve_openvmm_test_linux_kernel::Request::Get(
677 crate::resolve_openvmm_test_linux_kernel::OpenvmmTestKernelFile::Kernel,
678 CommonArch::Aarch64,
679 crate::resolve_openvmm_test_linux_kernel::CCA_LINUX_TEST_KERNEL_VERSION,
680 v,
681 )
682 })
683 });
684 let test_linux_bzimage_x64 = prebuilt_artifacts.test_linux_bzimage_x64.then(|| {
685 ctx.reqv(|v| {
686 crate::resolve_openvmm_test_linux_kernel::Request::Get(
687 crate::resolve_openvmm_test_linux_kernel::OpenvmmTestKernelFile::BzImage,
688 CommonArch::X86_64,
689 crate::resolve_openvmm_test_linux_kernel::DEFAULT_LINUX_TEST_KERNEL_VERSION,
690 v,
691 )
692 })
693 });
694
695 let uefi_x64 = prebuilt_artifacts.uefi_x64.then(|| {
696 ctx.reqv(|msvm_fd| crate::download_uefi_mu_msvm::Request::GetMsvmFd {
697 arch: CommonArch::X86_64,
698 flavor: uefi_firmware_flavor,
699 msvm_fd,
700 })
701 });
702 let uefi_aarch64 = prebuilt_artifacts.uefi_aarch64.then(|| {
703 ctx.reqv(|msvm_fd| crate::download_uefi_mu_msvm::Request::GetMsvmFd {
704 arch: CommonArch::Aarch64,
705 flavor: uefi_firmware_flavor,
706 msvm_fd,
707 })
708 });
709
710 let qemu_system_aarch64_linux_x64 =
711 prebuilt_artifacts.qemu_system_aarch64_linux_x64.then(|| {
712 ctx.reqv(|v| {
713 crate::resolve_openvmm_qemu::Request::Get(
714 crate::resolve_openvmm_qemu::QemuFile::SystemAarch64,
715 CommonArch::X86_64,
716 v,
717 )
718 })
719 });
720
721 let prebuilt_artifacts = VmmTestsPreBuiltArtifacts {
722 test_linux_kernel_x64,
723 test_linux_kernel_aarch64,
724 test_linux_kernel_cca_aarch64,
725 test_linux_initrd_x64,
726 test_linux_initrd_aarch64,
727 test_linux_bzimage_x64,
728 uefi_x64,
729 uefi_aarch64,
730 qemu_system_aarch64_linux_x64,
731 };
732
733 let virtio_win_dir = needs_virtio_win_drivers
734 .then(|| ctx.reqv(crate::resolve_openvmm_test_virtio_win::Request::Get));
735
736 let release_igvm_files = needs_release_igvm.then(|| {
737 ctx.reqv(
738 |v| crate::download_release_igvm_files_from_gh::resolve::Request {
739 arch,
740 release_igvm_files: v,
741 release_version: OpenhclReleaseVersion::latest(),
742 },
743 )
744 });
745
746 ctx.emit_rust_step("setting up vmm_tests content dir", |ctx| {
747 claim_vars!(
748 ctx,
749 (
750 test_content_dir,
751 openvmm_repo_path,
752 built_artifacts,
754 prebuilt_artifacts,
756 virtio_win_dir,
757 release_igvm_files,
758 )
759 );
760
761 done.claim(ctx);
762
763 move |rt| {
764 read_vars!(rt, (release_igvm_files, test_content_dir));
765
766 if !test_content_dir.exists() {
767 fs_err::create_dir_all(&test_content_dir)?
768 };
769
770 if let Some(openvmm_repo_path) = openvmm_repo_path {
771 let openvmm_repo_path = rt.read(openvmm_repo_path);
772
773 let nextest_config_file = PathBuf::new().join(".config").join("nextest.toml");
774 fs_err::create_dir_all(
775 test_content_dir
776 .join(&nextest_config_file)
777 .parent()
778 .context("no parent")?,
779 )?;
780 fs_err::copy(
781 openvmm_repo_path.join(&nextest_config_file),
782 test_content_dir.join(&nextest_config_file),
783 )?;
784
785 let repo_cargo_toml_file = Path::new("Cargo.toml");
786 fs_err::copy(
787 openvmm_repo_path.join(repo_cargo_toml_file),
788 test_content_dir.join(repo_cargo_toml_file),
789 )?;
790
791 let crate_cargo_toml_file = PathBuf::new()
792 .join("vmm_tests")
793 .join("vmm_tests")
794 .join("Cargo.toml");
795 fs_err::create_dir_all(
796 test_content_dir
797 .join(&crate_cargo_toml_file)
798 .parent()
799 .context("no parent")?,
800 )?;
801 fs_err::copy(
802 openvmm_repo_path.join(&crate_cargo_toml_file),
803 test_content_dir.join(&crate_cargo_toml_file),
804 )?;
805 }
806
807 built_artifacts.write(rt, &test_content_dir)?;
808
809 prebuilt_artifacts.write(rt, &test_content_dir)?;
810
811 if let Some(release_igvm_files) = release_igvm_files {
812 if let Some(src) = &release_igvm_files.openhcl {
813 fs_err::copy(
814 src,
815 test_content_dir
816 .join(openhcl_igvm::LATEST_RELEASE_STANDARD_X64::relative_path()),
817 )?;
818 }
819
820 if let Some(src) = &release_igvm_files.openhcl_aarch64 {
821 fs_err::copy(
822 src,
823 test_content_dir.join(
824 openhcl_igvm::LATEST_RELEASE_STANDARD_AARCH64::relative_path(),
825 ),
826 )?;
827 }
828
829 if let Some(src) = &release_igvm_files.openhcl_direct {
830 fs_err::copy(
831 src,
832 test_content_dir.join(
833 openhcl_igvm::LATEST_RELEASE_LINUX_DIRECT_X64::relative_path(),
834 ),
835 )?;
836 }
837 }
838
839 if let Some(virtio_win_dir) = virtio_win_dir {
840 let src = rt.read(virtio_win_dir);
841 let dst =
842 test_content_dir.join(virtio_win::VIRTIO_WINDOWS_DRIVERS::relative_path());
843 let _ = fs_err::remove_dir_all(&dst);
844 flowey_lib_common::_util::copy_dir_all(&src, &dst)?;
845 }
846
847 log::info!("final folder content: {}", test_content_dir.display());
849 fn list_dir(dir: PathBuf, layer: usize) -> anyhow::Result<()> {
850 if layer > 2
851 || dir
852 .file_name()
853 .and_then(|n| n.to_str())
854 .is_some_and(|n| ["temp", "test_results"].contains(&n))
855 {
856 log::info!("{}- ...", " ".repeat(layer * 2));
857 return Ok(());
858 }
859 for entry in dir.read_dir()? {
860 let entry = entry?;
861 log::info!("{}- {}", " ".repeat(layer * 2), entry.file_name().display());
862 let subdir = entry.path();
863 if subdir.is_dir() {
864 list_dir(subdir, layer + 1)?;
865 }
866 }
867 Ok(())
868 }
869 list_dir(test_content_dir, 0)?;
870
871 Ok(())
872 }
873 });
874
875 Ok(())
876 }
877}
878
879pub mod vmm_tests_artifact_builders {
884 use super::*;
885
886 vmm_tests_built_artifacts_builder!(
887 VmmTestsArtifactsBuilderLinuxX86,
888 (
889 pipette_windows_x64 => PipetteOutput,
891 nextest_vmm_tests_archive_linux_x64 => NextestVmmTestsArchive,
893 nextest_vmm_tests_archive_linux_musl_x64 => NextestVmmTestsArchive,
894 openvmm_linux_x64 => OpenvmmOutput,
895 openvmm_linux_musl_x64 => OpenvmmOutput,
896 openvmm_vhost_linux_x64 => OpenvmmVhostOutput,
897 pipette_linux_musl_x64 => PipetteOutput,
898 prep_steps_linux_musl_x64 => PrepStepsOutput,
899 snp_linux_direct_igvm_x64 => SnpLinuxDirectIgvmOutput,
900 tmk_vmm_linux_musl_x64 => TmkVmmOutput,
901 guest_test_uefi_x64 => GuestTestUefiOutput,
903 tmks_x64 => TmksOutput,
904 nextest_vmm_tests_archive_linux_musl_aarch64 => NextestVmmTestsArchive,
906 openvmm_linux_musl_aarch64 => OpenvmmOutput,
907 pipette_linux_musl_aarch64 => PipetteOutput,
908 )
909 );
910
911 vmm_tests_built_artifacts_builder!(
912 VmmTestsArtifactsBuilderLinuxMuslX86,
913 (
914 pipette_windows_x64 => PipetteOutput,
916 nextest_vmm_tests_archive_linux_musl_x64 => NextestVmmTestsArchive,
918 openvmm_linux_musl_x64 => OpenvmmOutput,
919 openvmm_vhost_linux_musl_x64 => OpenvmmVhostOutput,
920 pipette_linux_musl_x64 => PipetteOutput,
921 prep_steps_linux_musl_x64 => PrepStepsOutput,
922 snp_linux_direct_igvm_x64 => SnpLinuxDirectIgvmOutput,
923 tmk_vmm_linux_musl_x64 => TmkVmmOutput,
924 guest_test_uefi_x64 => GuestTestUefiOutput,
926 tmks_x64 => TmksOutput,
927 nextest_vmm_tests_archive_linux_musl_aarch64 => NextestVmmTestsArchive,
929 openvmm_linux_musl_aarch64 => OpenvmmOutput,
930 pipette_linux_musl_aarch64 => PipetteOutput,
931 )
932 );
933
934 vmm_tests_built_artifacts_builder!(
935 VmmTestsArtifactsBuilderWindowsX86,
936 (
937 nextest_vmm_tests_archive_windows_x64 => NextestVmmTestsArchive,
939 openvmm_windows_x64 => OpenvmmOutput,
940 pipette_windows_x64 => PipetteOutput,
941 tmk_vmm_windows_x64 => TmkVmmOutput,
942 prep_steps_windows_x64 => PrepStepsOutput,
943 vmgstool_windows_x64 => VmgstoolOutput,
944 vmgstool_dev_windows_x64 => VmgstoolOutput,
945 tpm_guest_tests_windows_x64 => TpmGuestTestsOutput,
946 test_igvm_agent_rpc_server_windows_x64 => TestIgvmAgentRpcServerOutput,
947 vmfirmwareigvm_cvm_x64 => VmfirmwareigvmDllOutput,
948 openhcl_standard_x64 => OpenhclIgvmOutput,
950 openhcl_cvm_x64 => OpenhclIgvmOutput,
951 openhcl_linux_direct_x64 => OpenhclIgvmOutput,
952 pipette_linux_musl_x64 => PipetteOutput,
953 tmk_vmm_linux_musl_x64 => TmkVmmOutput,
954 tpm_guest_tests_linux_x64 => TpmGuestTestsOutput,
955 guest_test_uefi_x64 => GuestTestUefiOutput,
957 tmks_x64 => TmksOutput,
958 )
959 );
960
961 vmm_tests_built_artifacts_builder!(
962 VmmTestsArtifactsBuilderWindowsAarch64,
963 (
964 nextest_vmm_tests_archive_windows_aarch64 => NextestVmmTestsArchive,
966 openvmm_windows_aarch64 => OpenvmmOutput,
967 pipette_windows_aarch64 => PipetteOutput,
968 tmk_vmm_windows_aarch64 => TmkVmmOutput,
969 vmgstool_windows_aarch64 => VmgstoolOutput,
970 vmgstool_dev_windows_aarch64 => VmgstoolOutput,
971 openhcl_standard_aarch64 => OpenhclIgvmOutput,
973 pipette_linux_musl_aarch64 => PipetteOutput,
974 tmk_vmm_linux_musl_aarch64 => TmkVmmOutput,
975 guest_test_uefi_aarch64 => GuestTestUefiOutput,
977 tmks_aarch64 => TmksOutput,
978 )
979 );
980}