1*03ce13f7SAndroid Build Coastguard Worker# Regres - SwiftShader automated testing 2*03ce13f7SAndroid Build Coastguard Worker 3*03ce13f7SAndroid Build Coastguard Worker## Introduction 4*03ce13f7SAndroid Build Coastguard Worker 5*03ce13f7SAndroid Build Coastguard WorkerRegres is a collection of tools to perform [dEQP](https://github.com/KhronosGroup/VK-GL-CTS) 6*03ce13f7SAndroid Build Coastguard Workerpresubmit and continuous integration testing and code coverage evaluation for 7*03ce13f7SAndroid Build Coastguard WorkerSwiftShader. 8*03ce13f7SAndroid Build Coastguard Worker 9*03ce13f7SAndroid Build Coastguard WorkerRegres provides: 10*03ce13f7SAndroid Build Coastguard Worker 11*03ce13f7SAndroid Build Coastguard Worker* [Presubmit testing](#presubmit-testing) - An automatic Vulkan 12*03ce13f7SAndroid Build Coastguard Worker dEQP test run for each Gerrit patchset put up for review. 13*03ce13f7SAndroid Build Coastguard Worker* [Continuous integration testing](#daily-run-continuous-integration-testing) - 14*03ce13f7SAndroid Build Coastguard Worker A Vulkan dEQP test run performed against the `master` branch each night. \ 15*03ce13f7SAndroid Build Coastguard Worker This nightly run also produces code coverage information which can be viewed at 16*03ce13f7SAndroid Build Coastguard Worker [swiftshader-regres.github.io/swiftshader-coverage](https://swiftshader-regres.github.io/swiftshader-coverage/). 17*03ce13f7SAndroid Build Coastguard Worker* [Local dEQP test runner](#local-dEQP-test-runner) Provides a local tool for 18*03ce13f7SAndroid Build Coastguard Worker efficiently running a number of dEQP tests based wildcard or regex name 19*03ce13f7SAndroid Build Coastguard Worker matching. 20*03ce13f7SAndroid Build Coastguard Worker 21*03ce13f7SAndroid Build Coastguard WorkerThe Regres source root directory is at [`<swiftshader>/tests/regres/`](https://cs.opensource.google/swiftshader/SwiftShader/+/master:tests/regres/). 22*03ce13f7SAndroid Build Coastguard Worker 23*03ce13f7SAndroid Build Coastguard Worker## Presubmit testing 24*03ce13f7SAndroid Build Coastguard Worker 25*03ce13f7SAndroid Build Coastguard WorkerRegres monitors changes that have been [put up for review with Gerrit](https://swiftshader-review.googlesource.com/q/status:open). 26*03ce13f7SAndroid Build Coastguard Worker 27*03ce13f7SAndroid Build Coastguard WorkerOnce a new [qualifying](#qualifying) patchset has been found, regres will 28*03ce13f7SAndroid Build Coastguard Workercheckout, build and test the change against the parent changelist. \ 29*03ce13f7SAndroid Build Coastguard WorkerAny differences in results are reported as a review comment on the change 30*03ce13f7SAndroid Build Coastguard Worker[[example]](https://swiftshader-review.googlesource.com/c/SwiftShader/+/46369/5#message-4f09ea3e6d01ed94ae26183c8b6c547c90492c12). 31*03ce13f7SAndroid Build Coastguard Worker 32*03ce13f7SAndroid Build Coastguard Worker### Qualifying 33*03ce13f7SAndroid Build Coastguard Worker 34*03ce13f7SAndroid Build Coastguard WorkerAs Regres may be running externally authored code on Google hardware, 35*03ce13f7SAndroid Build Coastguard WorkerRegres will only test a change if it is authored by or reviewed by a Googler. 36*03ce13f7SAndroid Build Coastguard Worker 37*03ce13f7SAndroid Build Coastguard WorkerOnly the most recent patchset of a change will be tested. If a new patchset is 38*03ce13f7SAndroid Build Coastguard Workerpushed while the previous is currently being tested, then testing will continue 39*03ce13f7SAndroid Build Coastguard Workerto completion and the previous patchsets will be posted, and the new patchset 40*03ce13f7SAndroid Build Coastguard Workerwill be queued for testing. 41*03ce13f7SAndroid Build Coastguard Worker 42*03ce13f7SAndroid Build Coastguard Worker### Prioritization 43*03ce13f7SAndroid Build Coastguard Worker 44*03ce13f7SAndroid Build Coastguard WorkerAt the time of writing a Regres presubmit run takes a little over 20 minutes to 45*03ce13f7SAndroid Build Coastguard Workercomplete, and there is a single Regres machine servicing all changes. 46*03ce13f7SAndroid Build Coastguard WorkerTo keep Regres responsive, changes are prioritized based on their 'readiness to 47*03ce13f7SAndroid Build Coastguard Workerland', which is determined by the change's `Kokoro-Presubmit`, `Code-Review` and 48*03ce13f7SAndroid Build Coastguard Worker`Presubmit-Ready` Gerrit labels. 49*03ce13f7SAndroid Build Coastguard Worker 50*03ce13f7SAndroid Build Coastguard Worker### Test Filtering 51*03ce13f7SAndroid Build Coastguard Worker 52*03ce13f7SAndroid Build Coastguard WorkerBy default, Regres will run all the test lists declared in the 53*03ce13f7SAndroid Build Coastguard Worker[`<swiftshader>/tests/regres/ci-tests.json`](https://cs.opensource.google/swiftshader/SwiftShader/+/master:tests/regres/ci-tests.json) file.\ 54*03ce13f7SAndroid Build Coastguard WorkerAs new functionally is being implemented, the test lists in `ci-tests.json` may 55*03ce13f7SAndroid Build Coastguard Workerreference known-passing test lists updated by the [daily run](#daily-run-continuous-integration-testing), 56*03ce13f7SAndroid Build Coastguard Workerso that failing tests for incomplete functionality are skipped, but tests that 57*03ce13f7SAndroid Build Coastguard Workerpass for new functionality *are tested* to ensure they do not regres. 58*03ce13f7SAndroid Build Coastguard Worker 59*03ce13f7SAndroid Build Coastguard WorkerAdditional tests names found in the files referenced by 60*03ce13f7SAndroid Build Coastguard Worker[`<swiftshader>/tests/regres/full-tests.json`](https://cs.opensource.google/swiftshader/SwiftShader/+/master:tests/regres/full-tests.json) 61*03ce13f7SAndroid Build Coastguard Workercan be explicitly included in the change's presubmit run 62*03ce13f7SAndroid Build Coastguard Workerby including a line in the change description with the signature: 63*03ce13f7SAndroid Build Coastguard Worker 64*03ce13f7SAndroid Build Coastguard Worker```text 65*03ce13f7SAndroid Build Coastguard WorkerTest: <dEQP-test-pattern> 66*03ce13f7SAndroid Build Coastguard Worker``` 67*03ce13f7SAndroid Build Coastguard Worker 68*03ce13f7SAndroid Build Coastguard Worker`<dEQP-test-pattern>` can be a single dEQP test name, or you can use wildcards 69*03ce13f7SAndroid Build Coastguard Worker[as documented here](https://golang.org/pkg/path/filepath/#Match). 70*03ce13f7SAndroid Build Coastguard Worker 71*03ce13f7SAndroid Build Coastguard WorkerYou can repeat `Test:` as many times as you like. `Tests:` is also acccepted. 72*03ce13f7SAndroid Build Coastguard Worker 73*03ce13f7SAndroid Build Coastguard Worker[For example](https://swiftshader-review.googlesource.com/c/SwiftShader/+/26574): 74*03ce13f7SAndroid Build Coastguard Worker 75*03ce13f7SAndroid Build Coastguard Worker```text 76*03ce13f7SAndroid Build Coastguard WorkerAdd support for OpLogicalEqual, OpLogicalNotEqual 77*03ce13f7SAndroid Build Coastguard Worker 78*03ce13f7SAndroid Build Coastguard WorkerTest: dEQP-VK.glsl.operator.bool_compare.* 79*03ce13f7SAndroid Build Coastguard WorkerTest: dEQP-VK.glsl.operator.binary_operator.equal.* 80*03ce13f7SAndroid Build Coastguard WorkerTest: dEQP-VK.glsl.operator.binary_operator.not_equal.* 81*03ce13f7SAndroid Build Coastguard WorkerBug: b/126870789 82*03ce13f7SAndroid Build Coastguard WorkerChange-Id: I9d33444d67792274d8027b7d1632235533cfc079 83*03ce13f7SAndroid Build Coastguard Worker``` 84*03ce13f7SAndroid Build Coastguard Worker 85*03ce13f7SAndroid Build Coastguard Worker## Daily-run continuous integration testing 86*03ce13f7SAndroid Build Coastguard Worker 87*03ce13f7SAndroid Build Coastguard WorkerOnce a day, regres will also test another set of tests from [`<swiftshader>/tests/regres/full-tests.json`](https://cs.opensource.google/swiftshader/SwiftShader/+/master:tests/regres/full-tests.json), 88*03ce13f7SAndroid Build Coastguard Workerand post the test result lists as a Gerrit changelist 89*03ce13f7SAndroid Build Coastguard Worker[[example]](https://swiftshader-review.googlesource.com/c/SwiftShader/+/46448). 90*03ce13f7SAndroid Build Coastguard Worker 91*03ce13f7SAndroid Build Coastguard WorkerThe daily run also performs code coverage instrumentation per dEQP test, 92*03ce13f7SAndroid Build Coastguard Workerautomatically uploading the results of all the dEQP tests to the viewer at 93*03ce13f7SAndroid Build Coastguard Worker[swiftshader-regres.github.io/swiftshader-coverage](https://swiftshader-regres.github.io/swiftshader-coverage/). 94*03ce13f7SAndroid Build Coastguard Worker 95*03ce13f7SAndroid Build Coastguard Worker## Local dEQP test runner 96*03ce13f7SAndroid Build Coastguard Worker 97*03ce13f7SAndroid Build Coastguard WorkerRegres also provides a multi-threaded, [process sandboxed](#process-sandboxing), 98*03ce13f7SAndroid Build Coastguard Workerlocal dEQP test runner with a wild-card / regex based test name matcher. 99*03ce13f7SAndroid Build Coastguard Worker 100*03ce13f7SAndroid Build Coastguard WorkerThe local test runner can be run with: 101*03ce13f7SAndroid Build Coastguard Worker 102*03ce13f7SAndroid Build Coastguard Worker[`<swiftshader>/tests/regres/run_testlist.sh`](https://cs.opensource.google/swiftshader/SwiftShader/+/master:tests/regres/run_testlist.sh) `--deqp-vk=<path to deqp-vk> [--filter=<test name filter>]` 103*03ce13f7SAndroid Build Coastguard Worker 104*03ce13f7SAndroid Build Coastguard Worker`<test name filter>` can be a single dEQP test name, or you can use wildcards 105*03ce13f7SAndroid Build Coastguard Worker[as documented here](https://golang.org/pkg/path/filepath/#Match). 106*03ce13f7SAndroid Build Coastguard WorkerAlternatively, start with a `/` to use a regex filter. 107*03ce13f7SAndroid Build Coastguard Worker 108*03ce13f7SAndroid Build Coastguard WorkerOther useful flags: 109*03ce13f7SAndroid Build Coastguard Worker 110*03ce13f7SAndroid Build Coastguard Worker```text 111*03ce13f7SAndroid Build Coastguard Worker -limit int 112*03ce13f7SAndroid Build Coastguard Worker only run a maximum of this number of tests 113*03ce13f7SAndroid Build Coastguard Worker -no-results 114*03ce13f7SAndroid Build Coastguard Worker disable generation of results.json file 115*03ce13f7SAndroid Build Coastguard Worker -output string 116*03ce13f7SAndroid Build Coastguard Worker path to an output JSON results file (default "results.json") 117*03ce13f7SAndroid Build Coastguard Worker -shuffle 118*03ce13f7SAndroid Build Coastguard Worker shuffle tests 119*03ce13f7SAndroid Build Coastguard Worker -test-list string 120*03ce13f7SAndroid Build Coastguard Worker path to a test list file (default "vk-master-PASS.txt") 121*03ce13f7SAndroid Build Coastguard Worker``` 122*03ce13f7SAndroid Build Coastguard Worker 123*03ce13f7SAndroid Build Coastguard WorkerRun [`<swiftshader>/tests/regres/run_testlist.sh`](https://cs.opensource.google/swiftshader/SwiftShader/+/master:tests/regres/run_testlist.sh) with `--help` to see all available flags. 124*03ce13f7SAndroid Build Coastguard Worker 125*03ce13f7SAndroid Build Coastguard Worker## Process sandboxing 126*03ce13f7SAndroid Build Coastguard Worker 127*03ce13f7SAndroid Build Coastguard WorkerRegres will run each dEQP test in a separate process to prevent state 128*03ce13f7SAndroid Build Coastguard Workerleakage between tests. 129*03ce13f7SAndroid Build Coastguard Worker 130*03ce13f7SAndroid Build Coastguard WorkerTests are run concurrently, and crashing processes will not take down the test 131*03ce13f7SAndroid Build Coastguard Workerrunner. 132*03ce13f7SAndroid Build Coastguard Worker 133*03ce13f7SAndroid Build Coastguard WorkerSome dEQP tests are known to perform excessive memory allocations (i.e. keep 134*03ce13f7SAndroid Build Coastguard Workerallocating until no more can be claimed from the OS). \ 135*03ce13f7SAndroid Build Coastguard WorkerIn order to prevent a single test starving other test processes of memory, each 136*03ce13f7SAndroid Build Coastguard Workerprocess is restricted to a fraction of the system's memory using [linux resource limits](https://man7.org/linux/man-pages/man2/getrlimit.2.html). 137*03ce13f7SAndroid Build Coastguard Worker 138*03ce13f7SAndroid Build Coastguard WorkerTests may also deadlock, so each test process has a time limit before they are 139*03ce13f7SAndroid Build Coastguard Workerautomatically killed. 140*03ce13f7SAndroid Build Coastguard Worker 141*03ce13f7SAndroid Build Coastguard Worker## Implementation details 142*03ce13f7SAndroid Build Coastguard Worker 143*03ce13f7SAndroid Build Coastguard Worker### Presubmit & daily run process 144*03ce13f7SAndroid Build Coastguard Worker 145*03ce13f7SAndroid Build Coastguard WorkerRegres runs until stopped, and will: 146*03ce13f7SAndroid Build Coastguard Worker 147*03ce13f7SAndroid Build Coastguard Worker* Download a known compatible version of Clang to a cache directory. This will 148*03ce13f7SAndroid Build Coastguard Worker be used for all compilation stages below. 149*03ce13f7SAndroid Build Coastguard Worker* Periodically poll Gerrit for recently opened changes 150*03ce13f7SAndroid Build Coastguard Worker* Periodically query Gerrit for details about each tracked change, determining 151*03ce13f7SAndroid Build Coastguard Worker [whether it should be tested](#qualifying), and determine its current 152*03ce13f7SAndroid Build Coastguard Worker [priority](#prioritization). 153*03ce13f7SAndroid Build Coastguard Worker* A qualifying change with the highest priority will be picked, and the 154*03ce13f7SAndroid Build Coastguard Worker following is performed for the change: 155*03ce13f7SAndroid Build Coastguard Worker 1. The change is `git fetch`ed into a temporary directory. 156*03ce13f7SAndroid Build Coastguard Worker 2. If not already cached, the dEQP version described in the 157*03ce13f7SAndroid Build Coastguard Worker change's [`<swiftshader>/tests/regres/deqp.json`](https://cs.opensource.google/swiftshader/SwiftShader/+/master:tests/regres/deqp.json) file is downloaded and built the into a cached directory. 158*03ce13f7SAndroid Build Coastguard Worker 3. The source for the change is built into a temporary build directory. 159*03ce13f7SAndroid Build Coastguard Worker 4. The built dEQP binaries are used to test the change. The full test results 160*03ce13f7SAndroid Build Coastguard Worker are stored in a cached directory. 161*03ce13f7SAndroid Build Coastguard Worker 5. If the parent change's test results aren't already cached, then steps 3 and 162*03ce13f7SAndroid Build Coastguard Worker 4 are repeated for the parent change. 163*03ce13f7SAndroid Build Coastguard Worker 6. The results of the two changes are diffed, and the results of the diff are 164*03ce13f7SAndroid Build Coastguard Worker posted to the change as a Gerrit review comment. 165*03ce13f7SAndroid Build Coastguard Worker* The above is repeated until it is time to perform a daily run, upon which: 166*03ce13f7SAndroid Build Coastguard Worker 1. The `HEAD` change of `master` is fetched into a temporary directory. 167*03ce13f7SAndroid Build Coastguard Worker 2. If not already cached, the dEQP version described in the 168*03ce13f7SAndroid Build Coastguard Worker change's [`<swiftshader>/tests/regres/deqp.json`](https://cs.opensource.google/swiftshader/SwiftShader/+/master:tests/regres/deqp.json) file is downloaded and built the into a cached directory. 169*03ce13f7SAndroid Build Coastguard Worker 3. The `HEAD` change is built into a temporary directory, optionally with code 170*03ce13f7SAndroid Build Coastguard Worker coverage instrumenting. 171*03ce13f7SAndroid Build Coastguard Worker 4. The build dEQP binaries are used to test the change. The full test results 172*03ce13f7SAndroid Build Coastguard Worker are stored in a cached directory, and the each test is binned by status and 173*03ce13f7SAndroid Build Coastguard Worker written to the [`<swiftshader>/tests/regres/testlists`](https://cs.opensource.google/swiftshader/SwiftShader/+/master:tests/regres/testlists) directory. 174*03ce13f7SAndroid Build Coastguard Worker 5. A new Gerrit change is created containing the updated test lists and put up 175*03ce13f7SAndroid Build Coastguard Worker for review, along with a summary of test result changes [[example]](https://swiftshader-review.googlesource.com/c/SwiftShader/+/46448). 176*03ce13f7SAndroid Build Coastguard Worker If there's an existing daily test change up for review then this is reused 177*03ce13f7SAndroid Build Coastguard Worker instead of creating another. 178*03ce13f7SAndroid Build Coastguard Worker 6. If the build included code coverage instrumentation, then the coverage 179*03ce13f7SAndroid Build Coastguard Worker results are collated from all test runs, processed and compressed, and 180*03ce13f7SAndroid Build Coastguard Worker uploaded to [github.com/swiftshader-regres/swiftshader-coverage](https://github.com/swiftshader-regres/swiftshader-coverage) 181*03ce13f7SAndroid Build Coastguard Worker which is immediately reflected at [swiftshader-regres.github.io/swiftshader-coverage](https://swiftshader-regres.github.io/swiftshader-coverage). 182*03ce13f7SAndroid Build Coastguard Worker This process is [described in more detail below](#code-coverage). 183*03ce13f7SAndroid Build Coastguard Worker 7. Stages 3 - 5 are repeated for both the LLVM and Subzero backends. 184*03ce13f7SAndroid Build Coastguard Worker 185*03ce13f7SAndroid Build Coastguard Worker### Caching 186*03ce13f7SAndroid Build Coastguard Worker 187*03ce13f7SAndroid Build Coastguard WorkerThe cache directory is heavily used to avoid duplicated work. For example, it 188*03ce13f7SAndroid Build Coastguard Workeris common for patchsets to be repeatedly pushed with the same parent change, so 189*03ce13f7SAndroid Build Coastguard Workerthe test results of the parent can be calculated once and stored. A tested 190*03ce13f7SAndroid Build Coastguard Workerpatchset that is merged into master would also be cached when used as a parent 191*03ce13f7SAndroid Build Coastguard Workerof another change. 192*03ce13f7SAndroid Build Coastguard Worker 193*03ce13f7SAndroid Build Coastguard WorkerThe cache needs to consider more than just the change identifier as the 194*03ce13f7SAndroid Build Coastguard Workercache-key for storing and retrieving data. Both the test lists and version of 195*03ce13f7SAndroid Build Coastguard WorkerdEQP used are dictated by the change being tested, and so both used as part of 196*03ce13f7SAndroid Build Coastguard Workerthe cache key. 197*03ce13f7SAndroid Build Coastguard Worker 198*03ce13f7SAndroid Build Coastguard Worker### Vulkan Loader usage 199*03ce13f7SAndroid Build Coastguard Worker 200*03ce13f7SAndroid Build Coastguard WorkerApplications make use of the Vulkan API by loading the [Vulkan Loader](https://github.com/KhronosGroup/Vulkan-Loader) 201*03ce13f7SAndroid Build Coastguard Workerlibrary (`libvulkan.so.1` on Linux), which enumerates available Vulkan 202*03ce13f7SAndroid Build Coastguard Workerimplementations (typically GPUs and their drivers) before an actual 'instance' 203*03ce13f7SAndroid Build Coastguard Workeris created to communicate with a specific Installable Client Driver (ICD). 204*03ce13f7SAndroid Build Coastguard Worker 205*03ce13f7SAndroid Build Coastguard WorkerHowever, SwiftShader can build into libvulkan.so.1 itself, which implements the 206*03ce13f7SAndroid Build Coastguard Workersame API entry functions as the Vulkan Loader. Regres by default will make dEQP 207*03ce13f7SAndroid Build Coastguard Workerload this SwiftShader library instead of the system's Vulkan Loader. It ensures 208*03ce13f7SAndroid Build Coastguard Workertest results are independent of the system's Vulkan setup. 209*03ce13f7SAndroid Build Coastguard Worker 210*03ce13f7SAndroid Build Coastguard WorkerTo override this, one can set LD_LIBRARY_PATH to point to the location of a 211*03ce13f7SAndroid Build Coastguard WorkerLoader's libvulkan.so.1. 212*03ce13f7SAndroid Build Coastguard Worker 213*03ce13f7SAndroid Build Coastguard Worker### Code coverage 214*03ce13f7SAndroid Build Coastguard Worker 215*03ce13f7SAndroid Build Coastguard WorkerThe [daily run](#daily-run-continuous-integration-testing) produces code 216*03ce13f7SAndroid Build Coastguard Workercoverage information that can be examined for each individual dEQP test at 217*03ce13f7SAndroid Build Coastguard Worker[swiftshader-regres.github.io/swiftshader-coverage](https://swiftshader-regres.github.io/swiftshader-coverage/). 218*03ce13f7SAndroid Build Coastguard Worker 219*03ce13f7SAndroid Build Coastguard WorkerThe process for generating this information is complex, and is described in 220*03ce13f7SAndroid Build Coastguard Workerdetail below: 221*03ce13f7SAndroid Build Coastguard Worker 222*03ce13f7SAndroid Build Coastguard Worker#### Per-test generation 223*03ce13f7SAndroid Build Coastguard Worker 224*03ce13f7SAndroid Build Coastguard WorkerCode coverage instrumentation is generated with 225*03ce13f7SAndroid Build Coastguard Worker[clang's `--coverage`](https://clang.llvm.org/docs/SourceBasedCodeCoverage.html) 226*03ce13f7SAndroid Build Coastguard Workerfunctionality. This compiler option is enabled by using SwiftShader's 227*03ce13f7SAndroid Build Coastguard Worker`SWIFTSHADER_EMIT_COVERAGE` CMake flag. 228*03ce13f7SAndroid Build Coastguard Worker 229*03ce13f7SAndroid Build Coastguard WorkerEach dEQP test process is run with a unique `LLVM_PROFILE_FILE` environment 230*03ce13f7SAndroid Build Coastguard Workervariable value which dictates where the process writes its raw coverage profile 231*03ce13f7SAndroid Build Coastguard Workerfile. Each process gets a different path so that we can emit coverage from 232*03ce13f7SAndroid Build Coastguard Workermultiple, concurrent dEQP test processes. 233*03ce13f7SAndroid Build Coastguard Worker 234*03ce13f7SAndroid Build Coastguard Worker#### Parsing 235*03ce13f7SAndroid Build Coastguard Worker 236*03ce13f7SAndroid Build Coastguard Worker[Clang provides two tools](https://clang.llvm.org/docs/SourceBasedCodeCoverage.html#creating-coverage-reports) for processing coverage data: 237*03ce13f7SAndroid Build Coastguard Worker 238*03ce13f7SAndroid Build Coastguard Worker* `llvm-profdata` indexes the raw `.profraw` coverage profile file and emits a 239*03ce13f7SAndroid Build Coastguard Worker `.profdata` file. 240*03ce13f7SAndroid Build Coastguard Worker* `llvm-cov` further processes the `.profdata` file into something human 241*03ce13f7SAndroid Build Coastguard Worker readable or machine parsable. 242*03ce13f7SAndroid Build Coastguard Worker 243*03ce13f7SAndroid Build Coastguard Worker`llvm-cov` provides many options, including emitting an pretty HTML file, but is 244*03ce13f7SAndroid Build Coastguard Workerremarkably slow at producing easily machine-parsable data. Fortunately the core 245*03ce13f7SAndroid Build Coastguard Workerof `llvm-cov` is [a few hundreds of lines of code](https://github.com/llvm/llvm-project/tree/master/llvm/tools/llvm-cov), as it relies on LLVM libraries to do the heavy lifting. Regres 246*03ce13f7SAndroid Build Coastguard Workerreplaces `llvm-cov` with ["`turbo-cov`"](https://cs.opensource.google/swiftshader/SwiftShader/+/master:tests/regres/cov/turbo-cov/) which efficiently converts a `.profdata` into a simple binary stream which can 247*03ce13f7SAndroid Build Coastguard Workerbe consumed by Regres. 248*03ce13f7SAndroid Build Coastguard Worker 249*03ce13f7SAndroid Build Coastguard Worker#### Processing 250*03ce13f7SAndroid Build Coastguard Worker 251*03ce13f7SAndroid Build Coastguard WorkerAt the time of writing there are over 560,000 individual dEQP tests, and around 252*03ce13f7SAndroid Build Coastguard Worker176,000 lines of C++ code in [`<swiftshader>/src`](https://cs.opensource.google/swiftshader/SwiftShader/+/master:src/). 253*03ce13f7SAndroid Build Coastguard WorkerIf you used 1 bit for each source line, per-line source coverage for all dEQP 254*03ce13f7SAndroid Build Coastguard Workertests would require over 11GiB of storage. That's just for one snapshot. 255*03ce13f7SAndroid Build Coastguard Worker 256*03ce13f7SAndroid Build Coastguard WorkerThe processing and compression schemes described below reduces this down to 257*03ce13f7SAndroid Build Coastguard Workeraround 10 MiB (~1100x reduction in size), and supports sub-line coverage scopes. 258*03ce13f7SAndroid Build Coastguard Worker 259*03ce13f7SAndroid Build Coastguard Worker##### Spans 260*03ce13f7SAndroid Build Coastguard Worker 261*03ce13f7SAndroid Build Coastguard WorkerCode coverage information is described in spans. 262*03ce13f7SAndroid Build Coastguard Worker 263*03ce13f7SAndroid Build Coastguard WorkerA span is a described as an interval of source locations, where a location is a 264*03ce13f7SAndroid Build Coastguard Workerline-column pair: 265*03ce13f7SAndroid Build Coastguard Worker 266*03ce13f7SAndroid Build Coastguard Worker```go 267*03ce13f7SAndroid Build Coastguard Workertype Location struct { 268*03ce13f7SAndroid Build Coastguard Worker Line, Column int 269*03ce13f7SAndroid Build Coastguard Worker} 270*03ce13f7SAndroid Build Coastguard Worker 271*03ce13f7SAndroid Build Coastguard Workertype Span struct { 272*03ce13f7SAndroid Build Coastguard Worker Start, End Location 273*03ce13f7SAndroid Build Coastguard Worker} 274*03ce13f7SAndroid Build Coastguard Worker``` 275*03ce13f7SAndroid Build Coastguard Worker 276*03ce13f7SAndroid Build Coastguard Worker##### Test tree construction 277*03ce13f7SAndroid Build Coastguard Worker 278*03ce13f7SAndroid Build Coastguard WorkerEach dEQP test is uniquely identified by a fully qualified name. 279*03ce13f7SAndroid Build Coastguard WorkerEach test belongs to a group, and that group may be nested within any number of 280*03ce13f7SAndroid Build Coastguard Workerparent groups. The groups are described in the test name, using dots (`.`) to 281*03ce13f7SAndroid Build Coastguard Workerdelimit the groups and leaf test name. 282*03ce13f7SAndroid Build Coastguard Worker 283*03ce13f7SAndroid Build Coastguard WorkerFor example, the fully qualified test name: 284*03ce13f7SAndroid Build Coastguard Worker 285*03ce13f7SAndroid Build Coastguard Worker`dEQP-VK.fragment_shader_interlock.basic.discard.ssbo.sample_unordered.4xaa.sample_shading.16x16` 286*03ce13f7SAndroid Build Coastguard Worker 287*03ce13f7SAndroid Build Coastguard WorkerCan be broken down into the following groups and test name: 288*03ce13f7SAndroid Build Coastguard Worker 289*03ce13f7SAndroid Build Coastguard Worker```text 290*03ce13f7SAndroid Build Coastguard WorkerdEQP-VK <-- root group name 291*03ce13f7SAndroid Build Coastguard Worker╰ fragment_shader_interlock 292*03ce13f7SAndroid Build Coastguard Worker ╰ basic.discard 293*03ce13f7SAndroid Build Coastguard Worker ╰ ssbo 294*03ce13f7SAndroid Build Coastguard Worker ╰ sample_unordered 295*03ce13f7SAndroid Build Coastguard Worker ╰ 4xaa 296*03ce13f7SAndroid Build Coastguard Worker ╰ sample_shading 297*03ce13f7SAndroid Build Coastguard Worker ╰ 16x16 <-- leaf test name 298*03ce13f7SAndroid Build Coastguard Worker``` 299*03ce13f7SAndroid Build Coastguard Worker 300*03ce13f7SAndroid Build Coastguard WorkerBreaking down fully qualified test names into groups provide a natural way to 301*03ce13f7SAndroid Build Coastguard Workerstructure coverage data, as tests of the same group are likely to have similar 302*03ce13f7SAndroid Build Coastguard Workercoverage spans. 303*03ce13f7SAndroid Build Coastguard Worker 304*03ce13f7SAndroid Build Coastguard WorkerSo, for each source file in the codebase, we create a tree with test groups as 305*03ce13f7SAndroid Build Coastguard Workernon-leaf nodes, and tests as leaf nodes. 306*03ce13f7SAndroid Build Coastguard Worker 307*03ce13f7SAndroid Build Coastguard WorkerFor example, given the following test list: 308*03ce13f7SAndroid Build Coastguard Worker 309*03ce13f7SAndroid Build Coastguard Worker```text 310*03ce13f7SAndroid Build Coastguard Workera.b.d.h 311*03ce13f7SAndroid Build Coastguard Workera.b.d.i.n 312*03ce13f7SAndroid Build Coastguard Workera.b.d.i.o 313*03ce13f7SAndroid Build Coastguard Workera.b.e.j 314*03ce13f7SAndroid Build Coastguard Workera.b.e.k.p 315*03ce13f7SAndroid Build Coastguard Workera.b.e.k.q 316*03ce13f7SAndroid Build Coastguard Workera.c.f 317*03ce13f7SAndroid Build Coastguard Workera.c.g.l.r 318*03ce13f7SAndroid Build Coastguard Workera.c.g.m 319*03ce13f7SAndroid Build Coastguard Worker``` 320*03ce13f7SAndroid Build Coastguard Worker 321*03ce13f7SAndroid Build Coastguard WorkerWe would construct the following tree: 322*03ce13f7SAndroid Build Coastguard Worker 323*03ce13f7SAndroid Build Coastguard Worker```text 324*03ce13f7SAndroid Build Coastguard Worker a 325*03ce13f7SAndroid Build Coastguard Worker ╭──────┴──────╮ 326*03ce13f7SAndroid Build Coastguard Worker b c 327*03ce13f7SAndroid Build Coastguard Worker ╭───┴───╮ ╭───┴───╮ 328*03ce13f7SAndroid Build Coastguard Worker d e f g 329*03ce13f7SAndroid Build Coastguard Worker ╭─┴─╮ ╭─┴─╮ ╭─┴─╮ 330*03ce13f7SAndroid Build Coastguard Worker h i j k l m 331*03ce13f7SAndroid Build Coastguard Worker ╭┴╮ ╭┴╮ │ 332*03ce13f7SAndroid Build Coastguard Worker n o p q r 333*03ce13f7SAndroid Build Coastguard Worker 334*03ce13f7SAndroid Build Coastguard Worker``` 335*03ce13f7SAndroid Build Coastguard Worker 336*03ce13f7SAndroid Build Coastguard WorkerEach leaf node in this tree (`h`, `n`, `o`, `j`, `p`, `q`, `f`, `r`, `m`) 337*03ce13f7SAndroid Build Coastguard Workerrepresent a test, and non-leaf nodes (`a`, `b`, `c`, `d`, `e`, `g`, `i`, `k`, 338*03ce13f7SAndroid Build Coastguard Worker`l`) are a groups. 339*03ce13f7SAndroid Build Coastguard Worker 340*03ce13f7SAndroid Build Coastguard WorkerTo begin, we create a test tree structure, and associate the full list of test 341*03ce13f7SAndroid Build Coastguard Workercoverage spans with every leaf node (test) in this tree. 342*03ce13f7SAndroid Build Coastguard Worker 343*03ce13f7SAndroid Build Coastguard WorkerThis data structure hasn't given us any compression benefits yet, but we can 344*03ce13f7SAndroid Build Coastguard Workernow do a few tricks to dramatically reduce number of spans needed to describe 345*03ce13f7SAndroid Build Coastguard Workerthe graph: 346*03ce13f7SAndroid Build Coastguard Worker 347*03ce13f7SAndroid Build Coastguard Worker##### Optimization 1: Common span promotion 348*03ce13f7SAndroid Build Coastguard Worker 349*03ce13f7SAndroid Build Coastguard WorkerThe first compression scheme is to promote common spans up the tree when they 350*03ce13f7SAndroid Build Coastguard Workerare common for all children. This will reduce the number of spans needed to be 351*03ce13f7SAndroid Build Coastguard Workerencoded in the final file. 352*03ce13f7SAndroid Build Coastguard Worker 353*03ce13f7SAndroid Build Coastguard WorkerFor example, if the test group `a` has 4 children that all share the same span 354*03ce13f7SAndroid Build Coastguard Worker`X`: 355*03ce13f7SAndroid Build Coastguard Worker 356*03ce13f7SAndroid Build Coastguard Worker```text 357*03ce13f7SAndroid Build Coastguard Worker a 358*03ce13f7SAndroid Build Coastguard Worker ╭───┬─┴─┬───╮ 359*03ce13f7SAndroid Build Coastguard Worker b c d e 360*03ce13f7SAndroid Build Coastguard Worker [X,Y] [X] [X] [X,Z] 361*03ce13f7SAndroid Build Coastguard Worker``` 362*03ce13f7SAndroid Build Coastguard Worker 363*03ce13f7SAndroid Build Coastguard WorkerThen span `X` can be promoted up to `a`: 364*03ce13f7SAndroid Build Coastguard Worker 365*03ce13f7SAndroid Build Coastguard Worker```text 366*03ce13f7SAndroid Build Coastguard Worker [X] 367*03ce13f7SAndroid Build Coastguard Worker a 368*03ce13f7SAndroid Build Coastguard Worker ╭───┬─┴─┬───╮ 369*03ce13f7SAndroid Build Coastguard Worker b c d e 370*03ce13f7SAndroid Build Coastguard Worker [Y] [] [] [Z] 371*03ce13f7SAndroid Build Coastguard Worker``` 372*03ce13f7SAndroid Build Coastguard Worker 373*03ce13f7SAndroid Build Coastguard Worker##### Optimization 2: Span XOR promotion 374*03ce13f7SAndroid Build Coastguard Worker 375*03ce13f7SAndroid Build Coastguard WorkerThis idea can be extended further, by not requiring all the children to share 376*03ce13f7SAndroid Build Coastguard Workerthe same span before promotion. If **most** child nodes share the same span, we 377*03ce13f7SAndroid Build Coastguard Workercan still promote the span, but this time we **remove** the span from the 378*03ce13f7SAndroid Build Coastguard Workerchildren **if they had it**, and **add** the span to children **if they didn't 379*03ce13f7SAndroid Build Coastguard Workerhave it**. 380*03ce13f7SAndroid Build Coastguard Worker 381*03ce13f7SAndroid Build Coastguard WorkerFor example, if the test group `a` has 4 children with 3 that share the span 382*03ce13f7SAndroid Build Coastguard Worker`X`: 383*03ce13f7SAndroid Build Coastguard Worker 384*03ce13f7SAndroid Build Coastguard Worker```text 385*03ce13f7SAndroid Build Coastguard Worker a 386*03ce13f7SAndroid Build Coastguard Worker ╭───┬─┴─┬───╮ 387*03ce13f7SAndroid Build Coastguard Worker b c d e 388*03ce13f7SAndroid Build Coastguard Worker [X,Y] [X] [] [X,Z] 389*03ce13f7SAndroid Build Coastguard Worker``` 390*03ce13f7SAndroid Build Coastguard Worker 391*03ce13f7SAndroid Build Coastguard WorkerThen span `X` can be promoted up to `a` by flipping the presence of `X` on the 392*03ce13f7SAndroid Build Coastguard Workerchild nodes: 393*03ce13f7SAndroid Build Coastguard Worker 394*03ce13f7SAndroid Build Coastguard Worker```text 395*03ce13f7SAndroid Build Coastguard Worker [X] 396*03ce13f7SAndroid Build Coastguard Worker a 397*03ce13f7SAndroid Build Coastguard Worker ╭───┬─┴─┬───╮ 398*03ce13f7SAndroid Build Coastguard Worker b c d e 399*03ce13f7SAndroid Build Coastguard Worker [Y] [] [X] [Z] 400*03ce13f7SAndroid Build Coastguard Worker``` 401*03ce13f7SAndroid Build Coastguard Worker 402*03ce13f7SAndroid Build Coastguard WorkerThis process repeats up the tree. 403*03ce13f7SAndroid Build Coastguard Worker 404*03ce13f7SAndroid Build Coastguard WorkerWith this optimization applied, we now need to traverse the tree from root to 405*03ce13f7SAndroid Build Coastguard Workerleaf in order to know whether a given span is in use for the leaf node (test): 406*03ce13f7SAndroid Build Coastguard Worker 407*03ce13f7SAndroid Build Coastguard Worker* If the span is encountered an **odd** number of times during traversal, then 408*03ce13f7SAndroid Build Coastguard Worker the span is **covered**. 409*03ce13f7SAndroid Build Coastguard Worker* If the span is encountered an **even** number of times during traversal, then 410*03ce13f7SAndroid Build Coastguard Worker the span is **not covered**. 411*03ce13f7SAndroid Build Coastguard Worker 412*03ce13f7SAndroid Build Coastguard WorkerSee [`tests/regres/cov/coverage_test.go`](https://cs.opensource.google/swiftshader/SwiftShader/+/master:tests/regres/cov/coverage_test.go) for more examples of this optimization. 413*03ce13f7SAndroid Build Coastguard Worker 414*03ce13f7SAndroid Build Coastguard Worker##### Optimization 3: Common span grouping 415*03ce13f7SAndroid Build Coastguard Worker 416*03ce13f7SAndroid Build Coastguard WorkerWith real world data, we encounter groups of spans that are commonly found 417*03ce13f7SAndroid Build Coastguard Workertogether. To further reduce coverage data, the whole graph is scanned for common 418*03ce13f7SAndroid Build Coastguard Workerspan patterns, and are indexed by each tree node. 419*03ce13f7SAndroid Build Coastguard WorkerThe XOR'ing of spans as described above is performed as if the spans were not 420*03ce13f7SAndroid Build Coastguard Workergrouped. 421*03ce13f7SAndroid Build Coastguard Worker 422*03ce13f7SAndroid Build Coastguard Worker##### Optimization 4: Lookup tables 423*03ce13f7SAndroid Build Coastguard Worker 424*03ce13f7SAndroid Build Coastguard WorkerAll spans, span-groups and strings are stored in de-duplicated tables, and are 425*03ce13f7SAndroid Build Coastguard Workerindexed wherever possible. 426*03ce13f7SAndroid Build Coastguard Worker 427*03ce13f7SAndroid Build Coastguard WorkerThe final serialization is performed by [`tests/regres/cov/serialization.go`](https://cs.opensource.google/swiftshader/SwiftShader/+/master:tests/regres/cov/serialization.go). 428*03ce13f7SAndroid Build Coastguard Worker 429*03ce13f7SAndroid Build Coastguard Worker##### Optimization 5: zlib compression 430*03ce13f7SAndroid Build Coastguard Worker 431*03ce13f7SAndroid Build Coastguard WorkerThe coverage data is encoded into JSON for parsing by the web page. 432*03ce13f7SAndroid Build Coastguard Worker 433*03ce13f7SAndroid Build Coastguard WorkerBefore writing the JSON file, the text data is zlib compressed. 434*03ce13f7SAndroid Build Coastguard Worker 435*03ce13f7SAndroid Build Coastguard Worker#### Presentation 436*03ce13f7SAndroid Build Coastguard Worker 437*03ce13f7SAndroid Build Coastguard WorkerThe zlib-compressed JSON coverage data is decompressed using 438*03ce13f7SAndroid Build Coastguard Worker[`pako`](https://github.com/nodeca/pako), and consumed by some 439*03ce13f7SAndroid Build Coastguard Worker[vanilla JavaScript](https://github.com/swiftshader-regres/swiftshader-coverage/blob/gh-pages/index.html). 440*03ce13f7SAndroid Build Coastguard Worker 441*03ce13f7SAndroid Build Coastguard Worker[`codemirror`](https://codemirror.net/) is used to perform coverage span and C++ 442*03ce13f7SAndroid Build Coastguard Workersyntax highlighting 443