1use flowey::node::prelude::ReadVar;
5use flowey::pipeline::prelude::*;
6use flowey_lib_hvlite::_jobs::local_build_and_run_nextest_vmm_tests::VmmTestSelectionFlags;
7use flowey_lib_hvlite::_jobs::local_build_and_run_nextest_vmm_tests::VmmTestSelections;
8use flowey_lib_hvlite::install_vmm_tests_deps::VmmTestsDepSelections;
9use flowey_lib_hvlite::run_cargo_build::common::CommonArch;
10use flowey_lib_hvlite::run_cargo_build::common::CommonTriple;
11use std::path::PathBuf;
12use vmm_test_images::KnownTestArtifacts;
13
14#[derive(clap::ValueEnum, Copy, Clone)]
15pub enum VmmTestTargetCli {
16 WindowsAarch64,
18 WindowsX64,
20 LinuxX64,
22}
23
24#[derive(clap::Args)]
26pub struct VmmTestsCli {
27 #[clap(long)]
31 target: Option<VmmTestTargetCli>,
32
33 #[clap(long)]
35 dir: PathBuf,
36
37 #[clap(long, conflicts_with("flags"))]
39 filter: Option<String>,
40 #[clap(long, conflicts_with("flags"), requires("filter"))]
42 artifacts: Vec<KnownTestArtifacts>,
43 #[clap(long)]
52 flags: Option<VmmTestSelectionFlags>,
53
54 #[clap(long)]
56 verbose: bool,
57 #[clap(long)]
59 install_missing_deps: bool,
60
61 #[clap(long)]
63 unstable_whp: bool,
64 #[clap(long)]
66 release: bool,
67
68 #[clap(long)]
70 build_only: bool,
71 #[clap(long)]
73 copy_extras: bool,
74
75 #[clap(long)]
77 custom_kernel_modules: Option<PathBuf>,
78 #[clap(long)]
80 custom_kernel: Option<PathBuf>,
81}
82
83impl IntoPipeline for VmmTestsCli {
84 fn into_pipeline(self, backend_hint: PipelineBackendHint) -> anyhow::Result<Pipeline> {
85 if !matches!(backend_hint, PipelineBackendHint::Local) {
86 anyhow::bail!("vmm-tests is for local use only")
87 }
88
89 let Self {
90 target,
91 dir,
92 filter,
93 artifacts,
94 flags,
95 verbose,
96 install_missing_deps,
97 unstable_whp,
98 release,
99 build_only,
100 copy_extras,
101 custom_kernel_modules,
102 custom_kernel,
103 } = self;
104
105 let openvmm_repo = flowey_lib_common::git_checkout::RepoSource::ExistingClone(
106 ReadVar::from_static(crate::repo_root()),
107 );
108
109 let mut pipeline = Pipeline::new();
110
111 let target = if let Some(t) = target {
112 t
113 } else {
114 match (
115 FlowArch::host(backend_hint),
116 FlowPlatform::host(backend_hint),
117 ) {
118 (FlowArch::Aarch64, FlowPlatform::Windows) => VmmTestTargetCli::WindowsAarch64,
119 (FlowArch::X86_64, FlowPlatform::Windows) => VmmTestTargetCli::WindowsX64,
120 (FlowArch::X86_64, FlowPlatform::Linux(_)) => VmmTestTargetCli::LinuxX64,
121 _ => anyhow::bail!("unsupported host"),
122 }
123 };
124
125 let target = match target {
126 VmmTestTargetCli::WindowsAarch64 => CommonTriple::AARCH64_WINDOWS_MSVC,
127 VmmTestTargetCli::WindowsX64 => CommonTriple::X86_64_WINDOWS_MSVC,
128 VmmTestTargetCli::LinuxX64 => CommonTriple::X86_64_LINUX_GNU,
129 };
130 let target_os = target.as_triple().operating_system;
131 let target_architecture = target.as_triple().architecture;
132
133 let recipe_arch = match target_architecture {
134 target_lexicon::Architecture::X86_64 => CommonArch::X86_64,
135 target_lexicon::Architecture::Aarch64(_) => CommonArch::Aarch64,
136 _ => anyhow::bail!("Unsupported architecture: {:?}", target_architecture),
137 };
138
139 let mut job = pipeline.new_job(
140 FlowPlatform::host(backend_hint),
141 FlowArch::host(backend_hint),
142 "build vmm test dependencies",
143 );
144
145 job = job.dep_on(|_| flowey_lib_hvlite::_jobs::cfg_versions::Request::Init);
146
147 if let (Some(kernel_path), Some(modules_path)) =
149 (custom_kernel.clone(), custom_kernel_modules.clone())
150 {
151 job =
152 job.dep_on(
153 move |_| flowey_lib_hvlite::_jobs::cfg_versions::Request::LocalKernel {
154 arch: recipe_arch,
155 kernel: ReadVar::from_static(kernel_path),
156 modules: ReadVar::from_static(modules_path),
157 },
158 );
159 }
160
161 job = job
162 .dep_on(
163 |_| flowey_lib_hvlite::_jobs::cfg_hvlite_reposource::Params {
164 hvlite_repo_source: openvmm_repo.clone(),
165 },
166 )
167 .dep_on(|_| flowey_lib_hvlite::_jobs::cfg_common::Params {
168 local_only: Some(flowey_lib_hvlite::_jobs::cfg_common::LocalOnlyParams {
169 interactive: true,
170 auto_install: install_missing_deps,
171 force_nuget_mono: false,
172 external_nuget_auth: false,
173 ignore_rust_version: true,
174 }),
175 verbose: ReadVar::from_static(verbose),
176 locked: false,
177 deny_warnings: false,
178 })
179 .dep_on(|ctx| {
180 flowey_lib_hvlite::_jobs::local_build_and_run_nextest_vmm_tests::Params {
181 target,
182 test_content_dir: dir,
183 selections: if let Some(filter) = filter {
184 VmmTestSelections::Custom {
185 filter,
186 artifacts,
187 build: Default::default(),
190 deps: match target_os {
191 target_lexicon::OperatingSystem::Windows => {
192 VmmTestsDepSelections::Windows {
193 hyperv: true,
194 whp: true,
195 hardware_isolation: match target_architecture {
198 target_lexicon::Architecture::Aarch64(_) => false,
199 target_lexicon::Architecture::X86_64 => true,
200 _ => panic!(
201 "Unhandled architecture: {:?}",
202 target_architecture
203 ),
204 },
205 }
206 }
207 target_lexicon::OperatingSystem::Linux => {
208 VmmTestsDepSelections::Linux
209 }
210 _ => unreachable!(),
211 },
212 }
213 } else {
214 VmmTestSelections::Flags(flags.unwrap_or_default())
215 },
216 unstable_whp,
217 release,
218 build_only,
219 copy_extras,
220 custom_kernel_modules,
221 custom_kernel,
222 done: ctx.new_done_handle(),
223 }
224 });
225
226 job.finish();
227
228 Ok(pipeline)
229 }
230}