blob: 4dceab2567810bc7db9e855e80cd8c615df7bb06 [file] [log] [blame] [view]
Max Moroz3a928902018-05-15 14:39:501# Code Coverage in Chromium
2
3### Coverage Dashboard: [https://chromium-coverage.appspot.com/]
Yuke Liaod3b46272018-03-14 18:25:144
Yuke Liao1ffc8cb62018-04-06 19:09:075Table of contents:
Max Moroz3a928902018-05-15 14:39:506
Yuke Liao1ffc8cb62018-04-06 19:09:077- [Coverage Script](#coverage-script)
8- [Workflow](#workflow)
9 * [Step 0 Download Tooling](#step-0-download-tooling)
10 * [Step 1 Build](#step-1-build)
11 * [Step 2 Create Raw Profiles](#step-2-create-raw-profiles)
12 * [Step 3 Create Indexed Profile](#step-3-create-indexed-profile)
13 * [Step 4 Create Coverage Reports](#step-4-create-coverage-reports)
Max Morozd73e45f2018-04-24 18:32:4714- [Contacts](#contacts)
15- [FAQ](#faq)
Yuke Liaod3b46272018-03-14 18:25:1416
Abhishek Aryaaf9811f22018-05-11 22:17:4817Chromium uses Clang source-based code coverage. This [documentation] explains
Yuke Liao1ffc8cb62018-04-06 19:09:0718how to use Clangs source-based coverage features in general.
Yuke Liaod3b46272018-03-14 18:25:1419
Abhishek Aryaaf9811f22018-05-11 22:17:4820In this document, we first introduce a code coverage script that can be used to
21generate code coverage reports for Chromium code in one command, and then
22describe the code coverage reports generation workflow.
Yuke Liaod3b46272018-03-14 18:25:1423
Yuke Liao1ffc8cb62018-04-06 19:09:0724## Coverage Script
25The [coverage script] automates the process described below and provides a
26one-stop service to generate code coverage reports in just one command.
Yuke Liaod3b46272018-03-14 18:25:1427
Yuke Liao1ffc8cb62018-04-06 19:09:0728This script is currently supported on Linux, Mac, iOS and ChromeOS platforms.
29
30Here is an example usage:
31
Yuke Liaod3b46272018-03-14 18:25:1432```
Yuke Liao1ffc8cb62018-04-06 19:09:0733$ gn gen out/coverage \
34 --args='use_clang_coverage=true is_component_build=false'
35$ python tools/code_coverage/coverage.py \
36 crypto_unittests url_unittests \
37 -b out/coverage -o out/report \
38 -c 'out/coverage/crypto_unittests' \
39 -c 'out/coverage/url_unittests --gtest_filter=URLParser.PathURL' \
40 -f url/ -f crypto/
41```
42The command above builds `crypto_unittests` and `url_unittests` targets and then
Abhishek Aryaaf9811f22018-05-11 22:17:4843runs them individually with their commands and arguments specified by the `-c` flag.
44For `url_unittests`, it only runs the test `URLParser.PathURL`. The coverage report
Yuke Liao1ffc8cb62018-04-06 19:09:0745is filtered to include only files and sub-directories under `url/` and `crypto/`
46directories.
47
Abhishek Aryaaf9811f22018-05-11 22:17:4848Aside from automating the process, this script provides visualization features to
Yuke Liao1ffc8cb62018-04-06 19:09:0749view code coverage breakdown by directories and by components, for example:
50
Abhishek Aryaaf9811f22018-05-11 22:17:4851### Directory View
Yuke Liao1ffc8cb62018-04-06 19:09:0752
53![code coverage report directory view]
54
Abhishek Aryaaf9811f22018-05-11 22:17:4855### Component View
Yuke Liao1ffc8cb62018-04-06 19:09:0756
57![code coverage report component view]
58
Abhishek Aryaaf9811f22018-05-11 22:17:4859### Source View
60
61When you click on a particular source file in one of the views above, you can check
62per-line coverage information such as
63
64- Uncovered / Covered line fragments, lines and code blocks. This information can be
65useful to identify areas of code that lack test coverage.
66- Per-line hit counts indicating how many times this line was hit by all tested targets.
67This information can be useful to determine hot spots in your code.
Abhishek Aryab23b1a72018-05-17 20:11:0968- Potentially dead code. See [dead code example].
Abhishek Aryaaf9811f22018-05-11 22:17:4869
70![code coverage source view]
71
Yuke Liao1ffc8cb62018-04-06 19:09:0772## Workflow
73This section presents the workflow of generating code coverage reports using two
74unit test targets in Chromium repo as an example: `crypto_unittests` and
75`url_unittests`, and the following diagram shows a step-by-step overview of the
76process.
77
78![code coverage generation workflow](images/code_coverage_workflow.png)
79
80### Step 0 Download Tooling
81Generating code coverage reports requires llvm-profdata and llvm-cov tools.
82Currently, these two tools are not part of Chromiums Clang bundle,
83[coverage script] downloads and updates them automatically, you can also
84download the tools manually ([link]).
85
86### Step 1 Build
87In Chromium, to compile code with coverage enabled, one needs to add
88`use_clang_coverage=true` and `is_component_build=false` GN flags to the args.gn
89file in the build output directory. Under the hood, they ensure
90`-fprofile-instr-generate` and `-fcoverage-mapping` flags are passed to the
91compiler.
92
93```
94$ gn gen out/coverage \
95 --args='use_clang_coverage=true is_component_build=false'
96$ gclient runhooks
97$ ninja -C out/coverage crypto_unittests url_unittests
Yuke Liaod3b46272018-03-14 18:25:1498```
99
Yuke Liao1ffc8cb62018-04-06 19:09:07100### Step 2 Create Raw Profiles
Abhishek Aryaaf9811f22018-05-11 22:17:48101The next step is to run the instrumented binaries. When the program exits, it
102writes a raw profile for each process. Because Chromium runs tests in
103multiple processes, the number of processes spawned can be as many as a few
104hundred, resulting in the generation of a few hundred gigabytes raw
105profiles. To limit the number of raw profiles, `%Nm` pattern in
Yuke Liao1ffc8cb62018-04-06 19:09:07106`LLVM_PROFILE_FILE` environment variable is used to run tests in multi-process
107mode, where `N` is the number of raw profiles. With `N = 4`, the total size of
108the raw profiles are limited to a few gigabytes.
109
110```
111$ export LLVM_PROFILE_FILE=”out/report/crypto_unittests.%4m.profraw”
112$ ./out/coverage/crypto_unittests
113$ ls out/report/
114crypto_unittests.3657994905831792357_0.profraw
115...
116crypto_unittests.3657994905831792357_3.profraw
117```
118
119### Step 3 Create Indexed Profile
120Raw profiles must be indexed before generating code coverage reports, and this
121is done using the `merge` command of `llvm-profdata` tool, which merges multiple
Abhishek Aryaaf9811f22018-05-11 22:17:48122raw profiles (.profraw) and indexes them to create a single profile (.profdata).
Yuke Liao1ffc8cb62018-04-06 19:09:07123
124At this point, all the raw profiles can be thrown away because their information
Abhishek Aryaaf9811f22018-05-11 22:17:48125is already contained in the indexed profile.
Yuke Liao1ffc8cb62018-04-06 19:09:07126
127```
128$ llvm-profdata merge -o out/report/coverage.profdata \
129 out/report/crypto_unittests.3657994905831792357_0.profraw
130...
131out/report/crypto_unittests.3657994905831792357_3.profraw
132out/report/url_unittests.714228855822523802_0.profraw
133...
134out/report/url_unittests.714228855822523802_3.profraw
135$ ls out/report/coverage.profdata
136out/report/coverage.profdata
137```
138
139### Step 4 Create Coverage Reports
140Finally, `llvm-cov` is used to render code coverage reports. There are different
Abhishek Aryaaf9811f22018-05-11 22:17:48141report generation modes, and all of them require the following as input:
142- Indexed profile
143- All built target binaries
144- All exercised source files.
Yuke Liao1ffc8cb62018-04-06 19:09:07145
Abhishek Aryaaf9811f22018-05-11 22:17:48146For example, the following command can be used to generate per-file line-by-line
Yuke Liao1ffc8cb62018-04-06 19:09:07147code coverage report:
148
149```
150$ llvm-cov show -output-dir=out/report -format=html \
151 -instr-profile=out/report/coverage.profdata \
152 -object=out/coverage/url_unittests \
153 out/coverage/crypto_unittests
154```
155
156For more information on how to use llvm-cov, please refer to the [guide].
Yuke Liaod3b46272018-03-14 18:25:14157
Max Morozd73e45f2018-04-24 18:32:47158## Contacts
159
160### Reporting problems
Yuke Liaod3b46272018-03-14 18:25:14161For any breakage report and feature requests, please [file a bug].
162
Max Morozd73e45f2018-04-24 18:32:47163### Mailing list
Yuke Liao1ffc8cb62018-04-06 19:09:07164For questions and general discussions, please join [chrome-code-coverage group].
165
Max Morozd73e45f2018-04-24 18:32:47166## FAQ
167
168### Can I use `is_component_build=true` for code coverage build?
169
170Yes, code coverage instrumentation works with both component and non-component
171builds. Component build is usually faster to compile, but can be up to several
172times slower to run with code coverage instrumentation. For more information,
Max Morozc5e364a2018-04-25 23:19:49173see [crbug.com/831939].
174
175### I am getting some warnings while using the script, is that fine?
176
Abhishek Aryaaf9811f22018-05-11 22:17:48177Usually this is not a critical issue, but in general we tend not to have any
Max Morozc5e364a2018-04-25 23:19:49178warnings. Please check the list of [known issues], and if there is a similar
179bug, leave a comment with the command you run, the output you get, and Chromium
180revision you use. Otherwise, please [file a new issue] providing the same
181information.
182
183### How do crashes affect code coverage?
184
185If a crash of any type occurs (Segmentation Fault, CHECK failure, ASan error),
186the crashing process will not dump coverage information necessary to generate
187code coverage report. For single-process applications (e.g. fuzz targets), that
188means no coverage will be reported at all. For multi-process applications, the
Abhishek Aryaaf9811f22018-05-11 22:17:48189report will be incomplete. It is important to fix the crash first. If this is
190happening only in the coverage instrumented build, please [file a bug].
Max Morozd73e45f2018-04-24 18:32:47191
Max Moroz63cd04d2018-05-02 16:40:23192### Is it possible to obtain code coverage from a full Chromium build?
193
194Yes, with some important caveats. It is possible to build `chrome` target with
195code coverage instrumentation enabled. However, there are some inconveniences
196involved:
197
198* Linking may take a while
199* The binary is huge (~4GB)
200* The browser "works", but is noticeably slow and laggy
201* The sandbox needs to be disabled (`--no-sandbox`)
Max Moroz63cd04d2018-05-02 16:40:23202
203For more information, please see [crbug.com/834781].
204
Max Moroz3a928902018-05-15 14:39:50205### Why do we see significantly different coverage reported on different revisions?
206
207There can be two possible scenarios:
208
209* It can be a one time flakiness due to a broken build or failing tests.
210* It can be caused by extension of the test suite used for generating code
211coverage reports. When we add new tests to the suite, the aggregate coverage
212reported usually grows after that.
213
214### How can I improve [coverage dashboard]?
215
216Source code of the dashboard is not open sourced at the moment, but if you are a
217Googler, you should have access to the code-coverage repository. There is a
218documentation and scripts for running it locally. To get access and report
219issues, ping chrome-code-coverage@ list.
220
221### Why is coverage for X not reported or unreasonably low, even though there is a test for X?
222
223There are several reasons why coverage reports can be incomplete or incorrect:
224
225* A particular test is not used for code coverage report generation. Please
226check the [test suite], and if the test is missing, upload a CL to add it.
227* A test may have a build failure or a runtime crash. Please check [the logs]
228for that particular test target (rightmost column on the [coverage dashboard]).
229If there is any failure, please upload a CL with the fix. If you can't fix it,
230feel free to [file a bug].
231* A particular test may not be available on a particular platform. As of now,
232only reports generated on Linux are available on the [coverage dashboard].
233
Max Moroz3a928902018-05-15 14:39:50234### Is coverage reported for the code executed inside the sandbox?
235
236Not at the moment until [crbug.com/842424] is resolved. We do not disable the
237sandbox when running the tests. However, if there are any other non-sandbox'ed
238tests for the same code, the coverage should be reported from those. For more
239information, see [crbug.com/842424].
240
Max Morozd73e45f2018-04-24 18:32:47241
Max Morozc5e364a2018-04-25 23:19:49242[chrome-code-coverage group]: https://groups.google.com/a/google.com/forum/#!forum/chrome-code-coverage
Max Moroz3a928902018-05-15 14:39:50243[code-coverage repository]: https://chrome-internal.googlesource.com/chrome/tools/code-coverage
244[coverage dashboard]: https://chromium-coverage.appspot.com/
Yuke Liao1ffc8cb62018-04-06 19:09:07245[coverage script]: https://cs.chromium.org/chromium/src/tools/code_coverage/coverage.py
246[code coverage report directory view]: images/code_coverage_directory_view.png
247[code coverage report component view]: images/code_coverage_component_view.png
Abhishek Aryaaf9811f22018-05-11 22:17:48248[code coverage source view]: images/code_coverage_source_view.png
Max Moroz3a928902018-05-15 14:39:50249[crbug.com/821617]: https://crbug.com/821617
Max Morozc5e364a2018-04-25 23:19:49250[crbug.com/831939]: https://crbug.com/831939
Max Moroz63cd04d2018-05-02 16:40:23251[crbug.com/834781]: https://crbug.com/834781
Max Moroz3a928902018-05-15 14:39:50252[crbug.com/842424]: https://crbug.com/842424
253[clang roll]: https://crbug.com/841908
Abhishek Aryab23b1a72018-05-17 20:11:09254[dead code example]: https://chromium.googlesource.com/chromium/src/+/ac6e09311fcc7e734be2ef21a9ccbbe04c4c4706
Max Morozc5e364a2018-04-25 23:19:49255[documentation]: https://clang.llvm.org/docs/SourceBasedCodeCoverage.html
Yuke Liao1ffc8cb62018-04-06 19:09:07256[file a bug]: https://bugs.chromium.org/p/chromium/issues/entry?components=Tools%3ECodeCoverage
Max Morozc5e364a2018-04-25 23:19:49257[file a new issue]: https://bugs.chromium.org/p/chromium/issues/entry?components=Tools%3ECodeCoverage
258[guide]: http://llvm.org/docs/CommandGuide/llvm-cov.html
Max Moroz3a928902018-05-15 14:39:50259[https://chromium-coverage.appspot.com/]: https://chromium-coverage.appspot.com/
Max Morozc5e364a2018-04-25 23:19:49260[known issues]: https://bugs.chromium.org/p/chromium/issues/list?q=component:Tools%3ECodeCoverage
261[link]: https://storage.googleapis.com/chromium-browser-clang-staging/
Max Moroz3a928902018-05-15 14:39:50262[test suite]: https://cs.chromium.org/chromium/src/tools/code_coverage/test_suite.txt
263[the logs]: https://chromium-coverage.appspot.com/reports/latest/linux/metadata/index.html