flowey_lib_hvlite/
test_nextest_vmm_tests_archive.rs1use crate::build_nextest_vmm_tests::NextestVmmTestsArchive;
11use crate::run_cargo_nextest_run::NextestProfile;
12use flowey::node::prelude::*;
13use flowey_lib_common::run_cargo_nextest_run::TestResults;
14use std::collections::BTreeMap;
15
16flowey_request! {
17 pub struct Request {
18 pub nextest_archive_file: ReadVar<NextestVmmTestsArchive>,
20 pub nextest_filter_expr: Option<String>,
22 pub nextest_profile: NextestProfile,
24 pub nextest_working_dir: Option<ReadVar<PathBuf>>,
26 pub nextest_config_file: Option<ReadVar<PathBuf>>,
28 pub nextest_bin: Option<ReadVar<PathBuf>>,
30 pub target: Option<ReadVar<target_lexicon::Triple>>,
32 pub extra_env: ReadVar<BTreeMap<String, String>>,
34 pub pre_run_deps: Vec<ReadVar<SideEffect>>,
38 pub hugetlb_2mb_overcommit_pages: Option<u64>,
40 pub results: WriteVar<TestResults>,
42 }
43}
44
45new_simple_flow_node!(struct Node);
46
47impl SimpleFlowNode for Node {
48 type Request = Request;
49
50 fn imports(ctx: &mut ImportCtx<'_>) {
51 ctx.import::<crate::run_cargo_nextest_run::Node>();
52 }
53
54 fn process_request(request: Self::Request, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
55 let Request {
56 nextest_archive_file,
57 nextest_filter_expr,
58 nextest_profile,
59 nextest_working_dir,
60 nextest_config_file,
61 nextest_bin,
62 target,
63 mut extra_env,
64 mut pre_run_deps,
65 hugetlb_2mb_overcommit_pages,
66 results,
67 } = request;
68
69 if hugetlb_2mb_overcommit_pages.is_some() {
70 extra_env = extra_env.map(ctx, |mut env| {
71 env.insert("OPENVMM_REQUIRE_2MB_HUGETLB".into(), "1".into());
72 env
73 });
74 }
75
76 if !matches!(ctx.backend(), FlowBackend::Local)
77 && matches!(ctx.platform(), FlowPlatform::Linux(_))
78 {
79 pre_run_deps.push({
80 ctx.emit_rust_step("ensure hypervisor device is accessible", |_| {
81 |rt| {
82 if Path::new("/dev/kvm").exists() {
85 flowey::shell_cmd!(rt, "sudo chmod a+rw /dev/kvm").run()?;
86 }
87 if Path::new("/dev/mshv").exists() {
88 flowey::shell_cmd!(rt, "sudo chmod a+rw /dev/mshv").run()?;
89 }
90 Ok(())
91 }
92 })
93 });
94
95 if let Some(overcommit_pages) = hugetlb_2mb_overcommit_pages {
96 pre_run_deps.push({
97 ctx.emit_rust_step("ensure 2 MiB hugetlb pages are available", move |_| {
98 move |rt| {
99 let hugepages_dir =
100 Path::new("/sys/kernel/mm/hugepages/hugepages-2048kB");
101
102 let read_counter = |name: &str| -> anyhow::Result<u64> {
103 let path = hugepages_dir.join(name);
104 let value = fs_err::read_to_string(&path)?;
105 Ok(value.trim().parse()?)
106 };
107
108 let write_overcommit_script = format!(
109 "echo {overcommit_pages} | sudo tee {path}",
110 path = hugepages_dir.join("nr_overcommit_hugepages").display(),
111 );
112 flowey::shell_cmd!(rt, "sh -c {write_overcommit_script}").run()?;
113
114 let nr_hugepages = read_counter("nr_hugepages")?;
115 let free_hugepages = read_counter("free_hugepages")?;
116 let nr_overcommit_hugepages = read_counter("nr_overcommit_hugepages")?;
117 let surplus_hugepages = read_counter("surplus_hugepages")?;
118
119 log::info!("2 MiB hugetlb nr_hugepages={nr_hugepages}");
120 log::info!("2 MiB hugetlb free_hugepages={free_hugepages}");
121 log::info!(
122 "2 MiB hugetlb nr_overcommit_hugepages={nr_overcommit_hugepages}"
123 );
124 log::info!("2 MiB hugetlb surplus_hugepages={surplus_hugepages}");
125
126 if nr_overcommit_hugepages < overcommit_pages {
127 anyhow::bail!(
128 "2 MiB hugetlb overcommit remains {}, below requested {}",
129 nr_overcommit_hugepages,
130 overcommit_pages
131 );
132 }
133
134 Ok(())
135 }
136 })
137 });
138 }
139 }
140
141 let nextest_archive = nextest_archive_file.map(ctx, |x| x.archive_file);
142
143 ctx.req(crate::run_cargo_nextest_run::Request {
144 friendly_name: "vmm_tests".into(),
145 run_kind: flowey_lib_common::run_cargo_nextest_run::NextestRunKind::RunFromArchive {
146 archive_file: nextest_archive,
147 target,
148 nextest_bin,
149 },
150 nextest_profile,
151 nextest_filter_expr,
152 nextest_working_dir,
153 nextest_config_file,
154 run_ignored: false,
155 extra_env: Some(extra_env),
156 pre_run_deps,
157 results,
158 });
159
160 Ok(())
161 }
162}