1*bb4ee6a4SAndroid Build Coastguard Worker# Testing 2*bb4ee6a4SAndroid Build Coastguard Worker 3*bb4ee6a4SAndroid Build Coastguard WorkerCrosvm runs on a variety of platforms with a significant amount of platform-specific code. Testing 4*bb4ee6a4SAndroid Build Coastguard Workeron all the supported platforms is crucial to keep crosvm healthy. 5*bb4ee6a4SAndroid Build Coastguard Worker 6*bb4ee6a4SAndroid Build Coastguard Worker## Types of tests 7*bb4ee6a4SAndroid Build Coastguard Worker 8*bb4ee6a4SAndroid Build Coastguard Worker### Unit Tests 9*bb4ee6a4SAndroid Build Coastguard Worker 10*bb4ee6a4SAndroid Build Coastguard WorkerUnit tests are your standard rust tests embedded with the rest of the code in `src/` and wrapped in 11*bb4ee6a4SAndroid Build Coastguard Workera `#[cfg(test)]` attribute. 12*bb4ee6a4SAndroid Build Coastguard Worker 13*bb4ee6a4SAndroid Build Coastguard WorkerUnit tests **cannot make any guarantees on the runtime environment**. Avoid doing the following in 14*bb4ee6a4SAndroid Build Coastguard Workerunit tests: 15*bb4ee6a4SAndroid Build Coastguard Worker 16*bb4ee6a4SAndroid Build Coastguard Worker- Avoid kernel features such as io_uring or userfaultfd, which may not be available on all kernels. 17*bb4ee6a4SAndroid Build Coastguard Worker- Avoid functionality that requires privileges (e.g. CAP_NET_ADMIN) 18*bb4ee6a4SAndroid Build Coastguard Worker- Avoid spawning threads or processes 19*bb4ee6a4SAndroid Build Coastguard Worker- Avoid accessing kernel devices 20*bb4ee6a4SAndroid Build Coastguard Worker- Avoid global state in unit tests 21*bb4ee6a4SAndroid Build Coastguard Worker 22*bb4ee6a4SAndroid Build Coastguard WorkerThis allows us to execute unit tests for any platform using emulators such as qemu-user-static or 23*bb4ee6a4SAndroid Build Coastguard Workerwine64. 24*bb4ee6a4SAndroid Build Coastguard Worker 25*bb4ee6a4SAndroid Build Coastguard Worker### Documentation tests 26*bb4ee6a4SAndroid Build Coastguard Worker 27*bb4ee6a4SAndroid Build Coastguard WorkerRust's 28*bb4ee6a4SAndroid Build Coastguard Worker[documentation tests](https://doc.rust-lang.org/rustdoc/write-documentation/documentation-tests.html) 29*bb4ee6a4SAndroid Build Coastguard Workercan be used to provide examples as part of the documentation that is verified by CI. 30*bb4ee6a4SAndroid Build Coastguard Worker 31*bb4ee6a4SAndroid Build Coastguard WorkerDocumentation tests are slow and not run as part of the usual workflows, but can be run locally 32*bb4ee6a4SAndroid Build Coastguard Workerwith: 33*bb4ee6a4SAndroid Build Coastguard Worker 34*bb4ee6a4SAndroid Build Coastguard Worker```sh 35*bb4ee6a4SAndroid Build Coastguard Worker./tools/presubmit doc_tests 36*bb4ee6a4SAndroid Build Coastguard Worker``` 37*bb4ee6a4SAndroid Build Coastguard Worker 38*bb4ee6a4SAndroid Build Coastguard Worker### Integration tests 39*bb4ee6a4SAndroid Build Coastguard Worker 40*bb4ee6a4SAndroid Build Coastguard WorkerCargo has native support for 41*bb4ee6a4SAndroid Build Coastguard Worker[integration testing](https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html). 42*bb4ee6a4SAndroid Build Coastguard WorkerIntegration tests are written just like unit tests, but live in a separate directory at `tests/`. 43*bb4ee6a4SAndroid Build Coastguard Worker 44*bb4ee6a4SAndroid Build Coastguard WorkerIntegration tests **guarantee that the test has privileged access to the test environment**. They 45*bb4ee6a4SAndroid Build Coastguard Workerare only executed when a device-under-test (DUT) is specified when running tests: 46*bb4ee6a4SAndroid Build Coastguard Worker 47*bb4ee6a4SAndroid Build Coastguard Worker```sh 48*bb4ee6a4SAndroid Build Coastguard Worker./tools/run_tests --dut=vm|host 49*bb4ee6a4SAndroid Build Coastguard Worker``` 50*bb4ee6a4SAndroid Build Coastguard Worker 51*bb4ee6a4SAndroid Build Coastguard Worker### End To End (E2E) tests 52*bb4ee6a4SAndroid Build Coastguard Worker 53*bb4ee6a4SAndroid Build Coastguard WorkerEnd to end tests live in the `e2e_tests` crate. The crate provides a framework to boot a guest with 54*bb4ee6a4SAndroid Build Coastguard Workercrosvm and execut commands in the guest to validate functionality at a high level. 55*bb4ee6a4SAndroid Build Coastguard Worker 56*bb4ee6a4SAndroid Build Coastguard WorkerE2E tests are executed just like integration tests. By giving 57*bb4ee6a4SAndroid Build Coastguard Worker[nextest's filter expressions](https://nexte.st/book/filter-expressions), you can run a subset of 58*bb4ee6a4SAndroid Build Coastguard Workerthe tests. 59*bb4ee6a4SAndroid Build Coastguard Worker 60*bb4ee6a4SAndroid Build Coastguard Worker```sh 61*bb4ee6a4SAndroid Build Coastguard Worker# Run all e2e tests 62*bb4ee6a4SAndroid Build Coastguard Worker./tools/run_tests --dut=vm --filter-expr 'package(e2e_tests)' 63*bb4ee6a4SAndroid Build Coastguard Worker# Run e2e tests whose name contains the string 'boot'. 64*bb4ee6a4SAndroid Build Coastguard Worker./tools/run_tests --dut=vm --filter-expr 'package(e2e_tests) and test(boot)' 65*bb4ee6a4SAndroid Build Coastguard Worker``` 66*bb4ee6a4SAndroid Build Coastguard Worker 67*bb4ee6a4SAndroid Build Coastguard Worker### Downstream Product tests 68*bb4ee6a4SAndroid Build Coastguard Worker 69*bb4ee6a4SAndroid Build Coastguard WorkerEach downstream product that uses crosvm is performing their own testing, e.g. ChromeOS is running 70*bb4ee6a4SAndroid Build Coastguard Workerhigh level testing of its VM features on ChromeOS hardware, while AOSP is running testing of their 71*bb4ee6a4SAndroid Build Coastguard WorkerVM features on AOSP hardware. 72*bb4ee6a4SAndroid Build Coastguard Worker 73*bb4ee6a4SAndroid Build Coastguard WorkerUpstream crosvm is not involved in these tests and they are not executed in crosvm CI. 74*bb4ee6a4SAndroid Build Coastguard Worker 75*bb4ee6a4SAndroid Build Coastguard Worker## Parallel test execution 76*bb4ee6a4SAndroid Build Coastguard Worker 77*bb4ee6a4SAndroid Build Coastguard WorkerCrosvm tests are executed in parallel, each test case in its own process via 78*bb4ee6a4SAndroid Build Coastguard Worker[cargo nextest](http://nexte.st). 79*bb4ee6a4SAndroid Build Coastguard Worker 80*bb4ee6a4SAndroid Build Coastguard WorkerThis requires tests to be cautious about global state, especially integration tests which interact 81*bb4ee6a4SAndroid Build Coastguard Workerwith system devices. 82*bb4ee6a4SAndroid Build Coastguard Worker 83*bb4ee6a4SAndroid Build Coastguard WorkerIf you require exclusive access to a device or file, you have to use 84*bb4ee6a4SAndroid Build Coastguard Worker[file-based locking](https://docs.rs/named-lock/latest/named_lock) to prevent access by other test 85*bb4ee6a4SAndroid Build Coastguard Workerprocesses. 86*bb4ee6a4SAndroid Build Coastguard Worker 87*bb4ee6a4SAndroid Build Coastguard Worker## Platforms tested 88*bb4ee6a4SAndroid Build Coastguard Worker 89*bb4ee6a4SAndroid Build Coastguard WorkerThe platforms below can all be tested using `tools/run_tests -p $platform`. The table indicates how 90*bb4ee6a4SAndroid Build Coastguard Workerthese tests are executed: 91*bb4ee6a4SAndroid Build Coastguard Worker 92*bb4ee6a4SAndroid Build Coastguard Worker| Platform | Build | Unit Tests | Integration Tests | E2E Tests | 93*bb4ee6a4SAndroid Build Coastguard Worker| :-------------------------- | :---: | :-----------------------: | :---------------: | :-------: | 94*bb4ee6a4SAndroid Build Coastguard Worker| x86_64 (linux) | ✅ | ✅ | ✅ | ✅ | 95*bb4ee6a4SAndroid Build Coastguard Worker| aarch64 (linux) | ✅ | ✅ (qemu-user[^qemu-user]) | ✅ (qemu[^qemu]) | ❌ | 96*bb4ee6a4SAndroid Build Coastguard Worker| armhf (linux) | ✅ | ✅ (qemu-user[^qemu-user]) | ❌ | ❌ | 97*bb4ee6a4SAndroid Build Coastguard Worker| mingw64[^windows] (linux) | | (wine64) | ❌ | ❌ | 98*bb4ee6a4SAndroid Build Coastguard Worker| mingw64[^windows] (windows) | | | | ❌ | 99*bb4ee6a4SAndroid Build Coastguard Worker 100*bb4ee6a4SAndroid Build Coastguard WorkerCrosvm CI will use the same configuration as `tools/run_tests`. 101*bb4ee6a4SAndroid Build Coastguard Worker 102*bb4ee6a4SAndroid Build Coastguard Worker## Debugging Tips 103*bb4ee6a4SAndroid Build Coastguard Worker 104*bb4ee6a4SAndroid Build Coastguard WorkerHere are some tips for developing or/and debugging crosvm tests. 105*bb4ee6a4SAndroid Build Coastguard Worker 106*bb4ee6a4SAndroid Build Coastguard Worker### Enter a test VM to see logs 107*bb4ee6a4SAndroid Build Coastguard Worker 108*bb4ee6a4SAndroid Build Coastguard WorkerWhen you run a test on a VM with `./tools/run_tests --dut=vm`, if the test fails, you'll see 109*bb4ee6a4SAndroid Build Coastguard Workerextracted log messages. To see the full messages or monitor the test process during the runtime, you 110*bb4ee6a4SAndroid Build Coastguard Workermay want to enter the test VM. 111*bb4ee6a4SAndroid Build Coastguard Worker 112*bb4ee6a4SAndroid Build Coastguard WorkerFirst, enter the VM's shell and start printing the syslog: 113*bb4ee6a4SAndroid Build Coastguard Worker 114*bb4ee6a4SAndroid Build Coastguard Worker```console 115*bb4ee6a4SAndroid Build Coastguard Worker$ ./tools/dev_container # Enter the dev_container 116*bb4ee6a4SAndroid Build Coastguard Worker$ ./tools/x86vm shell # Enter the test VM 117*bb4ee6a4SAndroid Build Coastguard Workercrosvm@testvm-x8664:~$ journalctl -f 118*bb4ee6a4SAndroid Build Coastguard Worker# syslog messages will be printed... 119*bb4ee6a4SAndroid Build Coastguard Worker``` 120*bb4ee6a4SAndroid Build Coastguard Worker 121*bb4ee6a4SAndroid Build Coastguard WorkerThen, open another terminal and run a test: 122*bb4ee6a4SAndroid Build Coastguard Worker 123*bb4ee6a4SAndroid Build Coastguard Worker```console 124*bb4ee6a4SAndroid Build Coastguard Worker$ ./tools/run_tests --dut=vm --filter-expr 'package(e2e_tests) and test(boot)' 125*bb4ee6a4SAndroid Build Coastguard Worker``` 126*bb4ee6a4SAndroid Build Coastguard Worker 127*bb4ee6a4SAndroid Build Coastguard WorkerSo you'll see the crosvm log in the first terminal. 128*bb4ee6a4SAndroid Build Coastguard Worker 129*bb4ee6a4SAndroid Build Coastguard Worker[^qemu-user]: qemu-aarch64-static or qemu-arm-static translate instructions into x86 and executes them on the 130*bb4ee6a4SAndroid Build Coastguard Worker host kernel. This works well for unit tests, but will fail when interacting with platform 131*bb4ee6a4SAndroid Build Coastguard Worker specific kernel features. 132*bb4ee6a4SAndroid Build Coastguard Worker 133*bb4ee6a4SAndroid Build Coastguard Worker[^qemu]: run_tests will launch a VM for testing in the background. This VM is using full system 134*bb4ee6a4SAndroid Build Coastguard Worker emulation, which causes tests to be slow. Also not all aarch64 features are properly emulated, 135*bb4ee6a4SAndroid Build Coastguard Worker which prevents us from running e2e tests. 136*bb4ee6a4SAndroid Build Coastguard Worker 137*bb4ee6a4SAndroid Build Coastguard Worker[^windows]: Windows builds of crosvm are a work in progress. Some tests are executed via wine64 on linux 138