flowey_lib_hvlite/_jobs/
setup_and_run_vmm_perf.rs1use crate::build_openvmm::OpenvmmOutput;
7use crate::build_vmm_perf::VmmPerfOutput;
8use crate::common::CommonArch;
9use crate::install_vmm_tests_external_deps::VmmTestsExternalDeps;
10use crate::install_vmm_tests_external_deps::VmmTestsExternalDepsLinux;
11use crate::install_vmm_tests_external_deps::VmmTestsExternalDepsWindows;
12use crate::run_vmm_perf::VmmPerfProfile;
13use flowey::node::prelude::*;
14use std::collections::BTreeMap;
15
16flowey_request! {
17 pub struct Params {
18 pub label: String,
19 pub runner: ReadVar<VmmPerfOutput>,
20 pub openvmm: ReadVar<OpenvmmOutput>,
21 pub profiles: Vec<VmmPerfProfile>,
22 pub vm_sizes_json: Option<String>,
23 pub parameters_json: Option<String>,
24 pub runtime_archive: Option<ReadVar<PathBuf>>,
26 pub root_dir: Option<ReadVar<PathBuf>>,
28 pub hugetlb_2mb_overcommit_pages: Option<u64>,
29 pub done: WriteVar<SideEffect>,
30 }
31}
32
33new_simple_flow_node!(struct Node);
34
35impl SimpleFlowNode for Node {
36 type Request = Params;
37
38 fn imports(ctx: &mut ImportCtx<'_>) {
39 ctx.import::<crate::download_uefi_mu_msvm::Node>();
40 ctx.import::<crate::download_vmm_perf_runtime::Node>();
41 ctx.import::<crate::install_vmm_tests_external_deps::Node>();
42 ctx.import::<crate::run_vmm_perf::Node>();
43 ctx.import::<flowey_lib_common::publish_test_results::Node>();
44 }
45
46 fn process_request(request: Self::Request, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
47 let Params {
48 label,
49 runner,
50 openvmm,
51 profiles,
52 vm_sizes_json,
53 parameters_json,
54 runtime_archive,
55 root_dir,
56 hugetlb_2mb_overcommit_pages,
57 done,
58 } = request;
59
60 if root_dir.is_some() && !matches!(ctx.backend(), FlowBackend::Local) {
61 anyhow::bail!("custom VMM.Perf root directories are local-only");
62 }
63 if runtime_archive.is_some() && !matches!(ctx.backend(), FlowBackend::Local) {
64 anyhow::bail!("custom VMM.Perf runtime archives are local-only");
65 }
66
67 let external_deps = match ctx.platform() {
68 FlowPlatform::Windows => VmmTestsExternalDeps::Windows(VmmTestsExternalDepsWindows {
69 hyperv: true,
70 whp: true,
71 hardware_isolation: false,
72 }),
73 FlowPlatform::Linux(_) => VmmTestsExternalDeps::Linux(VmmTestsExternalDepsLinux {
74 hugetlb_2mb_overcommit_pages,
75 prepare_vhost_vsock: false,
76 }),
77 _ => anyhow::bail!("VMM.Perf is unsupported on this platform"),
78 };
79 ctx.config(crate::install_vmm_tests_external_deps::Config {
80 selections: Some(external_deps),
81 auto_install: None,
82 });
83 let pre_run_deps = vec![ctx.reqv(crate::install_vmm_tests_external_deps::Request::Install)];
84
85 let firmware = ctx.reqv(|v| crate::download_uefi_mu_msvm::Request::GetMsvmFd {
86 arch: CommonArch::X86_64,
87 msvm_fd: v,
88 });
89 let runtime_archive = match runtime_archive {
90 Some(runtime_archive) => runtime_archive,
91 None => ctx.reqv(|v| crate::download_vmm_perf_runtime::Request::Get {
92 arch: CommonArch::X86_64,
93 runtime_archive: v,
94 }),
95 };
96 let job_root = match ctx.backend() {
97 FlowBackend::Local => root_dir
98 .ok_or_else(|| anyhow::anyhow!("local VMM.Perf runs require a root directory"))?,
99 FlowBackend::Ado => ctx
100 .get_ado_variable(AdoRuntimeVar::PIPELINE_WORKSPACE)
101 .map(ctx, |root| PathBuf::from(root).join("vp")),
102 FlowBackend::Github => ctx
103 .get_gh_context_var()
104 .global()
105 .runner_temp()
106 .map(ctx, |root| PathBuf::from(root).join("vp")),
107 };
108 let output_dir = job_root.clone().map(ctx, |root| root.join("results"));
109 let temp_dir = Some(job_root.map(ctx, |root| root.join("t")));
110
111 let result = ctx.reqv(|v| crate::run_vmm_perf::Request {
112 runner,
113 openvmm,
114 firmware,
115 runtime_archive,
116 output_dir,
117 temp_dir,
118 profiles,
119 vm_sizes_json,
120 parameters_json,
121 pre_run_deps,
122 output: v,
123 });
124
125 let publish_done = if matches!(ctx.backend(), FlowBackend::Local) {
126 result.clone().into_side_effect()
127 } else {
128 let results_dir = result.clone().map(ctx, |result| result.results_dir);
129 let test_results = result.clone().map(ctx, |result| {
130 flowey_lib_common::run_cargo_nextest_run::TestResults {
131 all_tests_passed: result.success,
132 junit_xml: None,
133 }
134 });
135 ctx.reqv(|v| flowey_lib_common::publish_test_results::Request {
136 test_results,
137 test_label: label,
138 attachments: BTreeMap::from([("results".into(), (results_dir, false))]),
139 output_dir: None,
140 upload_logs_on_success: true,
141 done: v,
142 })
143 };
144
145 ctx.emit_rust_step("report VMM.Perf result", |ctx| {
146 let result = result.claim(ctx);
147 publish_done.claim(ctx);
148 done.claim(ctx);
149 move |rt| {
150 let result = rt.read(result);
151 anyhow::ensure!(
152 result.success,
153 "VMM.Perf failed with exit code {}",
154 result
155 .exit_code
156 .map_or_else(|| "unknown".into(), |code| code.to_string())
157 );
158 Ok(())
159 }
160 });
161
162 Ok(())
163 }
164}