blob: 420d24756ba940981703cc75f5ec6ecf79dac38d [file] [log] [blame] [view]
Max Moroz3a928902018-05-15 14:39:501# Code Coverage in Chromium
2
Roberto Carrillo3b567862019-01-30 19:01:253### Coverage Dashboard: [https://analysis.chromium.org/p/chromium/coverage]
Yuke Liaod3b46272018-03-14 18:25:144
Yuke Liao1ffc8cb62018-04-06 19:09:075Table of contents:
Max Moroz3a928902018-05-15 14:39:506
Roberto Carrillo3b567862019-01-30 19:01:257- [Coverage Infrastructure](#coverage-infra)
8 * [Coverage Builders](#coverage-builders)
9 * [Coverage Service](#coverage-service)
10 * [Coverage Clients](#coverage-clients)
Yuke Liao1ffc8cb62018-04-06 19:09:0711- [Coverage Script](#coverage-script)
12- [Workflow](#workflow)
13 * [Step 0 Download Tooling](#step-0-download-tooling)
14 * [Step 1 Build](#step-1-build)
15 * [Step 2 Create Raw Profiles](#step-2-create-raw-profiles)
16 * [Step 3 Create Indexed Profile](#step-3-create-indexed-profile)
17 * [Step 4 Create Coverage Reports](#step-4-create-coverage-reports)
Max Morozd73e45f2018-04-24 18:32:4718- [Contacts](#contacts)
19- [FAQ](#faq)
Yuke Liaod3b46272018-03-14 18:25:1420
Roberto Carrillo3b567862019-01-30 19:01:2521Chromium uses source-based code coverage for clang-compiled languages such as
22C++. This [documentation] explains how to use Clangs source-based coverage
23features in general.
Yuke Liaod3b46272018-03-14 18:25:1424
Roberto Carrillo3b567862019-01-30 19:01:2525In this document, we first introduce the code coverage infrastructure that
26continuously generates code coverage information for the whole codebase and for
27specific CLs in Gerrit. For the latter, refer to
28[code\_coverage\_in\_gerrit.md](code_coverage_in_gerrit.md)
29We then present a script that can be used to locally generate code coverage
30reports with one command, and finally we provide a description of the
31process of producing these reports.
32
33## Coverage Infrastructure
34
35![coverage infra diagram]
36
37There are 3 layers in the system:
38
39### Coverage Builders
40
41The first layer is the LUCI builders that
42 - build instrumented targets,
43 - run the instrumented tests,
44 - merge the results into single streams,
45 - upload data to cloud storage.
46
47There are two types of builder:
48
49CI Builder
50
51The Code-coverage CI Builders periodically build all the test targets and fuzzer
52targets for a given platform and instrument all available source files. Then
53save the coverage data to a dedicated storage bucket.
54
55CQ Builder
56
57The code coverage CQ builders instrument only the files changed for a given CL.
58more information about per-cl coverage info in [this
59doc](code_coverage_in_gerrit.md)
60
61### Coverage Service
62
63The second layer in the system consists of an AppEngine application that
64consumes the coverage data from the builders above, structures it and stores it
65in cloud datastore. It then serves the information to the clients below.
66
67### Coverage Clients
68
69In the last layer we currently have two clients that consume the service:
70
71#### Coverage Dashboard
72
73The [coverage dashboard] front end is hosted in the same application as the
74service above.
75It shows the full-code coverage reports with links to the builds that generated
76them, as well as per-directory and per-component aggregation, and can be drilled
77down to the single line of code level of detail.
78
79Refer tho the following screenshots, or this [18-second video
80tutorial](https://www.youtube.com/watch?v=eX7im2_3YfA)
81
82##### Project View
83
84![coverage dashboard main view]
85
86##### Directory View
87
88![coverage dashboard directory view]
89
90##### Component View
91
92![coverage dashboard component view]
93
94##### Source View
95
96When you click on a particular source file in one of the views above, you can check
97per-line coverage information such as
98
99- Uncovered / Covered line fragments, lines and code blocks. This information can be
100useful to identify areas of code that lack test coverage.
101- Per-line hit counts indicating how many times this line was hit by all tested targets.
102This information can be useful to determine hot spots in your code.
103- Potentially dead code. See [dead code example].
104
105![coverage dashboard file view]
106
107#### Gerrit Coverage View
108
109The other client supported at the moment is the gerrit plugin for code coverage.
110
111![gerrit coverage view]
112
113See [this doc](code_coverage_in_gerrit.md) for information about the feature
114that allows gerrit to display code coverage information generated for a given CL
115by CQ bot. Or see this
116[15-second video tutorial](https://www.youtube.com/watch?v=cxXlYcSgIPE)
Yuke Liaod3b46272018-03-14 18:25:14117
Yuke Liao1ffc8cb62018-04-06 19:09:07118## Coverage Script
119The [coverage script] automates the process described below and provides a
Roberto Carrillo3b567862019-01-30 19:01:25120one-stop service to generate code coverage reports locally in just one command.
Yuke Liaod3b46272018-03-14 18:25:14121
Yuke Liao1ffc8cb62018-04-06 19:09:07122This script is currently supported on Linux, Mac, iOS and ChromeOS platforms.
123
124Here is an example usage:
125
Yuke Liaod3b46272018-03-14 18:25:14126```
Yuke Liao1ffc8cb62018-04-06 19:09:07127$ gn gen out/coverage \
Max Moroza5a95272018-08-31 16:20:55128 --args='use_clang_coverage=true is_component_build=false dcheck_always_on=true'
Yuke Liao1ffc8cb62018-04-06 19:09:07129$ python tools/code_coverage/coverage.py \
130 crypto_unittests url_unittests \
131 -b out/coverage -o out/report \
132 -c 'out/coverage/crypto_unittests' \
133 -c 'out/coverage/url_unittests --gtest_filter=URLParser.PathURL' \
134 -f url/ -f crypto/
135```
136The command above builds `crypto_unittests` and `url_unittests` targets and then
Max Moroza5a95272018-08-31 16:20:55137runs them individually with their commands and arguments specified by the `-c` flag.
Abhishek Aryaaf9811f22018-05-11 22:17:48138For `url_unittests`, it only runs the test `URLParser.PathURL`. The coverage report
Yuke Liao1ffc8cb62018-04-06 19:09:07139is filtered to include only files and sub-directories under `url/` and `crypto/`
140directories.
141
Abhishek Aryaaf9811f22018-05-11 22:17:48142Aside from automating the process, this script provides visualization features to
Roberto Carrillo3b567862019-01-30 19:01:25143view code coverage breakdown by directories and by components, similar to the
144views in the [coverage dashboard](#coverage-dashboard) above.
Abhishek Aryaaf9811f22018-05-11 22:17:48145
Yuke Liao1ffc8cb62018-04-06 19:09:07146## Workflow
147This section presents the workflow of generating code coverage reports using two
148unit test targets in Chromium repo as an example: `crypto_unittests` and
149`url_unittests`, and the following diagram shows a step-by-step overview of the
150process.
151
152![code coverage generation workflow](images/code_coverage_workflow.png)
153
154### Step 0 Download Tooling
155Generating code coverage reports requires llvm-profdata and llvm-cov tools.
156Currently, these two tools are not part of Chromiums Clang bundle,
157[coverage script] downloads and updates them automatically, you can also
Roberto Carrillo3b567862019-01-30 19:01:25158download the tools manually ([tools link]).
Yuke Liao1ffc8cb62018-04-06 19:09:07159
160### Step 1 Build
161In Chromium, to compile code with coverage enabled, one needs to add
162`use_clang_coverage=true` and `is_component_build=false` GN flags to the args.gn
163file in the build output directory. Under the hood, they ensure
164`-fprofile-instr-generate` and `-fcoverage-mapping` flags are passed to the
165compiler.
166
167```
168$ gn gen out/coverage \
169 --args='use_clang_coverage=true is_component_build=false'
170$ gclient runhooks
Max Morozf5b31fcd2018-08-10 21:55:48171$ autoninja -C out/coverage crypto_unittests url_unittests
Yuke Liaod3b46272018-03-14 18:25:14172```
173
Yuke Liao1ffc8cb62018-04-06 19:09:07174### Step 2 Create Raw Profiles
Yuke Liaobc35726b2018-10-31 22:16:21175The next step is to run the instrumented binaries. When the program exits, it
Abhishek Aryaaf9811f22018-05-11 22:17:48176writes a raw profile for each process. Because Chromium runs tests in
177multiple processes, the number of processes spawned can be as many as a few
178hundred, resulting in the generation of a few hundred gigabytes raw
179profiles. To limit the number of raw profiles, `%Nm` pattern in
Yuke Liao1ffc8cb62018-04-06 19:09:07180`LLVM_PROFILE_FILE` environment variable is used to run tests in multi-process
181mode, where `N` is the number of raw profiles. With `N = 4`, the total size of
182the raw profiles are limited to a few gigabytes.
183
184```
185$ export LLVM_PROFILE_FILE=”out/report/crypto_unittests.%4m.profraw”
186$ ./out/coverage/crypto_unittests
187$ ls out/report/
188crypto_unittests.3657994905831792357_0.profraw
189...
190crypto_unittests.3657994905831792357_3.profraw
191```
192
193### Step 3 Create Indexed Profile
194Raw profiles must be indexed before generating code coverage reports, and this
195is done using the `merge` command of `llvm-profdata` tool, which merges multiple
Abhishek Aryaaf9811f22018-05-11 22:17:48196raw profiles (.profraw) and indexes them to create a single profile (.profdata).
Yuke Liao1ffc8cb62018-04-06 19:09:07197
198At this point, all the raw profiles can be thrown away because their information
Abhishek Aryaaf9811f22018-05-11 22:17:48199is already contained in the indexed profile.
Yuke Liao1ffc8cb62018-04-06 19:09:07200
201```
202$ llvm-profdata merge -o out/report/coverage.profdata \
203 out/report/crypto_unittests.3657994905831792357_0.profraw
204...
205out/report/crypto_unittests.3657994905831792357_3.profraw
206out/report/url_unittests.714228855822523802_0.profraw
207...
208out/report/url_unittests.714228855822523802_3.profraw
209$ ls out/report/coverage.profdata
210out/report/coverage.profdata
211```
212
213### Step 4 Create Coverage Reports
214Finally, `llvm-cov` is used to render code coverage reports. There are different
Abhishek Aryaaf9811f22018-05-11 22:17:48215report generation modes, and all of them require the following as input:
216- Indexed profile
217- All built target binaries
218- All exercised source files.
Yuke Liao1ffc8cb62018-04-06 19:09:07219
Abhishek Aryaaf9811f22018-05-11 22:17:48220For example, the following command can be used to generate per-file line-by-line
Yuke Liao1ffc8cb62018-04-06 19:09:07221code coverage report:
222
223```
224$ llvm-cov show -output-dir=out/report -format=html \
225 -instr-profile=out/report/coverage.profdata \
226 -object=out/coverage/url_unittests \
227 out/coverage/crypto_unittests
228```
229
230For more information on how to use llvm-cov, please refer to the [guide].
Yuke Liaod3b46272018-03-14 18:25:14231
Max Morozd73e45f2018-04-24 18:32:47232## Contacts
233
234### Reporting problems
Yuke Liaod3b46272018-03-14 18:25:14235For any breakage report and feature requests, please [file a bug].
236
Max Morozd73e45f2018-04-24 18:32:47237### Mailing list
Yuke Liaobc35726b2018-10-31 22:16:21238For questions and general discussions, please join [code-coverage group].
Yuke Liao1ffc8cb62018-04-06 19:09:07239
Max Morozd73e45f2018-04-24 18:32:47240## FAQ
241
242### Can I use `is_component_build=true` for code coverage build?
243
244Yes, code coverage instrumentation works with both component and non-component
245builds. Component build is usually faster to compile, but can be up to several
246times slower to run with code coverage instrumentation. For more information,
Max Morozc5e364a2018-04-25 23:19:49247see [crbug.com/831939].
248
249### I am getting some warnings while using the script, is that fine?
250
Abhishek Aryaaf9811f22018-05-11 22:17:48251Usually this is not a critical issue, but in general we tend not to have any
Max Morozc5e364a2018-04-25 23:19:49252warnings. Please check the list of [known issues], and if there is a similar
253bug, leave a comment with the command you run, the output you get, and Chromium
254revision you use. Otherwise, please [file a new issue] providing the same
255information.
256
257### How do crashes affect code coverage?
258
Max Moroza5a95272018-08-31 16:20:55259If a crash of any type occurs (e.g. Segmentation Fault or ASan error), the
260crashing process might not dump coverage information necessary to generate
Max Morozc5e364a2018-04-25 23:19:49261code coverage report. For single-process applications (e.g. fuzz targets), that
Max Moroza5a95272018-08-31 16:20:55262means no coverage might be reported at all. For multi-process applications, the
263report might be incomplete. It is important to fix the crash first. If this is
Abhishek Aryaaf9811f22018-05-11 22:17:48264happening only in the coverage instrumented build, please [file a bug].
Max Morozd73e45f2018-04-24 18:32:47265
Max Moroza5a95272018-08-31 16:20:55266### How do assertions affect code coverage?
267
268If a crash is caused by CHECK or DCHECK, the coverage dump will still be written
269on the disk ([crrev.com/c/1172932]). However, if a crashing process calls the
270standard [assert] directly or through a custom wrapper, the dump will not be
271written (see [How do crashes affect code coverage?]).
272
Max Moroz63cd04d2018-05-02 16:40:23273### Is it possible to obtain code coverage from a full Chromium build?
274
275Yes, with some important caveats. It is possible to build `chrome` target with
276code coverage instrumentation enabled. However, there are some inconveniences
277involved:
278
279* Linking may take a while
280* The binary is huge (~4GB)
281* The browser "works", but is noticeably slow and laggy
282* The sandbox needs to be disabled (`--no-sandbox`)
Max Moroz63cd04d2018-05-02 16:40:23283
284For more information, please see [crbug.com/834781].
285
Max Moroz3a928902018-05-15 14:39:50286### Why do we see significantly different coverage reported on different revisions?
287
288There can be two possible scenarios:
289
290* It can be a one time flakiness due to a broken build or failing tests.
291* It can be caused by extension of the test suite used for generating code
292coverage reports. When we add new tests to the suite, the aggregate coverage
293reported usually grows after that.
294
295### How can I improve [coverage dashboard]?
296
297Source code of the dashboard is not open sourced at the moment, but if you are a
298Googler, you should have access to the code-coverage repository. There is a
299documentation and scripts for running it locally. To get access and report
300issues, ping chrome-code-coverage@ list.
301
Roberto Carrillo3b567862019-01-30 19:01:25302The code for the service and dashboard currently lives along with findit at
303[this location](https://chromium.googlesource.com/infra/infra/+/master/appengine/findit/)
304because of significant shared logic.
305
306The code used by the bots that generate the coverage data lives (among other
307places) in the
308[clang coverage recipe module](https://chromium.googlesource.com/chromium/tools/build/+/master/scripts/slave/recipe_modules/clang_coverage/)
309
Max Moroz3a928902018-05-15 14:39:50310### Why is coverage for X not reported or unreasonably low, even though there is a test for X?
311
312There are several reasons why coverage reports can be incomplete or incorrect:
313
314* A particular test is not used for code coverage report generation. Please
315check the [test suite], and if the test is missing, upload a CL to add it.
Roberto Carrillo3b567862019-01-30 19:01:25316* A test may have a build failure or a runtime crash. Please check the build
317for that particular report (rightmost column on the [coverage dashboard]).
Max Moroz3a928902018-05-15 14:39:50318If there is any failure, please upload a CL with the fix. If you can't fix it,
319feel free to [file a bug].
320* A particular test may not be available on a particular platform. As of now,
321only reports generated on Linux are available on the [coverage dashboard].
322
Max Moroz3a928902018-05-15 14:39:50323### Is coverage reported for the code executed inside the sandbox?
324
325Not at the moment until [crbug.com/842424] is resolved. We do not disable the
326sandbox when running the tests. However, if there are any other non-sandbox'ed
327tests for the same code, the coverage should be reported from those. For more
328information, see [crbug.com/842424].
329
Max Morozd73e45f2018-04-24 18:32:47330
Max Moroza5a95272018-08-31 16:20:55331[assert]: http://man7.org/linux/man-pages/man3/assert.3.html
Yuke Liaobc35726b2018-10-31 22:16:21332[code-coverage group]: https://groups.google.com/a/chromium.org/forum/#!forum/code-coverage
Max Moroz3a928902018-05-15 14:39:50333[code-coverage repository]: https://chrome-internal.googlesource.com/chrome/tools/code-coverage
Roberto Carrillo3b567862019-01-30 19:01:25334[coverage dashboard]: https://analysis.chromium.org/p/chromium/coverage
Yuke Liao1ffc8cb62018-04-06 19:09:07335[coverage script]: https://cs.chromium.org/chromium/src/tools/code_coverage/coverage.py
Roberto Carrillo3b567862019-01-30 19:01:25336[coverage infra diagram]: images/code_coverage_infra_diagram.png
337[coverage dashboard file view]: images/code_coverage_dashboard_file_view.png
338[coverage dashboard component view]: images/code_coverage_dashboard_component_view.png
339[coverage dashboard directory view]: images/code_coverage_dashboard_directory_view.png
340[coverage dashboard main view]: images/code_coverage_dashboard_main_view.png
Max Moroz3a928902018-05-15 14:39:50341[crbug.com/821617]: https://crbug.com/821617
Max Morozc5e364a2018-04-25 23:19:49342[crbug.com/831939]: https://crbug.com/831939
Max Moroz63cd04d2018-05-02 16:40:23343[crbug.com/834781]: https://crbug.com/834781
Max Moroz3a928902018-05-15 14:39:50344[crbug.com/842424]: https://crbug.com/842424
Max Moroza5a95272018-08-31 16:20:55345[crrev.com/c/1172932]: https://crrev.com/c/1172932
Max Moroz3a928902018-05-15 14:39:50346[clang roll]: https://crbug.com/841908
Abhishek Aryab23b1a72018-05-17 20:11:09347[dead code example]: https://chromium.googlesource.com/chromium/src/+/ac6e09311fcc7e734be2ef21a9ccbbe04c4c4706
Max Morozc5e364a2018-04-25 23:19:49348[documentation]: https://clang.llvm.org/docs/SourceBasedCodeCoverage.html
Yuke Liao1ffc8cb62018-04-06 19:09:07349[file a bug]: https://bugs.chromium.org/p/chromium/issues/entry?components=Tools%3ECodeCoverage
Max Morozc5e364a2018-04-25 23:19:49350[file a new issue]: https://bugs.chromium.org/p/chromium/issues/entry?components=Tools%3ECodeCoverage
Roberto Carrillo3b567862019-01-30 19:01:25351[gerrit coverage view]: images/code_coverage_uncovered_lines.png
Max Morozc5e364a2018-04-25 23:19:49352[guide]: http://llvm.org/docs/CommandGuide/llvm-cov.html
Max Moroza5a95272018-08-31 16:20:55353[How do crashes affect code coverage?]: #how-do-crashes-affect-code-coverage
Max Morozc5e364a2018-04-25 23:19:49354[known issues]: https://bugs.chromium.org/p/chromium/issues/list?q=component:Tools%3ECodeCoverage
Roberto Carrillo3b567862019-01-30 19:01:25355[tools link]: https://storage.googleapis.com/chromium-browser-clang-staging/
Max Moroz3a928902018-05-15 14:39:50356[test suite]: https://cs.chromium.org/chromium/src/tools/code_coverage/test_suite.txt