microsoft/openvmm
Publicmirrored fromhttps://github.com/microsoft/openvmmAvailable
Guide/src/dev_guide/tests/vmm.md
180lines · modecode
| 1 | # VMM Tests |
| 2 | |
| 3 | The OpenVMM repo contains a set of "heavyweight" VMM tests that fully boot a |
| 4 | virtual machine and run validation against it. Unlike Unit tests, these are all |
| 5 | centralized in a single top-level `vmm_tests` directory. |
| 6 | |
| 7 | The OpenVMM PR and CI pipelines will run the full test suite on all supported |
| 8 | platforms; you'd typically run only the tests relevant to the changes you're |
| 9 | working on. |
| 10 | |
| 11 | ## Writing VMM Tests |
| 12 | |
| 13 | To streamline the process of booting and interacting with VMs during VMM tests, the |
| 14 | OpenVMM project uses an in-house test framework/library called `petri`. |
| 15 | |
| 16 | The library does not yet have a stable API, so at this time, the best way to |
| 17 | learn how to write new VMM tests is by reading through the existing corpus of |
| 18 | tests (start with vmm_tests/vmm_tests/tests/tests/multiarch.rs), |
| 19 | as well as reading through `petri`'s rustdoc-generated API docs. |
| 20 | |
| 21 | The tests are currently generated using a macro (`#[vmm_test]`) that allows |
| 22 | the same test body to be run in a variety of scenarios, with different guest |
| 23 | operating systems, firmwares, and VMMs (including Hyper-V, which is useful |
| 24 | for testing certain OpenHCL features that aren't supported when using |
| 25 | OpenVMM as the host VMM). |
| 26 | |
| 27 | ### "heavy" tests |
| 28 | |
| 29 | The global [nextest.toml](https://github.com/microsoft/openvmm/blob/main/.config/nextest.toml) |
| 30 | configures how tests run in our test environments. The `default` and `ci` profiles |
| 31 | control things like timeouts, and how many resources we allocate to a given test. The number |
| 32 | of required threads is a fuzzy requirement relative to the number of VPs consumed by the VM under |
| 33 | test, the amount of memory your test needs, the host test framework (petri itself), and so on. |
| 34 | |
| 35 | We have some pre-defined overrides that perform filterset matching on test name. These overrides |
| 36 | are curated to balance individual trial (test case) performance against overall concurrency on |
| 37 | engineers' local machines and in CI. Put these special words in your test to opt in to that override: |
| 38 | |
| 39 | - `heavy` - if your test is heavier than the typical vmm_test. E.g., your test explicitly requests 16 virtual processors. |
| 40 | - `very_heavy` if your test is heavier than a `heavy` test. E.g., your test explicitly requests 32 virtual processors. |
| 41 | |
| 42 | ## Running VMM Tests (Flowey) |
| 43 | |
| 44 | The easiest way to run the VMM tests locally is using the |
| 45 | `cargo xflowey vmm-tests` command. To see the most up-to-date options, run: |
| 46 | `cargo xflowey vmm-tests --help`. When running Hyper-V tests, you will need |
| 47 | to use an administrator terminal window (this works even if you are running |
| 48 | from WSL2). When running Windows tests, the output dir should be on the |
| 49 | Windows file system. For example, from WSL2: |
| 50 | |
| 51 | ```bash |
| 52 | cargo xflowey vmm-tests --target windows-x64 --dir /mnt/e/vmm_tests |
| 53 | ``` |
| 54 | |
| 55 | This command will build or download all the test dependencies and copy them |
| 56 | to a self-contained folder that can be copied to another system for testing. |
| 57 | The folder will contain scripts for installing dependencies |
| 58 | (install_deps.ps1 on Windows) and running the tests (run.ps1 on Windows). |
| 59 | You can either specify a list of flags to disable certain tests and avoid |
| 60 | building/downloading some dependencies, or you can specify a custom |
| 61 | [nextest filter](https://nexte.st/docs/filtersets/) and list of artifacts. |
| 62 | In this case, all possible dependencies will be obtained since deriving them |
| 63 | from a test filter is not yet supported. |
| 64 | |
| 65 | ## Running VMM Tests (Manual) |
| 66 | |
| 67 | ```admonish tip |
| 68 | Note: We recommend using [cargo-nextest](https://nexte.st/) to run unit / VMM |
| 69 | tests. It is a significant improvement over the built-in `cargo test` runner, |
| 70 | and is the test runner we use in all our CI pipelines. |
| 71 | |
| 72 | You can install it locally by running: `cargo install cargo-nextest --locked` |
| 73 | |
| 74 | See the [cargo-nextest](https://nexte.st/) documentation for more info. |
| 75 | ``` |
| 76 | |
| 77 | You can directly invoke `cargo test` or `cargo nextest` to run the vmm |
| 78 | tests manually. |
| 79 | |
| 80 | Unlike Unit Tests, VMM tests may rely on additional external artifacts in order |
| 81 | to run. e.g: Virtual Disk Images, pre-built OpenHCL binaries, UEFI / PCAT |
| 82 | firmware blobs, etc. |
| 83 | |
| 84 | As such, the first step in running a VMM test is to ensure you have acquired all |
| 85 | external test artifacts it may depend upon. |
| 86 | |
| 87 | The VMM test infrastructure does not automatically fetch / rebuild |
| 88 | necessary artifacts unless you are using [flowey](#running-vmm-tests-flowey). |
| 89 | However, the test infrastructure is designed to report clear |
| 90 | and actionable error messages whenever a required test artifact cannot be found, |
| 91 | which provide detailed instructions on how to build / acquire the missing |
| 92 | artifact. Some dependencies can only be built on Linux (OpenHCL and Linux |
| 93 | pipette, for example). If you are building on Linux and want to run Windows |
| 94 | guest tests, pipette will need to be |
| 95 | [cross compiled for Windows](#linux-cross-compiling-pipetteexe). |
| 96 | |
| 97 | ```admonish warning |
| 98 | `cargo nextest run` won't rebuild any of your changes. Make sure you `cargo build` |
| 99 | or `cargo xflowey igvm [RECIPE]` first! |
| 100 | ``` |
| 101 | |
| 102 | VMM tests are run using standard Rust test infrastructure, and are invoked via |
| 103 | `cargo test` / `cargo nextest`. |
| 104 | |
| 105 | ```bash |
| 106 | cargo nextest run -p vmm_tests [TEST_FILTERS] |
| 107 | ``` |
| 108 | |
| 109 | For example, to run a simple VMM test that simply boots using UEFI: |
| 110 | |
| 111 | ```bash |
| 112 | cargo nextest run -p vmm_tests multiarch::openvmm_uefi_x64_frontpage |
| 113 | ``` |
| 114 | |
| 115 | And, for further example, to rebuild everything* and run all* the tests |
| 116 | (see below for details on these steps): |
| 117 | |
| 118 | *This will not work for Hyper-V tests. TMK tests need additional build steps. |
| 119 | |
| 120 | ```bash |
| 121 | # Install (most) of the dependencies; cargo nextest run may tell you |
| 122 | # about other deps. |
| 123 | rustup target add x86_64-unknown-none |
| 124 | rustup target add x86_64-unknown-uefi |
| 125 | rustup target add x86_64-pc-windows-msvc |
| 126 | sudo apt install clang-tools-14 lld-14 |
| 127 | |
| 128 | cargo install cargo-nextest --locked |
| 129 | |
| 130 | cargo xtask guest-test download-image |
| 131 | cargo xtask guest-test uefi --bootx64 |
| 132 | |
| 133 | # Rebuild all, and run all tests |
| 134 | cargo build --target x86_64-pc-windows-msvc -p pipette |
| 135 | cargo build --target x86_64-unknown-linux-musl -p pipette |
| 136 | |
| 137 | cargo build --target x86_64-pc-windows-msvc -p openvmm |
| 138 | |
| 139 | cargo xflowey build-igvm x64-test-linux-direct |
| 140 | cargo xflowey build-igvm x64-cvm |
| 141 | cargo xflowey build-igvm x64 |
| 142 | |
| 143 | cargo nextest run --target x86_64-pc-windows-msvc -p vmm_tests --filter-expr 'all() & !test(hyperv) & !test(tmk)' |
| 144 | ``` |
| 145 | |
| 146 | ### \[Linux] Cross-compiling `pipette.exe` |
| 147 | |
| 148 | These commands might use the test agent (`pipette`) that is put inside the VM, |
| 149 | and if the host machine OS and the guest machine OS are different, a setup |
| 150 | is required for cross-building. The recommended approach is to use WSL2 and |
| 151 | cross-compile using the freely available Microsoft Visual Studio Build Tools |
| 152 | or Microsoft Visual Studio Community Edition as described in |
| 153 | [\[WSL2\] Cross Compiling from WSL2 to Windows](../getting_started/cross_compile.md) |
| 154 | |
| 155 | If that is not possible, here is another option that relies on [MinGW-w64](https://www.mingw-w64.org/) |
| 156 | and doesn't require installing Windows: |
| 157 | |
| 158 | ```bash |
| 159 | # Do 1 once, do 2 as needed. |
| 160 | # |
| 161 | # 1. Setup the toolchain |
| 162 | rustup target add x86_64-pc-windows-gnu |
| 163 | sudo apt-get install mingw-w64-x86-64-dev |
| 164 | mingw-genlib -a x86_64 ./support/pal/api-ms-win-security-base-private-l1-1-1.def |
| 165 | sudo mv libapi-ms-win-security-base-private-l1-1-1.a /usr/x86_64-w64-mingw32/lib |
| 166 | |
| 167 | # 2. Build Pipette (builds target/x86_64-pc-windows-gnu/debug/pipette.exe first) |
| 168 | cargo build --target x86_64-pc-windows-gnu -p pipette |
| 169 | ``` |
| 170 | |
| 171 | ```bash |
| 172 | # Run a test |
| 173 | cargo nextest run -p vmm_tests multiarch::openvmm_uefi_x64_windows_datacenter_core_2022_x64_boot |
| 174 | ``` |
| 175 | |
| 176 | ### Printing logs for VMM Tests |
| 177 | |
| 178 | In order to see the OpenVMM logs while running a VMM test, do the following: |
| 179 | 1. Add the `--no-capture` flag to your `cargo nextest` command. |
| 180 | 2. Set `OPENVMM_LOG=trace`, replacing `trace` with the log level you want to view. |
| 181 | |