From af89852fca056202aae57f58ffd097f8b9f8e314 Mon Sep 17 00:00:00 2001 From: John Starks Date: Sun, 26 Jul 2026 06:14:52 -0700 Subject: [PATCH 01/17] vmm_tests: add virtio-villain conformance test runner virtio-villain is a guest-side virtio fault-injection and conformance suite whose static musl init drives the virtio transports itself and feeds out-of-spec virtqueue inputs to the device model, printing a verdict per test on the serial console. This wires it into OpenVMM as an automated test suite so that malformed-descriptor handling and other virtio robustness bugs are caught by CI. The new virtio_villain_tests crate uses petri as a library plus libtest-mimic to expose one nextest case per villain test. Each case boots a single kitchen-sink OpenVMM VM with vv.test= on the kernel command line, waits for it to halt, and reads the verdict from the teed serial log. Villain's initramfs and tests.tsv are supplied via VILLAIN_INITRAMFS/VILLAIN_TSV (later resolved from an openvmm-deps release), and the guest kernel is reused from the existing linux-direct test artifact. Some malformed-descriptor tests send OpenVMM's virtio worker into a non-terminating loop that the VM cannot recover from or even tear down. Rather than paper over that product bug, per-test slow-timeout overrides in nextest terminate such a run and report it as a failure, and the tests known to trigger it are marked ignored so they are skipped in CI but remain runnable locally during fix development. To make results visible on the logview website, the runner writes the per-test petri.jsonl plus the petri.passed/failed markers the uploader counts, and honors TEST_OUTPUT_PATH so CI can publish all logs uniformly. The petri initrd-override and log-source seams are generalized so a caller can supply its own fully-formed initrd and obtain per-test log directories. A resolve_virtio_villain flowey node and a thin `xflowey virtio-villain-run` command download the artifact, build OpenVMM, stage the guest kernel, and run the suite; both stay inert until openvmm-deps cuts a release containing the artifact. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7b5df162-05ee-40d7-85c3-ce37b6783805 --- .config/nextest.toml | 18 ++ Cargo.lock | 25 ++ Cargo.toml | 1 + flowey/flowey_hvlite/src/pipelines/mod.rs | 6 + .../src/pipelines/virtio_villain_run.rs | 89 +++++++ .../src/_jobs/cfg_versions.rs | 7 + .../src/_jobs/local_run_virtio_villain.rs | 144 ++++++++++ flowey/flowey_lib_hvlite/src/_jobs/mod.rs | 1 + flowey/flowey_lib_hvlite/src/lib.rs | 1 + .../src/resolve_virtio_villain.rs | 196 ++++++++++++++ petri/src/tracing.rs | 45 ++-- petri/src/vm/openvmm/construct.rs | 14 +- vmm_tests/virtio_villain_tests/Cargo.toml | 41 +++ .../src/known_failures.rs | 76 ++++++ vmm_tests/virtio_villain_tests/src/lib.rs | 14 + vmm_tests/virtio_villain_tests/src/run.rs | 249 ++++++++++++++++++ vmm_tests/virtio_villain_tests/src/villain.rs | 212 +++++++++++++++ .../virtio_villain_tests/tests/villain.rs | 219 +++++++++++++++ 18 files changed, 1334 insertions(+), 24 deletions(-) create mode 100644 flowey/flowey_hvlite/src/pipelines/virtio_villain_run.rs create mode 100644 flowey/flowey_lib_hvlite/src/_jobs/local_run_virtio_villain.rs create mode 100644 flowey/flowey_lib_hvlite/src/resolve_virtio_villain.rs create mode 100644 vmm_tests/virtio_villain_tests/Cargo.toml create mode 100644 vmm_tests/virtio_villain_tests/src/known_failures.rs create mode 100644 vmm_tests/virtio_villain_tests/src/lib.rs create mode 100644 vmm_tests/virtio_villain_tests/src/run.rs create mode 100644 vmm_tests/virtio_villain_tests/src/villain.rs create mode 100644 vmm_tests/virtio_villain_tests/tests/villain.rs diff --git a/.config/nextest.toml b/.config/nextest.toml index ef238deecd..a8ef16d7af 100644 --- a/.config/nextest.toml +++ b/.config/nextest.toml @@ -23,6 +23,24 @@ # https://nexte.st/docs/configuration/per-test-overrides/#override-precedence # https://nexte.st/docs/configuration/?h=hierar#hierarchical-configuration +# virtio-villain tests each boot a dedicated VM that runs one fault-injection +# test and powers off. A test that never halts indicates a genuinely wedged +# guest or device model (e.g. a malformed-descriptor host hang that OpenVMM +# cannot recover from or even tear down) -- a real product bug. Terminate such +# a test so it is reported as a failure rather than hanging the run. Require +# two threads per test to bound concurrency and avoid vCPU starvation that +# would otherwise cause spurious slow boots. (The package name does not contain +# "vmm_tests", so the package(~vmm_tests) overrides below do not apply here.) +[[profile.default.overrides]] +filter = 'package(virtio_villain_tests)' +slow-timeout = { period = "20s", terminate-after = 3 } +threads-required = 2 + +[[profile.ci.overrides]] +filter = 'package(virtio_villain_tests)' +slow-timeout = { period = "20s", terminate-after = 3 } +threads-required = 2 + [[profile.ci.overrides]] # use fuzzy-matching for the package() to allow out-of-tree tests to use the # same profile diff --git a/Cargo.lock b/Cargo.lock index 5fa20ffc28..bb3a0c6fa4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9816,6 +9816,31 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "virtio_villain_tests" +version = "0.0.0" +dependencies = [ + "anyhow", + "clap", + "disk_backend_resources", + "fs-err", + "libtest-mimic", + "net_backend_resources", + "openvmm_defs", + "pal_async", + "petri", + "petri_artifact_resolver_openvmm_known_paths", + "petri_artifacts_common", + "petri_artifacts_core", + "petri_artifacts_vmm_test", + "serial_core", + "tempfile", + "tracing", + "unix_socket", + "virtio_resources", + "vm_resource", +] + [[package]] name = "virtio_vsock" version = "0.0.0" diff --git a/Cargo.toml b/Cargo.toml index 96fd973c8a..bdf336cebc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,7 @@ members = [ # VMM tests "vmm_tests/prep_steps", "vmm_tests/vmm_tests", + "vmm_tests/virtio_villain_tests", # Performance tests "petri/burette", # hyper-v tooling diff --git a/flowey/flowey_hvlite/src/pipelines/mod.rs b/flowey/flowey_hvlite/src/pipelines/mod.rs index 101f7adf9e..b86e9b8702 100644 --- a/flowey/flowey_hvlite/src/pipelines/mod.rs +++ b/flowey/flowey_hvlite/src/pipelines/mod.rs @@ -4,6 +4,7 @@ use cca_tests::CcaTestsCli; use flowey::pipeline::prelude::*; use restore_packages::RestorePackagesCli; +use virtio_villain_run::VirtioVillainRunCli; use vmm_tests_run::VmmTestsRunCli; pub mod build_docs; @@ -13,6 +14,7 @@ pub mod cca_tests; pub mod checkin_gates; pub mod custom_vmfirmwareigvm_dll; pub mod restore_packages; +pub mod virtio_villain_run; pub mod vmm_tests_run; #[derive(clap::Subcommand)] @@ -39,6 +41,9 @@ pub enum OpenvmmPipelines { /// Build and run VMM tests with automatic artifact discovery VmmTestsRun(VmmTestsRunCli), + /// Build and run the virtio-villain guest conformance tests against OpenVMM + VirtioVillainRun(VirtioVillainRunCli), + /// Build and run CCA tests with installation of emulation environment supported CcaTests(CcaTestsCli), } @@ -69,6 +74,7 @@ impl IntoPipeline for OpenvmmPipelines { }, OpenvmmPipelines::RestorePackages(cmd) => cmd.into_pipeline(pipeline_hint), OpenvmmPipelines::VmmTestsRun(cmd) => cmd.into_pipeline(pipeline_hint), + OpenvmmPipelines::VirtioVillainRun(cmd) => cmd.into_pipeline(pipeline_hint), OpenvmmPipelines::CcaTests(cmd) => cmd.into_pipeline(pipeline_hint), } } diff --git a/flowey/flowey_hvlite/src/pipelines/virtio_villain_run.rs b/flowey/flowey_hvlite/src/pipelines/virtio_villain_run.rs new file mode 100644 index 0000000000..b1313c008e --- /dev/null +++ b/flowey/flowey_hvlite/src/pipelines/virtio_villain_run.rs @@ -0,0 +1,89 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +//! Build OpenVMM and run the virtio-villain guest conformance / fault-injection +//! test suite against it. +//! +//! virtio-villain ships as a versioned artifact from the `openvmm-deps` GitHub +//! release. This pipeline downloads that artifact, builds OpenVMM, stages the +//! guest test kernel, and runs the `virtio_villain_tests` nextest suite. +//! +//! Note: this is inert until `openvmm-deps` cuts a release that includes the +//! virtio-villain artifact (and `cfg_versions::OPENVMM_DEPS` is bumped to it). + +use flowey::node::prelude::ReadVar; +use flowey::pipeline::prelude::*; +use flowey_lib_hvlite::common::CommonArch; + +/// Build and run the virtio-villain test suite against OpenVMM. +#[derive(clap::Args)] +pub struct VirtioVillainRunCli { + /// Also run known-failing (ignored) villain tests. These are skipped by + /// default because they exercise OpenVMM bugs (some wedge the VM); enable + /// this during fix development. + #[clap(long)] + pub run_ignored: bool, + + /// Verbose pipeline output. + #[clap(long)] + pub verbose: bool, +} + +impl IntoPipeline for VirtioVillainRunCli { + fn into_pipeline(self, backend_hint: PipelineBackendHint) -> anyhow::Result { + let Self { + run_ignored, + verbose, + } = self; + + // Phase 1 is Linux-only (villain drives OpenVMM under KVM). + let arch = match ( + FlowArch::host(backend_hint), + FlowPlatform::host(backend_hint), + ) { + (FlowArch::X86_64, FlowPlatform::Linux(_)) => CommonArch::X86_64, + (FlowArch::Aarch64, FlowPlatform::Linux(_)) => CommonArch::Aarch64, + _ => anyhow::bail!("virtio-villain tests currently require a Linux host"), + }; + + let openvmm_repo = flowey_lib_common::git_checkout::RepoSource::ExistingClone( + ReadVar::from_static(crate::repo_root()), + ); + + let mut pipeline = Pipeline::new(); + + pipeline + .new_job( + FlowPlatform::host(backend_hint), + FlowArch::host(backend_hint), + "virtio-villain: run tests", + ) + .dep_on(|_| flowey_lib_hvlite::_jobs::cfg_versions::Request::Init) + .dep_on( + |_| flowey_lib_hvlite::_jobs::cfg_hvlite_reposource::Params { + hvlite_repo_source: openvmm_repo.clone(), + }, + ) + .dep_on(|_| flowey_lib_hvlite::_jobs::cfg_common::Params { + local_only: Some(flowey_lib_hvlite::_jobs::cfg_common::LocalOnlyParams { + interactive: true, + auto_install: true, + ignore_rust_version: true, + }), + verbose: ReadVar::from_static(verbose), + locked: false, + deny_warnings: false, + no_incremental: false, + }) + .dep_on( + |ctx| flowey_lib_hvlite::_jobs::local_run_virtio_villain::Params { + arch, + run_ignored, + done: ctx.new_done_handle(), + }, + ) + .finish(); + + Ok(pipeline) + } +} diff --git a/flowey/flowey_lib_hvlite/src/_jobs/cfg_versions.rs b/flowey/flowey_lib_hvlite/src/_jobs/cfg_versions.rs index 4602ba5fe4..f4f99bd4df 100644 --- a/flowey/flowey_lib_hvlite/src/_jobs/cfg_versions.rs +++ b/flowey/flowey_lib_hvlite/src/_jobs/cfg_versions.rs @@ -64,6 +64,7 @@ impl FlowNode for Node { ctx.import::(); ctx.import::(); ctx.import::(); + ctx.import::(); ctx.import::(); ctx.import::(); ctx.import::(); @@ -223,6 +224,12 @@ impl FlowNode for Node { version: Some(OPENVMM_DEPS.into()), ..Default::default() }); + // Inert until openvmm-deps cuts a release that includes the + // virtio-villain artifact; the resolve node only downloads on demand. + ctx.config(crate::resolve_virtio_villain::Config { + version: Some(OPENVMM_DEPS.into()), + ..Default::default() + }); ctx.config(crate::resolve_openvmm_qemu::Config { version: Some(OPENVMM_DEPS.into()), ..Default::default() diff --git a/flowey/flowey_lib_hvlite/src/_jobs/local_run_virtio_villain.rs b/flowey/flowey_lib_hvlite/src/_jobs/local_run_virtio_villain.rs new file mode 100644 index 0000000000..439c0ec632 --- /dev/null +++ b/flowey/flowey_lib_hvlite/src/_jobs/local_run_virtio_villain.rs @@ -0,0 +1,144 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +//! Local job: build OpenVMM, stage the openvmm-deps guest kernel, resolve the +//! virtio-villain artifact, and run the `virtio_villain_tests` nextest suite +//! against OpenVMM. +//! +//! This is the "thin sibling" of the full `vmm_tests` local runner: the villain +//! crate resolves everything else it needs (the guest Linux kernel, the OpenVMM +//! binary) from the known-paths magicpath / target dir, so all this job has to +//! do is make those two things exist and hand the crate its guest artifact via +//! the `VILLAIN_INITRAMFS` / `VILLAIN_TSV` env vars. +//! +//! Known-failing villain tests are marked *ignored* by the harness, so they are +//! skipped by default. Pass `run_ignored` to run them too (e.g. during fix +//! development). + +use crate::common::CommonArch; +use crate::common::CommonProfile; +use crate::common::CommonTriple; +use crate::run_cargo_nextest_run::NextestProfile; +use flowey::node::prelude::*; +use flowey_lib_common::run_cargo_build::CargoBuildProfile; +use flowey_lib_common::run_cargo_nextest_run::NextestRunKind; +use flowey_lib_common::run_cargo_nextest_run::build_params::NextestBuildParams; +use flowey_lib_common::run_cargo_nextest_run::build_params::TestPackages; +use std::collections::BTreeMap; + +flowey_request! { + pub struct Params { + /// Guest/host architecture to test. Phase 1 is Linux-only (KVM). + pub arch: CommonArch, + /// Also run known-failing (ignored) villain tests. + pub run_ignored: bool, + pub done: WriteVar, + } +} + +new_simple_flow_node!(struct Node); + +impl SimpleFlowNode for Node { + type Request = Params; + + fn imports(ctx: &mut ImportCtx<'_>) { + ctx.import::(); + ctx.import::(); + ctx.import::(); + ctx.import::(); + ctx.import::(); + } + + fn process_request(request: Self::Request, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> { + let Params { + arch, + run_ignored, + done, + } = request; + + // Phase 1: Linux host only (villain drives OpenVMM under KVM). + let target = match arch { + CommonArch::X86_64 => CommonTriple::X86_64_LINUX_GNU, + CommonArch::Aarch64 => CommonTriple::AARCH64_LINUX_GNU, + }; + + // Build the OpenVMM binary the villain crate launches. Building it for + // the same target triple that nextest uses lands it next to the test + // binary, where the known-paths resolver looks for it. + let openvmm_built = ctx + .reqv(|v| crate::build_openvmm::Request { + params: crate::build_openvmm::OpenvmmBuildParams { + target: target.clone(), + profile: CommonProfile::Debug, + features: Default::default(), + }, + version: None, + openvmm: v, + }) + .into_side_effect(); + + // Stage the openvmm-deps guest Linux kernel (and shared deps) into the + // magicpath, so the villain crate's linux-direct firmware resolves. + let magicpath_done = + ctx.reqv(|done| crate::init_openvmm_magicpath_openvmm_deps::Request { arch, done }); + + // Resolve the virtio-villain guest artifact (initramfs + tests.tsv). + let villain = ctx.reqv(|v| crate::resolve_virtio_villain::Request::Get(arch, v)); + + // Hand the two villain files to the crate via env vars. + let run_env = villain.map(ctx, |a| { + BTreeMap::from([ + ( + "VILLAIN_INITRAMFS".to_string(), + a.initramfs.display().to_string(), + ), + ("VILLAIN_TSV".to_string(), a.tsv.display().to_string()), + ]) + }); + + // Build env for the test binary compilation (native, so effectively a + // no-op, but keeps cross-build parity with the vmm_tests runner). + let build_env = ctx.reqv(|v| crate::init_cross_build::Request { + target: target.as_triple(), + injected_env: v, + }); + + let build_params = NextestBuildParams { + packages: ReadVar::from_static(TestPackages::Crates { + crates: vec!["virtio_villain_tests".into()], + }), + features: Default::default(), + no_default_features: false, + target: target.as_triple(), + profile: CargoBuildProfile::Debug, + extra_env: build_env, + }; + + let results = ctx.reqv(|results| crate::run_cargo_nextest_run::Request { + friendly_name: "virtio_villain_tests".into(), + run_kind: NextestRunKind::BuildAndRun(build_params), + nextest_profile: NextestProfile::Default, + nextest_filter_expr: None, + nextest_working_dir: None, + nextest_config_file: None, + run_ignored, + extra_env: Some(run_env), + pre_run_deps: vec![openvmm_built, magicpath_done], + results, + }); + + ctx.emit_rust_step("report virtio-villain test results", |ctx| { + done.claim(ctx); + let results = results.claim(ctx); + move |rt| { + let results = rt.read(results); + if !results.all_tests_passed { + anyhow::bail!("virtio-villain tests failed"); + } + Ok(()) + } + }); + + Ok(()) + } +} diff --git a/flowey/flowey_lib_hvlite/src/_jobs/mod.rs b/flowey/flowey_lib_hvlite/src/_jobs/mod.rs index be79bee33d..13b903bbaf 100644 --- a/flowey/flowey_lib_hvlite/src/_jobs/mod.rs +++ b/flowey/flowey_lib_hvlite/src/_jobs/mod.rs @@ -29,6 +29,7 @@ pub mod local_custom_vmfirmwareigvm_dll; pub mod local_install_cca_emu; pub mod local_restore_packages; pub mod local_run_cca_test; +pub mod local_run_virtio_villain; pub mod local_update_cca_emu; pub mod publish_vmgstool_gh_release; pub mod test_local_flowey_build_igvm; diff --git a/flowey/flowey_lib_hvlite/src/lib.rs b/flowey/flowey_lib_hvlite/src/lib.rs index b9d4afa76f..18487a3905 100644 --- a/flowey/flowey_lib_hvlite/src/lib.rs +++ b/flowey/flowey_lib_hvlite/src/lib.rs @@ -59,6 +59,7 @@ pub mod resolve_openvmm_qemu; pub mod resolve_openvmm_test_initrd; pub mod resolve_openvmm_test_linux_kernel; pub mod resolve_openvmm_test_virtio_win; +pub mod resolve_virtio_villain; pub mod run_cargo_build; pub mod run_cargo_nextest_run; pub mod run_igvmfilegen; diff --git a/flowey/flowey_lib_hvlite/src/resolve_virtio_villain.rs b/flowey/flowey_lib_hvlite/src/resolve_virtio_villain.rs new file mode 100644 index 0000000000..76f2aa377d --- /dev/null +++ b/flowey/flowey_lib_hvlite/src/resolve_virtio_villain.rs @@ -0,0 +1,196 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +//! Download the virtio-villain guest test artifact from the `openvmm-deps` +//! GitHub release, or use a local directory if specified. +//! +//! virtio-villain ships as its own versioned artifact +//! (`openvmm-test-virtio-villain...tar.gz`) containing the guest +//! `initramfs.cpio.gz` (a static musl `init` that drives the virtio fault +//! injection) and `tests.tsv` (the enumerated test list). The +//! `virtio_villain_tests` crate consumes these two files via the +//! `VILLAIN_INITRAMFS` / `VILLAIN_TSV` env vars. +//! +//! This node is inert until `openvmm-deps` cuts a release that includes the +//! virtio-villain artifact (and [`crate::_jobs::cfg_versions::OPENVMM_DEPS`] is +//! bumped to it). Until then, use a local path override. + +use crate::common::CommonArch; +use flowey::node::prelude::*; +use std::collections::BTreeMap; +use std::collections::BTreeSet; + +/// Resolved paths to the two files that make up the virtio-villain artifact. +#[derive(Clone, Serialize, Deserialize)] +pub struct VirtioVillainArtifact { + /// Path to `initramfs.cpio.gz`. + pub initramfs: PathBuf, + /// Path to `tests.tsv`. + pub tsv: PathBuf, +} + +flowey_config! { + /// Config for the resolve_virtio_villain node. + pub struct Config { + /// Specify version of the github release to pull from. + pub version: Option, + /// Use a locally-downloaded virtio-villain artifact directory (which + /// must contain `initramfs.cpio.gz` and `tests.tsv`), keyed by + /// architecture. + pub local_paths: BTreeMap>, + } +} + +flowey_request! { + pub enum Request { + /// Get the resolved virtio-villain artifact for a given architecture. + Get(CommonArch, WriteVar), + } +} + +new_flow_node_with_config!(struct Node); + +impl FlowNodeWithConfig for Node { + type Request = Request; + type Config = Config; + + fn imports(ctx: &mut ImportCtx<'_>) { + ctx.import::(); + ctx.import::(); + } + + fn emit( + config: Config, + requests: Vec, + ctx: &mut NodeCtx<'_>, + ) -> anyhow::Result<()> { + let Config { + version, + local_paths, + } = config; + let mut deps: BTreeMap>> = BTreeMap::new(); + + for req in requests { + match req { + Request::Get(arch, var) => { + deps.entry(arch).or_default().push(var); + } + } + } + + if version.is_some() && !local_paths.is_empty() { + anyhow::bail!("Cannot specify both Version and LocalPath requests"); + } + + if version.is_none() && local_paths.is_empty() { + anyhow::bail!("Must specify a Version or LocalPath request"); + } + + // -- end of req processing -- // + + if deps.is_empty() { + return Ok(()); + } + + if !local_paths.is_empty() { + ctx.emit_rust_step("use local virtio-villain artifact", |ctx| { + let deps = deps.claim(ctx); + let local_paths: BTreeMap<_, _> = local_paths + .into_iter() + .map(|(key, var)| (key, var.claim(ctx))) + .collect(); + move |rt| { + let resolved_paths: BTreeMap = local_paths + .into_iter() + .map(|(key, var)| (key, rt.read(var))) + .collect(); + + for (arch, vars) in deps { + let base_dir = resolved_paths.get(&arch).ok_or_else(|| { + anyhow::anyhow!("No local path specified for {:?}", arch) + })?; + let artifact = resolve_from_dir(base_dir)?; + rt.write_all(vars, &artifact) + } + + Ok(()) + } + }); + + return Ok(()); + } + + // The openvmm-test-virtio-villain...tar.gz archive contains + // `initramfs.cpio.gz` and `tests.tsv` at the archive root. Download one + // archive per requested architecture. + let needed_archives: BTreeSet = deps.keys().copied().collect(); + + let mut archives = BTreeMap::new(); + for arch in needed_archives { + let version = version.clone().expect("local requests handled above"); + let arch_str = match arch { + CommonArch::X86_64 => "x86_64", + CommonArch::Aarch64 => "aarch64", + }; + let archive = ctx.reqv(|v| flowey_lib_common::download_gh_release::Request { + repo_owner: "microsoft".into(), + repo_name: "openvmm-deps".into(), + needs_auth: false, + tag: version.clone(), + file_name: format!("openvmm-test-virtio-villain.{arch_str}.{version}.tar.gz"), + path: v, + }); + archives.insert(arch, archive); + } + + let persistent_dir = ctx.persistent_dir(); + + ctx.emit_rust_step("unpack virtio-villain artifacts", |ctx| { + let persistent_dir = persistent_dir.claim(ctx); + let archives = archives.claim(ctx); + let deps = deps.claim(ctx); + let version = version.clone().expect("local requests handled above"); + move |rt| { + let persistent_dir = persistent_dir.map(|d| rt.read(d)); + + let mut extract_dirs = BTreeMap::new(); + for (arch, archive) in archives { + let file = rt.read(archive); + let dir = flowey_lib_common::_util::extract::extract_tar_gz_if_new( + rt, + persistent_dir.as_deref(), + &file, + &version, + )?; + extract_dirs.insert(arch, dir); + } + + for (arch, vars) in deps { + let artifact = resolve_from_dir(&extract_dirs[&arch])?; + rt.write_all(vars, &artifact) + } + + Ok(()) + } + }); + + Ok(()) + } +} + +/// Resolve the two virtio-villain files from a directory, erroring if either is +/// missing. +fn resolve_from_dir(dir: &Path) -> anyhow::Result { + let initramfs = dir.join("initramfs.cpio.gz"); + let tsv = dir.join("tests.tsv"); + if !initramfs.exists() { + anyhow::bail!( + "virtio-villain initramfs.cpio.gz not found in {}", + dir.display() + ); + } + if !tsv.exists() { + anyhow::bail!("virtio-villain tests.tsv not found in {}", dir.display()); + } + Ok(VirtioVillainArtifact { initramfs, tsv }) +} diff --git a/petri/src/tracing.rs b/petri/src/tracing.rs index a565fdb5dc..836a3f0035 100644 --- a/petri/src/tracing.rs +++ b/petri/src/tracing.rs @@ -286,14 +286,35 @@ macro_rules! log { }; } -/// Initialize Petri tracing with the given output path for log files. +/// Creates a [`PetriLogSource`] rooted at `root_path` **without** installing a +/// global tracing subscriber. /// -/// Events go to three places: -/// - `petri.jsonl`, in newline-separated JSON format. -/// - standard output, in human readable format. -/// - a log file, in human readable format. This file is `petri.log`, except -/// for events whose target ends in `.log`, which go to separate files named by -/// the target. +/// Use this to obtain an additional, independently-rooted log source (for +/// example, a per-test directory so each VM's serial console lands in its own +/// `linux.log`) after the global subscriber has already been installed once via +/// [`try_init_tracing`]. This is required by standalone multi-test binaries +/// (e.g. the villain runner) that generate many trials in a single process: +/// [`try_init_tracing`] can only install the global subscriber once, so +/// per-test log isolation relies on constructing per-test log sources here. +pub fn new_log_source(root_path: &Path) -> anyhow::Result { + // Canonicalize so that printed attachment paths are most likely to work. + let root_path = root_path.fs_err_canonicalize()?; + let jsonl = File::create(root_path.join("petri.jsonl"))?; + let logger = PetriLogSource(Arc::new(LogSourceInner { + json_log: JsonLog(Arc::new(jsonl)), + root_path, + log_files: Default::default(), + attachments: Default::default(), + })); + Ok(logger) +} + +/// Initializes the global tracing subscriber and returns a [`PetriLogSource`] +/// rooted at `root_path`. +/// +/// This installs the process-wide tracing subscriber and may only be called +/// once per process; use [`new_log_source`] to obtain additional log sources +/// rooted at other directories afterwards. pub fn try_init_tracing( root_path: &Path, default_level: LevelFilter, @@ -305,15 +326,7 @@ pub fn try_init_tracing( Targets::new().with_default(default_level) }; - // Canonicalize so that printed attachment paths are most likely to work. - let root_path = root_path.fs_err_canonicalize()?; - let jsonl = File::create(root_path.join("petri.jsonl"))?; - let logger = PetriLogSource(Arc::new(LogSourceInner { - json_log: JsonLog(Arc::new(jsonl)), - root_path, - log_files: Default::default(), - attachments: Default::default(), - })); + let logger = new_log_source(root_path)?; let petri_log = logger.log_file("petri")?; diff --git a/petri/src/vm/openvmm/construct.rs b/petri/src/vm/openvmm/construct.rs index 67c37d84ee..01ec302fe1 100644 --- a/petri/src/vm/openvmm/construct.rs +++ b/petri/src/vm/openvmm/construct.rs @@ -172,15 +172,13 @@ impl PetriVmConfigOpenVmm { let mut load_mode = setup.load_firmware()?; - // If using pipette-as-init, replace the initrd with the pre-built - // one that has pipette injected. run_core() guarantees that - // prebuilt_initrd is set when uses_pipette_as_init is true. - if properties.uses_pipette_as_init { + // If a prebuilt initrd was provided, use it in place of the initrd + // produced by `load_firmware()`. This covers both the pipette-as-init + // path (run_core() injects pipette into a prebuilt initrd) and callers + // that supply their own fully-formed initrd (e.g. the virtio-villain + // runner, whose initramfs is its own PID-1 `init`). + if let Some(prebuilt) = properties.prebuilt_initrd.as_ref() { if let LoadMode::Linux { initrd, .. } = &mut load_mode { - let prebuilt = properties - .prebuilt_initrd - .as_ref() - .expect("uses_pipette_as_init requires prebuilt_initrd"); let file = std::fs::File::open(prebuilt).with_context(|| { format!("failed to open prebuilt initrd at {}", prebuilt.display()) })?; diff --git a/vmm_tests/virtio_villain_tests/Cargo.toml b/vmm_tests/virtio_villain_tests/Cargo.toml new file mode 100644 index 0000000000..31f58a80e7 --- /dev/null +++ b/vmm_tests/virtio_villain_tests/Cargo.toml @@ -0,0 +1,41 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +[package] +name = "virtio_villain_tests" +edition.workspace = true +rust-version.workspace = true + +[[test]] +name = "villain" +# Custom libtest-mimic harness: one trial is generated per villain test, so +# `cargo nextest run -p virtio_villain_tests` discovers and runs each villain +# test in its own process. Requires the villain image/TSV (see tests/villain.rs). +harness = false + +[dependencies] +petri.workspace = true +petri_artifacts_common.workspace = true +petri_artifacts_core.workspace = true +petri_artifacts_vmm_test.workspace = true +petri_artifact_resolver_openvmm_known_paths.workspace = true +openvmm_defs.workspace = true +virtio_resources.workspace = true +disk_backend_resources.workspace = true +net_backend_resources.workspace = true +serial_core.workspace = true +vm_resource.workspace = true +pal_async.workspace = true + +anyhow.workspace = true +clap = { workspace = true, features = ["derive"] } +fs-err.workspace = true +libtest-mimic.workspace = true +tempfile.workspace = true +tracing.workspace = true + +[target.'cfg(unix)'.dependencies] +unix_socket.workspace = true + +[lints] +workspace = true diff --git a/vmm_tests/virtio_villain_tests/src/known_failures.rs b/vmm_tests/virtio_villain_tests/src/known_failures.rs new file mode 100644 index 0000000000..a6d3129d62 --- /dev/null +++ b/vmm_tests/virtio_villain_tests/src/known_failures.rs @@ -0,0 +1,76 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +//! OpenVMM-specific list of villain tests that are **known to fail** and are +//! therefore marked *ignored* in the libtest-mimic harness. +//! +//! This list lives here (in the OpenVMM tree), not upstream in villain, +//! because it describes OpenVMM device-model bugs, not villain bugs. +//! +//! Ignored tests behave like libtest `#[ignore]` tests: +//! - They are **skipped by default**, so CI (which runs with the default +//! `run-ignored` setting) does not run them. This keeps the gate green +//! against known product bugs and, importantly, avoids paying the per-test +//! timeout for cases that wedge OpenVMM (see below). +//! - They can still be run locally during fix development with +//! `cargo nextest run -p virtio_villain_tests --run-ignored all` +//! (or `--run-ignored ignored-only` to run *only* the known failures). +//! +//! Why ignore rather than invert (XFAIL)? Several of these are unrecoverable +//! host hangs: OpenVMM's virtio worker spins on a malformed descriptor chain +//! and the VM never powers off (and cannot even be torn down). Such a test can +//! only be ended by the external nextest timeout, so it can never reach an +//! in-harness "expected failure" inversion. Skipping is both correct and much +//! cheaper. +//! +//! When a bug is fixed, remove its entry here; the test then runs (and gates) +//! in CI again. Each entry should link to a filed OpenVMM issue. + +/// A villain test that OpenVMM is known to fail, and that we therefore skip by +/// default (mark ignored). +pub struct KnownFailure { + /// The villain test name (matches `tests.tsv` column 1 / `vv.test=`). + pub name: &'static str, + /// Human-readable reason, ideally referencing a tracking issue, e.g. + /// `"virtio-blk unbounded descriptor walk (microsoft/openvmm#NNNN)"`. + pub reason: &'static str, +} + +/// The known-failure list. Keep sorted by name. +/// +/// The initial entries are the virtio-blk (device 0x1042) malformed-descriptor +/// cases confirmed to send OpenVMM's virtio worker into a non-terminating loop +/// (an unrecoverable, guest-triggerable host hang). Issues still need to be +/// filed; update the `reason` with the issue link once they are. +pub const KNOWN_FAILURES: &[KnownFailure] = &[ + KnownFailure { + name: "B0002", + reason: "virtio-blk sector*512+data_len 64-bit wrap wedges the device \ + (microsoft/openvmm#TODO)", + }, + KnownFailure { + name: "P0003", + reason: "virtio-blk packed descriptor list exceeding queue size wedges \ + the device (microsoft/openvmm#TODO)", + }, + KnownFailure { + name: "T0001", + reason: "virtio-blk self-looping descriptor chain hangs the virtio \ + worker unrecoverably (microsoft/openvmm#TODO)", + }, + KnownFailure { + name: "T0002", + reason: "virtio-blk descriptor chain exceeding queue size hangs the \ + virtio worker unrecoverably (microsoft/openvmm#TODO)", + }, + KnownFailure { + name: "T0003", + reason: "virtio-blk out-of-bounds descriptor `next` index hangs the \ + virtio worker unrecoverably (microsoft/openvmm#TODO)", + }, +]; + +/// Look up the known-failure entry for `name`, if present. +pub fn lookup(name: &str) -> Option<&'static KnownFailure> { + KNOWN_FAILURES.iter().find(|e| e.name == name) +} diff --git a/vmm_tests/virtio_villain_tests/src/lib.rs b/vmm_tests/virtio_villain_tests/src/lib.rs new file mode 100644 index 0000000000..cf65b3785d --- /dev/null +++ b/vmm_tests/virtio_villain_tests/src/lib.rs @@ -0,0 +1,14 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +//! Library half of the virtio-villain OpenVMM test runner: villain test +//! enumeration, serial verdict parsing, the OpenVMM known-failure list, and the +//! per-test VM driver. +//! +//! The nextest harness entrypoint lives in the `tests/villain.rs` +//! `harness = false` `[[test]]` target, which enumerates the villain +//! `tests.tsv` into one libtest-mimic trial per test. + +pub mod known_failures; +pub mod run; +pub mod villain; diff --git a/vmm_tests/virtio_villain_tests/src/run.rs b/vmm_tests/virtio_villain_tests/src/run.rs new file mode 100644 index 0000000000..19ed98eca4 --- /dev/null +++ b/vmm_tests/virtio_villain_tests/src/run.rs @@ -0,0 +1,249 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +//! Runs a single villain test in one OpenVMM VM and reads its serial verdict. + +use crate::villain::VerdictScan; +use crate::villain::scan_verdict; +use anyhow::Context as _; +use petri_artifacts_common::tags::MachineArch; +use std::path::PathBuf; + +/// Guest kernel initcalls to blacklist so the in-guest virtio drivers don't +/// claim the devices villain wants to drive itself. Mirrors villain's own +/// runner (`run`, `skip_initcalls`). +const INITCALL_BLACKLIST: &str = concat!( + "virtio_blk_init,", + "virtio_net_driver_init,", + "virtio_console_init,", + "virtio_balloon_driver_init,", + "virtio_rng_driver_init,", + "virtio_mem_driver_init,", + "virtio_pmem_driver_init,", + "virtio_iommu_drv_init,", + "virtio_fs_init,", + "virtio_vsock_init,", + "virtio_rtc_drv_init,", + "virtio_watchdog_driver_init,", + "virtio_input_driver_init,", + "ext4_init_fs,", + "fuse_init,", + "audit_init,", + "cpufreq_core_init", +); + +/// Static, per-run VM parameters shared by every villain test. +#[derive(Clone)] +pub struct VmParams { + /// Path to villain's `initramfs.cpio.gz` (bare PID-1 `init`). + pub initramfs: PathBuf, + /// Guest architecture (host arch for Phase 1). + pub arch: MachineArch, + /// Guest RAM in bytes. + pub mem_bytes: u64, +} + +/// Boot one VM for `test_name`, wait for it to halt, and scan the serial +/// console log for the verdict marker. +/// +/// `log_source` must be rooted at this test's own directory so that its +/// `linux.log` (the teed serial0 console) is isolated from other tests. +pub fn run_one( + params: &VmParams, + artifacts: &petri::TestArtifacts, + log_source: &petri::PetriLogSource, + test_name: &str, +) -> anyhow::Result { + // Backing resources for the kitchen-sink devices. These must live until + // after the VM tears down, so they are owned here and only their paths + // are moved into the config closure. + let pmem_file = tempfile::NamedTempFile::new().context("failed to create pmem backing file")?; + pmem_file + .as_file() + .set_len(128 * 1024 * 1024) + .context("failed to size pmem backing file")?; + let pmem_path = pmem_file.path().to_string_lossy().into_owned(); + + let fs_dir = tempfile::tempdir().context("failed to create virtio-fs root")?; + let fs_path = fs_dir.path().to_string_lossy().into_owned(); + + #[cfg(unix)] + let vsock_dir = tempfile::tempdir().context("failed to create vsock dir")?; + #[cfg(unix)] + let vsock_socket = vsock_dir.path().join("vsock"); + + let arch = params.arch; + let console = match arch { + MachineArch::X86_64 => "ttyS0", + MachineArch::Aarch64 => "ttyAMA0", + }; + let cmdline = + format!("console={console} initcall_blacklist={INITCALL_BLACKLIST} vv.test={test_name}"); + + let initramfs = params.initramfs.clone(); + let mem_bytes = params.mem_bytes; + + let log_path = log_source.output_dir().join("linux.log"); + + pal_async::DefaultPool::run_with(async |driver| -> anyhow::Result<()> { + let mut post_test_hooks = Vec::new(); + let petri_params = petri::PetriTestParams { + test_name, + logger: log_source, + post_test_hooks: &mut post_test_hooks, + }; + + let resolver = petri::ArtifactResolver::resolver(artifacts); + let firmware = petri::Firmware::linux_direct(&resolver, arch); + let vm_artifacts = petri::PetriVmArtifacts::::new( + &resolver, firmware, arch, false, + ) + .context("firmware/arch not compatible with OpenVMM backend")?; + + let builder = petri::PetriVmBuilder::minimal(petri_params, vm_artifacts, &driver)? + .with_serial_output() + .with_processor_topology(petri::ProcessorTopology { + vp_count: 1, + ..Default::default() + }) + .with_memory(petri::MemoryConfig { + startup_bytes: mem_bytes, + ..Default::default() + }) + .with_prebuilt_initrd(initramfs) + .modify_backend(move |b| { + attach_kitchen_sink( + b, + cmdline, + pmem_path, + fs_path, + #[cfg(unix)] + vsock_socket, + ) + }); + + let mut vm = builder + .run_without_agent() + .await + .context("failed to boot villain VM")?; + + // Villain runs the selected test, prints `[TAG] `, then powers + // off (reboot(RB_POWER_OFF)). Wait for that halt. + // + // A genuinely wedged device model (e.g. a malformed descriptor chain + // that sends OpenVMM's virtio worker into a non-terminating loop) will + // never power off and cannot even be torn down. We deliberately do NOT + // paper over that here: the nextest per-test `slow-timeout` + // (.config/nextest.toml) terminates such a test and reports it as a + // failure, which is the correct outcome for a real product bug. + let halt = vm + .wait_for_halt() + .await + .context("villain VM did not halt")?; + tracing::info!(?halt, "villain VM halted"); + vm.teardown().await.context("failed to tear down VM")?; + Ok(()) + })?; + + let log = fs_err::read_to_string(&log_path) + .with_context(|| format!("failed to read serial log {}", log_path.display()))?; + + // Keep backing resources alive until here. + drop(pmem_file); + drop(fs_dir); + #[cfg(unix)] + drop(vsock_dir); + + Ok(scan_verdict(&log, test_name)) +} + +/// Attach every virtio device villain can probe, plus the required cmdline. +/// Devices OpenVMM does not model are simply omitted; villain self-SKIPs them. +fn attach_kitchen_sink( + b: petri::openvmm::PetriVmConfigOpenVmm, + cmdline: String, + pmem_path: String, + fs_path: String, + #[cfg(unix)] vsock_socket: PathBuf, +) -> petri::openvmm::PetriVmConfigOpenVmm { + use openvmm_defs::config::LoadMode; + use openvmm_defs::config::PcieDeviceConfig; + use vm_resource::IntoResource; + use vm_resource::Resource; + use vm_resource::kind::VirtioDeviceHandle; + + // Collect every virtio device villain can probe as an inner + // `Resource`. Each is later wrapped in a + // `VirtioPciDeviceHandle` and attached to its own PCIe root port. Devices + // OpenVMM does not model are simply omitted; villain self-SKIPs them. + let mut inner: Vec> = vec![ + // rng + virtio_resources::rng::VirtioRngHandle.into_resource(), + // block (RAM-backed, writable) + virtio_resources::blk::VirtioBlkHandle { + disk: disk_backend_resources::LayeredDiskHandle::single_layer( + disk_backend_resources::layer::RamDiskLayerHandle { + len: Some(64 * 1024 * 1024), + sector_size: None, + }, + ) + .into_resource(), + read_only: false, + } + .into_resource(), + // console (serial backend goes nowhere) + virtio_resources::console::VirtioConsoleHandle { + backend: serial_core::resources::DisconnectedSerialBackendHandle.into_resource(), + } + .into_resource(), + // net (null endpoint: drops tx, never rx) + virtio_resources::net::VirtioNetHandle { + max_queues: None, + mac_address: net_backend_resources::mac_address::MacAddress::new([ + 0x00, 0x15, 0x5d, 0x00, 0x00, 0x01, + ]), + endpoint: net_backend_resources::null::NullHandle.into_resource(), + } + .into_resource(), + // virtio-fs (built-in HostFs backend, no external virtiofsd) + virtio_resources::fs::VirtioFsHandle { + tag: "villainfs".into(), + fs: virtio_resources::fs::VirtioFsBackend::HostFs { + root_path: fs_path, + mount_options: String::new(), + }, + } + .into_resource(), + // pmem (file-backed) + virtio_resources::pmem::VirtioPmemHandle { path: pmem_path }.into_resource(), + ]; + + // vsock (unix only: needs a bound listener) + #[cfg(unix)] + if let Ok(listener) = unix_socket::UnixListener::bind(&vsock_socket) { + inner.push( + virtio_resources::vsock::VirtioVsockHandle { + guest_cid: 3, + base_path: vsock_socket.to_string_lossy().into_owned(), + listener, + } + .into_resource(), + ); + } + + // One PCIe root port per device (segment 0, root complex 0). + b.with_pcie_root_topology(1, 1, inner.len() as u64) + .with_custom_config(move |c| { + // Replace the kernel command line wholesale. + if let LoadMode::Linux { cmdline: cl, .. } = &mut c.load_mode { + *cl = cmdline; + } + + for (i, handle) in inner.into_iter().enumerate() { + c.pcie_devices.push(PcieDeviceConfig { + port_name: format!("s0rc0rp{i}"), + resource: virtio_resources::VirtioPciDeviceHandle(handle).into_resource(), + }); + } + }) +} diff --git a/vmm_tests/virtio_villain_tests/src/villain.rs b/vmm_tests/virtio_villain_tests/src/villain.rs new file mode 100644 index 0000000000..13eaa8f2f7 --- /dev/null +++ b/vmm_tests/virtio_villain_tests/src/villain.rs @@ -0,0 +1,212 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +//! Enumeration of virtio-villain tests and parsing of their serial verdicts. + +use anyhow::Context as _; +use std::path::Path; + +/// A single villain test, as described by one row of `tests.tsv`. +/// +/// `tests.tsv` is emitted by `init --list-tsv` (see villain `bin/init.c`) with +/// one tab-separated row per test and no header: +/// +/// ```text +/// name desc version spec_section device_id flags required_features min_queues +/// ``` +#[derive(Debug, Clone)] +pub struct VillainTest { + /// Test identifier, passed to the guest via `vv.test=` and matched + /// against the serial verdict marker. + pub name: String, + /// Human-readable description. + pub desc: String, + /// virtio device id the test targets (e.g. `0x0002` for block). + pub device_id: u16, +} + +/// Parse `tests.tsv` into the list of villain tests. +pub fn parse_tsv(path: &Path) -> anyhow::Result> { + let text = fs_err::read_to_string(path)?; + let mut tests = Vec::new(); + for (lineno, line) in text.lines().enumerate() { + let line = line.trim_end_matches('\r'); + if line.is_empty() { + continue; + } + let mut cols = line.split('\t'); + let name = cols + .next() + .filter(|s| !s.is_empty()) + .with_context(|| format!("{}:{}: missing test name", path.display(), lineno + 1))?; + let desc = cols.next().unwrap_or_default(); + // Columns: version, spec_section, device_id, flags, required_features, min_queues. + let _version = cols.next(); + let _spec_section = cols.next(); + let device_id = cols.next().unwrap_or("0x0000"); + let device_id = device_id + .strip_prefix("0x") + .and_then(|h| u16::from_str_radix(h, 16).ok()) + .unwrap_or(0); + + tests.push(VillainTest { + name: name.to_string(), + desc: desc.to_string(), + device_id, + }); + } + anyhow::ensure!(!tests.is_empty(), "no tests found in {}", path.display()); + Ok(tests) +} + +/// The verdict the guest emits on the serial console for a test. +/// +/// The guest prints `[] ` (villain `bin/init.c`), where `` is +/// one of these values. The device-health re-probe that distinguishes REJECT +/// from WEDGED is computed by the guest itself; the host only reads the marker. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Verdict { + /// Device accepted the (valid) input and behaved correctly. + Pass, + /// Device correctly rejected the malformed input and stayed alive. + Reject, + /// Device absent or precondition unmet; the test did not run. + Skip, + /// Device accepted malformed input / misbehaved. + Fail, + /// Device stopped responding after the malformed input. + Wedged, + /// Known-failing test that failed as expected (guest-side xfail). + Xfail, + /// Known-failing test that unexpectedly passed (guest-side xfail). + Xpass, +} + +impl Verdict { + fn from_tag(tag: &str) -> Option { + Some(match tag { + "PASS" => Verdict::Pass, + "REJECT" => Verdict::Reject, + "SKIP" => Verdict::Skip, + "FAIL" => Verdict::Fail, + "WEDGED" => Verdict::Wedged, + "XFAIL" => Verdict::Xfail, + "XPASS" => Verdict::Xpass, + _ => return None, + }) + } + + /// Whether this verdict is a "good" outcome (the device model behaved + /// correctly, the test did not apply, or it is a guest-side xfail/xpass — + /// none of which indicate an OpenVMM device-model bug). + pub fn is_good(self) -> bool { + matches!( + self, + Verdict::Pass | Verdict::Reject | Verdict::Skip | Verdict::Xfail | Verdict::Xpass + ) + } +} + +/// The result of scanning a serial log for a single test's verdict. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum VerdictScan { + /// The test's own `[TAG] ` marker was found. + Found(Verdict), + /// No villain markers appeared at all (guest never got far enough). + NoMarkers, + /// Other villain markers were present, but not this test's line + /// (device wedged mid-test and never printed a verdict). + MarkerMissing, +} + +/// Scan a captured serial console log for `name`'s verdict marker. +/// +/// Villain prints one `[] ` line per test. A test may share the log +/// with unrelated boot output; we match the exact test name. +pub fn scan_verdict(log: &str, name: &str) -> VerdictScan { + let mut saw_any_marker = false; + for line in log.lines() { + let line = line.trim(); + // Markers look like "[PASS] blk.split.bad_desc". Find the closing + // bracket and split into tag + remainder. + let Some(rest) = line.strip_prefix('[') else { + continue; + }; + let Some((tag, remainder)) = rest.split_once(']') else { + continue; + }; + let Some(verdict) = Verdict::from_tag(tag) else { + continue; + }; + saw_any_marker = true; + // The name is the first whitespace-delimited token after the tag. + // Some markers carry a trailing reason, e.g. + // "[SKIP] D0001 (no device 0x1063)", so match only the first token + // rather than the whole remainder. Villain test names never contain + // whitespace (see `tests.tsv`). + if remainder.split_whitespace().next() == Some(name) { + return VerdictScan::Found(verdict); + } + } + if saw_any_marker { + VerdictScan::MarkerMissing + } else { + VerdictScan::NoMarkers + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn scan_finds_exact_marker() { + let log = "\ +[vv] virtio-villain +[SKIP] blk.other +[PASS] blk.split.bad_desc +"; + assert_eq!( + scan_verdict(log, "blk.split.bad_desc"), + VerdictScan::Found(Verdict::Pass) + ); + assert_eq!( + scan_verdict(log, "blk.other"), + VerdictScan::Found(Verdict::Skip) + ); + } + + #[test] + fn scan_marker_with_trailing_reason() { + // Villain appends a reason to some SKIP markers; the name is still the + // first token (bin/init.c: "[SKIP] %s (no device 0x%04x)"). + let log = "[vv] virtio-villain\n[SKIP] D0001 (no device 0x1063)\n"; + assert_eq!( + scan_verdict(log, "D0001"), + VerdictScan::Found(Verdict::Skip) + ); + // A name that is a prefix of the marked test must not match. + assert_eq!(scan_verdict(log, "D000"), VerdictScan::MarkerMissing); + } + + #[test] + fn scan_missing_vs_no_markers() { + assert_eq!(scan_verdict("[FAIL] a\n", "b"), VerdictScan::MarkerMissing); + assert_eq!(scan_verdict("booting...\n", "b"), VerdictScan::NoMarkers); + } + + #[test] + fn parse_tsv_row() { + let dir = tempfile::tempdir().unwrap(); + let p = dir.path().join("tests.tsv"); + std::fs::write( + &p, + "blk.split.bad_desc\tvalidates descriptor\t1.2\t2.6.5\t0x0002\t0\t0x0000000000000000\t1\n", + ) + .unwrap(); + let tests = parse_tsv(&p).unwrap(); + assert_eq!(tests.len(), 1); + assert_eq!(tests[0].name, "blk.split.bad_desc"); + assert_eq!(tests[0].device_id, 0x0002); + } +} diff --git a/vmm_tests/virtio_villain_tests/tests/villain.rs b/vmm_tests/virtio_villain_tests/tests/villain.rs new file mode 100644 index 0000000000..b62395428f --- /dev/null +++ b/vmm_tests/virtio_villain_tests/tests/villain.rs @@ -0,0 +1,219 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +//! Standalone test runner that drives [virtio-villain] against OpenVMM. +//! +//! virtio-villain is a guest-side virtio protocol fault-injection / conformance +//! suite: a static musl `init` (PID 1) that walks the virtio transports itself +//! and injects out-of-spec virtqueue inputs, printing a verdict marker per test +//! on the serial console before powering off. +//! +//! This binary uses **petri as a library** (like `burette`) plus +//! **libtest-mimic** to expose one test case per villain test. Each case boots +//! a single "kitchen-sink" OpenVMM VM (every supported virtio device attached; +//! absent devices self-SKIP in the guest) with `vv.test=` on the kernel +//! command line, waits for the VM to halt, and reads the `[TAG] ` verdict +//! from petri's teed serial log. Villain tests that OpenVMM is known to fail +//! ([`known_failures`]) are marked *ignored*, so CI skips them but they can +//! still be run locally with `--run-ignored`. +//! +//! Phase 1: PCI transport, x86_64/KVM. The villain `initramfs.cpio.gz` and +//! `tests.tsv` are supplied locally via `--villain-initramfs`/`--villain-tsv` +//! (or the `VILLAIN_INITRAMFS`/`VILLAIN_TSV` env vars); the guest kernel is the +//! existing OpenVMM linux-direct test `vmlinux`. A later phase resolves these +//! from the `openvmm-deps` release artifact via flowey. +//! +//! [virtio-villain]: https://github.com/weltling/virtio-villain + +mod run { + pub use virtio_villain_tests::run::*; +} + +use anyhow::Context as _; +use clap::Parser; +use libtest_mimic::Failed; +use libtest_mimic::Trial; +use petri_artifacts_common::tags::MachineArch; +use std::path::PathBuf; +use virtio_villain_tests::known_failures; +use virtio_villain_tests::villain; +use virtio_villain_tests::villain::VerdictScan; + +#[derive(Parser)] +#[command( + name = "virtio_villain_tests", + about = "Run virtio-villain against OpenVMM" +)] +struct Cli { + /// Path to villain's `initramfs.cpio.gz`. Falls back to the + /// `VILLAIN_INITRAMFS` environment variable. + #[arg(long)] + villain_initramfs: Option, + + /// Path to villain's `tests.tsv` (from `init --list-tsv`). Falls back to + /// the `VILLAIN_TSV` environment variable. + #[arg(long)] + villain_tsv: Option, + + /// Base directory for per-test petri logs. Defaults to `TEST_OUTPUT_PATH` + /// (the same env var the petri known-paths resolver honors, so CI can point + /// all runners at one publishable directory) if set, else + /// `vmm_test_results/virtio_villain`. + #[arg(long)] + log_dir: Option, + + /// Guest RAM in MiB. + #[arg(long, default_value_t = 512)] + mem_mb: u64, + + #[command(flatten)] + inner: libtest_mimic::Arguments, +} + +/// Two-pass artifact resolution (the petri-tool / burette pattern): resolve the +/// reused OpenVMM linux-direct kernel for the host architecture. +fn register_artifacts(resolver: &petri::ArtifactResolver<'_>) { + let firmware = petri::Firmware::linux_direct(resolver, MachineArch::host()); + petri::PetriVmArtifacts::::new( + resolver, + firmware, + MachineArch::host(), + false, + ); +} + +fn resolve_artifacts() -> anyhow::Result { + let resolver = + petri_artifact_resolver_openvmm_known_paths::OpenvmmKnownPathsTestArtifactResolver::new(""); + let mut requirements = petri::TestArtifactRequirements::new(); + register_artifacts(&petri::ArtifactResolver::collector(&mut requirements)); + let artifacts = requirements + .resolve(&resolver) + .context("failed to resolve test artifacts")?; + register_artifacts(&petri::ArtifactResolver::resolver(&artifacts)); + Ok(artifacts) +} + +/// Sanitize a villain test name into a filesystem-safe directory component. +fn sanitize(name: &str) -> String { + name.chars() + .map(|c| { + if c.is_ascii_alphanumeric() || matches!(c, '.' | '-' | '_') { + c + } else { + '_' + } + }) + .collect() +} + +/// Turn a scan result into a test outcome. Known-failing tests are marked +/// ignored at trial-construction time (see [`known_failures`]) rather than +/// inverted here, so this is a straight good→Ok / bad→Err mapping. +fn evaluate(scan: VerdictScan) -> anyhow::Result<()> { + let (good, detail) = match scan { + VerdictScan::Found(v) => (v.is_good(), format!("{v:?}")), + VerdictScan::MarkerMissing => (false, "WEDGED (no verdict marker for this test)".into()), + VerdictScan::NoMarkers => (false, "FAIL (guest emitted no villain markers)".into()), + }; + + if good { + Ok(()) + } else { + anyhow::bail!("{detail}") + } +} + +fn main() -> anyhow::Result<()> { + let mut cli = Cli::parse(); + + let initramfs = cli + .villain_initramfs + .clone() + .or_else(|| std::env::var_os("VILLAIN_INITRAMFS").map(PathBuf::from)); + let tsv = cli + .villain_tsv + .clone() + .or_else(|| std::env::var_os("VILLAIN_TSV").map(PathBuf::from)) + .context("villain tsv not specified (--villain-tsv or VILLAIN_TSV)")?; + + let tests = villain::parse_tsv(&tsv)?; + + // Resolve the base log dir: explicit `--log-dir`, else `TEST_OUTPUT_PATH` + // (petri convention, so CI publishes all runners' logs uniformly), else a + // repo-relative default. + let log_dir = cli + .log_dir + .clone() + .or_else(|| std::env::var_os("TEST_OUTPUT_PATH").map(PathBuf::from)) + .unwrap_or_else(|| PathBuf::from("vmm_test_results/virtio_villain")); + + // Listing (used by nextest for discovery) must emit *only* the libtest + // `: test` lines on stdout — so skip tracing init (which prints an + // `[[ATTACHMENT]]` line), the log dir, and VM artifact/initramfs resolution. + // Those are only needed when we actually run VMs. + let (artifacts, initramfs, _base_logger) = if cli.inner.list { + (None, PathBuf::new(), None) + } else { + // Install the global tracing subscriber once, rooted at the base log + // dir. Per-test log sources (each with their own serial `linux.log`) + // are created below via `petri::new_log_source`. + fs_err::create_dir_all(&log_dir)?; + let base_logger = + petri::try_init_tracing(&log_dir, tracing::level_filters::LevelFilter::INFO) + .context("failed to initialize tracing")?; + let initramfs = initramfs.context( + "villain initramfs not specified (--villain-initramfs or VILLAIN_INITRAMFS)", + )?; + (Some(resolve_artifacts()?), initramfs, Some(base_logger)) + }; + + let params = run::VmParams { + initramfs, + arch: MachineArch::host(), + mem_bytes: cli.mem_mb * 1024 * 1024, + }; + + let base_log_dir = log_dir.clone(); + let trials: Vec = tests + .into_iter() + .map(|test| { + let params = params.clone(); + let artifacts = artifacts.clone(); + let base_log_dir = base_log_dir.clone(); + let name = test.name.clone(); + let desc = test.desc.clone(); + let device_id = test.device_id; + let ignored = known_failures::lookup(&name).is_some(); + Trial::test(test.name.clone(), move || -> Result<(), Failed> { + let artifacts = artifacts + .as_ref() + .context("artifacts were not resolved (internal error)") + .map_err(|e| Failed::from(format!("{e:#}")))?; + tracing::info!(name, desc, device_id, "running villain test"); + let test_dir = base_log_dir.join(sanitize(&name)); + fs_err::create_dir_all(&test_dir).map_err(|e| Failed::from(format!("{e:#}")))?; + let log_source = petri::new_log_source(&test_dir) + .context("failed to create per-test log source") + .map_err(|e| Failed::from(format!("{e:#}")))?; + let result = + run::run_one(¶ms, artifacts, &log_source, &name).and_then(evaluate); + // Write the petri.passed/petri.failed marker (and log the + // outcome to petri.jsonl) so the logview uploader counts this + // test. villain tests are never "unstable" — known failures are + // skipped via the ignored flag instead. + log_source.log_test_result(&name, &result, false); + result.map_err(|e| Failed::from(format!("{e:#}"))) + }) + .with_ignored_flag(ignored) + }) + .collect(); + + // These VMs are heavy; run them one at a time in-process. Under nextest, + // each test runs in its own process regardless. + if cli.inner.test_threads.is_none() { + cli.inner.test_threads = Some(1); + } + + libtest_mimic::run(&cli.inner, trials).exit(); +} From c19f9495de7f5d8c401715716841369ffb93d037 Mon Sep 17 00:00:00 2001 From: John Starks Date: Sun, 26 Jul 2026 06:41:12 -0700 Subject: [PATCH 02/17] flowey: add per-PR virtio-villain CI job with logview results Wire the virtio-villain conformance suite into checkin-gates as a separate, parallel per-PR job on the x64 Linux KVM pool. It runs alongside the vmm_tests jobs so it doesn't extend the critical path, and publishes JUnit plus per-test petri logs. The logs artifact is named `x64-linux-kvm-virtio-villain-vmm-tests-logs` so it matches the `upload-petri-results` workflow glob (`*-vmm-tests-logs`) and villain results surface on the logview website with no workflow changes. The local-run job is generalized into `run_virtio_villain_tests` with a `nextest_profile` and optional `publish` parameter: the xflowey `virtio-villain-run` pipeline uses the Default profile and no publishing, while CI uses the Ci profile (to emit JUnit) and routes petri's per-test logs through `TEST_OUTPUT_PATH` so they can be published. The publish step is claimed by the report step, so logs upload even when tests fail. The job is inert until openvmm-deps ships the virtio-villain artifact and `OPENVMM_DEPS` is bumped; it is landed in PR CI now so its results can seed the known-failure list once the release exists. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7b5df162-05ee-40d7-85c3-ce37b6783805 --- .github/workflows/openvmm-ci.yaml | 530 +++++++++++++----- .github/workflows/openvmm-pr-release.yaml | 245 +++++++- .github/workflows/openvmm-pr.yaml | 256 ++++++++- ci-flowey/openvmm-pr.yaml | 201 +++++++ .../src/pipelines/checkin_gates.rs | 50 ++ .../src/pipelines/virtio_villain_run.rs | 5 +- flowey/flowey_lib_hvlite/src/_jobs/mod.rs | 2 +- ...villain.rs => run_virtio_villain_tests.rs} | 112 +++- 8 files changed, 1233 insertions(+), 168 deletions(-) rename flowey/flowey_lib_hvlite/src/_jobs/{local_run_virtio_villain.rs => run_virtio_villain_tests.rs} (52%) diff --git a/.github/workflows/openvmm-ci.yaml b/.github/workflows/openvmm-ci.yaml index 6e802d997c..179567d5a7 100644 --- a/.github/workflows/openvmm-ci.yaml +++ b/.github/workflows/openvmm-ci.yaml @@ -3481,9 +3481,9 @@ jobs: - name: 🌼📦 Download artifacts uses: actions/download-artifact@v8 with: - pattern: '{_internal-flowey-bootstrap-x86_64-windows-uid-13,x64-guest_test_uefi,x64-linux-musl-pipette,x64-linux-musl-tmk_vmm,x64-linux-tpm_guest_tests,x64-openhcl-igvm,x64-openhcl-igvm-cvm,x64-openhcl-igvm-test-linux-direct,x64-tmks,x64-windows-openvmm,x64-windows-pipette,x64-windows-prep_steps,x64-windows-test_igvm_agent_rpc_server,x64-windows-tmk_vmm,x64-windows-tpm_guest_tests,x64-windows-vmgstool,x64-windows-vmgstool-dev,x64-windows-vmm-tests-archive}' + pattern: '{_internal-flowey-bootstrap-x86_64-windows-uid-14,x64-guest_test_uefi,x64-linux-musl-pipette,x64-linux-musl-tmk_vmm,x64-linux-tpm_guest_tests,x64-openhcl-igvm,x64-openhcl-igvm-cvm,x64-openhcl-igvm-test-linux-direct,x64-tmks,x64-windows-openvmm,x64-windows-pipette,x64-windows-prep_steps,x64-windows-test_igvm_agent_rpc_server,x64-windows-tmk_vmm,x64-windows-tpm_guest_tests,x64-windows-vmgstool,x64-windows-vmgstool-dev,x64-windows-vmm-tests-archive}' path: ${{ runner.temp }}/used_artifacts/ - - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-13" >> $GITHUB_PATH + - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-14" >> $GITHUB_PATH shell: bash name: 🌼📦 Add flowey to PATH - name: 🌼🛫 Initialize job @@ -3492,7 +3492,7 @@ jobs: AgentTempDirNormal=$(echo "$AgentTempDirNormal" | sed -e 's|\\|\/|g' -e 's|^\([A-Za-z]\)\:/\(.*\)|/\L\1\E/\2|') echo "AgentTempDirNormal=$AgentTempDirNormal" >> $GITHUB_ENV - chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-13/flowey.exe + chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-14/flowey.exe echo '"debug"' | flowey.exe v 19 'FLOWEY_LOG' update echo "${{ runner.temp }}/work" | flowey.exe v 19 '_internal_WORKING_DIR' --is-raw-string update @@ -3949,9 +3949,9 @@ jobs: - name: 🌼📦 Download artifacts uses: actions/download-artifact@v8 with: - pattern: '{_internal-flowey-bootstrap-x86_64-windows-uid-13,x64-guest_test_uefi,x64-linux-musl-pipette,x64-linux-musl-tmk_vmm,x64-linux-tpm_guest_tests,x64-mi-secure-openhcl-igvm,x64-mi-secure-openhcl-igvm-cvm,x64-mi-secure-openhcl-igvm-test-linux-direct,x64-tmks,x64-windows-openvmm,x64-windows-pipette,x64-windows-prep_steps,x64-windows-test_igvm_agent_rpc_server,x64-windows-tmk_vmm,x64-windows-tpm_guest_tests,x64-windows-vmgstool,x64-windows-vmgstool-dev,x64-windows-vmm-tests-archive}' + pattern: '{_internal-flowey-bootstrap-x86_64-windows-uid-14,x64-guest_test_uefi,x64-linux-musl-pipette,x64-linux-musl-tmk_vmm,x64-linux-tpm_guest_tests,x64-mi-secure-openhcl-igvm,x64-mi-secure-openhcl-igvm-cvm,x64-mi-secure-openhcl-igvm-test-linux-direct,x64-tmks,x64-windows-openvmm,x64-windows-pipette,x64-windows-prep_steps,x64-windows-test_igvm_agent_rpc_server,x64-windows-tmk_vmm,x64-windows-tpm_guest_tests,x64-windows-vmgstool,x64-windows-vmgstool-dev,x64-windows-vmm-tests-archive}' path: ${{ runner.temp }}/used_artifacts/ - - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-13" >> $GITHUB_PATH + - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-14" >> $GITHUB_PATH shell: bash name: 🌼📦 Add flowey to PATH - name: 🌼🛫 Initialize job @@ -3960,7 +3960,7 @@ jobs: AgentTempDirNormal=$(echo "$AgentTempDirNormal" | sed -e 's|\\|\/|g' -e 's|^\([A-Za-z]\)\:/\(.*\)|/\L\1\E/\2|') echo "AgentTempDirNormal=$AgentTempDirNormal" >> $GITHUB_ENV - chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-13/flowey.exe + chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-14/flowey.exe echo '"debug"' | flowey.exe v 20 'FLOWEY_LOG' update echo "${{ runner.temp }}/work" | flowey.exe v 20 '_internal_WORKING_DIR' --is-raw-string update @@ -4227,9 +4227,9 @@ jobs: - name: 🌼📦 Download artifacts uses: actions/download-artifact@v8 with: - pattern: '{_internal-flowey-bootstrap-x86_64-windows-uid-13,x64-guest_test_uefi,x64-linux-musl-pipette,x64-linux-musl-tmk_vmm,x64-linux-tpm_guest_tests,x64-openhcl-igvm,x64-openhcl-igvm-cvm,x64-openhcl-igvm-test-linux-direct,x64-tmks,x64-windows-openvmm,x64-windows-pipette,x64-windows-prep_steps,x64-windows-test_igvm_agent_rpc_server,x64-windows-tmk_vmm,x64-windows-tpm_guest_tests,x64-windows-vmgstool,x64-windows-vmgstool-dev,x64-windows-vmm-tests-archive}' + pattern: '{_internal-flowey-bootstrap-x86_64-windows-uid-14,x64-guest_test_uefi,x64-linux-musl-pipette,x64-linux-musl-tmk_vmm,x64-linux-tpm_guest_tests,x64-openhcl-igvm,x64-openhcl-igvm-cvm,x64-openhcl-igvm-test-linux-direct,x64-tmks,x64-windows-openvmm,x64-windows-pipette,x64-windows-prep_steps,x64-windows-test_igvm_agent_rpc_server,x64-windows-tmk_vmm,x64-windows-tpm_guest_tests,x64-windows-vmgstool,x64-windows-vmgstool-dev,x64-windows-vmm-tests-archive}' path: ${{ runner.temp }}/used_artifacts/ - - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-13" >> $GITHUB_PATH + - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-14" >> $GITHUB_PATH shell: bash name: 🌼📦 Add flowey to PATH - name: 🌼🛫 Initialize job @@ -4238,7 +4238,7 @@ jobs: AgentTempDirNormal=$(echo "$AgentTempDirNormal" | sed -e 's|\\|\/|g' -e 's|^\([A-Za-z]\)\:/\(.*\)|/\L\1\E/\2|') echo "AgentTempDirNormal=$AgentTempDirNormal" >> $GITHUB_ENV - chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-13/flowey.exe + chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-14/flowey.exe echo '"debug"' | flowey.exe v 21 'FLOWEY_LOG' update echo "${{ runner.temp }}/work" | flowey.exe v 21 '_internal_WORKING_DIR' --is-raw-string update @@ -4509,9 +4509,9 @@ jobs: - name: 🌼📦 Download artifacts uses: actions/download-artifact@v8 with: - pattern: '{_internal-flowey-bootstrap-x86_64-windows-uid-13,x64-guest_test_uefi,x64-linux-musl-pipette,x64-linux-musl-tmk_vmm,x64-linux-tpm_guest_tests,x64-openhcl-igvm,x64-openhcl-igvm-cvm,x64-openhcl-igvm-test-linux-direct,x64-tmks,x64-windows-openvmm,x64-windows-pipette,x64-windows-prep_steps,x64-windows-test_igvm_agent_rpc_server,x64-windows-tmk_vmm,x64-windows-tpm_guest_tests,x64-windows-vmgstool,x64-windows-vmgstool-dev,x64-windows-vmm-tests-archive}' + pattern: '{_internal-flowey-bootstrap-x86_64-windows-uid-14,x64-guest_test_uefi,x64-linux-musl-pipette,x64-linux-musl-tmk_vmm,x64-linux-tpm_guest_tests,x64-openhcl-igvm,x64-openhcl-igvm-cvm,x64-openhcl-igvm-test-linux-direct,x64-tmks,x64-windows-openvmm,x64-windows-pipette,x64-windows-prep_steps,x64-windows-test_igvm_agent_rpc_server,x64-windows-tmk_vmm,x64-windows-tpm_guest_tests,x64-windows-vmgstool,x64-windows-vmgstool-dev,x64-windows-vmm-tests-archive}' path: ${{ runner.temp }}/used_artifacts/ - - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-13" >> $GITHUB_PATH + - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-14" >> $GITHUB_PATH shell: bash name: 🌼📦 Add flowey to PATH - name: 🌼🛫 Initialize job @@ -4520,7 +4520,7 @@ jobs: AgentTempDirNormal=$(echo "$AgentTempDirNormal" | sed -e 's|\\|\/|g' -e 's|^\([A-Za-z]\)\:/\(.*\)|/\L\1\E/\2|') echo "AgentTempDirNormal=$AgentTempDirNormal" >> $GITHUB_ENV - chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-13/flowey.exe + chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-14/flowey.exe echo '"debug"' | flowey.exe v 22 'FLOWEY_LOG' update echo "${{ runner.temp }}/work" | flowey.exe v 22 '_internal_WORKING_DIR' --is-raw-string update @@ -4792,9 +4792,9 @@ jobs: - name: 🌼📦 Download artifacts uses: actions/download-artifact@v8 with: - pattern: '{_internal-flowey-bootstrap-x86_64-windows-uid-13,x64-guest_test_uefi,x64-linux-musl-pipette,x64-linux-musl-tmk_vmm,x64-linux-tpm_guest_tests,x64-openhcl-igvm,x64-openhcl-igvm-cvm,x64-openhcl-igvm-test-linux-direct,x64-tmks,x64-windows-openvmm,x64-windows-pipette,x64-windows-prep_steps,x64-windows-test_igvm_agent_rpc_server,x64-windows-tmk_vmm,x64-windows-tpm_guest_tests,x64-windows-vmgstool,x64-windows-vmgstool-dev,x64-windows-vmm-tests-archive}' + pattern: '{_internal-flowey-bootstrap-x86_64-windows-uid-14,x64-guest_test_uefi,x64-linux-musl-pipette,x64-linux-musl-tmk_vmm,x64-linux-tpm_guest_tests,x64-openhcl-igvm,x64-openhcl-igvm-cvm,x64-openhcl-igvm-test-linux-direct,x64-tmks,x64-windows-openvmm,x64-windows-pipette,x64-windows-prep_steps,x64-windows-test_igvm_agent_rpc_server,x64-windows-tmk_vmm,x64-windows-tpm_guest_tests,x64-windows-vmgstool,x64-windows-vmgstool-dev,x64-windows-vmm-tests-archive}' path: ${{ runner.temp }}/used_artifacts/ - - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-13" >> $GITHUB_PATH + - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-14" >> $GITHUB_PATH shell: bash name: 🌼📦 Add flowey to PATH - name: 🌼🛫 Initialize job @@ -4803,7 +4803,7 @@ jobs: AgentTempDirNormal=$(echo "$AgentTempDirNormal" | sed -e 's|\\|\/|g' -e 's|^\([A-Za-z]\)\:/\(.*\)|/\L\1\E/\2|') echo "AgentTempDirNormal=$AgentTempDirNormal" >> $GITHUB_ENV - chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-13/flowey.exe + chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-14/flowey.exe echo '"debug"' | flowey.exe v 23 'FLOWEY_LOG' update echo "${{ runner.temp }}/work" | flowey.exe v 23 '_internal_WORKING_DIR' --is-raw-string update @@ -5073,9 +5073,9 @@ jobs: - name: 🌼📦 Download artifacts uses: actions/download-artifact@v8 with: - pattern: '{_internal-flowey-bootstrap-x86_64-linux-uid-11,x64-guest_test_uefi,x64-linux-musl-pipette,x64-linux-musl-tmk_vmm,x64-linux-openvmm,x64-linux-openvmm_vhost,x64-linux-prep_steps,x64-linux-vmm-tests-archive,x64-tmks,x64-windows-pipette}' + pattern: '{_internal-flowey-bootstrap-x86_64-linux-uid-12,x64-guest_test_uefi,x64-linux-musl-pipette,x64-linux-musl-tmk_vmm,x64-linux-openvmm,x64-linux-openvmm_vhost,x64-linux-prep_steps,x64-linux-vmm-tests-archive,x64-tmks,x64-windows-pipette}' path: ${{ runner.temp }}/used_artifacts/ - - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-11" >> $GITHUB_PATH + - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-12" >> $GITHUB_PATH shell: bash name: 🌼📦 Add flowey to PATH - name: 🌼🛫 Initialize job @@ -5084,7 +5084,7 @@ jobs: AgentTempDirNormal=$(echo "$AgentTempDirNormal" | sed -e 's|\\|\/|g' -e 's|^\([A-Za-z]\)\:/\(.*\)|/\L\1\E/\2|') echo "AgentTempDirNormal=$AgentTempDirNormal" >> $GITHUB_ENV - chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-11/flowey + chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-12/flowey echo '"debug"' | flowey v 24 'FLOWEY_LOG' update echo "${{ runner.temp }}/work" | flowey v 24 '_internal_WORKING_DIR' --is-raw-string update @@ -5971,9 +5971,9 @@ jobs: - name: 🌼📦 Download artifacts uses: actions/download-artifact@v8 with: - pattern: '{_internal-flowey-bootstrap-x86_64-linux-uid-12,aarch64-guest_test_uefi,aarch64-linux-musl-openvmm,aarch64-linux-musl-pipette,aarch64-linux-musl-tmk_vmm,aarch64-linux-vmm-tests-archive,aarch64-tmks,x64-linux-incubator}' + pattern: '{_internal-flowey-bootstrap-x86_64-linux-uid-13,aarch64-guest_test_uefi,aarch64-linux-musl-openvmm,aarch64-linux-musl-pipette,aarch64-linux-musl-tmk_vmm,aarch64-linux-vmm-tests-archive,aarch64-tmks,x64-linux-incubator}' path: ${{ runner.temp }}/used_artifacts/ - - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-12" >> $GITHUB_PATH + - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-13" >> $GITHUB_PATH shell: bash name: 🌼📦 Add flowey to PATH - name: 🌼🛫 Initialize job @@ -5982,7 +5982,7 @@ jobs: AgentTempDirNormal=$(echo "$AgentTempDirNormal" | sed -e 's|\\|\/|g' -e 's|^\([A-Za-z]\)\:/\(.*\)|/\L\1\E/\2|') echo "AgentTempDirNormal=$AgentTempDirNormal" >> $GITHUB_ENV - chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-12/flowey + chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-13/flowey echo '"debug"' | flowey v 27 'FLOWEY_LOG' update echo "${{ runner.temp }}/work" | flowey v 27 '_internal_WORKING_DIR' --is-raw-string update @@ -6224,8 +6224,12 @@ jobs: run: flowey e 27 flowey_lib_common::cache 11 shell: bash job28: - name: test flowey local backend - runs-on: ubuntu-latest + name: run vmm-tests [x64-linux-kvm-virtio-villain] + runs-on: + - self-hosted + - 1ES.Pool=openvmm-gh-amd-westus3-v7 + - 1ES.ImageOverride=ubuntu2404-amd64 + - JobId=job28-${{ github.run_id }}-${{ github.run_number }}-${{ github.run_attempt }} permissions: contents: read id-token: write @@ -6298,10 +6302,55 @@ jobs: ${{ inputs.verbose != '' && inputs.verbose || 'false' }} EOF shell: bash + - name: create cargo-nextest cache dir + run: |- + flowey e 28 flowey_lib_common::cfg_cargo_common_flags 0 + flowey e 28 flowey_lib_common::download_cargo_nextest 0 + flowey e 28 flowey_lib_common::download_cargo_nextest 1 + flowey e 28 flowey_lib_common::download_cargo_nextest 2 + flowey e 28 flowey_lib_common::download_cargo_nextest 3 + shell: bash + - name: Pre-processing cache vars + run: |- + flowey e 28 flowey_lib_common::cache 0 + flowey v 28 'flowey_lib_common::cache:2:flowey_lib_common/src/cache.rs' --is-raw-string write-to-env github floweyvar4 + flowey v 28 'flowey_lib_common::cache:1:flowey_lib_common/src/cache.rs' --is-raw-string write-to-env github floweyvar5 + shell: bash + - id: flowey_lib_common__cache__1 + uses: actions/cache@v5 + with: + key: ${{ env.floweyvar4 }} + path: ${{ env.floweyvar5 }} + name: 'Restore cache: cargo-nextest' + - name: downloading cargo-nextest + run: |- + flowey v 28 'flowey_lib_common::cache:4:flowey_lib_common/src/cache.rs' --is-raw-string update --env-source steps.flowey_lib_common__cache__1.outputs.cache-hit <> "$GITHUB_PATH" + rustup show + if: runner.os == 'Linux' + name: rustup (Linux) + shell: bash + - run: | + set -x + curl --fail -sSfLo rustup-init.exe https://win.rustup.rs/x86_64 --output rustup-init + ./rustup-init.exe -y --default-toolchain=1.95.0 + echo "$USERPROFILE\\.cargo\\bin" >> $GITHUB_PATH + if: runner.os == 'Windows' && runner.arch == 'X64' + name: rustup (Windows X64) + shell: bash + - run: | + set -x + curl --fail -sSfLo rustup-init.exe https://win.rustup.rs/aarch64 --output rustup-init + ./rustup-init.exe -y --default-toolchain=1.95.0 + echo "$USERPROFILE\\.cargo\\bin" >> $GITHUB_PATH + if: runner.os == 'Windows' && runner.arch == 'ARM64' + name: rustup (Windows ARM64) + shell: bash + - uses: actions/checkout@v6 with: - pattern: '{_internal-flowey-bootstrap-x86_64-linux-uid-12,aarch64-linux-vmgstool,aarch64-windows-vmgstool,x64-linux-vmgstool,x64-windows-vmgstool}' - path: ${{ runner.temp }}/used_artifacts/ - - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-12" >> $GITHUB_PATH + path: flowey_bootstrap + - name: Build flowey + run: | + set -x + CARGO_INCREMENTAL=0 cargo build -p flowey_hvlite --target x86_64-unknown-linux-gnu --profile flowey-ci + OutDirNormal=$(echo "${{ runner.temp }}/bootstrapped-flowey" | sed -e 's|\\|\/|g' -e 's|^\([A-Za-z]\)\:/\(.*\)|/\L\1\E/\2|') + mkdir -p "$OutDirNormal" + mv ./.github/workflows/openvmm-ci.yaml "$OutDirNormal/pipeline.yaml" + mv target/x86_64-unknown-linux-gnu/flowey-ci/flowey_hvlite "$OutDirNormal/flowey" + working-directory: flowey_bootstrap + shell: bash + - run: echo "${{ runner.temp }}/bootstrapped-flowey" >> $GITHUB_PATH shell: bash name: 🌼📦 Add flowey to PATH + - name: 🌼🔎 Self-check YAML + run: |- + ESCAPED_AGENT_TEMPDIR=$( + cat <<'EOF' | sed 's/\\/\\\\/g' + ${{ runner.temp }} + EOF + ) + flowey pipeline github --runtime $ESCAPED_AGENT_TEMPDIR/bootstrapped-flowey/pipeline.yaml --out .github/workflows/openvmm-ci.yaml ci checkin-gates --config=ci + shell: bash - name: 🌼🛫 Initialize job run: | AgentTempDirNormal="${{ runner.temp }}" AgentTempDirNormal=$(echo "$AgentTempDirNormal" | sed -e 's|\\|\/|g' -e 's|^\([A-Za-z]\)\:/\(.*\)|/\L\1\E/\2|') echo "AgentTempDirNormal=$AgentTempDirNormal" >> $GITHUB_ENV - chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-12/flowey + chmod +x $AgentTempDirNormal/bootstrapped-flowey/flowey echo '"debug"' | flowey v 29 'FLOWEY_LOG' update echo "${{ runner.temp }}/work" | flowey v 29 '_internal_WORKING_DIR' --is-raw-string update @@ -6399,47 +6566,6 @@ jobs: cat <<'EOF' | flowey v 29 'verbose' update ${{ inputs.verbose != '' && inputs.verbose || 'false' }} EOF - echo "$AgentTempDirNormal/used_artifacts/aarch64-linux-vmgstool" | flowey v 29 'artifact_use_from_aarch64-linux-vmgstool' --is-raw-string update - echo "$AgentTempDirNormal/used_artifacts/aarch64-windows-vmgstool" | flowey v 29 'artifact_use_from_aarch64-windows-vmgstool' --is-raw-string update - echo "$AgentTempDirNormal/used_artifacts/x64-linux-vmgstool" | flowey v 29 'artifact_use_from_x64-linux-vmgstool' --is-raw-string update - echo "$AgentTempDirNormal/used_artifacts/x64-windows-vmgstool" | flowey v 29 'artifact_use_from_x64-windows-vmgstool' --is-raw-string update - shell: bash - - name: create gh cache dir - run: flowey e 29 flowey_lib_common::download_gh_cli 0 - shell: bash - - name: Pre-processing cache vars - run: |- - flowey e 29 flowey_lib_common::cache 0 - flowey v 29 'flowey_lib_common::cache:2:flowey_lib_common/src/cache.rs' --is-raw-string write-to-env github floweyvar2 - flowey v 29 'flowey_lib_common::cache:1:flowey_lib_common/src/cache.rs' --is-raw-string write-to-env github floweyvar3 - shell: bash - - id: flowey_lib_common__cache__1 - uses: actions/cache@v5 - with: - key: ${{ env.floweyvar2 }} - path: ${{ env.floweyvar3 }} - name: 'Restore cache: gh-cli' - - name: installing gh - run: |- - flowey v 29 'flowey_lib_common::cache:4:flowey_lib_common/src/cache.rs' --is-raw-string update --env-source steps.flowey_lib_common__cache__1.outputs.cache-hit <> $GITHUB_PATH + shell: bash + name: 🌼📦 Add flowey to PATH + - name: 🌼🛫 Initialize job + run: | + AgentTempDirNormal="${{ runner.temp }}" + AgentTempDirNormal=$(echo "$AgentTempDirNormal" | sed -e 's|\\|\/|g' -e 's|^\([A-Za-z]\)\:/\(.*\)|/\L\1\E/\2|') + echo "AgentTempDirNormal=$AgentTempDirNormal" >> $GITHUB_ENV + + chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-13/flowey + + echo '"debug"' | flowey v 30 'FLOWEY_LOG' update + echo "${{ runner.temp }}/work" | flowey v 30 '_internal_WORKING_DIR' --is-raw-string update + + cat <<'EOF' | flowey v 30 'verbose' update + ${{ inputs.verbose != '' && inputs.verbose || 'false' }} + EOF + echo "$AgentTempDirNormal/used_artifacts/aarch64-linux-vmgstool" | flowey v 30 'artifact_use_from_aarch64-linux-vmgstool' --is-raw-string update + echo "$AgentTempDirNormal/used_artifacts/aarch64-windows-vmgstool" | flowey v 30 'artifact_use_from_aarch64-windows-vmgstool' --is-raw-string update + echo "$AgentTempDirNormal/used_artifacts/x64-linux-vmgstool" | flowey v 30 'artifact_use_from_x64-linux-vmgstool' --is-raw-string update + echo "$AgentTempDirNormal/used_artifacts/x64-windows-vmgstool" | flowey v 30 'artifact_use_from_x64-windows-vmgstool' --is-raw-string update + shell: bash + - name: create gh cache dir + run: flowey e 30 flowey_lib_common::download_gh_cli 0 + shell: bash + - name: Pre-processing cache vars + run: |- + flowey e 30 flowey_lib_common::cache 0 + flowey v 30 'flowey_lib_common::cache:2:flowey_lib_common/src/cache.rs' --is-raw-string write-to-env github floweyvar2 + flowey v 30 'flowey_lib_common::cache:1:flowey_lib_common/src/cache.rs' --is-raw-string write-to-env github floweyvar3 + shell: bash + - id: flowey_lib_common__cache__1 + uses: actions/cache@v5 + with: + key: ${{ env.floweyvar2 }} + path: ${{ env.floweyvar3 }} + name: 'Restore cache: gh-cli' + - name: installing gh + run: |- + flowey v 30 'flowey_lib_common::cache:4:flowey_lib_common/src/cache.rs' --is-raw-string update --env-source steps.flowey_lib_common__cache__1.outputs.cache-hit <> $GITHUB_PATH + shell: bash + name: 🌼📦 Add flowey to PATH + - name: 🌼🛫 Initialize job + run: | + AgentTempDirNormal="${{ runner.temp }}" + AgentTempDirNormal=$(echo "$AgentTempDirNormal" | sed -e 's|\\|\/|g' -e 's|^\([A-Za-z]\)\:/\(.*\)|/\L\1\E/\2|') + echo "AgentTempDirNormal=$AgentTempDirNormal" >> $GITHUB_ENV + + chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-1/flowey + + echo '"debug"' | flowey v 29 'FLOWEY_LOG' update + echo "${{ runner.temp }}/work" | flowey v 29 '_internal_WORKING_DIR' --is-raw-string update + + cat <<'EOF' | flowey v 29 'verbose' update + ${{ inputs.verbose != '' && inputs.verbose || 'false' }} + EOF + shell: bash + - name: check if openvmm needs to be cloned + run: |- + flowey e 29 flowey_lib_common::git_checkout 0 + flowey v 29 'flowey_lib_common::git_checkout:0:flowey_lib_common/src/git_checkout.rs' --is-raw-string --condvar flowey_lib_common::git_checkout:1:flowey_lib_common/src/git_checkout.rs write-to-env github floweyvar1 + flowey v 29 'flowey_lib_common::git_checkout:1:flowey_lib_common/src/git_checkout.rs' write-to-env github FLOWEY_CONDITION + shell: bash + - id: flowey_lib_common__git_checkout__1 + uses: actions/checkout@v6 + with: + fetch-depth: '1' + path: repo0 + persist-credentials: ${{ env.floweyvar1 }} + name: checkout repo openvmm + if: ${{ fromJSON(env.FLOWEY_CONDITION) }} + - name: report cloned repo directories + run: |- + flowey v 29 'flowey_lib_common::git_checkout:4:flowey_core/src/node/github_context.rs' --is-raw-string update --env-source github.workspace <> $GITHUB_PATH + shell: bash + name: 🌼📦 Add flowey to PATH + - name: 🌼🛫 Initialize job + run: | + AgentTempDirNormal="${{ runner.temp }}" + AgentTempDirNormal=$(echo "$AgentTempDirNormal" | sed -e 's|\\|\/|g' -e 's|^\([A-Za-z]\)\:/\(.*\)|/\L\1\E/\2|') + echo "AgentTempDirNormal=$AgentTempDirNormal" >> $GITHUB_ENV + + chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-1/flowey + + echo '"debug"' | flowey v 31 'FLOWEY_LOG' update + echo "${{ runner.temp }}/work" | flowey v 31 '_internal_WORKING_DIR' --is-raw-string update + + cat <<'EOF' | flowey v 31 'verbose' update + ${{ inputs.verbose != '' && inputs.verbose || 'false' }} + EOF + shell: bash + - name: check if openvmm needs to be cloned + run: |- + flowey e 31 flowey_lib_common::git_checkout 0 + flowey v 31 'flowey_lib_common::git_checkout:0:flowey_lib_common/src/git_checkout.rs' --is-raw-string --condvar flowey_lib_common::git_checkout:1:flowey_lib_common/src/git_checkout.rs write-to-env github floweyvar1 + flowey v 31 'flowey_lib_common::git_checkout:1:flowey_lib_common/src/git_checkout.rs' write-to-env github FLOWEY_CONDITION + shell: bash + - id: flowey_lib_common__git_checkout__1 + uses: actions/checkout@v6 + with: + fetch-depth: '1' + path: repo0 + persist-credentials: ${{ env.floweyvar1 }} + name: checkout repo openvmm + if: ${{ fromJSON(env.FLOWEY_CONDITION) }} + - name: report cloned repo directories + run: |- + flowey v 31 'flowey_lib_common::git_checkout:4:flowey_core/src/node/github_context.rs' --is-raw-string update --env-source github.workspace <-vmm-tests-logs`. + pub junit_test_label: String, + /// Local-backend only: copy JUnit + logs into this published artifact dir. + pub artifact_dir: Option>, +} + flowey_request! { pub struct Params { /// Guest/host architecture to test. Phase 1 is Linux-only (KVM). pub arch: CommonArch, /// Also run known-failing (ignored) villain tests. pub run_ignored: bool, + /// Nextest profile: `Default` for local, `Ci` to emit JUnit. + pub nextest_profile: NextestProfile, + /// When set, publish results (JUnit + petri logs) for logview. + pub publish: Option, pub done: WriteVar, } } @@ -47,12 +68,15 @@ impl SimpleFlowNode for Node { ctx.import::(); ctx.import::(); ctx.import::(); + ctx.import::(); } fn process_request(request: Self::Request, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> { let Params { arch, run_ignored, + nextest_profile, + publish, done, } = request; @@ -85,15 +109,48 @@ impl SimpleFlowNode for Node { // Resolve the virtio-villain guest artifact (initramfs + tests.tsv). let villain = ctx.reqv(|v| crate::resolve_virtio_villain::Request::Get(arch, v)); - // Hand the two villain files to the crate via env vars. - let run_env = villain.map(ctx, |a| { - BTreeMap::from([ - ( - "VILLAIN_INITRAMFS".to_string(), - a.initramfs.display().to_string(), - ), - ("VILLAIN_TSV".to_string(), a.tsv.display().to_string()), - ]) + // When publishing, route petri's per-test logs into a dedicated dir so + // we can hand it to publish_test_results as the "logs" attachment. + let test_log_path = if publish.is_some() { + let (path, write_path) = ctx.new_var(); + ctx.emit_rust_step("create virtio-villain test output dir", |ctx| { + let write_path = write_path.claim(ctx); + move |rt| { + let dir = std::env::current_dir()? + .join("vmm_test_results") + .join("virtio_villain"); + fs_err::create_dir_all(&dir)?; + rt.write(write_path, &dir); + Ok(()) + } + }); + Some(path) + } else { + None + }; + + // Hand the two villain files (and, when publishing, TEST_OUTPUT_PATH) to + // the crate via env vars. + let (run_env, write_run_env) = ctx.new_var(); + ctx.emit_minor_rust_step("assemble virtio-villain test env", |ctx| { + let villain = villain.claim(ctx); + let test_log_path = test_log_path.clone().map(|p| p.claim(ctx)); + let write_run_env = write_run_env.claim(ctx); + move |rt| { + let a = rt.read(villain); + let mut env = BTreeMap::from([ + ( + "VILLAIN_INITRAMFS".to_string(), + a.initramfs.display().to_string(), + ), + ("VILLAIN_TSV".to_string(), a.tsv.display().to_string()), + ]); + if let Some(p) = test_log_path { + let p = rt.read(p); + env.insert("TEST_OUTPUT_PATH".to_string(), p.display().to_string()); + } + rt.write(write_run_env, &env); + } }); // Build env for the test binary compilation (native, so effectively a @@ -117,7 +174,7 @@ impl SimpleFlowNode for Node { let results = ctx.reqv(|results| crate::run_cargo_nextest_run::Request { friendly_name: "virtio_villain_tests".into(), run_kind: NextestRunKind::BuildAndRun(build_params), - nextest_profile: NextestProfile::Default, + nextest_profile, nextest_filter_expr: None, nextest_working_dir: None, nextest_config_file: None, @@ -127,7 +184,36 @@ impl SimpleFlowNode for Node { results, }); + // When publishing, upload JUnit + per-test petri logs so the + // upload-petri-results workflow forwards them to logview. The publish + // step is claimed by the report step below, so logs upload even when + // tests fail. + let reported_results = if let Some(VillainPublish { + junit_test_label, + artifact_dir, + }) = publish + { + let test_log_path = test_log_path + .expect("test_log_path is set whenever publish is set") + .depending_on(ctx, &results); + let junit_xml = results.clone().map(ctx, |r| r.junit_xml); + Some( + ctx.reqv(|v| flowey_lib_common::publish_test_results::Request { + junit_xml, + test_label: junit_test_label, + attachments: BTreeMap::from([("logs".to_string(), (test_log_path, false))]), + output_dir: artifact_dir, + done: v, + }), + ) + } else { + None + }; + ctx.emit_rust_step("report virtio-villain test results", |ctx| { + if let Some(reported_results) = reported_results { + reported_results.claim(ctx); + } done.claim(ctx); let results = results.claim(ctx); move |rt| { From 0aeb3ae9796971a3c40ab771f0076cf9d984d2e5 Mon Sep 17 00:00:00 2001 From: John Starks Date: Sun, 26 Jul 2026 09:44:00 -0700 Subject: [PATCH 03/17] flowey: split virtio-villain CI into build-archive and consume-test jobs Rework the per-PR virtio-villain CI job so the KVM test machines no longer need a Rust toolchain or build dependencies (protoc, mesh, etc.). Following the established vmm_tests pattern, a build machine now produces a nextest archive plus the openvmm binary as artifacts, and the KVM test job simply downloads them and runs cargo-nextest from the archive. A new build-side node (build_nextest_virtio_villain_tests) mirrors the vmm_tests archive build and publishes a NextestVirtioVillainTestsArchive. A new consume/test node stages the reused openvmm binary and guest kernel into a content dir via init_vmm_tests_env so the known-paths resolver finds them without a build, merges the villain guest artifact env, grants KVM access, and runs the archive under the ci nextest profile before publishing JUnit and logs for logview. The former local job reverts to a local-only xflowey virtio-villain-run runner. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7b5df162-05ee-40d7-85c3-ce37b6783805 --- .github/workflows/openvmm-ci.yaml | 254 ++++------ .github/workflows/openvmm-pr-release.yaml | 147 +++--- .github/workflows/openvmm-pr.yaml | 147 +++--- ci-flowey/openvmm-pr.yaml | 435 +++++++++--------- .../src/pipelines/checkin_gates.rs | 60 ++- .../src/pipelines/virtio_villain_run.rs | 3 - ...and_test_nextest_virtio_villain_archive.rs | 208 +++++++++ flowey/flowey_lib_hvlite/src/_jobs/mod.rs | 1 + .../src/_jobs/run_virtio_villain_tests.rs | 122 +---- .../src/build_nextest_virtio_villain_tests.rs | 121 +++++ flowey/flowey_lib_hvlite/src/lib.rs | 1 + 11 files changed, 855 insertions(+), 644 deletions(-) create mode 100644 flowey/flowey_lib_hvlite/src/_jobs/consume_and_test_nextest_virtio_villain_archive.rs create mode 100644 flowey/flowey_lib_hvlite/src/build_nextest_virtio_villain_tests.rs diff --git a/.github/workflows/openvmm-ci.yaml b/.github/workflows/openvmm-ci.yaml index 179567d5a7..00783adfb2 100644 --- a/.github/workflows/openvmm-ci.yaml +++ b/.github/workflows/openvmm-ci.yaml @@ -3481,9 +3481,9 @@ jobs: - name: 🌼📦 Download artifacts uses: actions/download-artifact@v8 with: - pattern: '{_internal-flowey-bootstrap-x86_64-windows-uid-14,x64-guest_test_uefi,x64-linux-musl-pipette,x64-linux-musl-tmk_vmm,x64-linux-tpm_guest_tests,x64-openhcl-igvm,x64-openhcl-igvm-cvm,x64-openhcl-igvm-test-linux-direct,x64-tmks,x64-windows-openvmm,x64-windows-pipette,x64-windows-prep_steps,x64-windows-test_igvm_agent_rpc_server,x64-windows-tmk_vmm,x64-windows-tpm_guest_tests,x64-windows-vmgstool,x64-windows-vmgstool-dev,x64-windows-vmm-tests-archive}' + pattern: '{_internal-flowey-bootstrap-x86_64-windows-uid-13,x64-guest_test_uefi,x64-linux-musl-pipette,x64-linux-musl-tmk_vmm,x64-linux-tpm_guest_tests,x64-openhcl-igvm,x64-openhcl-igvm-cvm,x64-openhcl-igvm-test-linux-direct,x64-tmks,x64-windows-openvmm,x64-windows-pipette,x64-windows-prep_steps,x64-windows-test_igvm_agent_rpc_server,x64-windows-tmk_vmm,x64-windows-tpm_guest_tests,x64-windows-vmgstool,x64-windows-vmgstool-dev,x64-windows-vmm-tests-archive}' path: ${{ runner.temp }}/used_artifacts/ - - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-14" >> $GITHUB_PATH + - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-13" >> $GITHUB_PATH shell: bash name: 🌼📦 Add flowey to PATH - name: 🌼🛫 Initialize job @@ -3492,7 +3492,7 @@ jobs: AgentTempDirNormal=$(echo "$AgentTempDirNormal" | sed -e 's|\\|\/|g' -e 's|^\([A-Za-z]\)\:/\(.*\)|/\L\1\E/\2|') echo "AgentTempDirNormal=$AgentTempDirNormal" >> $GITHUB_ENV - chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-14/flowey.exe + chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-13/flowey.exe echo '"debug"' | flowey.exe v 19 'FLOWEY_LOG' update echo "${{ runner.temp }}/work" | flowey.exe v 19 '_internal_WORKING_DIR' --is-raw-string update @@ -3949,9 +3949,9 @@ jobs: - name: 🌼📦 Download artifacts uses: actions/download-artifact@v8 with: - pattern: '{_internal-flowey-bootstrap-x86_64-windows-uid-14,x64-guest_test_uefi,x64-linux-musl-pipette,x64-linux-musl-tmk_vmm,x64-linux-tpm_guest_tests,x64-mi-secure-openhcl-igvm,x64-mi-secure-openhcl-igvm-cvm,x64-mi-secure-openhcl-igvm-test-linux-direct,x64-tmks,x64-windows-openvmm,x64-windows-pipette,x64-windows-prep_steps,x64-windows-test_igvm_agent_rpc_server,x64-windows-tmk_vmm,x64-windows-tpm_guest_tests,x64-windows-vmgstool,x64-windows-vmgstool-dev,x64-windows-vmm-tests-archive}' + pattern: '{_internal-flowey-bootstrap-x86_64-windows-uid-13,x64-guest_test_uefi,x64-linux-musl-pipette,x64-linux-musl-tmk_vmm,x64-linux-tpm_guest_tests,x64-mi-secure-openhcl-igvm,x64-mi-secure-openhcl-igvm-cvm,x64-mi-secure-openhcl-igvm-test-linux-direct,x64-tmks,x64-windows-openvmm,x64-windows-pipette,x64-windows-prep_steps,x64-windows-test_igvm_agent_rpc_server,x64-windows-tmk_vmm,x64-windows-tpm_guest_tests,x64-windows-vmgstool,x64-windows-vmgstool-dev,x64-windows-vmm-tests-archive}' path: ${{ runner.temp }}/used_artifacts/ - - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-14" >> $GITHUB_PATH + - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-13" >> $GITHUB_PATH shell: bash name: 🌼📦 Add flowey to PATH - name: 🌼🛫 Initialize job @@ -3960,7 +3960,7 @@ jobs: AgentTempDirNormal=$(echo "$AgentTempDirNormal" | sed -e 's|\\|\/|g' -e 's|^\([A-Za-z]\)\:/\(.*\)|/\L\1\E/\2|') echo "AgentTempDirNormal=$AgentTempDirNormal" >> $GITHUB_ENV - chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-14/flowey.exe + chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-13/flowey.exe echo '"debug"' | flowey.exe v 20 'FLOWEY_LOG' update echo "${{ runner.temp }}/work" | flowey.exe v 20 '_internal_WORKING_DIR' --is-raw-string update @@ -4039,6 +4039,7 @@ jobs: flowey.exe e 20 flowey_lib_common::system_info 0 flowey.exe e 20 flowey_lib_hvlite::git_checkout_openvmm_repo 0 flowey.exe e 20 flowey_lib_hvlite::run_cargo_nextest_run 0 + flowey.exe e 20 flowey_core::pipeline::artifact::resolve 15 flowey.exe e 20 flowey_core::pipeline::artifact::resolve 13 flowey.exe e 20 flowey_core::pipeline::artifact::resolve 3 flowey.exe e 20 flowey_core::pipeline::artifact::resolve 11 @@ -4053,7 +4054,6 @@ jobs: flowey.exe e 20 flowey_core::pipeline::artifact::resolve 9 flowey.exe e 20 flowey_core::pipeline::artifact::resolve 12 flowey.exe e 20 flowey_core::pipeline::artifact::resolve 14 - flowey.exe e 20 flowey_core::pipeline::artifact::resolve 15 shell: bash - name: creating new test content dir run: flowey.exe e 20 flowey_lib_hvlite::_jobs::consume_and_test_nextest_vmm_tests_archive 0 @@ -4227,9 +4227,9 @@ jobs: - name: 🌼📦 Download artifacts uses: actions/download-artifact@v8 with: - pattern: '{_internal-flowey-bootstrap-x86_64-windows-uid-14,x64-guest_test_uefi,x64-linux-musl-pipette,x64-linux-musl-tmk_vmm,x64-linux-tpm_guest_tests,x64-openhcl-igvm,x64-openhcl-igvm-cvm,x64-openhcl-igvm-test-linux-direct,x64-tmks,x64-windows-openvmm,x64-windows-pipette,x64-windows-prep_steps,x64-windows-test_igvm_agent_rpc_server,x64-windows-tmk_vmm,x64-windows-tpm_guest_tests,x64-windows-vmgstool,x64-windows-vmgstool-dev,x64-windows-vmm-tests-archive}' + pattern: '{_internal-flowey-bootstrap-x86_64-windows-uid-13,x64-guest_test_uefi,x64-linux-musl-pipette,x64-linux-musl-tmk_vmm,x64-linux-tpm_guest_tests,x64-openhcl-igvm,x64-openhcl-igvm-cvm,x64-openhcl-igvm-test-linux-direct,x64-tmks,x64-windows-openvmm,x64-windows-pipette,x64-windows-prep_steps,x64-windows-test_igvm_agent_rpc_server,x64-windows-tmk_vmm,x64-windows-tpm_guest_tests,x64-windows-vmgstool,x64-windows-vmgstool-dev,x64-windows-vmm-tests-archive}' path: ${{ runner.temp }}/used_artifacts/ - - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-14" >> $GITHUB_PATH + - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-13" >> $GITHUB_PATH shell: bash name: 🌼📦 Add flowey to PATH - name: 🌼🛫 Initialize job @@ -4238,7 +4238,7 @@ jobs: AgentTempDirNormal=$(echo "$AgentTempDirNormal" | sed -e 's|\\|\/|g' -e 's|^\([A-Za-z]\)\:/\(.*\)|/\L\1\E/\2|') echo "AgentTempDirNormal=$AgentTempDirNormal" >> $GITHUB_ENV - chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-14/flowey.exe + chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-13/flowey.exe echo '"debug"' | flowey.exe v 21 'FLOWEY_LOG' update echo "${{ runner.temp }}/work" | flowey.exe v 21 '_internal_WORKING_DIR' --is-raw-string update @@ -4509,9 +4509,9 @@ jobs: - name: 🌼📦 Download artifacts uses: actions/download-artifact@v8 with: - pattern: '{_internal-flowey-bootstrap-x86_64-windows-uid-14,x64-guest_test_uefi,x64-linux-musl-pipette,x64-linux-musl-tmk_vmm,x64-linux-tpm_guest_tests,x64-openhcl-igvm,x64-openhcl-igvm-cvm,x64-openhcl-igvm-test-linux-direct,x64-tmks,x64-windows-openvmm,x64-windows-pipette,x64-windows-prep_steps,x64-windows-test_igvm_agent_rpc_server,x64-windows-tmk_vmm,x64-windows-tpm_guest_tests,x64-windows-vmgstool,x64-windows-vmgstool-dev,x64-windows-vmm-tests-archive}' + pattern: '{_internal-flowey-bootstrap-x86_64-windows-uid-13,x64-guest_test_uefi,x64-linux-musl-pipette,x64-linux-musl-tmk_vmm,x64-linux-tpm_guest_tests,x64-openhcl-igvm,x64-openhcl-igvm-cvm,x64-openhcl-igvm-test-linux-direct,x64-tmks,x64-windows-openvmm,x64-windows-pipette,x64-windows-prep_steps,x64-windows-test_igvm_agent_rpc_server,x64-windows-tmk_vmm,x64-windows-tpm_guest_tests,x64-windows-vmgstool,x64-windows-vmgstool-dev,x64-windows-vmm-tests-archive}' path: ${{ runner.temp }}/used_artifacts/ - - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-14" >> $GITHUB_PATH + - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-13" >> $GITHUB_PATH shell: bash name: 🌼📦 Add flowey to PATH - name: 🌼🛫 Initialize job @@ -4520,7 +4520,7 @@ jobs: AgentTempDirNormal=$(echo "$AgentTempDirNormal" | sed -e 's|\\|\/|g' -e 's|^\([A-Za-z]\)\:/\(.*\)|/\L\1\E/\2|') echo "AgentTempDirNormal=$AgentTempDirNormal" >> $GITHUB_ENV - chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-14/flowey.exe + chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-13/flowey.exe echo '"debug"' | flowey.exe v 22 'FLOWEY_LOG' update echo "${{ runner.temp }}/work" | flowey.exe v 22 '_internal_WORKING_DIR' --is-raw-string update @@ -4792,9 +4792,9 @@ jobs: - name: 🌼📦 Download artifacts uses: actions/download-artifact@v8 with: - pattern: '{_internal-flowey-bootstrap-x86_64-windows-uid-14,x64-guest_test_uefi,x64-linux-musl-pipette,x64-linux-musl-tmk_vmm,x64-linux-tpm_guest_tests,x64-openhcl-igvm,x64-openhcl-igvm-cvm,x64-openhcl-igvm-test-linux-direct,x64-tmks,x64-windows-openvmm,x64-windows-pipette,x64-windows-prep_steps,x64-windows-test_igvm_agent_rpc_server,x64-windows-tmk_vmm,x64-windows-tpm_guest_tests,x64-windows-vmgstool,x64-windows-vmgstool-dev,x64-windows-vmm-tests-archive}' + pattern: '{_internal-flowey-bootstrap-x86_64-windows-uid-13,x64-guest_test_uefi,x64-linux-musl-pipette,x64-linux-musl-tmk_vmm,x64-linux-tpm_guest_tests,x64-openhcl-igvm,x64-openhcl-igvm-cvm,x64-openhcl-igvm-test-linux-direct,x64-tmks,x64-windows-openvmm,x64-windows-pipette,x64-windows-prep_steps,x64-windows-test_igvm_agent_rpc_server,x64-windows-tmk_vmm,x64-windows-tpm_guest_tests,x64-windows-vmgstool,x64-windows-vmgstool-dev,x64-windows-vmm-tests-archive}' path: ${{ runner.temp }}/used_artifacts/ - - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-14" >> $GITHUB_PATH + - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-13" >> $GITHUB_PATH shell: bash name: 🌼📦 Add flowey to PATH - name: 🌼🛫 Initialize job @@ -4803,7 +4803,7 @@ jobs: AgentTempDirNormal=$(echo "$AgentTempDirNormal" | sed -e 's|\\|\/|g' -e 's|^\([A-Za-z]\)\:/\(.*\)|/\L\1\E/\2|') echo "AgentTempDirNormal=$AgentTempDirNormal" >> $GITHUB_ENV - chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-14/flowey.exe + chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-13/flowey.exe echo '"debug"' | flowey.exe v 23 'FLOWEY_LOG' update echo "${{ runner.temp }}/work" | flowey.exe v 23 '_internal_WORKING_DIR' --is-raw-string update @@ -5073,9 +5073,9 @@ jobs: - name: 🌼📦 Download artifacts uses: actions/download-artifact@v8 with: - pattern: '{_internal-flowey-bootstrap-x86_64-linux-uid-12,x64-guest_test_uefi,x64-linux-musl-pipette,x64-linux-musl-tmk_vmm,x64-linux-openvmm,x64-linux-openvmm_vhost,x64-linux-prep_steps,x64-linux-vmm-tests-archive,x64-tmks,x64-windows-pipette}' + pattern: '{_internal-flowey-bootstrap-x86_64-linux-uid-11,x64-guest_test_uefi,x64-linux-musl-pipette,x64-linux-musl-tmk_vmm,x64-linux-openvmm,x64-linux-openvmm_vhost,x64-linux-prep_steps,x64-linux-vmm-tests-archive,x64-tmks,x64-windows-pipette}' path: ${{ runner.temp }}/used_artifacts/ - - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-12" >> $GITHUB_PATH + - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-11" >> $GITHUB_PATH shell: bash name: 🌼📦 Add flowey to PATH - name: 🌼🛫 Initialize job @@ -5084,7 +5084,7 @@ jobs: AgentTempDirNormal=$(echo "$AgentTempDirNormal" | sed -e 's|\\|\/|g' -e 's|^\([A-Za-z]\)\:/\(.*\)|/\L\1\E/\2|') echo "AgentTempDirNormal=$AgentTempDirNormal" >> $GITHUB_ENV - chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-12/flowey + chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-11/flowey echo '"debug"' | flowey v 24 'FLOWEY_LOG' update echo "${{ runner.temp }}/work" | flowey v 24 '_internal_WORKING_DIR' --is-raw-string update @@ -5971,9 +5971,9 @@ jobs: - name: 🌼📦 Download artifacts uses: actions/download-artifact@v8 with: - pattern: '{_internal-flowey-bootstrap-x86_64-linux-uid-13,aarch64-guest_test_uefi,aarch64-linux-musl-openvmm,aarch64-linux-musl-pipette,aarch64-linux-musl-tmk_vmm,aarch64-linux-vmm-tests-archive,aarch64-tmks,x64-linux-incubator}' + pattern: '{_internal-flowey-bootstrap-x86_64-linux-uid-12,aarch64-guest_test_uefi,aarch64-linux-musl-openvmm,aarch64-linux-musl-pipette,aarch64-linux-musl-tmk_vmm,aarch64-linux-vmm-tests-archive,aarch64-tmks,x64-linux-incubator}' path: ${{ runner.temp }}/used_artifacts/ - - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-13" >> $GITHUB_PATH + - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-12" >> $GITHUB_PATH shell: bash name: 🌼📦 Add flowey to PATH - name: 🌼🛫 Initialize job @@ -5982,7 +5982,7 @@ jobs: AgentTempDirNormal=$(echo "$AgentTempDirNormal" | sed -e 's|\\|\/|g' -e 's|^\([A-Za-z]\)\:/\(.*\)|/\L\1\E/\2|') echo "AgentTempDirNormal=$AgentTempDirNormal" >> $GITHUB_ENV - chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-13/flowey + chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-12/flowey echo '"debug"' | flowey v 27 'FLOWEY_LOG' update echo "${{ runner.temp }}/work" | flowey v 27 '_internal_WORKING_DIR' --is-raw-string update @@ -6233,67 +6233,25 @@ jobs: permissions: contents: read id-token: write + needs: + - job9 if: github.event.pull_request.draft == false steps: - - run: | - set -x - i=0; while [ $i -lt 5 ] && ! sudo apt-get update; do let "i=i+1"; sleep 1; done; - sudo apt-get -o DPkg::Lock::Timeout=60 install gcc -y - curl --fail --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- --default-toolchain=1.95.0 -y - . "$HOME/.cargo/env" - echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" - rustup show - if: runner.os == 'Linux' - name: rustup (Linux) - shell: bash - - run: | - set -x - curl --fail -sSfLo rustup-init.exe https://win.rustup.rs/x86_64 --output rustup-init - ./rustup-init.exe -y --default-toolchain=1.95.0 - echo "$USERPROFILE\\.cargo\\bin" >> $GITHUB_PATH - if: runner.os == 'Windows' && runner.arch == 'X64' - name: rustup (Windows X64) - shell: bash - - run: | - set -x - curl --fail -sSfLo rustup-init.exe https://win.rustup.rs/aarch64 --output rustup-init - ./rustup-init.exe -y --default-toolchain=1.95.0 - echo "$USERPROFILE\\.cargo\\bin" >> $GITHUB_PATH - if: runner.os == 'Windows' && runner.arch == 'ARM64' - name: rustup (Windows ARM64) - shell: bash - - uses: actions/checkout@v6 + - name: 🌼📦 Download artifacts + uses: actions/download-artifact@v8 with: - path: flowey_bootstrap - - name: Build flowey - run: | - set -x - CARGO_INCREMENTAL=0 cargo build -p flowey_hvlite --target x86_64-unknown-linux-gnu --profile flowey-ci - OutDirNormal=$(echo "${{ runner.temp }}/bootstrapped-flowey" | sed -e 's|\\|\/|g' -e 's|^\([A-Za-z]\)\:/\(.*\)|/\L\1\E/\2|') - mkdir -p "$OutDirNormal" - mv ./.github/workflows/openvmm-ci.yaml "$OutDirNormal/pipeline.yaml" - mv target/x86_64-unknown-linux-gnu/flowey-ci/flowey_hvlite "$OutDirNormal/flowey" - working-directory: flowey_bootstrap - shell: bash - - run: echo "${{ runner.temp }}/bootstrapped-flowey" >> $GITHUB_PATH + pattern: '{_internal-flowey-bootstrap-x86_64-linux-uid-11,x64-linux-openvmm,x64-linux-virtio-villain-tests-archive}' + path: ${{ runner.temp }}/used_artifacts/ + - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-11" >> $GITHUB_PATH shell: bash name: 🌼📦 Add flowey to PATH - - name: 🌼🔎 Self-check YAML - run: |- - ESCAPED_AGENT_TEMPDIR=$( - cat <<'EOF' | sed 's/\\/\\\\/g' - ${{ runner.temp }} - EOF - ) - flowey pipeline github --runtime $ESCAPED_AGENT_TEMPDIR/bootstrapped-flowey/pipeline.yaml --out .github/workflows/openvmm-ci.yaml ci checkin-gates --config=ci - shell: bash - name: 🌼🛫 Initialize job run: | AgentTempDirNormal="${{ runner.temp }}" AgentTempDirNormal=$(echo "$AgentTempDirNormal" | sed -e 's|\\|\/|g' -e 's|^\([A-Za-z]\)\:/\(.*\)|/\L\1\E/\2|') echo "AgentTempDirNormal=$AgentTempDirNormal" >> $GITHUB_ENV - chmod +x $AgentTempDirNormal/bootstrapped-flowey/flowey + chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-11/flowey echo '"debug"' | flowey v 28 'FLOWEY_LOG' update echo "${{ runner.temp }}/work" | flowey v 28 '_internal_WORKING_DIR' --is-raw-string update @@ -6301,10 +6259,14 @@ jobs: cat <<'EOF' | flowey v 28 'verbose' update ${{ inputs.verbose != '' && inputs.verbose || 'false' }} EOF + echo "$AgentTempDirNormal/used_artifacts/x64-linux-openvmm" | flowey v 28 'artifact_use_from_x64-linux-openvmm' --is-raw-string update + echo "$AgentTempDirNormal/used_artifacts/x64-linux-virtio-villain-tests-archive" | flowey v 28 'artifact_use_from_x64-linux-virtio-villain-tests-archive' --is-raw-string update + shell: bash + - name: ensure hypervisor device is accessible + run: flowey e 28 flowey_lib_hvlite::_jobs::consume_and_test_nextest_virtio_villain_archive 3 shell: bash - name: create cargo-nextest cache dir run: |- - flowey e 28 flowey_lib_common::cfg_cargo_common_flags 0 flowey e 28 flowey_lib_common::download_cargo_nextest 0 flowey e 28 flowey_lib_common::download_cargo_nextest 1 flowey e 28 flowey_lib_common::download_cargo_nextest 2 @@ -6330,23 +6292,6 @@ jobs: flowey e 28 flowey_lib_common::cache 2 flowey e 28 flowey_lib_common::download_cargo_nextest 4 shell: bash - - name: add default cargo home to path - run: flowey e 28 flowey_lib_common::install_rust 0 - shell: bash - - name: install Rust - run: flowey e 28 flowey_lib_common::install_rust 1 - shell: bash - - name: report $CARGO_HOME - run: flowey e 28 flowey_lib_common::install_rust 3 - shell: bash - - name: installing cargo-nextest - run: flowey e 28 flowey_lib_common::install_cargo_nextest 0 - shell: bash - - name: detect active toolchain - run: |- - flowey e 28 flowey_lib_common::install_rust 2 - flowey e 28 flowey_lib_hvlite::init_cross_build 0 - shell: bash - name: check if openvmm needs to be cloned run: |- flowey e 28 flowey_lib_common::git_checkout 0 @@ -6372,7 +6317,13 @@ jobs: run: |- flowey e 28 flowey_lib_common::system_info 0 flowey e 28 flowey_lib_hvlite::git_checkout_openvmm_repo 0 - flowey e 28 flowey_lib_hvlite::run_cargo_nextest_run 0 + flowey e 28 flowey_lib_hvlite::_jobs::consume_and_test_nextest_virtio_villain_archive 4 + flowey e 28 flowey_core::pipeline::artifact::resolve 1 + flowey e 28 flowey_lib_hvlite::_jobs::consume_and_test_nextest_virtio_villain_archive 5 + flowey e 28 flowey_core::pipeline::artifact::resolve 0 + shell: bash + - name: creating new test content dir + run: flowey e 28 flowey_lib_hvlite::_jobs::consume_and_test_nextest_virtio_villain_archive 0 shell: bash - name: create gh-release-download cache dir run: flowey e 28 flowey_lib_common::download_gh_release 0 @@ -6397,17 +6348,11 @@ jobs: flowey e 28 flowey_lib_common::cache 6 flowey e 28 flowey_lib_common::download_gh_release 1 shell: bash - - name: unpack virtio-villain artifacts - run: flowey e 28 flowey_lib_hvlite::resolve_virtio_villain 0 - shell: bash - - name: create virtio-villain test output dir - run: |- - flowey e 28 flowey_lib_hvlite::_jobs::run_virtio_villain_tests 0 - flowey e 28 flowey_lib_hvlite::_jobs::run_virtio_villain_tests 1 - flowey e 28 flowey_lib_hvlite::run_cargo_nextest_run 1 + - name: unpack openvmm-test-initrd archives + run: flowey e 28 flowey_lib_hvlite::resolve_openvmm_test_initrd 0 shell: bash - - name: generate nextest command - run: flowey e 28 flowey_lib_common::gen_cargo_nextest_run_cmd 0 + - name: unpack openvmm-test-linux archives + run: flowey e 28 flowey_lib_hvlite::resolve_openvmm_test_linux_kernel 0 shell: bash - name: checking if packages need to be installed run: flowey e 28 flowey_lib_common::install_dist_pkg 0 @@ -6415,47 +6360,35 @@ jobs: - name: installing packages run: flowey e 28 flowey_lib_common::install_dist_pkg 1 shell: bash - - name: set '-Dwarnings' in .cargo/config.toml - run: flowey e 28 flowey_lib_hvlite::init_openvmm_cargo_config_deny_warnings 0 - shell: bash - - name: unpack protoc - run: |- - flowey e 28 flowey_lib_common::resolve_protoc 0 - flowey e 28 flowey_lib_hvlite::cfg_openvmm_magicpath 0 + - name: unpack mu_msvm package (x64) + run: flowey e 28 flowey_lib_hvlite::download_uefi_mu_msvm 0 shell: bash - - name: symlink protoc - run: |- - flowey e 28 flowey_lib_hvlite::init_openvmm_magicpath_protoc 0 - flowey e 28 flowey_lib_hvlite::init_cross_build 1 + - name: unpack openvmm-test-virtio-win archive + run: flowey e 28 flowey_lib_hvlite::resolve_openvmm_test_virtio_win 0 shell: bash - - name: cargo build openvmm - run: |- - flowey e 28 flowey_lib_common::run_cargo_build 0 - flowey e 28 flowey_lib_hvlite::run_cargo_build 0 + - name: setting up vmm_tests env + run: flowey e 28 flowey_lib_hvlite::init_vmm_tests_env 0 shell: bash - - name: split debug symbols + - name: unpack virtio-villain artifacts run: |- - flowey e 28 flowey_lib_hvlite::run_split_debug_info 0 - flowey e 28 flowey_lib_hvlite::run_cargo_build 1 - flowey e 28 flowey_lib_hvlite::build_openvmm 0 - shell: bash - - name: unpack openvmm-deps archive - run: flowey e 28 flowey_lib_hvlite::resolve_openvmm_deps 0 - shell: bash - - name: unpack openvmm-test-linux archives - run: flowey e 28 flowey_lib_hvlite::resolve_openvmm_test_linux_kernel 0 + flowey e 28 flowey_lib_hvlite::resolve_virtio_villain 0 + flowey e 28 flowey_lib_hvlite::_jobs::consume_and_test_nextest_virtio_villain_archive 1 + flowey e 28 flowey_lib_hvlite::_jobs::consume_and_test_nextest_virtio_villain_archive 2 + flowey e 28 flowey_lib_hvlite::run_cargo_nextest_run 1 shell: bash - - name: unpack openvmm-test-initrd archives - run: flowey e 28 flowey_lib_hvlite::resolve_openvmm_test_initrd 0 + - name: generate nextest command + run: flowey e 28 flowey_lib_common::gen_cargo_nextest_run_cmd 0 shell: bash - - name: copy X86_64 openvmm-deps files to magicpath - run: flowey e 28 flowey_lib_hvlite::init_openvmm_magicpath_openvmm_deps 0 + - name: install vmm tests deps (linux) + run: |- + flowey e 28 flowey_lib_hvlite::install_vmm_tests_deps 0 + flowey e 28 flowey_lib_hvlite::run_cargo_nextest_run 0 shell: bash - name: run 'virtio_villain_tests' nextest tests run: |- flowey e 28 flowey_lib_common::run_cargo_nextest_run 0 flowey e 28 flowey_lib_common::run_cargo_nextest_run 1 - flowey e 28 flowey_lib_hvlite::_jobs::run_virtio_villain_tests 3 + flowey e 28 flowey_lib_hvlite::_jobs::consume_and_test_nextest_virtio_villain_archive 7 flowey e 28 flowey_lib_common::publish_test_results 0 flowey e 28 flowey_lib_common::publish_test_results 1 flowey v 28 'flowey_lib_common::publish_test_results:2:flowey_lib_common/src/publish_test_results.rs' --is-raw-string --condvar flowey_lib_common::publish_test_results:0:flowey_lib_common/src/publish_test_results.rs write-to-env github floweyvar1 @@ -6470,7 +6403,7 @@ jobs: if: ${{ fromJSON(env.FLOWEY_CONDITION) }} - name: 🦀 flowey rust steps run: |- - flowey e 28 flowey_lib_hvlite::_jobs::run_virtio_villain_tests 2 + flowey e 28 flowey_lib_hvlite::_jobs::consume_and_test_nextest_virtio_villain_archive 6 flowey e 28 flowey_lib_common::publish_test_results 3 flowey e 28 flowey_lib_common::publish_test_results 4 flowey v 28 'flowey_lib_common::publish_test_results:7:flowey_lib_common/src/publish_test_results.rs' --is-raw-string --condvar flowey_lib_common::publish_test_results:5:flowey_lib_common/src/publish_test_results.rs write-to-env github floweyvar2 @@ -6484,7 +6417,7 @@ jobs: name: 'publish test results: x64-linux-kvm-virtio-villain-vmm-tests (logs)' if: ${{ fromJSON(env.FLOWEY_CONDITION) }} - name: report virtio-villain test results - run: flowey e 28 flowey_lib_hvlite::_jobs::run_virtio_villain_tests 4 + run: flowey e 28 flowey_lib_hvlite::_jobs::consume_and_test_nextest_virtio_villain_archive 8 shell: bash - name: 'validate cache entry: cargo-nextest' run: flowey e 28 flowey_lib_common::cache 3 @@ -7052,9 +6985,9 @@ jobs: - name: 🌼📦 Download artifacts uses: actions/download-artifact@v8 with: - pattern: '{_internal-flowey-bootstrap-x86_64-linux-uid-13,aarch64-linux-vmgstool,aarch64-windows-vmgstool,x64-linux-vmgstool,x64-windows-vmgstool}' + pattern: '{_internal-flowey-bootstrap-x86_64-linux-uid-12,aarch64-linux-vmgstool,aarch64-windows-vmgstool,x64-linux-vmgstool,x64-windows-vmgstool}' path: ${{ runner.temp }}/used_artifacts/ - - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-13" >> $GITHUB_PATH + - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-12" >> $GITHUB_PATH shell: bash name: 🌼📦 Add flowey to PATH - name: 🌼🛫 Initialize job @@ -7063,7 +6996,7 @@ jobs: AgentTempDirNormal=$(echo "$AgentTempDirNormal" | sed -e 's|\\|\/|g' -e 's|^\([A-Za-z]\)\:/\(.*\)|/\L\1\E/\2|') echo "AgentTempDirNormal=$AgentTempDirNormal" >> $GITHUB_ENV - chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-13/flowey + chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-12/flowey echo '"debug"' | flowey v 30 'FLOWEY_LOG' update echo "${{ runner.temp }}/work" | flowey v 30 '_internal_WORKING_DIR' --is-raw-string update @@ -8249,7 +8182,7 @@ jobs: - name: 🌼🥾 Publish bootstrapped flowey uses: actions/upload-artifact@v7 with: - name: _internal-flowey-bootstrap-x86_64-windows-uid-14 + name: _internal-flowey-bootstrap-x86_64-windows-uid-13 path: ${{ runner.temp }}/bootstrapped-flowey job8: name: build artifacts (for VMM tests) [aarch64-linux] @@ -8682,7 +8615,7 @@ jobs: - name: 🌼🥾 Publish bootstrapped flowey uses: actions/upload-artifact@v7 with: - name: _internal-flowey-bootstrap-x86_64-linux-uid-13 + name: _internal-flowey-bootstrap-x86_64-linux-uid-12 path: ${{ runner.temp }}/bootstrapped-flowey job9: name: build artifacts (for VMM tests) [x64-linux] @@ -8778,6 +8711,8 @@ jobs: echo "$AgentTempDirNormal/publish_artifacts/x64-linux-openvmm_vhost" | flowey v 9 'artifact_publish_from_x64-linux-openvmm_vhost' --is-raw-string update mkdir -p "$AgentTempDirNormal/publish_artifacts/x64-linux-prep_steps" echo "$AgentTempDirNormal/publish_artifacts/x64-linux-prep_steps" | flowey v 9 'artifact_publish_from_x64-linux-prep_steps' --is-raw-string update + mkdir -p "$AgentTempDirNormal/publish_artifacts/x64-linux-virtio-villain-tests-archive" + echo "$AgentTempDirNormal/publish_artifacts/x64-linux-virtio-villain-tests-archive" | flowey v 9 'artifact_publish_from_x64-linux-virtio-villain-tests-archive' --is-raw-string update mkdir -p "$AgentTempDirNormal/publish_artifacts/x64-linux-vmgs_lib" echo "$AgentTempDirNormal/publish_artifacts/x64-linux-vmgs_lib" | flowey v 9 'artifact_publish_from_x64-linux-vmgs_lib' --is-raw-string update mkdir -p "$AgentTempDirNormal/publish_artifacts/x64-linux-vmgstool" @@ -8864,7 +8799,7 @@ jobs: - name: symlink protoc run: |- flowey e 9 flowey_lib_hvlite::init_openvmm_magicpath_protoc 0 - flowey e 9 flowey_lib_hvlite::init_cross_build 1 + flowey e 9 flowey_lib_hvlite::init_cross_build 2 shell: bash - name: cargo build openvmm run: |- @@ -8877,7 +8812,7 @@ jobs: flowey e 9 flowey_lib_hvlite::run_cargo_build 5 flowey e 9 flowey_lib_hvlite::build_openvmm 0 flowey e 9 flowey_core::pipeline::artifact::publish 0 - flowey e 9 flowey_lib_hvlite::init_cross_build 3 + flowey e 9 flowey_lib_hvlite::init_cross_build 4 shell: bash - name: cargo build openvmm_vhost run: |- @@ -8890,7 +8825,7 @@ jobs: flowey e 9 flowey_lib_hvlite::run_cargo_build 9 flowey e 9 flowey_lib_hvlite::build_openvmm_vhost 0 flowey e 9 flowey_core::pipeline::artifact::publish 1 - flowey e 9 flowey_lib_hvlite::init_cross_build 6 + flowey e 9 flowey_lib_hvlite::init_cross_build 7 shell: bash - name: cargo build vmgstool run: |- @@ -8903,7 +8838,7 @@ jobs: flowey e 9 flowey_lib_hvlite::run_cargo_build 18 flowey e 9 flowey_lib_hvlite::build_vmgstool 0 flowey e 9 flowey_core::pipeline::artifact::publish 2 - flowey e 9 flowey_lib_hvlite::init_cross_build 5 + flowey e 9 flowey_lib_hvlite::init_cross_build 6 shell: bash - name: cargo build vmgstool run: |- @@ -8916,7 +8851,7 @@ jobs: flowey e 9 flowey_lib_hvlite::run_cargo_build 16 flowey e 9 flowey_lib_hvlite::build_vmgstool 1 flowey e 9 flowey_core::pipeline::artifact::publish 3 - flowey e 9 flowey_lib_hvlite::init_cross_build 4 + flowey e 9 flowey_lib_hvlite::init_cross_build 5 shell: bash - name: cargo build vmgs_lib run: |- @@ -8929,7 +8864,7 @@ jobs: flowey e 9 flowey_lib_hvlite::build_and_test_vmgs_lib 1 flowey e 9 flowey_lib_hvlite::build_and_test_vmgs_lib 2 flowey e 9 flowey_core::pipeline::artifact::publish 4 - flowey e 9 flowey_lib_hvlite::init_cross_build 2 + flowey e 9 flowey_lib_hvlite::init_cross_build 3 shell: bash - name: cargo build igvmfilegen run: |- @@ -8942,7 +8877,7 @@ jobs: flowey e 9 flowey_lib_hvlite::run_cargo_build 1 flowey e 9 flowey_lib_hvlite::build_igvmfilegen 0 flowey e 9 flowey_core::pipeline::artifact::publish 5 - flowey e 9 flowey_lib_hvlite::init_cross_build 7 + flowey e 9 flowey_lib_hvlite::init_cross_build 8 shell: bash - name: cargo build ohcldiag-dev run: |- @@ -8962,7 +8897,7 @@ jobs: - name: extract X86_64 sysroot.tar.gz run: |- flowey e 9 flowey_lib_hvlite::init_openvmm_magicpath_openhcl_sysroot 0 - flowey e 9 flowey_lib_hvlite::init_cross_build 9 + flowey e 9 flowey_lib_hvlite::init_cross_build 10 shell: bash - name: cargo build openvmm run: |- @@ -8975,7 +8910,7 @@ jobs: flowey e 9 flowey_lib_hvlite::run_cargo_build 7 flowey e 9 flowey_lib_hvlite::build_openvmm 1 flowey e 9 flowey_core::pipeline::artifact::publish 7 - flowey e 9 flowey_lib_hvlite::init_cross_build 10 + flowey e 9 flowey_lib_hvlite::init_cross_build 11 shell: bash - name: cargo build openvmm_vhost run: |- @@ -8988,7 +8923,7 @@ jobs: flowey e 9 flowey_lib_hvlite::run_cargo_build 11 flowey e 9 flowey_lib_hvlite::build_openvmm_vhost 1 flowey e 9 flowey_core::pipeline::artifact::publish 8 - flowey e 9 flowey_lib_hvlite::init_cross_build 11 + flowey e 9 flowey_lib_hvlite::init_cross_build 12 shell: bash - name: cargo build prep_steps run: |- @@ -9035,20 +8970,27 @@ jobs: - name: installing cargo-nextest run: |- flowey e 9 flowey_lib_common::install_cargo_nextest 0 - flowey e 9 flowey_lib_hvlite::init_cross_build 0 + flowey e 9 flowey_lib_hvlite::init_cross_build 1 shell: bash - name: build + archive 'vmm_tests' nextests run: |- - flowey e 9 flowey_lib_common::run_cargo_nextest_archive 0 + flowey e 9 flowey_lib_common::run_cargo_nextest_archive 1 flowey e 9 flowey_lib_hvlite::build_nextest_vmm_tests 0 flowey e 9 flowey_core::pipeline::artifact::publish 10 - flowey e 9 flowey_lib_hvlite::init_cross_build 8 + flowey e 9 flowey_lib_hvlite::init_cross_build 9 shell: bash - name: build + archive 'vmm_tests' nextests run: |- - flowey e 9 flowey_lib_common::run_cargo_nextest_archive 1 + flowey e 9 flowey_lib_common::run_cargo_nextest_archive 2 flowey e 9 flowey_lib_hvlite::build_nextest_vmm_tests 1 flowey e 9 flowey_core::pipeline::artifact::publish 11 + flowey e 9 flowey_lib_hvlite::init_cross_build 0 + shell: bash + - name: build + archive 'virtio_villain_tests' nextests + run: |- + flowey e 9 flowey_lib_common::run_cargo_nextest_archive 0 + flowey e 9 flowey_lib_hvlite::build_nextest_virtio_villain_tests 0 + flowey e 9 flowey_core::pipeline::artifact::publish 12 shell: bash - name: 'validate cache entry: cargo-nextest' run: flowey e 9 flowey_lib_common::cache 3 @@ -9104,6 +9046,12 @@ jobs: name: x64-linux-prep_steps path: ${{ runner.temp }}/publish_artifacts/x64-linux-prep_steps/ include-hidden-files: true + - name: 🌼📦 Publish x64-linux-virtio-villain-tests-archive + uses: actions/upload-artifact@v7 + with: + name: x64-linux-virtio-villain-tests-archive + path: ${{ runner.temp }}/publish_artifacts/x64-linux-virtio-villain-tests-archive/ + include-hidden-files: true - name: 🌼📦 Publish x64-linux-vmgs_lib uses: actions/upload-artifact@v7 with: @@ -9134,5 +9082,5 @@ jobs: - name: 🌼🥾 Publish bootstrapped flowey uses: actions/upload-artifact@v7 with: - name: _internal-flowey-bootstrap-x86_64-linux-uid-12 + name: _internal-flowey-bootstrap-x86_64-linux-uid-11 path: ${{ runner.temp }}/bootstrapped-flowey diff --git a/.github/workflows/openvmm-pr-release.yaml b/.github/workflows/openvmm-pr-release.yaml index cd48e1ae32..d8bc50c10d 100644 --- a/.github/workflows/openvmm-pr-release.yaml +++ b/.github/workflows/openvmm-pr-release.yaml @@ -3812,6 +3812,7 @@ jobs: flowey.exe e 20 flowey_lib_common::system_info 0 flowey.exe e 20 flowey_lib_hvlite::git_checkout_openvmm_repo 0 flowey.exe e 20 flowey_lib_hvlite::run_cargo_nextest_run 0 + flowey.exe e 20 flowey_core::pipeline::artifact::resolve 3 flowey.exe e 20 flowey_core::pipeline::artifact::resolve 11 flowey.exe e 20 flowey_core::pipeline::artifact::resolve 4 flowey.exe e 20 flowey_core::pipeline::artifact::resolve 5 @@ -3826,7 +3827,6 @@ jobs: flowey.exe e 20 flowey_core::pipeline::artifact::resolve 14 flowey.exe e 20 flowey_core::pipeline::artifact::resolve 15 flowey.exe e 20 flowey_core::pipeline::artifact::resolve 13 - flowey.exe e 20 flowey_core::pipeline::artifact::resolve 3 shell: bash - name: creating new test content dir run: flowey.exe e 20 flowey_lib_hvlite::_jobs::consume_and_test_nextest_vmm_tests_archive 0 @@ -6014,13 +6014,14 @@ jobs: id-token: write needs: - job0 + - job9 if: contains(github.event.pull_request.labels.*.name, 'release-ci-required') && github.event.pull_request.draft == false steps: - name: 🌼📦 Download artifacts uses: actions/download-artifact@v8 with: - name: _internal-flowey-bootstrap-x86_64-linux-uid-1 - path: ${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-1/ + pattern: '{_internal-flowey-bootstrap-x86_64-linux-uid-1,x64-linux-openvmm,x64-linux-virtio-villain-tests-archive}' + path: ${{ runner.temp }}/used_artifacts/ - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-1" >> $GITHUB_PATH shell: bash name: 🌼📦 Add flowey to PATH @@ -6038,10 +6039,14 @@ jobs: cat <<'EOF' | flowey v 28 'verbose' update ${{ inputs.verbose != '' && inputs.verbose || 'false' }} EOF + echo "$AgentTempDirNormal/used_artifacts/x64-linux-openvmm" | flowey v 28 'artifact_use_from_x64-linux-openvmm' --is-raw-string update + echo "$AgentTempDirNormal/used_artifacts/x64-linux-virtio-villain-tests-archive" | flowey v 28 'artifact_use_from_x64-linux-virtio-villain-tests-archive' --is-raw-string update + shell: bash + - name: ensure hypervisor device is accessible + run: flowey e 28 flowey_lib_hvlite::_jobs::consume_and_test_nextest_virtio_villain_archive 3 shell: bash - name: create cargo-nextest cache dir run: |- - flowey e 28 flowey_lib_common::cfg_cargo_common_flags 0 flowey e 28 flowey_lib_common::download_cargo_nextest 0 flowey e 28 flowey_lib_common::download_cargo_nextest 1 flowey e 28 flowey_lib_common::download_cargo_nextest 2 @@ -6067,23 +6072,6 @@ jobs: flowey e 28 flowey_lib_common::cache 2 flowey e 28 flowey_lib_common::download_cargo_nextest 4 shell: bash - - name: add default cargo home to path - run: flowey e 28 flowey_lib_common::install_rust 0 - shell: bash - - name: install Rust - run: flowey e 28 flowey_lib_common::install_rust 1 - shell: bash - - name: report $CARGO_HOME - run: flowey e 28 flowey_lib_common::install_rust 3 - shell: bash - - name: installing cargo-nextest - run: flowey e 28 flowey_lib_common::install_cargo_nextest 0 - shell: bash - - name: detect active toolchain - run: |- - flowey e 28 flowey_lib_common::install_rust 2 - flowey e 28 flowey_lib_hvlite::init_cross_build 0 - shell: bash - name: check if openvmm needs to be cloned run: |- flowey e 28 flowey_lib_common::git_checkout 0 @@ -6109,7 +6097,13 @@ jobs: run: |- flowey e 28 flowey_lib_common::system_info 0 flowey e 28 flowey_lib_hvlite::git_checkout_openvmm_repo 0 - flowey e 28 flowey_lib_hvlite::run_cargo_nextest_run 0 + flowey e 28 flowey_lib_hvlite::_jobs::consume_and_test_nextest_virtio_villain_archive 4 + flowey e 28 flowey_core::pipeline::artifact::resolve 1 + flowey e 28 flowey_lib_hvlite::_jobs::consume_and_test_nextest_virtio_villain_archive 5 + flowey e 28 flowey_core::pipeline::artifact::resolve 0 + shell: bash + - name: creating new test content dir + run: flowey e 28 flowey_lib_hvlite::_jobs::consume_and_test_nextest_virtio_villain_archive 0 shell: bash - name: create gh-release-download cache dir run: flowey e 28 flowey_lib_common::download_gh_release 0 @@ -6134,17 +6128,11 @@ jobs: flowey e 28 flowey_lib_common::cache 6 flowey e 28 flowey_lib_common::download_gh_release 1 shell: bash - - name: unpack virtio-villain artifacts - run: flowey e 28 flowey_lib_hvlite::resolve_virtio_villain 0 - shell: bash - - name: create virtio-villain test output dir - run: |- - flowey e 28 flowey_lib_hvlite::_jobs::run_virtio_villain_tests 0 - flowey e 28 flowey_lib_hvlite::_jobs::run_virtio_villain_tests 1 - flowey e 28 flowey_lib_hvlite::run_cargo_nextest_run 1 + - name: unpack openvmm-test-initrd archives + run: flowey e 28 flowey_lib_hvlite::resolve_openvmm_test_initrd 0 shell: bash - - name: generate nextest command - run: flowey e 28 flowey_lib_common::gen_cargo_nextest_run_cmd 0 + - name: unpack openvmm-test-linux archives + run: flowey e 28 flowey_lib_hvlite::resolve_openvmm_test_linux_kernel 0 shell: bash - name: checking if packages need to be installed run: flowey e 28 flowey_lib_common::install_dist_pkg 0 @@ -6152,47 +6140,35 @@ jobs: - name: installing packages run: flowey e 28 flowey_lib_common::install_dist_pkg 1 shell: bash - - name: set '-Dwarnings' in .cargo/config.toml - run: flowey e 28 flowey_lib_hvlite::init_openvmm_cargo_config_deny_warnings 0 - shell: bash - - name: unpack protoc - run: |- - flowey e 28 flowey_lib_common::resolve_protoc 0 - flowey e 28 flowey_lib_hvlite::cfg_openvmm_magicpath 0 + - name: unpack mu_msvm package (x64) + run: flowey e 28 flowey_lib_hvlite::download_uefi_mu_msvm 0 shell: bash - - name: symlink protoc - run: |- - flowey e 28 flowey_lib_hvlite::init_openvmm_magicpath_protoc 0 - flowey e 28 flowey_lib_hvlite::init_cross_build 1 + - name: unpack openvmm-test-virtio-win archive + run: flowey e 28 flowey_lib_hvlite::resolve_openvmm_test_virtio_win 0 shell: bash - - name: cargo build openvmm - run: |- - flowey e 28 flowey_lib_common::run_cargo_build 0 - flowey e 28 flowey_lib_hvlite::run_cargo_build 0 + - name: setting up vmm_tests env + run: flowey e 28 flowey_lib_hvlite::init_vmm_tests_env 0 shell: bash - - name: split debug symbols + - name: unpack virtio-villain artifacts run: |- - flowey e 28 flowey_lib_hvlite::run_split_debug_info 0 - flowey e 28 flowey_lib_hvlite::run_cargo_build 1 - flowey e 28 flowey_lib_hvlite::build_openvmm 0 - shell: bash - - name: unpack openvmm-deps archive - run: flowey e 28 flowey_lib_hvlite::resolve_openvmm_deps 0 - shell: bash - - name: unpack openvmm-test-linux archives - run: flowey e 28 flowey_lib_hvlite::resolve_openvmm_test_linux_kernel 0 + flowey e 28 flowey_lib_hvlite::resolve_virtio_villain 0 + flowey e 28 flowey_lib_hvlite::_jobs::consume_and_test_nextest_virtio_villain_archive 1 + flowey e 28 flowey_lib_hvlite::_jobs::consume_and_test_nextest_virtio_villain_archive 2 + flowey e 28 flowey_lib_hvlite::run_cargo_nextest_run 1 shell: bash - - name: unpack openvmm-test-initrd archives - run: flowey e 28 flowey_lib_hvlite::resolve_openvmm_test_initrd 0 + - name: generate nextest command + run: flowey e 28 flowey_lib_common::gen_cargo_nextest_run_cmd 0 shell: bash - - name: copy X86_64 openvmm-deps files to magicpath - run: flowey e 28 flowey_lib_hvlite::init_openvmm_magicpath_openvmm_deps 0 + - name: install vmm tests deps (linux) + run: |- + flowey e 28 flowey_lib_hvlite::install_vmm_tests_deps 0 + flowey e 28 flowey_lib_hvlite::run_cargo_nextest_run 0 shell: bash - name: run 'virtio_villain_tests' nextest tests run: |- flowey e 28 flowey_lib_common::run_cargo_nextest_run 0 flowey e 28 flowey_lib_common::run_cargo_nextest_run 1 - flowey e 28 flowey_lib_hvlite::_jobs::run_virtio_villain_tests 3 + flowey e 28 flowey_lib_hvlite::_jobs::consume_and_test_nextest_virtio_villain_archive 7 flowey e 28 flowey_lib_common::publish_test_results 0 flowey e 28 flowey_lib_common::publish_test_results 1 flowey v 28 'flowey_lib_common::publish_test_results:2:flowey_lib_common/src/publish_test_results.rs' --is-raw-string --condvar flowey_lib_common::publish_test_results:0:flowey_lib_common/src/publish_test_results.rs write-to-env github floweyvar1 @@ -6207,7 +6183,7 @@ jobs: if: ${{ fromJSON(env.FLOWEY_CONDITION) }} - name: 🦀 flowey rust steps run: |- - flowey e 28 flowey_lib_hvlite::_jobs::run_virtio_villain_tests 2 + flowey e 28 flowey_lib_hvlite::_jobs::consume_and_test_nextest_virtio_villain_archive 6 flowey e 28 flowey_lib_common::publish_test_results 3 flowey e 28 flowey_lib_common::publish_test_results 4 flowey v 28 'flowey_lib_common::publish_test_results:7:flowey_lib_common/src/publish_test_results.rs' --is-raw-string --condvar flowey_lib_common::publish_test_results:5:flowey_lib_common/src/publish_test_results.rs write-to-env github floweyvar2 @@ -6221,7 +6197,7 @@ jobs: name: 'publish test results: x64-linux-kvm-virtio-villain-vmm-tests (logs)' if: ${{ fromJSON(env.FLOWEY_CONDITION) }} - name: report virtio-villain test results - run: flowey e 28 flowey_lib_hvlite::_jobs::run_virtio_villain_tests 4 + run: flowey e 28 flowey_lib_hvlite::_jobs::consume_and_test_nextest_virtio_villain_archive 8 shell: bash - name: 'validate cache entry: cargo-nextest' run: flowey e 28 flowey_lib_common::cache 3 @@ -8200,6 +8176,8 @@ jobs: echo "$AgentTempDirNormal/publish_artifacts/x64-linux-openvmm_vhost" | flowey v 9 'artifact_publish_from_x64-linux-openvmm_vhost' --is-raw-string update mkdir -p "$AgentTempDirNormal/publish_artifacts/x64-linux-prep_steps" echo "$AgentTempDirNormal/publish_artifacts/x64-linux-prep_steps" | flowey v 9 'artifact_publish_from_x64-linux-prep_steps' --is-raw-string update + mkdir -p "$AgentTempDirNormal/publish_artifacts/x64-linux-virtio-villain-tests-archive" + echo "$AgentTempDirNormal/publish_artifacts/x64-linux-virtio-villain-tests-archive" | flowey v 9 'artifact_publish_from_x64-linux-virtio-villain-tests-archive' --is-raw-string update mkdir -p "$AgentTempDirNormal/publish_artifacts/x64-linux-vmgs_lib" echo "$AgentTempDirNormal/publish_artifacts/x64-linux-vmgs_lib" | flowey v 9 'artifact_publish_from_x64-linux-vmgs_lib' --is-raw-string update mkdir -p "$AgentTempDirNormal/publish_artifacts/x64-linux-vmgstool" @@ -8286,7 +8264,7 @@ jobs: - name: symlink protoc run: |- flowey e 9 flowey_lib_hvlite::init_openvmm_magicpath_protoc 0 - flowey e 9 flowey_lib_hvlite::init_cross_build 1 + flowey e 9 flowey_lib_hvlite::init_cross_build 2 shell: bash - name: cargo build openvmm run: |- @@ -8299,7 +8277,7 @@ jobs: flowey e 9 flowey_lib_hvlite::run_cargo_build 5 flowey e 9 flowey_lib_hvlite::build_openvmm 0 flowey e 9 flowey_core::pipeline::artifact::publish 0 - flowey e 9 flowey_lib_hvlite::init_cross_build 3 + flowey e 9 flowey_lib_hvlite::init_cross_build 4 shell: bash - name: cargo build openvmm_vhost run: |- @@ -8312,7 +8290,7 @@ jobs: flowey e 9 flowey_lib_hvlite::run_cargo_build 9 flowey e 9 flowey_lib_hvlite::build_openvmm_vhost 0 flowey e 9 flowey_core::pipeline::artifact::publish 1 - flowey e 9 flowey_lib_hvlite::init_cross_build 6 + flowey e 9 flowey_lib_hvlite::init_cross_build 7 shell: bash - name: cargo build vmgstool run: |- @@ -8325,7 +8303,7 @@ jobs: flowey e 9 flowey_lib_hvlite::run_cargo_build 18 flowey e 9 flowey_lib_hvlite::build_vmgstool 0 flowey e 9 flowey_core::pipeline::artifact::publish 2 - flowey e 9 flowey_lib_hvlite::init_cross_build 5 + flowey e 9 flowey_lib_hvlite::init_cross_build 6 shell: bash - name: cargo build vmgstool run: |- @@ -8338,7 +8316,7 @@ jobs: flowey e 9 flowey_lib_hvlite::run_cargo_build 16 flowey e 9 flowey_lib_hvlite::build_vmgstool 1 flowey e 9 flowey_core::pipeline::artifact::publish 3 - flowey e 9 flowey_lib_hvlite::init_cross_build 4 + flowey e 9 flowey_lib_hvlite::init_cross_build 5 shell: bash - name: cargo build vmgs_lib run: |- @@ -8351,7 +8329,7 @@ jobs: flowey e 9 flowey_lib_hvlite::build_and_test_vmgs_lib 1 flowey e 9 flowey_lib_hvlite::build_and_test_vmgs_lib 2 flowey e 9 flowey_core::pipeline::artifact::publish 4 - flowey e 9 flowey_lib_hvlite::init_cross_build 2 + flowey e 9 flowey_lib_hvlite::init_cross_build 3 shell: bash - name: cargo build igvmfilegen run: |- @@ -8364,7 +8342,7 @@ jobs: flowey e 9 flowey_lib_hvlite::run_cargo_build 1 flowey e 9 flowey_lib_hvlite::build_igvmfilegen 0 flowey e 9 flowey_core::pipeline::artifact::publish 5 - flowey e 9 flowey_lib_hvlite::init_cross_build 7 + flowey e 9 flowey_lib_hvlite::init_cross_build 8 shell: bash - name: cargo build ohcldiag-dev run: |- @@ -8384,7 +8362,7 @@ jobs: - name: extract X86_64 sysroot.tar.gz run: |- flowey e 9 flowey_lib_hvlite::init_openvmm_magicpath_openhcl_sysroot 0 - flowey e 9 flowey_lib_hvlite::init_cross_build 9 + flowey e 9 flowey_lib_hvlite::init_cross_build 10 shell: bash - name: cargo build openvmm run: |- @@ -8397,7 +8375,7 @@ jobs: flowey e 9 flowey_lib_hvlite::run_cargo_build 7 flowey e 9 flowey_lib_hvlite::build_openvmm 1 flowey e 9 flowey_core::pipeline::artifact::publish 7 - flowey e 9 flowey_lib_hvlite::init_cross_build 10 + flowey e 9 flowey_lib_hvlite::init_cross_build 11 shell: bash - name: cargo build openvmm_vhost run: |- @@ -8410,7 +8388,7 @@ jobs: flowey e 9 flowey_lib_hvlite::run_cargo_build 11 flowey e 9 flowey_lib_hvlite::build_openvmm_vhost 1 flowey e 9 flowey_core::pipeline::artifact::publish 8 - flowey e 9 flowey_lib_hvlite::init_cross_build 11 + flowey e 9 flowey_lib_hvlite::init_cross_build 12 shell: bash - name: cargo build prep_steps run: |- @@ -8457,20 +8435,27 @@ jobs: - name: installing cargo-nextest run: |- flowey e 9 flowey_lib_common::install_cargo_nextest 0 - flowey e 9 flowey_lib_hvlite::init_cross_build 0 + flowey e 9 flowey_lib_hvlite::init_cross_build 1 shell: bash - name: build + archive 'vmm_tests' nextests run: |- - flowey e 9 flowey_lib_common::run_cargo_nextest_archive 0 + flowey e 9 flowey_lib_common::run_cargo_nextest_archive 1 flowey e 9 flowey_lib_hvlite::build_nextest_vmm_tests 0 flowey e 9 flowey_core::pipeline::artifact::publish 10 - flowey e 9 flowey_lib_hvlite::init_cross_build 8 + flowey e 9 flowey_lib_hvlite::init_cross_build 9 shell: bash - name: build + archive 'vmm_tests' nextests run: |- - flowey e 9 flowey_lib_common::run_cargo_nextest_archive 1 + flowey e 9 flowey_lib_common::run_cargo_nextest_archive 2 flowey e 9 flowey_lib_hvlite::build_nextest_vmm_tests 1 flowey e 9 flowey_core::pipeline::artifact::publish 11 + flowey e 9 flowey_lib_hvlite::init_cross_build 0 + shell: bash + - name: build + archive 'virtio_villain_tests' nextests + run: |- + flowey e 9 flowey_lib_common::run_cargo_nextest_archive 0 + flowey e 9 flowey_lib_hvlite::build_nextest_virtio_villain_tests 0 + flowey e 9 flowey_core::pipeline::artifact::publish 12 shell: bash - name: 'validate cache entry: cargo-nextest' run: flowey e 9 flowey_lib_common::cache 3 @@ -8526,6 +8511,12 @@ jobs: name: x64-linux-prep_steps path: ${{ runner.temp }}/publish_artifacts/x64-linux-prep_steps/ include-hidden-files: true + - name: 🌼📦 Publish x64-linux-virtio-villain-tests-archive + uses: actions/upload-artifact@v7 + with: + name: x64-linux-virtio-villain-tests-archive + path: ${{ runner.temp }}/publish_artifacts/x64-linux-virtio-villain-tests-archive/ + include-hidden-files: true - name: 🌼📦 Publish x64-linux-vmgs_lib uses: actions/upload-artifact@v7 with: diff --git a/.github/workflows/openvmm-pr.yaml b/.github/workflows/openvmm-pr.yaml index 82f9862fef..7f3cb91a9e 100644 --- a/.github/workflows/openvmm-pr.yaml +++ b/.github/workflows/openvmm-pr.yaml @@ -4217,6 +4217,7 @@ jobs: flowey.exe e 22 flowey_lib_common::system_info 0 flowey.exe e 22 flowey_lib_hvlite::git_checkout_openvmm_repo 0 flowey.exe e 22 flowey_lib_hvlite::run_cargo_nextest_run 0 + flowey.exe e 22 flowey_core::pipeline::artifact::resolve 3 flowey.exe e 22 flowey_core::pipeline::artifact::resolve 11 flowey.exe e 22 flowey_core::pipeline::artifact::resolve 4 flowey.exe e 22 flowey_core::pipeline::artifact::resolve 5 @@ -4231,7 +4232,6 @@ jobs: flowey.exe e 22 flowey_core::pipeline::artifact::resolve 14 flowey.exe e 22 flowey_core::pipeline::artifact::resolve 15 flowey.exe e 22 flowey_core::pipeline::artifact::resolve 13 - flowey.exe e 22 flowey_core::pipeline::artifact::resolve 3 shell: bash - name: creating new test content dir run: flowey.exe e 22 flowey_lib_hvlite::_jobs::consume_and_test_nextest_vmm_tests_archive 0 @@ -6778,13 +6778,14 @@ jobs: id-token: write needs: - job0 + - job9 if: github.event.pull_request.draft == false steps: - name: 🌼📦 Download artifacts uses: actions/download-artifact@v8 with: - name: _internal-flowey-bootstrap-x86_64-linux-uid-1 - path: ${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-1/ + pattern: '{_internal-flowey-bootstrap-x86_64-linux-uid-1,x64-linux-openvmm,x64-linux-virtio-villain-tests-archive}' + path: ${{ runner.temp }}/used_artifacts/ - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-1" >> $GITHUB_PATH shell: bash name: 🌼📦 Add flowey to PATH @@ -6802,10 +6803,14 @@ jobs: cat <<'EOF' | flowey v 30 'verbose' update ${{ inputs.verbose != '' && inputs.verbose || 'false' }} EOF + echo "$AgentTempDirNormal/used_artifacts/x64-linux-openvmm" | flowey v 30 'artifact_use_from_x64-linux-openvmm' --is-raw-string update + echo "$AgentTempDirNormal/used_artifacts/x64-linux-virtio-villain-tests-archive" | flowey v 30 'artifact_use_from_x64-linux-virtio-villain-tests-archive' --is-raw-string update + shell: bash + - name: ensure hypervisor device is accessible + run: flowey e 30 flowey_lib_hvlite::_jobs::consume_and_test_nextest_virtio_villain_archive 3 shell: bash - name: create cargo-nextest cache dir run: |- - flowey e 30 flowey_lib_common::cfg_cargo_common_flags 0 flowey e 30 flowey_lib_common::download_cargo_nextest 0 flowey e 30 flowey_lib_common::download_cargo_nextest 1 flowey e 30 flowey_lib_common::download_cargo_nextest 2 @@ -6831,23 +6836,6 @@ jobs: flowey e 30 flowey_lib_common::cache 2 flowey e 30 flowey_lib_common::download_cargo_nextest 4 shell: bash - - name: add default cargo home to path - run: flowey e 30 flowey_lib_common::install_rust 0 - shell: bash - - name: install Rust - run: flowey e 30 flowey_lib_common::install_rust 1 - shell: bash - - name: report $CARGO_HOME - run: flowey e 30 flowey_lib_common::install_rust 3 - shell: bash - - name: installing cargo-nextest - run: flowey e 30 flowey_lib_common::install_cargo_nextest 0 - shell: bash - - name: detect active toolchain - run: |- - flowey e 30 flowey_lib_common::install_rust 2 - flowey e 30 flowey_lib_hvlite::init_cross_build 0 - shell: bash - name: check if openvmm needs to be cloned run: |- flowey e 30 flowey_lib_common::git_checkout 0 @@ -6873,7 +6861,13 @@ jobs: run: |- flowey e 30 flowey_lib_common::system_info 0 flowey e 30 flowey_lib_hvlite::git_checkout_openvmm_repo 0 - flowey e 30 flowey_lib_hvlite::run_cargo_nextest_run 0 + flowey e 30 flowey_lib_hvlite::_jobs::consume_and_test_nextest_virtio_villain_archive 4 + flowey e 30 flowey_core::pipeline::artifact::resolve 1 + flowey e 30 flowey_lib_hvlite::_jobs::consume_and_test_nextest_virtio_villain_archive 5 + flowey e 30 flowey_core::pipeline::artifact::resolve 0 + shell: bash + - name: creating new test content dir + run: flowey e 30 flowey_lib_hvlite::_jobs::consume_and_test_nextest_virtio_villain_archive 0 shell: bash - name: create gh-release-download cache dir run: flowey e 30 flowey_lib_common::download_gh_release 0 @@ -6898,17 +6892,11 @@ jobs: flowey e 30 flowey_lib_common::cache 6 flowey e 30 flowey_lib_common::download_gh_release 1 shell: bash - - name: unpack virtio-villain artifacts - run: flowey e 30 flowey_lib_hvlite::resolve_virtio_villain 0 - shell: bash - - name: create virtio-villain test output dir - run: |- - flowey e 30 flowey_lib_hvlite::_jobs::run_virtio_villain_tests 0 - flowey e 30 flowey_lib_hvlite::_jobs::run_virtio_villain_tests 1 - flowey e 30 flowey_lib_hvlite::run_cargo_nextest_run 1 + - name: unpack openvmm-test-initrd archives + run: flowey e 30 flowey_lib_hvlite::resolve_openvmm_test_initrd 0 shell: bash - - name: generate nextest command - run: flowey e 30 flowey_lib_common::gen_cargo_nextest_run_cmd 0 + - name: unpack openvmm-test-linux archives + run: flowey e 30 flowey_lib_hvlite::resolve_openvmm_test_linux_kernel 0 shell: bash - name: checking if packages need to be installed run: flowey e 30 flowey_lib_common::install_dist_pkg 0 @@ -6916,47 +6904,35 @@ jobs: - name: installing packages run: flowey e 30 flowey_lib_common::install_dist_pkg 1 shell: bash - - name: set '-Dwarnings' in .cargo/config.toml - run: flowey e 30 flowey_lib_hvlite::init_openvmm_cargo_config_deny_warnings 0 - shell: bash - - name: unpack protoc - run: |- - flowey e 30 flowey_lib_common::resolve_protoc 0 - flowey e 30 flowey_lib_hvlite::cfg_openvmm_magicpath 0 + - name: unpack mu_msvm package (x64) + run: flowey e 30 flowey_lib_hvlite::download_uefi_mu_msvm 0 shell: bash - - name: symlink protoc - run: |- - flowey e 30 flowey_lib_hvlite::init_openvmm_magicpath_protoc 0 - flowey e 30 flowey_lib_hvlite::init_cross_build 1 + - name: unpack openvmm-test-virtio-win archive + run: flowey e 30 flowey_lib_hvlite::resolve_openvmm_test_virtio_win 0 shell: bash - - name: cargo build openvmm - run: |- - flowey e 30 flowey_lib_common::run_cargo_build 0 - flowey e 30 flowey_lib_hvlite::run_cargo_build 0 + - name: setting up vmm_tests env + run: flowey e 30 flowey_lib_hvlite::init_vmm_tests_env 0 shell: bash - - name: split debug symbols + - name: unpack virtio-villain artifacts run: |- - flowey e 30 flowey_lib_hvlite::run_split_debug_info 0 - flowey e 30 flowey_lib_hvlite::run_cargo_build 1 - flowey e 30 flowey_lib_hvlite::build_openvmm 0 - shell: bash - - name: unpack openvmm-deps archive - run: flowey e 30 flowey_lib_hvlite::resolve_openvmm_deps 0 - shell: bash - - name: unpack openvmm-test-linux archives - run: flowey e 30 flowey_lib_hvlite::resolve_openvmm_test_linux_kernel 0 + flowey e 30 flowey_lib_hvlite::resolve_virtio_villain 0 + flowey e 30 flowey_lib_hvlite::_jobs::consume_and_test_nextest_virtio_villain_archive 1 + flowey e 30 flowey_lib_hvlite::_jobs::consume_and_test_nextest_virtio_villain_archive 2 + flowey e 30 flowey_lib_hvlite::run_cargo_nextest_run 1 shell: bash - - name: unpack openvmm-test-initrd archives - run: flowey e 30 flowey_lib_hvlite::resolve_openvmm_test_initrd 0 + - name: generate nextest command + run: flowey e 30 flowey_lib_common::gen_cargo_nextest_run_cmd 0 shell: bash - - name: copy X86_64 openvmm-deps files to magicpath - run: flowey e 30 flowey_lib_hvlite::init_openvmm_magicpath_openvmm_deps 0 + - name: install vmm tests deps (linux) + run: |- + flowey e 30 flowey_lib_hvlite::install_vmm_tests_deps 0 + flowey e 30 flowey_lib_hvlite::run_cargo_nextest_run 0 shell: bash - name: run 'virtio_villain_tests' nextest tests run: |- flowey e 30 flowey_lib_common::run_cargo_nextest_run 0 flowey e 30 flowey_lib_common::run_cargo_nextest_run 1 - flowey e 30 flowey_lib_hvlite::_jobs::run_virtio_villain_tests 3 + flowey e 30 flowey_lib_hvlite::_jobs::consume_and_test_nextest_virtio_villain_archive 7 flowey e 30 flowey_lib_common::publish_test_results 0 flowey e 30 flowey_lib_common::publish_test_results 1 flowey v 30 'flowey_lib_common::publish_test_results:2:flowey_lib_common/src/publish_test_results.rs' --is-raw-string --condvar flowey_lib_common::publish_test_results:0:flowey_lib_common/src/publish_test_results.rs write-to-env github floweyvar1 @@ -6971,7 +6947,7 @@ jobs: if: ${{ fromJSON(env.FLOWEY_CONDITION) }} - name: 🦀 flowey rust steps run: |- - flowey e 30 flowey_lib_hvlite::_jobs::run_virtio_villain_tests 2 + flowey e 30 flowey_lib_hvlite::_jobs::consume_and_test_nextest_virtio_villain_archive 6 flowey e 30 flowey_lib_common::publish_test_results 3 flowey e 30 flowey_lib_common::publish_test_results 4 flowey v 30 'flowey_lib_common::publish_test_results:7:flowey_lib_common/src/publish_test_results.rs' --is-raw-string --condvar flowey_lib_common::publish_test_results:5:flowey_lib_common/src/publish_test_results.rs write-to-env github floweyvar2 @@ -6985,7 +6961,7 @@ jobs: name: 'publish test results: x64-linux-kvm-virtio-villain-vmm-tests (logs)' if: ${{ fromJSON(env.FLOWEY_CONDITION) }} - name: report virtio-villain test results - run: flowey e 30 flowey_lib_hvlite::_jobs::run_virtio_villain_tests 4 + run: flowey e 30 flowey_lib_hvlite::_jobs::consume_and_test_nextest_virtio_villain_archive 8 shell: bash - name: 'validate cache entry: cargo-nextest' run: flowey e 30 flowey_lib_common::cache 3 @@ -8673,6 +8649,8 @@ jobs: echo "$AgentTempDirNormal/publish_artifacts/x64-linux-openvmm_vhost" | flowey v 9 'artifact_publish_from_x64-linux-openvmm_vhost' --is-raw-string update mkdir -p "$AgentTempDirNormal/publish_artifacts/x64-linux-prep_steps" echo "$AgentTempDirNormal/publish_artifacts/x64-linux-prep_steps" | flowey v 9 'artifact_publish_from_x64-linux-prep_steps' --is-raw-string update + mkdir -p "$AgentTempDirNormal/publish_artifacts/x64-linux-virtio-villain-tests-archive" + echo "$AgentTempDirNormal/publish_artifacts/x64-linux-virtio-villain-tests-archive" | flowey v 9 'artifact_publish_from_x64-linux-virtio-villain-tests-archive' --is-raw-string update mkdir -p "$AgentTempDirNormal/publish_artifacts/x64-linux-vmgs_lib" echo "$AgentTempDirNormal/publish_artifacts/x64-linux-vmgs_lib" | flowey v 9 'artifact_publish_from_x64-linux-vmgs_lib' --is-raw-string update mkdir -p "$AgentTempDirNormal/publish_artifacts/x64-linux-vmgstool" @@ -8759,7 +8737,7 @@ jobs: - name: symlink protoc run: |- flowey e 9 flowey_lib_hvlite::init_openvmm_magicpath_protoc 0 - flowey e 9 flowey_lib_hvlite::init_cross_build 1 + flowey e 9 flowey_lib_hvlite::init_cross_build 2 shell: bash - name: cargo build openvmm run: |- @@ -8772,7 +8750,7 @@ jobs: flowey e 9 flowey_lib_hvlite::run_cargo_build 5 flowey e 9 flowey_lib_hvlite::build_openvmm 0 flowey e 9 flowey_core::pipeline::artifact::publish 0 - flowey e 9 flowey_lib_hvlite::init_cross_build 3 + flowey e 9 flowey_lib_hvlite::init_cross_build 4 shell: bash - name: cargo build openvmm_vhost run: |- @@ -8785,7 +8763,7 @@ jobs: flowey e 9 flowey_lib_hvlite::run_cargo_build 9 flowey e 9 flowey_lib_hvlite::build_openvmm_vhost 0 flowey e 9 flowey_core::pipeline::artifact::publish 1 - flowey e 9 flowey_lib_hvlite::init_cross_build 6 + flowey e 9 flowey_lib_hvlite::init_cross_build 7 shell: bash - name: cargo build vmgstool run: |- @@ -8798,7 +8776,7 @@ jobs: flowey e 9 flowey_lib_hvlite::run_cargo_build 18 flowey e 9 flowey_lib_hvlite::build_vmgstool 0 flowey e 9 flowey_core::pipeline::artifact::publish 2 - flowey e 9 flowey_lib_hvlite::init_cross_build 5 + flowey e 9 flowey_lib_hvlite::init_cross_build 6 shell: bash - name: cargo build vmgstool run: |- @@ -8811,7 +8789,7 @@ jobs: flowey e 9 flowey_lib_hvlite::run_cargo_build 16 flowey e 9 flowey_lib_hvlite::build_vmgstool 1 flowey e 9 flowey_core::pipeline::artifact::publish 3 - flowey e 9 flowey_lib_hvlite::init_cross_build 4 + flowey e 9 flowey_lib_hvlite::init_cross_build 5 shell: bash - name: cargo build vmgs_lib run: |- @@ -8824,7 +8802,7 @@ jobs: flowey e 9 flowey_lib_hvlite::build_and_test_vmgs_lib 1 flowey e 9 flowey_lib_hvlite::build_and_test_vmgs_lib 2 flowey e 9 flowey_core::pipeline::artifact::publish 4 - flowey e 9 flowey_lib_hvlite::init_cross_build 2 + flowey e 9 flowey_lib_hvlite::init_cross_build 3 shell: bash - name: cargo build igvmfilegen run: |- @@ -8837,7 +8815,7 @@ jobs: flowey e 9 flowey_lib_hvlite::run_cargo_build 1 flowey e 9 flowey_lib_hvlite::build_igvmfilegen 0 flowey e 9 flowey_core::pipeline::artifact::publish 5 - flowey e 9 flowey_lib_hvlite::init_cross_build 7 + flowey e 9 flowey_lib_hvlite::init_cross_build 8 shell: bash - name: cargo build ohcldiag-dev run: |- @@ -8857,7 +8835,7 @@ jobs: - name: extract X86_64 sysroot.tar.gz run: |- flowey e 9 flowey_lib_hvlite::init_openvmm_magicpath_openhcl_sysroot 0 - flowey e 9 flowey_lib_hvlite::init_cross_build 9 + flowey e 9 flowey_lib_hvlite::init_cross_build 10 shell: bash - name: cargo build openvmm run: |- @@ -8870,7 +8848,7 @@ jobs: flowey e 9 flowey_lib_hvlite::run_cargo_build 7 flowey e 9 flowey_lib_hvlite::build_openvmm 1 flowey e 9 flowey_core::pipeline::artifact::publish 7 - flowey e 9 flowey_lib_hvlite::init_cross_build 10 + flowey e 9 flowey_lib_hvlite::init_cross_build 11 shell: bash - name: cargo build openvmm_vhost run: |- @@ -8883,7 +8861,7 @@ jobs: flowey e 9 flowey_lib_hvlite::run_cargo_build 11 flowey e 9 flowey_lib_hvlite::build_openvmm_vhost 1 flowey e 9 flowey_core::pipeline::artifact::publish 8 - flowey e 9 flowey_lib_hvlite::init_cross_build 11 + flowey e 9 flowey_lib_hvlite::init_cross_build 12 shell: bash - name: cargo build prep_steps run: |- @@ -8930,20 +8908,27 @@ jobs: - name: installing cargo-nextest run: |- flowey e 9 flowey_lib_common::install_cargo_nextest 0 - flowey e 9 flowey_lib_hvlite::init_cross_build 0 + flowey e 9 flowey_lib_hvlite::init_cross_build 1 shell: bash - name: build + archive 'vmm_tests' nextests run: |- - flowey e 9 flowey_lib_common::run_cargo_nextest_archive 0 + flowey e 9 flowey_lib_common::run_cargo_nextest_archive 1 flowey e 9 flowey_lib_hvlite::build_nextest_vmm_tests 0 flowey e 9 flowey_core::pipeline::artifact::publish 10 - flowey e 9 flowey_lib_hvlite::init_cross_build 8 + flowey e 9 flowey_lib_hvlite::init_cross_build 9 shell: bash - name: build + archive 'vmm_tests' nextests run: |- - flowey e 9 flowey_lib_common::run_cargo_nextest_archive 1 + flowey e 9 flowey_lib_common::run_cargo_nextest_archive 2 flowey e 9 flowey_lib_hvlite::build_nextest_vmm_tests 1 flowey e 9 flowey_core::pipeline::artifact::publish 11 + flowey e 9 flowey_lib_hvlite::init_cross_build 0 + shell: bash + - name: build + archive 'virtio_villain_tests' nextests + run: |- + flowey e 9 flowey_lib_common::run_cargo_nextest_archive 0 + flowey e 9 flowey_lib_hvlite::build_nextest_virtio_villain_tests 0 + flowey e 9 flowey_core::pipeline::artifact::publish 12 shell: bash - name: 'validate cache entry: cargo-nextest' run: flowey e 9 flowey_lib_common::cache 3 @@ -8999,6 +8984,12 @@ jobs: name: x64-linux-prep_steps path: ${{ runner.temp }}/publish_artifacts/x64-linux-prep_steps/ include-hidden-files: true + - name: 🌼📦 Publish x64-linux-virtio-villain-tests-archive + uses: actions/upload-artifact@v7 + with: + name: x64-linux-virtio-villain-tests-archive + path: ${{ runner.temp }}/publish_artifacts/x64-linux-virtio-villain-tests-archive/ + include-hidden-files: true - name: 🌼📦 Publish x64-linux-vmgs_lib uses: actions/upload-artifact@v7 with: diff --git a/ci-flowey/openvmm-pr.yaml b/ci-flowey/openvmm-pr.yaml index f02e0e4dc6..9862cb66cd 100644 --- a/ci-flowey/openvmm-pr.yaml +++ b/ci-flowey/openvmm-pr.yaml @@ -223,207 +223,6 @@ jobs: - publish: $(FLOWEY_TEMP_DIR)/bootstrapped-flowey displayName: 🌼🥾 Publish bootstrapped flowey artifact: _internal-flowey-bootstrap-x86_64-linux-uid-1 -- job: job21 - displayName: run vmm-tests [x64-linux-kvm-virtio-villain] - pool: - demands: - - ImageOverride -equals ubuntu2404-amd64 - name: openvmm-ado-amd-westus2-v6 - dependsOn: - - job0 - condition: and(succeeded(), not(canceled())) - variables: - - name: FLOWEY_TEMP_DIR - value: $(Build.StagingDirectory)/.flowey-internal - steps: - - task: DownloadPipelineArtifact@2 - displayName: 🌼🥾 Download bootstrapped flowey - inputs: - artifact: _internal-flowey-bootstrap-x86_64-linux-uid-1 - path: $(FLOWEY_TEMP_DIR)/bootstrapped-flowey - - bash: | - set -e - AgentTempDirNormal="$(FLOWEY_TEMP_DIR)" - AgentTempDirNormal=$(echo "$AgentTempDirNormal" | sed -e 's|\\|\/|g' -e 's|^\([A-Za-z]\)\:/\(.*\)|/\L\1\E/\2|') - echo "##vso[task.setvariable variable=AgentTempDirNormal;]$AgentTempDirNormal" - - chmod +x $AgentTempDirNormal/bootstrapped-flowey/flowey - FLOWEY_BIN="$AgentTempDirNormal/bootstrapped-flowey/flowey" - echo "##vso[task.setvariable variable=FLOWEY_BIN;]$FLOWEY_BIN" - displayName: Set flowey path - - bash: | - set -e - echo '"debug"' | $FLOWEY_BIN v 21 'FLOWEY_LOG' update - echo "$(FLOWEY_TEMP_DIR)/work" | $FLOWEY_BIN v 21 '_internal_WORKING_DIR' --is-raw-string update - - cat <<'EOF' | tr '[:upper:]' '[:lower:]' | $FLOWEY_BIN v 21 'verbose' update - ${{ parameters.verbose }} - EOF - displayName: 🌼🛫 Initialize job - - bash: |- - set -e - $(FLOWEY_BIN) e 21 flowey_lib_common::cfg_cargo_common_flags 0 - $(FLOWEY_BIN) e 21 flowey_lib_common::download_cargo_nextest 0 - $(FLOWEY_BIN) e 21 flowey_lib_common::download_cargo_nextest 1 - $(FLOWEY_BIN) e 21 flowey_lib_common::download_cargo_nextest 2 - $(FLOWEY_BIN) e 21 flowey_lib_common::download_cargo_nextest 3 - displayName: create cargo-nextest cache dir - - bash: |- - set -e - $(FLOWEY_BIN) e 21 flowey_lib_common::cache 0 - $FLOWEY_BIN v 21 'flowey_lib_common::cache:1:flowey_lib_common/src/cache.rs' --is-raw-string write-to-env ado floweyvar3 - $FLOWEY_BIN v 21 'flowey_lib_common::cache:2:flowey_lib_common/src/cache.rs' --is-raw-string write-to-env ado floweyvar4 - displayName: Pre-processing cache vars - - task: Cache@2 - inputs: - key: $(floweyvar4) - path: $(floweyvar3) - cacheHitVar: FLOWEY_CACHE_HITVAR - displayName: 'Restore cache: cargo-nextest' - - bash: |- - set -e - $FLOWEY_BIN v 21 'flowey_lib_common::cache:4:flowey_lib_common/src/cache.rs' --is-raw-string update --env-source FLOWEY_CACHE_HITVAR <<'EOF' - $(FLOWEY_CACHE_HITVAR) - EOF - $(FLOWEY_BIN) e 21 flowey_lib_common::cache 2 - displayName: map ADO hitvar to flowey - - bash: $(FLOWEY_BIN) e 21 flowey_lib_common::download_cargo_nextest 4 - displayName: downloading cargo-nextest - - bash: $(FLOWEY_BIN) e 21 flowey_lib_common::install_rust 0 - displayName: install Rust - - bash: $(FLOWEY_BIN) e 21 flowey_lib_common::install_rust 2 - displayName: report $CARGO_HOME - - bash: $(FLOWEY_BIN) e 21 flowey_lib_common::install_cargo_nextest 0 - displayName: installing cargo-nextest - - bash: |- - set -e - $(FLOWEY_BIN) e 21 flowey_lib_common::install_rust 1 - $(FLOWEY_BIN) e 21 flowey_lib_hvlite::init_cross_build 0 - displayName: detect active toolchain - - bash: |- - set -e - $(FLOWEY_BIN) e 21 flowey_lib_common::git_checkout 0 - $FLOWEY_BIN v 21 'flowey_lib_common::git_checkout:0:flowey_lib_common/src/git_checkout.rs' --is-raw-string --condvar flowey_lib_common::git_checkout:1:flowey_lib_common/src/git_checkout.rs write-to-env ado floweyvar2 - $FLOWEY_BIN v 21 'flowey_lib_common::git_checkout:1:flowey_lib_common/src/git_checkout.rs' write-to-env ado FLOWEY_CONDITION - displayName: check if openvmm needs to be cloned - - checkout: self - path: repo0 - fetchTags: false - fetchDepth: 1 - persistCredentials: $(floweyvar2) - submodules: recursive - displayName: checkout repo openvmm - condition: and(eq(variables['FLOWEY_CONDITION'], true), succeeded(), not(canceled())) - - bash: |- - set -e - $FLOWEY_BIN v 21 'flowey_lib_common::git_checkout:4:flowey_lib_common/src/git_checkout.rs' --is-raw-string update --env-source Pipeline.Workspace <<'EOF' - $(Pipeline.Workspace) - EOF - $(FLOWEY_BIN) e 21 flowey_lib_common::git_checkout 3 - displayName: report cloned repo directories - - bash: |- - set -e - $(FLOWEY_BIN) e 21 flowey_lib_common::system_info 0 - $(FLOWEY_BIN) e 21 flowey_lib_hvlite::git_checkout_openvmm_repo 0 - $(FLOWEY_BIN) e 21 flowey_lib_hvlite::run_cargo_nextest_run 0 - displayName: print system info - - bash: $(FLOWEY_BIN) e 21 flowey_lib_common::download_gh_release 0 - displayName: create gh-release-download cache dir - - bash: |- - set -e - $(FLOWEY_BIN) e 21 flowey_lib_common::cache 4 - $FLOWEY_BIN v 21 'flowey_lib_common::cache:8:flowey_lib_common/src/cache.rs' --is-raw-string write-to-env ado floweyvar5 - $FLOWEY_BIN v 21 'flowey_lib_common::cache:9:flowey_lib_common/src/cache.rs' --is-raw-string write-to-env ado floweyvar6 - displayName: Pre-processing cache vars - - task: Cache@2 - inputs: - key: $(floweyvar6) - path: $(floweyvar5) - cacheHitVar: FLOWEY_CACHE_HITVAR - displayName: 'Restore cache: gh-release-download' - - bash: |- - set -e - $FLOWEY_BIN v 21 'flowey_lib_common::cache:11:flowey_lib_common/src/cache.rs' --is-raw-string update --env-source FLOWEY_CACHE_HITVAR <<'EOF' - $(FLOWEY_CACHE_HITVAR) - EOF - $(FLOWEY_BIN) e 21 flowey_lib_common::cache 6 - displayName: map ADO hitvar to flowey - - bash: $(FLOWEY_BIN) e 21 flowey_lib_common::download_gh_release 1 - displayName: download artifacts from github releases - - bash: $(FLOWEY_BIN) e 21 flowey_lib_hvlite::resolve_virtio_villain 0 - displayName: unpack virtio-villain artifacts - - bash: |- - set -e - $(FLOWEY_BIN) e 21 flowey_lib_hvlite::_jobs::run_virtio_villain_tests 0 - $(FLOWEY_BIN) e 21 flowey_lib_hvlite::_jobs::run_virtio_villain_tests 1 - $(FLOWEY_BIN) e 21 flowey_lib_hvlite::run_cargo_nextest_run 1 - displayName: create virtio-villain test output dir - - bash: $(FLOWEY_BIN) e 21 flowey_lib_common::gen_cargo_nextest_run_cmd 0 - displayName: generate nextest command - - bash: $(FLOWEY_BIN) e 21 flowey_lib_common::install_dist_pkg 0 - displayName: checking if packages need to be installed - - bash: $(FLOWEY_BIN) e 21 flowey_lib_common::install_dist_pkg 1 - displayName: installing packages - - bash: $(FLOWEY_BIN) e 21 flowey_lib_hvlite::init_openvmm_cargo_config_deny_warnings 0 - displayName: set '-Dwarnings' in .cargo/config.toml - - bash: |- - set -e - $(FLOWEY_BIN) e 21 flowey_lib_common::resolve_protoc 0 - $(FLOWEY_BIN) e 21 flowey_lib_hvlite::cfg_openvmm_magicpath 0 - displayName: unpack protoc - - bash: |- - set -e - $(FLOWEY_BIN) e 21 flowey_lib_hvlite::init_openvmm_magicpath_protoc 0 - $(FLOWEY_BIN) e 21 flowey_lib_hvlite::init_cross_build 1 - displayName: symlink protoc - - bash: |- - set -e - $(FLOWEY_BIN) e 21 flowey_lib_common::run_cargo_build 0 - $(FLOWEY_BIN) e 21 flowey_lib_hvlite::run_cargo_build 0 - displayName: cargo build openvmm - - bash: |- - set -e - $(FLOWEY_BIN) e 21 flowey_lib_hvlite::run_split_debug_info 0 - $(FLOWEY_BIN) e 21 flowey_lib_hvlite::run_cargo_build 1 - $(FLOWEY_BIN) e 21 flowey_lib_hvlite::build_openvmm 0 - displayName: split debug symbols - - bash: $(FLOWEY_BIN) e 21 flowey_lib_hvlite::resolve_openvmm_deps 0 - displayName: unpack openvmm-deps archive - - bash: $(FLOWEY_BIN) e 21 flowey_lib_hvlite::resolve_openvmm_test_linux_kernel 0 - displayName: unpack openvmm-test-linux archives - - bash: $(FLOWEY_BIN) e 21 flowey_lib_hvlite::resolve_openvmm_test_initrd 0 - displayName: unpack openvmm-test-initrd archives - - bash: $(FLOWEY_BIN) e 21 flowey_lib_hvlite::init_openvmm_magicpath_openvmm_deps 0 - displayName: copy X86_64 openvmm-deps files to magicpath - - bash: |- - set -e - $(FLOWEY_BIN) e 21 flowey_lib_common::run_cargo_nextest_run 0 - $(FLOWEY_BIN) e 21 flowey_lib_common::run_cargo_nextest_run 1 - $(FLOWEY_BIN) e 21 flowey_lib_hvlite::_jobs::run_virtio_villain_tests 3 - $(FLOWEY_BIN) e 21 flowey_lib_common::publish_test_results 1 - $(FLOWEY_BIN) e 21 flowey_lib_common::ado_task_publish_test_results 0 - $(FLOWEY_BIN) e 21 flowey_lib_common::publish_test_results 0 - $FLOWEY_BIN v 21 'flowey_lib_common::ado_task_publish_test_results:0:flowey_lib_common/src/ado_task_publish_test_results.rs' --is-raw-string --condvar flowey_lib_common::publish_test_results:0:flowey_lib_common/src/publish_test_results.rs write-to-env ado floweyvar1 - $FLOWEY_BIN v 21 'flowey_lib_common::publish_test_results:0:flowey_lib_common/src/publish_test_results.rs' write-to-env ado FLOWEY_CONDITION - displayName: run 'virtio_villain_tests' nextest tests - - task: PublishTestResults@2 - inputs: - testResultsFormat: JUnit - testResultsFiles: $(floweyvar1) - testRunTitle: x64-linux-kvm-virtio-villain-vmm-tests - displayName: 'publish test results: x64-linux-kvm-virtio-villain-vmm-tests (JUnit XML)' - condition: and(eq(variables['FLOWEY_CONDITION'], true), succeeded(), not(canceled())) - - bash: |- - set -e - $(FLOWEY_BIN) e 21 flowey_lib_hvlite::_jobs::run_virtio_villain_tests 2 - $(FLOWEY_BIN) e 21 flowey_lib_common::publish_test_results 2 - $(FLOWEY_BIN) e 21 flowey_lib_common::publish_test_results 3 - $(FLOWEY_BIN) e 21 flowey_lib_hvlite::_jobs::run_virtio_villain_tests 4 - displayName: report virtio-villain test results - - bash: $(FLOWEY_BIN) e 21 flowey_lib_common::cache 3 - displayName: 'validate cache entry: cargo-nextest' - - bash: $(FLOWEY_BIN) e 21 flowey_lib_common::cache 7 - displayName: 'validate cache entry: gh-release-download' - job: job15 displayName: clippy [x64-linux-musl, misc nostd], unit tests [x64-linux-musl] pool: @@ -2135,6 +1934,8 @@ jobs: echo "$(FLOWEY_TEMP_DIR)/publish_artifacts/x64-linux-openvmm_vhost" | $FLOWEY_BIN v 9 'artifact_publish_from_x64-linux-openvmm_vhost' --is-raw-string update mkdir -p "$(AgentTempDirNormal)/publish_artifacts/x64-linux-prep_steps" echo "$(FLOWEY_TEMP_DIR)/publish_artifacts/x64-linux-prep_steps" | $FLOWEY_BIN v 9 'artifact_publish_from_x64-linux-prep_steps' --is-raw-string update + mkdir -p "$(AgentTempDirNormal)/publish_artifacts/x64-linux-virtio-villain-tests-archive" + echo "$(FLOWEY_TEMP_DIR)/publish_artifacts/x64-linux-virtio-villain-tests-archive" | $FLOWEY_BIN v 9 'artifact_publish_from_x64-linux-virtio-villain-tests-archive' --is-raw-string update mkdir -p "$(AgentTempDirNormal)/publish_artifacts/x64-linux-vmgs_lib" echo "$(FLOWEY_TEMP_DIR)/publish_artifacts/x64-linux-vmgs_lib" | $FLOWEY_BIN v 9 'artifact_publish_from_x64-linux-vmgs_lib' --is-raw-string update mkdir -p "$(AgentTempDirNormal)/publish_artifacts/x64-linux-vmgstool" @@ -2214,7 +2015,7 @@ jobs: - bash: |- set -e $(FLOWEY_BIN) e 9 flowey_lib_hvlite::init_openvmm_magicpath_protoc 0 - $(FLOWEY_BIN) e 9 flowey_lib_hvlite::init_cross_build 1 + $(FLOWEY_BIN) e 9 flowey_lib_hvlite::init_cross_build 2 displayName: symlink protoc - bash: |- set -e @@ -2227,7 +2028,7 @@ jobs: $(FLOWEY_BIN) e 9 flowey_lib_hvlite::run_cargo_build 5 $(FLOWEY_BIN) e 9 flowey_lib_hvlite::build_openvmm 0 $(FLOWEY_BIN) e 9 flowey_core::pipeline::artifact::publish 0 - $(FLOWEY_BIN) e 9 flowey_lib_hvlite::init_cross_build 3 + $(FLOWEY_BIN) e 9 flowey_lib_hvlite::init_cross_build 4 displayName: split debug symbols - bash: |- set -e @@ -2240,7 +2041,7 @@ jobs: $(FLOWEY_BIN) e 9 flowey_lib_hvlite::run_cargo_build 9 $(FLOWEY_BIN) e 9 flowey_lib_hvlite::build_openvmm_vhost 0 $(FLOWEY_BIN) e 9 flowey_core::pipeline::artifact::publish 1 - $(FLOWEY_BIN) e 9 flowey_lib_hvlite::init_cross_build 6 + $(FLOWEY_BIN) e 9 flowey_lib_hvlite::init_cross_build 7 displayName: split debug symbols - bash: |- set -e @@ -2253,7 +2054,7 @@ jobs: $(FLOWEY_BIN) e 9 flowey_lib_hvlite::run_cargo_build 18 $(FLOWEY_BIN) e 9 flowey_lib_hvlite::build_vmgstool 0 $(FLOWEY_BIN) e 9 flowey_core::pipeline::artifact::publish 2 - $(FLOWEY_BIN) e 9 flowey_lib_hvlite::init_cross_build 5 + $(FLOWEY_BIN) e 9 flowey_lib_hvlite::init_cross_build 6 displayName: split debug symbols - bash: |- set -e @@ -2266,7 +2067,7 @@ jobs: $(FLOWEY_BIN) e 9 flowey_lib_hvlite::run_cargo_build 16 $(FLOWEY_BIN) e 9 flowey_lib_hvlite::build_vmgstool 1 $(FLOWEY_BIN) e 9 flowey_core::pipeline::artifact::publish 3 - $(FLOWEY_BIN) e 9 flowey_lib_hvlite::init_cross_build 4 + $(FLOWEY_BIN) e 9 flowey_lib_hvlite::init_cross_build 5 displayName: split debug symbols - bash: |- set -e @@ -2279,7 +2080,7 @@ jobs: $(FLOWEY_BIN) e 9 flowey_lib_hvlite::build_and_test_vmgs_lib 1 $(FLOWEY_BIN) e 9 flowey_lib_hvlite::build_and_test_vmgs_lib 2 $(FLOWEY_BIN) e 9 flowey_core::pipeline::artifact::publish 4 - $(FLOWEY_BIN) e 9 flowey_lib_hvlite::init_cross_build 2 + $(FLOWEY_BIN) e 9 flowey_lib_hvlite::init_cross_build 3 displayName: test vmgs_lib - bash: |- set -e @@ -2292,7 +2093,7 @@ jobs: $(FLOWEY_BIN) e 9 flowey_lib_hvlite::run_cargo_build 1 $(FLOWEY_BIN) e 9 flowey_lib_hvlite::build_igvmfilegen 0 $(FLOWEY_BIN) e 9 flowey_core::pipeline::artifact::publish 5 - $(FLOWEY_BIN) e 9 flowey_lib_hvlite::init_cross_build 7 + $(FLOWEY_BIN) e 9 flowey_lib_hvlite::init_cross_build 8 displayName: split debug symbols - bash: |- set -e @@ -2311,7 +2112,7 @@ jobs: - bash: |- set -e $(FLOWEY_BIN) e 9 flowey_lib_hvlite::init_openvmm_magicpath_openhcl_sysroot 0 - $(FLOWEY_BIN) e 9 flowey_lib_hvlite::init_cross_build 9 + $(FLOWEY_BIN) e 9 flowey_lib_hvlite::init_cross_build 10 displayName: extract X86_64 sysroot.tar.gz - bash: |- set -e @@ -2324,7 +2125,7 @@ jobs: $(FLOWEY_BIN) e 9 flowey_lib_hvlite::run_cargo_build 7 $(FLOWEY_BIN) e 9 flowey_lib_hvlite::build_openvmm 1 $(FLOWEY_BIN) e 9 flowey_core::pipeline::artifact::publish 7 - $(FLOWEY_BIN) e 9 flowey_lib_hvlite::init_cross_build 10 + $(FLOWEY_BIN) e 9 flowey_lib_hvlite::init_cross_build 11 displayName: split debug symbols - bash: |- set -e @@ -2337,7 +2138,7 @@ jobs: $(FLOWEY_BIN) e 9 flowey_lib_hvlite::run_cargo_build 11 $(FLOWEY_BIN) e 9 flowey_lib_hvlite::build_openvmm_vhost 1 $(FLOWEY_BIN) e 9 flowey_core::pipeline::artifact::publish 8 - $(FLOWEY_BIN) e 9 flowey_lib_hvlite::init_cross_build 11 + $(FLOWEY_BIN) e 9 flowey_lib_hvlite::init_cross_build 12 displayName: split debug symbols - bash: |- set -e @@ -2384,21 +2185,28 @@ jobs: - bash: |- set -e $(FLOWEY_BIN) e 9 flowey_lib_common::install_cargo_nextest 0 - $(FLOWEY_BIN) e 9 flowey_lib_hvlite::init_cross_build 0 + $(FLOWEY_BIN) e 9 flowey_lib_hvlite::init_cross_build 1 displayName: installing cargo-nextest - bash: |- set -e - $(FLOWEY_BIN) e 9 flowey_lib_common::run_cargo_nextest_archive 0 + $(FLOWEY_BIN) e 9 flowey_lib_common::run_cargo_nextest_archive 1 $(FLOWEY_BIN) e 9 flowey_lib_hvlite::build_nextest_vmm_tests 0 $(FLOWEY_BIN) e 9 flowey_core::pipeline::artifact::publish 10 - $(FLOWEY_BIN) e 9 flowey_lib_hvlite::init_cross_build 8 + $(FLOWEY_BIN) e 9 flowey_lib_hvlite::init_cross_build 9 displayName: build + archive 'vmm_tests' nextests - bash: |- set -e - $(FLOWEY_BIN) e 9 flowey_lib_common::run_cargo_nextest_archive 1 + $(FLOWEY_BIN) e 9 flowey_lib_common::run_cargo_nextest_archive 2 $(FLOWEY_BIN) e 9 flowey_lib_hvlite::build_nextest_vmm_tests 1 $(FLOWEY_BIN) e 9 flowey_core::pipeline::artifact::publish 11 + $(FLOWEY_BIN) e 9 flowey_lib_hvlite::init_cross_build 0 displayName: build + archive 'vmm_tests' nextests + - bash: |- + set -e + $(FLOWEY_BIN) e 9 flowey_lib_common::run_cargo_nextest_archive 0 + $(FLOWEY_BIN) e 9 flowey_lib_hvlite::build_nextest_virtio_villain_tests 0 + $(FLOWEY_BIN) e 9 flowey_core::pipeline::artifact::publish 12 + displayName: build + archive 'virtio_villain_tests' nextests - bash: $(FLOWEY_BIN) e 9 flowey_lib_common::cache 3 displayName: 'validate cache entry: cargo-nextest' - bash: $(FLOWEY_BIN) e 9 flowey_lib_common::cache 7 @@ -2427,6 +2235,9 @@ jobs: - publish: $(FLOWEY_TEMP_DIR)/publish_artifacts/x64-linux-prep_steps displayName: 🌼📦 Publish x64-linux-prep_steps artifact: x64-linux-prep_steps + - publish: $(FLOWEY_TEMP_DIR)/publish_artifacts/x64-linux-virtio-villain-tests-archive + displayName: 🌼📦 Publish x64-linux-virtio-villain-tests-archive + artifact: x64-linux-virtio-villain-tests-archive - publish: $(FLOWEY_TEMP_DIR)/publish_artifacts/x64-linux-vmgs_lib displayName: 🌼📦 Publish x64-linux-vmgs_lib artifact: x64-linux-vmgs_lib @@ -2439,6 +2250,198 @@ jobs: - publish: $(FLOWEY_TEMP_DIR)/publish_artifacts/x64-linux-vmm-tests-archive displayName: 🌼📦 Publish x64-linux-vmm-tests-archive artifact: x64-linux-vmm-tests-archive +- job: job21 + displayName: run vmm-tests [x64-linux-kvm-virtio-villain] + pool: + demands: + - ImageOverride -equals ubuntu2404-amd64 + name: openvmm-ado-amd-westus2-v6 + dependsOn: + - job0 + - job9 + condition: and(succeeded(), not(canceled())) + variables: + - name: FLOWEY_TEMP_DIR + value: $(Build.StagingDirectory)/.flowey-internal + steps: + - task: DownloadPipelineArtifact@2 + displayName: 🌼🥾 Download bootstrapped flowey + inputs: + artifact: _internal-flowey-bootstrap-x86_64-linux-uid-1 + path: $(FLOWEY_TEMP_DIR)/bootstrapped-flowey + - task: DownloadPipelineArtifact@2 + displayName: 🌼📦 Download x64-linux-openvmm + inputs: + artifact: x64-linux-openvmm + path: $(FLOWEY_TEMP_DIR)/used_artifacts/x64-linux-openvmm + - task: DownloadPipelineArtifact@2 + displayName: 🌼📦 Download x64-linux-virtio-villain-tests-archive + inputs: + artifact: x64-linux-virtio-villain-tests-archive + path: $(FLOWEY_TEMP_DIR)/used_artifacts/x64-linux-virtio-villain-tests-archive + - bash: | + set -e + AgentTempDirNormal="$(FLOWEY_TEMP_DIR)" + AgentTempDirNormal=$(echo "$AgentTempDirNormal" | sed -e 's|\\|\/|g' -e 's|^\([A-Za-z]\)\:/\(.*\)|/\L\1\E/\2|') + echo "##vso[task.setvariable variable=AgentTempDirNormal;]$AgentTempDirNormal" + + chmod +x $AgentTempDirNormal/bootstrapped-flowey/flowey + FLOWEY_BIN="$AgentTempDirNormal/bootstrapped-flowey/flowey" + echo "##vso[task.setvariable variable=FLOWEY_BIN;]$FLOWEY_BIN" + displayName: Set flowey path + - bash: | + set -e + echo '"debug"' | $FLOWEY_BIN v 21 'FLOWEY_LOG' update + echo "$(FLOWEY_TEMP_DIR)/work" | $FLOWEY_BIN v 21 '_internal_WORKING_DIR' --is-raw-string update + + cat <<'EOF' | tr '[:upper:]' '[:lower:]' | $FLOWEY_BIN v 21 'verbose' update + ${{ parameters.verbose }} + EOF + echo "$(FLOWEY_TEMP_DIR)/used_artifacts/x64-linux-openvmm" | $FLOWEY_BIN v 21 'artifact_use_from_x64-linux-openvmm' --is-raw-string update + echo "$(FLOWEY_TEMP_DIR)/used_artifacts/x64-linux-virtio-villain-tests-archive" | $FLOWEY_BIN v 21 'artifact_use_from_x64-linux-virtio-villain-tests-archive' --is-raw-string update + displayName: 🌼🛫 Initialize job + - bash: $(FLOWEY_BIN) e 21 flowey_lib_hvlite::_jobs::consume_and_test_nextest_virtio_villain_archive 3 + displayName: ensure hypervisor device is accessible + - bash: |- + set -e + $(FLOWEY_BIN) e 21 flowey_lib_common::download_cargo_nextest 0 + $(FLOWEY_BIN) e 21 flowey_lib_common::download_cargo_nextest 1 + $(FLOWEY_BIN) e 21 flowey_lib_common::download_cargo_nextest 2 + $(FLOWEY_BIN) e 21 flowey_lib_common::download_cargo_nextest 3 + displayName: create cargo-nextest cache dir + - bash: |- + set -e + $(FLOWEY_BIN) e 21 flowey_lib_common::cache 0 + $FLOWEY_BIN v 21 'flowey_lib_common::cache:1:flowey_lib_common/src/cache.rs' --is-raw-string write-to-env ado floweyvar3 + $FLOWEY_BIN v 21 'flowey_lib_common::cache:2:flowey_lib_common/src/cache.rs' --is-raw-string write-to-env ado floweyvar4 + displayName: Pre-processing cache vars + - task: Cache@2 + inputs: + key: $(floweyvar4) + path: $(floweyvar3) + cacheHitVar: FLOWEY_CACHE_HITVAR + displayName: 'Restore cache: cargo-nextest' + - bash: |- + set -e + $FLOWEY_BIN v 21 'flowey_lib_common::cache:4:flowey_lib_common/src/cache.rs' --is-raw-string update --env-source FLOWEY_CACHE_HITVAR <<'EOF' + $(FLOWEY_CACHE_HITVAR) + EOF + $(FLOWEY_BIN) e 21 flowey_lib_common::cache 2 + displayName: map ADO hitvar to flowey + - bash: $(FLOWEY_BIN) e 21 flowey_lib_common::download_cargo_nextest 4 + displayName: downloading cargo-nextest + - bash: |- + set -e + $(FLOWEY_BIN) e 21 flowey_lib_common::git_checkout 0 + $FLOWEY_BIN v 21 'flowey_lib_common::git_checkout:0:flowey_lib_common/src/git_checkout.rs' --is-raw-string --condvar flowey_lib_common::git_checkout:1:flowey_lib_common/src/git_checkout.rs write-to-env ado floweyvar2 + $FLOWEY_BIN v 21 'flowey_lib_common::git_checkout:1:flowey_lib_common/src/git_checkout.rs' write-to-env ado FLOWEY_CONDITION + displayName: check if openvmm needs to be cloned + - checkout: self + path: repo0 + fetchTags: false + fetchDepth: 1 + persistCredentials: $(floweyvar2) + submodules: recursive + displayName: checkout repo openvmm + condition: and(eq(variables['FLOWEY_CONDITION'], true), succeeded(), not(canceled())) + - bash: |- + set -e + $FLOWEY_BIN v 21 'flowey_lib_common::git_checkout:4:flowey_lib_common/src/git_checkout.rs' --is-raw-string update --env-source Pipeline.Workspace <<'EOF' + $(Pipeline.Workspace) + EOF + $(FLOWEY_BIN) e 21 flowey_lib_common::git_checkout 3 + displayName: report cloned repo directories + - bash: |- + set -e + $(FLOWEY_BIN) e 21 flowey_lib_common::system_info 0 + $(FLOWEY_BIN) e 21 flowey_lib_hvlite::git_checkout_openvmm_repo 0 + $(FLOWEY_BIN) e 21 flowey_lib_hvlite::_jobs::consume_and_test_nextest_virtio_villain_archive 4 + $(FLOWEY_BIN) e 21 flowey_core::pipeline::artifact::resolve 1 + $(FLOWEY_BIN) e 21 flowey_lib_hvlite::_jobs::consume_and_test_nextest_virtio_villain_archive 5 + $(FLOWEY_BIN) e 21 flowey_core::pipeline::artifact::resolve 0 + displayName: print system info + - bash: $(FLOWEY_BIN) e 21 flowey_lib_hvlite::_jobs::consume_and_test_nextest_virtio_villain_archive 0 + displayName: creating new test content dir + - bash: $(FLOWEY_BIN) e 21 flowey_lib_common::download_gh_release 0 + displayName: create gh-release-download cache dir + - bash: |- + set -e + $(FLOWEY_BIN) e 21 flowey_lib_common::cache 4 + $FLOWEY_BIN v 21 'flowey_lib_common::cache:8:flowey_lib_common/src/cache.rs' --is-raw-string write-to-env ado floweyvar5 + $FLOWEY_BIN v 21 'flowey_lib_common::cache:9:flowey_lib_common/src/cache.rs' --is-raw-string write-to-env ado floweyvar6 + displayName: Pre-processing cache vars + - task: Cache@2 + inputs: + key: $(floweyvar6) + path: $(floweyvar5) + cacheHitVar: FLOWEY_CACHE_HITVAR + displayName: 'Restore cache: gh-release-download' + - bash: |- + set -e + $FLOWEY_BIN v 21 'flowey_lib_common::cache:11:flowey_lib_common/src/cache.rs' --is-raw-string update --env-source FLOWEY_CACHE_HITVAR <<'EOF' + $(FLOWEY_CACHE_HITVAR) + EOF + $(FLOWEY_BIN) e 21 flowey_lib_common::cache 6 + displayName: map ADO hitvar to flowey + - bash: $(FLOWEY_BIN) e 21 flowey_lib_common::download_gh_release 1 + displayName: download artifacts from github releases + - bash: $(FLOWEY_BIN) e 21 flowey_lib_hvlite::resolve_openvmm_test_initrd 0 + displayName: unpack openvmm-test-initrd archives + - bash: $(FLOWEY_BIN) e 21 flowey_lib_hvlite::resolve_openvmm_test_linux_kernel 0 + displayName: unpack openvmm-test-linux archives + - bash: $(FLOWEY_BIN) e 21 flowey_lib_common::install_dist_pkg 0 + displayName: checking if packages need to be installed + - bash: $(FLOWEY_BIN) e 21 flowey_lib_common::install_dist_pkg 1 + displayName: installing packages + - bash: $(FLOWEY_BIN) e 21 flowey_lib_hvlite::download_uefi_mu_msvm 0 + displayName: unpack mu_msvm package (x64) + - bash: $(FLOWEY_BIN) e 21 flowey_lib_hvlite::resolve_openvmm_test_virtio_win 0 + displayName: unpack openvmm-test-virtio-win archive + - bash: $(FLOWEY_BIN) e 21 flowey_lib_hvlite::init_vmm_tests_env 0 + displayName: setting up vmm_tests env + - bash: |- + set -e + $(FLOWEY_BIN) e 21 flowey_lib_hvlite::resolve_virtio_villain 0 + $(FLOWEY_BIN) e 21 flowey_lib_hvlite::_jobs::consume_and_test_nextest_virtio_villain_archive 1 + $(FLOWEY_BIN) e 21 flowey_lib_hvlite::_jobs::consume_and_test_nextest_virtio_villain_archive 2 + $(FLOWEY_BIN) e 21 flowey_lib_hvlite::run_cargo_nextest_run 1 + displayName: unpack virtio-villain artifacts + - bash: $(FLOWEY_BIN) e 21 flowey_lib_common::gen_cargo_nextest_run_cmd 0 + displayName: generate nextest command + - bash: |- + set -e + $(FLOWEY_BIN) e 21 flowey_lib_hvlite::install_vmm_tests_deps 0 + $(FLOWEY_BIN) e 21 flowey_lib_hvlite::run_cargo_nextest_run 0 + displayName: install vmm tests deps (linux) + - bash: |- + set -e + $(FLOWEY_BIN) e 21 flowey_lib_common::run_cargo_nextest_run 0 + $(FLOWEY_BIN) e 21 flowey_lib_common::run_cargo_nextest_run 1 + $(FLOWEY_BIN) e 21 flowey_lib_hvlite::_jobs::consume_and_test_nextest_virtio_villain_archive 7 + $(FLOWEY_BIN) e 21 flowey_lib_common::publish_test_results 1 + $(FLOWEY_BIN) e 21 flowey_lib_common::ado_task_publish_test_results 0 + $(FLOWEY_BIN) e 21 flowey_lib_common::publish_test_results 0 + $FLOWEY_BIN v 21 'flowey_lib_common::ado_task_publish_test_results:0:flowey_lib_common/src/ado_task_publish_test_results.rs' --is-raw-string --condvar flowey_lib_common::publish_test_results:0:flowey_lib_common/src/publish_test_results.rs write-to-env ado floweyvar1 + $FLOWEY_BIN v 21 'flowey_lib_common::publish_test_results:0:flowey_lib_common/src/publish_test_results.rs' write-to-env ado FLOWEY_CONDITION + displayName: run 'virtio_villain_tests' nextest tests + - task: PublishTestResults@2 + inputs: + testResultsFormat: JUnit + testResultsFiles: $(floweyvar1) + testRunTitle: x64-linux-kvm-virtio-villain-vmm-tests + displayName: 'publish test results: x64-linux-kvm-virtio-villain-vmm-tests (JUnit XML)' + condition: and(eq(variables['FLOWEY_CONDITION'], true), succeeded(), not(canceled())) + - bash: |- + set -e + $(FLOWEY_BIN) e 21 flowey_lib_hvlite::_jobs::consume_and_test_nextest_virtio_villain_archive 6 + $(FLOWEY_BIN) e 21 flowey_lib_common::publish_test_results 2 + $(FLOWEY_BIN) e 21 flowey_lib_common::publish_test_results 3 + $(FLOWEY_BIN) e 21 flowey_lib_hvlite::_jobs::consume_and_test_nextest_virtio_villain_archive 8 + displayName: report virtio-villain test results + - bash: $(FLOWEY_BIN) e 21 flowey_lib_common::cache 3 + displayName: 'validate cache entry: cargo-nextest' + - bash: $(FLOWEY_BIN) e 21 flowey_lib_common::cache 7 + displayName: 'validate cache entry: gh-release-download' - job: job8 displayName: build artifacts (for VMM tests) [aarch64-linux] pool: @@ -5277,6 +5280,7 @@ jobs: $(FLOWEY_BIN) e 17 flowey_lib_common::system_info 0 $(FLOWEY_BIN) e 17 flowey_lib_hvlite::git_checkout_openvmm_repo 0 $(FLOWEY_BIN) e 17 flowey_lib_hvlite::run_cargo_nextest_run 0 + $(FLOWEY_BIN) e 17 flowey_core::pipeline::artifact::resolve 3 $(FLOWEY_BIN) e 17 flowey_core::pipeline::artifact::resolve 11 $(FLOWEY_BIN) e 17 flowey_core::pipeline::artifact::resolve 4 $(FLOWEY_BIN) e 17 flowey_core::pipeline::artifact::resolve 5 @@ -5291,7 +5295,6 @@ jobs: $(FLOWEY_BIN) e 17 flowey_core::pipeline::artifact::resolve 14 $(FLOWEY_BIN) e 17 flowey_core::pipeline::artifact::resolve 15 $(FLOWEY_BIN) e 17 flowey_core::pipeline::artifact::resolve 13 - $(FLOWEY_BIN) e 17 flowey_core::pipeline::artifact::resolve 3 displayName: print system info - bash: $(FLOWEY_BIN) e 17 flowey_lib_hvlite::_jobs::consume_and_test_nextest_vmm_tests_archive 0 displayName: creating new test content dir diff --git a/flowey/flowey_hvlite/src/pipelines/checkin_gates.rs b/flowey/flowey_hvlite/src/pipelines/checkin_gates.rs index 6e2b2bf487..b6511518ce 100644 --- a/flowey/flowey_hvlite/src/pipelines/checkin_gates.rs +++ b/flowey/flowey_hvlite/src/pipelines/checkin_gates.rs @@ -203,6 +203,14 @@ impl IntoPipeline for CheckinGatesCli { let (pub_vmm_tests_archive_linux_aarch64, use_vmm_tests_archive_linux_aarch64) = pipeline.new_typed_artifact("aarch64-linux-vmm-tests-archive"); + // virtio-villain nextest archive (built on the linux build machine, + // consumed by the KVM villain test job) + the OpenVMM binary it drives, + // reused from the linux build job below. + let (pub_villain_archive_linux_x86, use_villain_archive_linux_x86) = + pipeline.new_typed_artifact("x64-linux-virtio-villain-tests-archive"); + let mut pub_villain_archive_linux_x86 = Some(pub_villain_archive_linux_x86); + let mut use_openvmm_linux_x86 = None; + // wrap each publish handle in an option, so downstream code can // `.take()` the handle when emitting the corresponding job let mut pub_vmm_tests_archive_linux_x86 = Some(pub_vmm_tests_archive_linux_x86); @@ -803,6 +811,7 @@ impl IntoPipeline for CheckinGatesCli { match arch { CommonArch::X86_64 => { vmm_tests_artifacts_linux_x86.use_openvmm = Some(use_openvmm.clone()); + use_openvmm_linux_x86 = Some(use_openvmm.clone()); vmm_tests_artifacts_linux_x86.use_openvmm_vhost = Some(use_openvmm_vhost.clone()); vmm_tests_artifacts_linux_x86.use_prep_steps = Some(use_prep_steps.clone()); @@ -986,6 +995,23 @@ impl IntoPipeline for CheckinGatesCli { ), } }); + + // Also build the virtio-villain nextest archive on this + // build machine so the KVM villain test job can consume it + // without a Rust toolchain. + let pub_villain_archive_linux_x86 = + pub_villain_archive_linux_x86.take().unwrap(); + job = job.publish(pub_villain_archive_linux_x86, |archive| { + flowey_lib_hvlite::build_nextest_virtio_villain_tests::Request { + target: CommonTriple::Common { + arch, + platform: CommonPlatform::LinuxGnu, + } + .as_triple(), + profile: CommonProfile::from_release(release), + archive, + } + }); } CommonArch::Aarch64 => { let pub_vmm_tests_archive_linux_aarch64 = @@ -1763,9 +1789,12 @@ impl IntoPipeline for CheckinGatesCli { // virtio-villain conformance suite: a separate, parallel per-PR job that // drives OpenVMM under KVM against the guest-side villain test matrix. // - // It runs alongside the vmm_tests jobs (own pool, own artifact) for - // parallelism. The `-vmm-tests` suffix on the label makes the published - // logs artifact (`x64-linux-kvm-virtio-villain-vmm-tests-logs`) match the + // It consumes the villain nextest archive + the OpenVMM binary built by + // the linux build job above, so this test job needs no Rust toolchain + // (matching the vmm_tests build/consume split). It runs alongside the + // vmm_tests jobs for parallelism. The `-vmm-tests` suffix on the label + // makes the published logs artifact + // (`x64-linux-kvm-virtio-villain-vmm-tests-logs`) match the // `upload-petri-results` workflow glob, so villain results land on the // logview website alongside the regular VMM test results. // @@ -1783,6 +1812,10 @@ impl IntoPipeline for CheckinGatesCli { None }; + let use_openvmm = use_openvmm_linux_x86 + .clone() + .expect("linux x86 openvmm artifact built above"); + let villain_job = pipeline .new_job( FlowPlatform::Linux(FlowPlatformLinuxDistro::Ubuntu), @@ -1791,21 +1824,18 @@ impl IntoPipeline for CheckinGatesCli { ) .gh_set_pool(gh_pools::linux_amd_v7_1es()) .ado_set_pool(ado_pools::linux_amd_v6_1es()) - .dep_on( - |ctx| flowey_lib_hvlite::_jobs::run_virtio_villain_tests::Params { + .dep_on(|ctx| { + flowey_lib_hvlite::_jobs::consume_and_test_nextest_virtio_villain_archive::Params { + junit_test_label: test_label, + nextest_villain_archive: ctx + .use_typed_artifact(&use_villain_archive_linux_x86), + openvmm: ctx.use_typed_artifact(&use_openvmm), arch: CommonArch::X86_64, run_ignored: false, - nextest_profile: - flowey_lib_hvlite::run_cargo_nextest_run::NextestProfile::Ci, - publish: Some( - flowey_lib_hvlite::_jobs::run_virtio_villain_tests::VillainPublish { - junit_test_label: test_label, - artifact_dir: pub_villain_results.map(|x| ctx.publish_artifact(x)), - }, - ), + artifact_dir: pub_villain_results.map(|x| ctx.publish_artifact(x)), done: ctx.new_done_handle(), - }, - ) + } + }) .finish(); all_jobs.push(villain_job); } diff --git a/flowey/flowey_hvlite/src/pipelines/virtio_villain_run.rs b/flowey/flowey_hvlite/src/pipelines/virtio_villain_run.rs index ab15ea9740..614049cec6 100644 --- a/flowey/flowey_hvlite/src/pipelines/virtio_villain_run.rs +++ b/flowey/flowey_hvlite/src/pipelines/virtio_villain_run.rs @@ -79,9 +79,6 @@ impl IntoPipeline for VirtioVillainRunCli { |ctx| flowey_lib_hvlite::_jobs::run_virtio_villain_tests::Params { arch, run_ignored, - nextest_profile: - flowey_lib_hvlite::run_cargo_nextest_run::NextestProfile::Default, - publish: None, done: ctx.new_done_handle(), }, ) diff --git a/flowey/flowey_lib_hvlite/src/_jobs/consume_and_test_nextest_virtio_villain_archive.rs b/flowey/flowey_lib_hvlite/src/_jobs/consume_and_test_nextest_virtio_villain_archive.rs new file mode 100644 index 0000000000..f49efb36e3 --- /dev/null +++ b/flowey/flowey_lib_hvlite/src/_jobs/consume_and_test_nextest_virtio_villain_archive.rs @@ -0,0 +1,208 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +//! Consume a pre-built virtio-villain nextest archive and run it against +//! OpenVMM on a KVM test machine. +//! +//! This is the "test half" of the build/consume split (mirroring +//! [`crate::_jobs::consume_and_test_nextest_vmm_tests_archive`]): the archive +//! and the OpenVMM binary are built on a *build* machine (which has protoc, the +//! musl sysroot, etc.) and handed here as artifacts, so this job needs no Rust +//! toolchain — only the runtime bits (OpenVMM, the guest kernel, and the +//! villain guest artifact). +//! +//! Results (JUnit + per-test petri logs) are published so the +//! `upload-petri-results` workflow forwards them to the logview website. The +//! publish step is claimed by the report step, so logs upload even when tests +//! fail. + +use crate::build_nextest_virtio_villain_tests::NextestVirtioVillainTestsArchive; +use crate::build_openvmm::OpenvmmOutput; +use crate::common::CommonArch; +use crate::common::CommonTriple; +use crate::install_vmm_tests_deps::VmmTestsDepSelections; +use crate::run_cargo_nextest_run::NextestProfile; +use flowey::node::prelude::*; +use flowey_lib_common::run_cargo_nextest_run::NextestRunKind; +use std::collections::BTreeMap; + +flowey_request! { + pub struct Params { + /// Artifact label prefix for the published results. To be picked up by + /// the `upload-petri-results` workflow (which globs `*-vmm-tests-logs`), + /// this MUST end in `-vmm-tests` so the logs attachment becomes + /// `-logs`. + pub junit_test_label: String, + /// Pre-built virtio-villain nextest archive. + pub nextest_villain_archive: ReadVar, + /// Pre-built OpenVMM binary (the villain crate launches this). + pub openvmm: ReadVar, + /// Guest/host architecture to test. Phase 1 is Linux-only (KVM). + pub arch: CommonArch, + /// Also run known-failing (ignored) villain tests. + pub run_ignored: bool, + /// Local-backend only: copy JUnit + logs into this published artifact + /// dir. + pub artifact_dir: Option>, + pub done: WriteVar, + } +} + +new_simple_flow_node!(struct Node); + +impl SimpleFlowNode for Node { + type Request = Params; + + fn imports(ctx: &mut ImportCtx<'_>) { + ctx.import::(); + ctx.import::(); + ctx.import::(); + ctx.import::(); + ctx.import::(); + ctx.import::(); + } + + fn process_request(request: Self::Request, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> { + let Params { + junit_test_label, + nextest_villain_archive, + openvmm, + arch, + run_ignored, + artifact_dir, + done, + } = request; + + // Phase 1: Linux host only (villain drives OpenVMM under KVM). + let target = match arch { + CommonArch::X86_64 => CommonTriple::X86_64_LINUX_GNU, + CommonArch::Aarch64 => CommonTriple::AARCH64_LINUX_GNU, + } + .as_triple(); + + // Ad-hoc, step-local dir used as a staging ground for test content + // (OpenVMM binary + guest kernel), mirroring the vmm_tests consume job. + let test_content_dir = ctx.emit_rust_stepv("creating new test content dir", |_| { + |_| Ok(std::env::current_dir()?.absolute()?) + }); + + // Stage OpenVMM + the linux-direct guest kernel into the content dir and + // get the env the villain crate needs (VMM_TESTS_CONTENT_DIR points the + // known-paths resolver at OpenVMM + the kernel; TEST_OUTPUT_PATH is the + // publishable per-test log dir). All the other `register_*` inputs are + // vmm_tests-specific and villain does not use them. + let (test_log_path, get_test_log_path) = ctx.new_var(); + let base_env = ctx.reqv(|get_env| crate::init_vmm_tests_env::Request { + test_content_dir: test_content_dir.clone(), + vmm_tests_target: target.clone(), + register_openvmm: Some(openvmm), + register_openvmm_vhost: None, + register_pipette_windows: None, + register_pipette_linux_musl: None, + register_guest_test_uefi: None, + register_tmks: None, + register_tmk_vmm: None, + register_tmk_vmm_linux_musl: None, + register_vmgstool: None, + register_vmgstool_dev: None, + register_tpm_guest_tests_windows: None, + register_tpm_guest_tests_linux: None, + register_test_igvm_agent_rpc_server: None, + disk_images_dir: None, + register_openhcl_igvm_files: Vec::new(), + get_test_log_path: Some(get_test_log_path), + get_env, + release_igvm_files: None, + use_relative_paths: false, + disable_remote_artifacts: true, + reuse_prepped_vhds: false, + }); + + // Resolve the villain guest artifact (initramfs + tests.tsv) and merge + // its env vars into the base env. + let villain = ctx.reqv(|v| crate::resolve_virtio_villain::Request::Get(arch, v)); + let extra_env = base_env.zip(ctx, villain).map(ctx, |(mut env, a)| { + env.insert( + "VILLAIN_INITRAMFS".to_string(), + a.initramfs.display().to_string(), + ); + env.insert("VILLAIN_TSV".to_string(), a.tsv.display().to_string()); + env + }); + + // Runtime dependencies for the test machine (no Rust toolchain needed). + ctx.config(crate::install_vmm_tests_deps::Config { + selections: Some(VmmTestsDepSelections::Linux), + auto_install: None, + }); + let mut pre_run_deps = vec![ctx.reqv(crate::install_vmm_tests_deps::Request::Install)]; + + // Make /dev/kvm accessible to the test (CI machines only). + if !matches!(ctx.backend(), FlowBackend::Local) { + pre_run_deps.push( + ctx.emit_rust_step("ensure hypervisor device is accessible", |_| { + |rt| { + if Path::new("/dev/kvm").exists() { + flowey::shell_cmd!(rt, "sudo chmod a+rw /dev/kvm").run()?; + } + Ok(()) + } + }), + ); + } + + // Use the repo's nextest config so the villain per-test slow-timeout + // overrides (`.config/nextest.toml`) apply. + let openvmm_repo_path = ctx.reqv(crate::git_checkout_openvmm_repo::req::GetRepoDir); + let nextest_config_file = openvmm_repo_path + .clone() + .map(ctx, |p| p.join(".config").join("nextest.toml")); + + let nextest_archive = nextest_villain_archive.map(ctx, |x| x.archive_file); + + let results = ctx.reqv(|results| crate::run_cargo_nextest_run::Request { + friendly_name: "virtio_villain_tests".into(), + run_kind: NextestRunKind::RunFromArchive { + archive_file: nextest_archive, + target: None, + nextest_bin: None, + }, + nextest_profile: NextestProfile::Ci, + nextest_filter_expr: None, + nextest_working_dir: Some(openvmm_repo_path), + nextest_config_file: Some(nextest_config_file), + run_ignored, + extra_env: Some(extra_env), + pre_run_deps, + results, + }); + + // Publish JUnit + per-test petri logs so the upload-petri-results + // workflow forwards them to logview. The publish step is claimed by the + // report step below, so logs upload even when tests fail. + let test_log_path = test_log_path.depending_on(ctx, &results); + let junit_xml = results.clone().map(ctx, |r| r.junit_xml); + let reported_results = ctx.reqv(|v| flowey_lib_common::publish_test_results::Request { + junit_xml, + test_label: junit_test_label, + attachments: BTreeMap::from([("logs".to_string(), (test_log_path, false))]), + output_dir: artifact_dir, + done: v, + }); + + ctx.emit_rust_step("report virtio-villain test results", |ctx| { + reported_results.claim(ctx); + done.claim(ctx); + let results = results.claim(ctx); + move |rt| { + let results = rt.read(results); + if !results.all_tests_passed { + anyhow::bail!("virtio-villain tests failed"); + } + Ok(()) + } + }); + + Ok(()) + } +} diff --git a/flowey/flowey_lib_hvlite/src/_jobs/mod.rs b/flowey/flowey_lib_hvlite/src/_jobs/mod.rs index c68ce8c845..8b4082c56f 100644 --- a/flowey/flowey_lib_hvlite/src/_jobs/mod.rs +++ b/flowey/flowey_lib_hvlite/src/_jobs/mod.rs @@ -21,6 +21,7 @@ pub mod check_openvmm_hcl_size; pub mod check_xtask_fmt; pub mod consolidate_and_publish_gh_pages; pub mod consume_and_test_nextest_unit_tests_archive; +pub mod consume_and_test_nextest_virtio_villain_archive; pub mod consume_and_test_nextest_vmm_tests_archive; pub mod local_build_and_run_nextest_vmm_tests; pub mod local_build_igvm; diff --git a/flowey/flowey_lib_hvlite/src/_jobs/run_virtio_villain_tests.rs b/flowey/flowey_lib_hvlite/src/_jobs/run_virtio_villain_tests.rs index 73cecbaae2..7d0a8e4fb0 100644 --- a/flowey/flowey_lib_hvlite/src/_jobs/run_virtio_villain_tests.rs +++ b/flowey/flowey_lib_hvlite/src/_jobs/run_virtio_villain_tests.rs @@ -1,20 +1,21 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -//! Job: build OpenVMM, stage the openvmm-deps guest kernel, resolve the +//! Local job: build OpenVMM, stage the openvmm-deps guest kernel, resolve the //! virtio-villain artifact, and run the `virtio_villain_tests` nextest suite //! against OpenVMM. //! -//! This is the "thin sibling" of the full `vmm_tests` runner: the villain crate -//! resolves everything else it needs (the guest Linux kernel, the OpenVMM -//! binary) from the known-paths magicpath / target dir, so all this job has to -//! do is make those two things exist and hand the crate its guest artifact via -//! the `VILLAIN_INITRAMFS` / `VILLAIN_TSV` env vars. +//! This is the *local* (xflowey `virtio-villain-run`) runner: it builds +//! everything from source on the developer's machine and runs it in one shot. +//! CI instead splits the work — [`crate::build_nextest_virtio_villain_tests`] +//! builds a nextest archive on a build machine and +//! [`crate::_jobs::consume_and_test_nextest_virtio_villain_archive`] runs it on +//! a KVM test machine that has no Rust toolchain. //! -//! It serves two callers: the `virtio-villain-run` xflowey pipeline (local -//! dev, `NextestProfile::Default`, no publishing) and the checkin-gates CI job -//! (`NextestProfile::Ci`, `publish: Some(..)` so JUnit + per-test petri logs -//! reach the logview website via the `upload-petri-results` workflow). +//! The villain crate resolves everything else it needs (the guest Linux kernel, +//! the OpenVMM binary) from the known-paths magicpath / target dir, so all this +//! job has to do is make those two things exist and hand the crate its guest +//! artifact via the `VILLAIN_INITRAMFS` / `VILLAIN_TSV` env vars. //! //! Known-failing villain tests are marked *ignored* by the harness, so they are //! skipped by default. Pass `run_ignored` to run them too (e.g. during fix @@ -31,28 +32,12 @@ use flowey_lib_common::run_cargo_nextest_run::build_params::NextestBuildParams; use flowey_lib_common::run_cargo_nextest_run::build_params::TestPackages; use std::collections::BTreeMap; -/// Publish JUnit + per-test petri logs so results reach the logview website. -#[derive(Serialize, Deserialize)] -pub struct VillainPublish { - /// Artifact label prefix for the published results. To be picked up by the - /// `upload-petri-results` workflow (which globs `*-vmm-tests-logs`), this - /// MUST end in `-vmm-tests` so the logs attachment becomes - /// `