blob: f872e65facb1b8889409a6c713f5512467fe9b33 [file] [log] [blame] [view]
Max Moroz3a928902018-05-15 14:39:501# Code Coverage in Chromium
2
Roberto Carrillo5221fc12019-01-30 21:34:503### Coverage Dashboard: [link](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)
Roberto Carrillobc1560e2019-01-30 20:08:5811- [Local Coverage Script](#local-coverage-script)
Yuke Liao1ffc8cb62018-04-06 19:09:0712 * [Step 0 Download Tooling](#step-0-download-tooling)
13 * [Step 1 Build](#step-1-build)
14 * [Step 2 Create Raw Profiles](#step-2-create-raw-profiles)
15 * [Step 3 Create Indexed Profile](#step-3-create-indexed-profile)
16 * [Step 4 Create Coverage Reports](#step-4-create-coverage-reports)
Max Morozd73e45f2018-04-24 18:32:4717- [Contacts](#contacts)
18- [FAQ](#faq)
Yuke Liaod3b46272018-03-14 18:25:1419
Roberto Carrillo3b567862019-01-30 19:01:2520Chromium uses source-based code coverage for clang-compiled languages such as
21C++. This [documentation] explains how to use Clang’s source-based coverage
22features in general.
Yuke Liaod3b46272018-03-14 18:25:1423
Roberto Carrillo3b567862019-01-30 19:01:2524In this document, we first introduce the code coverage infrastructure that
25continuously generates code coverage information for the whole codebase and for
26specific CLs in Gerrit. For the latter, refer to
Roberto Carrillo5221fc12019-01-30 21:34:5027[code\_coverage\_in\_gerrit.md](code_coverage_in_gerrit.md).
Roberto Carrillo3b567862019-01-30 19:01:2528We then present a script that can be used to locally generate code coverage
29reports with one command, and finally we provide a description of the
30process of producing these reports.
31
32## Coverage Infrastructure
33
34![coverage infra diagram]
35
36There are 3 layers in the system:
37
38### Coverage Builders
39
40The first layer is the LUCI builders that
41 - build instrumented targets,
42 - run the instrumented tests,
43 - merge the results into single streams,
44 - upload data to cloud storage.
45
46There are two types of builder:
47
48CI Builder
49
Yuke Liao43bbbcd52019-06-21 19:34:5050The code coverage CI Builders periodically build all the test targets and fuzzer
Roberto Carrillo3b567862019-01-30 19:01:2551targets for a given platform and instrument all available source files. Then
52save the coverage data to a dedicated storage bucket.
53
54CQ Builder
55
56The code coverage CQ builders instrument only the files changed for a given CL.
Yuke Liao43bbbcd52019-06-21 19:34:5057More information about per-cl coverage info in [this
Roberto Carrillo5221fc12019-01-30 21:34:5058doc](code_coverage_in_gerrit.md).
Roberto Carrillo3b567862019-01-30 19:01:2559
60### Coverage Service
61
62The second layer in the system consists of an AppEngine application that
63consumes the coverage data from the builders above, structures it and stores it
64in cloud datastore. It then serves the information to the clients below.
65
66### Coverage Clients
67
68In the last layer we currently have two clients that consume the service:
69
70#### Coverage Dashboard
71
72The [coverage dashboard] front end is hosted in the same application as the
73service above.
74It shows the full-code coverage reports with links to the builds that generated
75them, as well as per-directory and per-component aggregation, and can be drilled
76down to the single line of code level of detail.
77
Yuke Liao43bbbcd52019-06-21 19:34:5078Refer to the following screenshots:
Roberto Carrillo3b567862019-01-30 19:01:2579
80##### Directory View
81
Yuke Liao43bbbcd52019-06-21 19:34:5082See coverage breakdown by directories (default landing page).
83
Roberto Carrillo3b567862019-01-30 19:01:2584![coverage dashboard directory view]
85
86##### Component View
87
Yuke Liao43bbbcd52019-06-21 19:34:5088Use the view dropdown menu to switch between directory and component.
89
Roberto Carrillo3b567862019-01-30 19:01:2590![coverage dashboard component view]
91
92##### Source View
93
Yuke Liao43bbbcd52019-06-21 19:34:5094Click on a particular source file in one of the views above to see line-by-line
95coverage breakdown, and it's useful to identify:
96- Uncovered lines and code blocks that lack test coverage.
Roberto Carrillo3b567862019-01-30 19:01:2597- Potentially dead code. See [dead code example].
Yuke Liao43bbbcd52019-06-21 19:34:5098- Hot spots in your code.
Roberto Carrillo3b567862019-01-30 19:01:2599
100![coverage dashboard file view]
101
Yuke Liao43bbbcd52019-06-21 19:34:50102##### Project View
103
104Click on "Previous Reports" to check out the coverage history of the project.
105
106![coverage dashboard link to previous reports]
107
108List of historical coverage reports are in reverse chronological order.
109
110![coverage dashboard previous reports]
111
Roberto Carrillo3b567862019-01-30 19:01:25112#### Gerrit Coverage View
113
114The other client supported at the moment is the gerrit plugin for code coverage.
115
116![gerrit coverage view]
117
118See [this doc](code_coverage_in_gerrit.md) for information about the feature
119that allows gerrit to display code coverage information generated for a given CL
120by CQ bot. Or see this
Roberto Carrillo5221fc12019-01-30 21:34:50121[15-second video tutorial](https://www.youtube.com/watch?v=cxXlYcSgIPE).
Yuke Liaod3b46272018-03-14 18:25:14122
Roberto Carrillobc1560e2019-01-30 20:08:58123## Local Coverage Script
Yuke Liao1ffc8cb62018-04-06 19:09:07124The [coverage script] automates the process described below and provides a
Roberto Carrillo3b567862019-01-30 19:01:25125one-stop service to generate code coverage reports locally in just one command.
Yuke Liaod3b46272018-03-14 18:25:14126
Yuke Liao1ffc8cb62018-04-06 19:09:07127This script is currently supported on Linux, Mac, iOS and ChromeOS platforms.
128
129Here is an example usage:
130
Yuke Liaod3b46272018-03-14 18:25:14131```
Yuke Liao1ffc8cb62018-04-06 19:09:07132$ gn gen out/coverage \
Max Moroza5a95272018-08-31 16:20:55133 --args='use_clang_coverage=true is_component_build=false dcheck_always_on=true'
Yuke Liao1ffc8cb62018-04-06 19:09:07134$ python tools/code_coverage/coverage.py \
135 crypto_unittests url_unittests \
136 -b out/coverage -o out/report \
137 -c 'out/coverage/crypto_unittests' \
138 -c 'out/coverage/url_unittests --gtest_filter=URLParser.PathURL' \
139 -f url/ -f crypto/
140```
141The command above builds `crypto_unittests` and `url_unittests` targets and then
Max Moroza5a95272018-08-31 16:20:55142runs them individually with their commands and arguments specified by the `-c` flag.
Abhishek Aryaaf9811f22018-05-11 22:17:48143For `url_unittests`, it only runs the test `URLParser.PathURL`. The coverage report
Yuke Liao1ffc8cb62018-04-06 19:09:07144is filtered to include only files and sub-directories under `url/` and `crypto/`
145directories.
146
Abhishek Aryaaf9811f22018-05-11 22:17:48147Aside from automating the process, this script provides visualization features to
Roberto Carrillo3b567862019-01-30 19:01:25148view code coverage breakdown by directories and by components, similar to the
149views in the [coverage dashboard](#coverage-dashboard) above.
Abhishek Aryaaf9811f22018-05-11 22:17:48150
Yuke Liao1ffc8cb62018-04-06 19:09:07151## Workflow
152This section presents the workflow of generating code coverage reports using two
153unit test targets in Chromium repo as an example: `crypto_unittests` and
154`url_unittests`, and the following diagram shows a step-by-step overview of the
155process.
156
157![code coverage generation workflow](images/code_coverage_workflow.png)
158
159### Step 0 Download Tooling
160Generating code coverage reports requires llvm-profdata and llvm-cov tools.
161Currently, these two tools are not part of Chromium’s Clang bundle,
162[coverage script] downloads and updates them automatically, you can also
Roberto Carrillo3b567862019-01-30 19:01:25163download the tools manually ([tools link]).
Yuke Liao1ffc8cb62018-04-06 19:09:07164
165### Step 1 Build
166In Chromium, to compile code with coverage enabled, one needs to add
167`use_clang_coverage=true` and `is_component_build=false` GN flags to the args.gn
168file in the build output directory. Under the hood, they ensure
169`-fprofile-instr-generate` and `-fcoverage-mapping` flags are passed to the
170compiler.
171
172```
173$ gn gen out/coverage \
174 --args='use_clang_coverage=true is_component_build=false'
175$ gclient runhooks
Max Morozf5b31fcd2018-08-10 21:55:48176$ autoninja -C out/coverage crypto_unittests url_unittests
Yuke Liaod3b46272018-03-14 18:25:14177```
178
Yuke Liao1ffc8cb62018-04-06 19:09:07179### Step 2 Create Raw Profiles
Yuke Liaobc35726b2018-10-31 22:16:21180The next step is to run the instrumented binaries. When the program exits, it
Abhishek Aryaaf9811f22018-05-11 22:17:48181writes a raw profile for each process. Because Chromium runs tests in
182multiple processes, the number of processes spawned can be as many as a few
183hundred, resulting in the generation of a few hundred gigabytes’ raw
184profiles. To limit the number of raw profiles, `%Nm` pattern in
Yuke Liao1ffc8cb62018-04-06 19:09:07185`LLVM_PROFILE_FILE` environment variable is used to run tests in multi-process
186mode, where `N` is the number of raw profiles. With `N = 4`, the total size of
187the raw profiles are limited to a few gigabytes.
188
189```
190$ export LLVM_PROFILE_FILE=”out/report/crypto_unittests.%4m.profraw”
191$ ./out/coverage/crypto_unittests
192$ ls out/report/
193crypto_unittests.3657994905831792357_0.profraw
194...
195crypto_unittests.3657994905831792357_3.profraw
196```
197
198### Step 3 Create Indexed Profile
199Raw profiles must be indexed before generating code coverage reports, and this
200is done using the `merge` command of `llvm-profdata` tool, which merges multiple
Abhishek Aryaaf9811f22018-05-11 22:17:48201raw profiles (.profraw) and indexes them to create a single profile (.profdata).
Yuke Liao1ffc8cb62018-04-06 19:09:07202
203At this point, all the raw profiles can be thrown away because their information
Abhishek Aryaaf9811f22018-05-11 22:17:48204is already contained in the indexed profile.
Yuke Liao1ffc8cb62018-04-06 19:09:07205
206```
207$ llvm-profdata merge -o out/report/coverage.profdata \
208 out/report/crypto_unittests.3657994905831792357_0.profraw
209...
210out/report/crypto_unittests.3657994905831792357_3.profraw
211out/report/url_unittests.714228855822523802_0.profraw
212...
213out/report/url_unittests.714228855822523802_3.profraw
214$ ls out/report/coverage.profdata
215out/report/coverage.profdata
216```
217
218### Step 4 Create Coverage Reports
219Finally, `llvm-cov` is used to render code coverage reports. There are different
Abhishek Aryaaf9811f22018-05-11 22:17:48220report generation modes, and all of them require the following as input:
221- Indexed profile
222- All built target binaries
Roberto Carrillo5221fc12019-01-30 21:34:50223- All exercised source files
Yuke Liao1ffc8cb62018-04-06 19:09:07224
Abhishek Aryaaf9811f22018-05-11 22:17:48225For example, the following command can be used to generate per-file line-by-line
Yuke Liao1ffc8cb62018-04-06 19:09:07226code coverage report:
227
228```
229$ llvm-cov show -output-dir=out/report -format=html \
230 -instr-profile=out/report/coverage.profdata \
231 -object=out/coverage/url_unittests \
232 out/coverage/crypto_unittests
233```
234
235For more information on how to use llvm-cov, please refer to the [guide].
Yuke Liaod3b46272018-03-14 18:25:14236
Max Morozd73e45f2018-04-24 18:32:47237## Contacts
238
239### Reporting problems
Yuke Liaod3b46272018-03-14 18:25:14240For any breakage report and feature requests, please [file a bug].
241
Max Morozd73e45f2018-04-24 18:32:47242### Mailing list
Yuke Liaobc35726b2018-10-31 22:16:21243For questions and general discussions, please join [code-coverage group].
Yuke Liao1ffc8cb62018-04-06 19:09:07244
Max Morozd73e45f2018-04-24 18:32:47245## FAQ
246
247### Can I use `is_component_build=true` for code coverage build?
248
249Yes, code coverage instrumentation works with both component and non-component
250builds. Component build is usually faster to compile, but can be up to several
251times slower to run with code coverage instrumentation. For more information,
Max Morozc5e364a2018-04-25 23:19:49252see [crbug.com/831939].
253
254### I am getting some warnings while using the script, is that fine?
255
Abhishek Aryaaf9811f22018-05-11 22:17:48256Usually this is not a critical issue, but in general we tend not to have any
Max Morozc5e364a2018-04-25 23:19:49257warnings. Please check the list of [known issues], and if there is a similar
258bug, leave a comment with the command you run, the output you get, and Chromium
Yuke Liao03c644072019-07-30 18:33:40259revision you use. Otherwise, please [file a bug] providing the same information.
Max Morozc5e364a2018-04-25 23:19:49260
261### How do crashes affect code coverage?
262
Max Moroza5a95272018-08-31 16:20:55263If a crash of any type occurs (e.g. Segmentation Fault or ASan error), the
264crashing process might not dump coverage information necessary to generate
Max Morozc5e364a2018-04-25 23:19:49265code coverage report. For single-process applications (e.g. fuzz targets), that
Max Moroza5a95272018-08-31 16:20:55266means no coverage might be reported at all. For multi-process applications, the
267report might be incomplete. It is important to fix the crash first. If this is
Abhishek Aryaaf9811f22018-05-11 22:17:48268happening only in the coverage instrumented build, please [file a bug].
Max Morozd73e45f2018-04-24 18:32:47269
Max Moroza5a95272018-08-31 16:20:55270### How do assertions affect code coverage?
271
272If a crash is caused by CHECK or DCHECK, the coverage dump will still be written
273on the disk ([crrev.com/c/1172932]). However, if a crashing process calls the
274standard [assert] directly or through a custom wrapper, the dump will not be
275written (see [How do crashes affect code coverage?]).
276
Max Moroz63cd04d2018-05-02 16:40:23277### Is it possible to obtain code coverage from a full Chromium build?
278
279Yes, with some important caveats. It is possible to build `chrome` target with
280code coverage instrumentation enabled. However, there are some inconveniences
281involved:
282
283* Linking may take a while
284* The binary is huge (~4GB)
285* The browser "works", but is noticeably slow and laggy
286* The sandbox needs to be disabled (`--no-sandbox`)
Max Moroz63cd04d2018-05-02 16:40:23287
288For more information, please see [crbug.com/834781].
289
Max Moroz3a928902018-05-15 14:39:50290### Why do we see significantly different coverage reported on different revisions?
291
292There can be two possible scenarios:
293
294* It can be a one time flakiness due to a broken build or failing tests.
295* It can be caused by extension of the test suite used for generating code
296coverage reports. When we add new tests to the suite, the aggregate coverage
297reported usually grows after that.
298
299### How can I improve [coverage dashboard]?
300
Roberto Carrillo3b567862019-01-30 19:01:25301The code for the service and dashboard currently lives along with findit at
302[this location](https://chromium.googlesource.com/infra/infra/+/master/appengine/findit/)
303because of significant shared logic.
304
305The code used by the bots that generate the coverage data lives (among other
306places) in the
Yuke Liao04efa972019-06-26 21:14:07307[code coverage recipe module](https://chromium.googlesource.com/chromium/tools/build/+/master/scripts/slave/recipe_modules/code_coverage/).
Roberto Carrillo3b567862019-01-30 19:01:25308
Max Moroz3a928902018-05-15 14:39:50309### Why is coverage for X not reported or unreasonably low, even though there is a test for X?
310
311There are several reasons why coverage reports can be incomplete or incorrect:
312
313* A particular test is not used for code coverage report generation. Please
Roberto Carrillo5221fc12019-01-30 21:34:50314[file a bug].
Roberto Carrillo3b567862019-01-30 19:01:25315* A test may have a build failure or a runtime crash. Please check the build
316for that particular report (rightmost column on the [coverage dashboard]).
Max Moroz3a928902018-05-15 14:39:50317If there is any failure, please upload a CL with the fix. If you can't fix it,
318feel free to [file a bug].
319* A particular test may not be available on a particular platform. As of now,
Yuke Liao43bbbcd52019-06-21 19:34:50320only reports generated on Linux and CrOS are available on the
321[coverage dashboard].
Max Moroz3a928902018-05-15 14:39:50322
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
Yuke Liao43bbbcd52019-06-21 19:34:50340[coverage dashboard link to previous reports]: images/code_coverage_dashboard_link_to_previous_reports.png
341[coverage dashboard previous reports]: images/code_coverage_dashboard_previous_reports.png
Max Moroz3a928902018-05-15 14:39:50342[crbug.com/821617]: https://crbug.com/821617
Max Morozc5e364a2018-04-25 23:19:49343[crbug.com/831939]: https://crbug.com/831939
Max Moroz63cd04d2018-05-02 16:40:23344[crbug.com/834781]: https://crbug.com/834781
Max Moroz3a928902018-05-15 14:39:50345[crbug.com/842424]: https://crbug.com/842424
Max Moroza5a95272018-08-31 16:20:55346[crrev.com/c/1172932]: https://crrev.com/c/1172932
Max Moroz3a928902018-05-15 14:39:50347[clang roll]: https://crbug.com/841908
Abhishek Aryab23b1a72018-05-17 20:11:09348[dead code example]: https://chromium.googlesource.com/chromium/src/+/ac6e09311fcc7e734be2ef21a9ccbbe04c4c4706
Max Morozc5e364a2018-04-25 23:19:49349[documentation]: https://clang.llvm.org/docs/SourceBasedCodeCoverage.html
Yuke Liao03c644072019-07-30 18:33:40350[file a bug]: https://bugs.chromium.org/p/chromium/issues/entry?components=Infra%3ETest%3ECodeCoverage
Yuke Liao43bbbcd52019-06-21 19:34:50351[gerrit coverage view]: images/code_coverage_annotations.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
Yuke Liao03c644072019-07-30 18:33:40354[known issues]: https://bugs.chromium.org/p/chromium/issues/list?q=component:Infra%3ETest%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