blob: 342ff3c8d7a71eaee244631dce0532fa19137285 [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 \
Max Moroza5a95272018-08-31 16:20:5534 --args='use_clang_coverage=true is_component_build=false dcheck_always_on=true'
Yuke Liao1ffc8cb62018-04-06 19:09:0735$ 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
Max Moroza5a95272018-08-31 16:20:5543runs them individually with their commands and arguments specified by the `-c` flag.
Abhishek Aryaaf9811f22018-05-11 22:17:4844For `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
Yuke Liaobc35726b2018-10-31 22:16:2164- Uncovered / Covered line fragments, lines and code blocks. This information can be
Abhishek Aryaaf9811f22018-05-11 22:17:4865useful to identify areas of code that lack test coverage.
Yuke Liaobc35726b2018-10-31 22:16:2166- Per-line hit counts indicating how many times this line was hit by all tested targets.
Abhishek Aryaaf9811f22018-05-11 22:17:4867This 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
Max Morozf5b31fcd2018-08-10 21:55:4897$ autoninja -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
Yuke Liaobc35726b2018-10-31 22:16:21101The next step is to run the instrumented binaries. When the program exits, it
Abhishek Aryaaf9811f22018-05-11 22:17:48102writes 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 Liaobc35726b2018-10-31 22:16:21164For questions and general discussions, please join [code-coverage group].
Yuke Liao1ffc8cb62018-04-06 19:09:07165
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
Max Moroza5a95272018-08-31 16:20:55185If a crash of any type occurs (e.g. Segmentation Fault or ASan error), the
186crashing process might not dump coverage information necessary to generate
Max Morozc5e364a2018-04-25 23:19:49187code coverage report. For single-process applications (e.g. fuzz targets), that
Max Moroza5a95272018-08-31 16:20:55188means no coverage might be reported at all. For multi-process applications, the
189report might be incomplete. It is important to fix the crash first. If this is
Abhishek Aryaaf9811f22018-05-11 22:17:48190happening only in the coverage instrumented build, please [file a bug].
Max Morozd73e45f2018-04-24 18:32:47191
Max Moroza5a95272018-08-31 16:20:55192### How do assertions affect code coverage?
193
194If a crash is caused by CHECK or DCHECK, the coverage dump will still be written
195on the disk ([crrev.com/c/1172932]). However, if a crashing process calls the
196standard [assert] directly or through a custom wrapper, the dump will not be
197written (see [How do crashes affect code coverage?]).
198
Max Moroz63cd04d2018-05-02 16:40:23199### Is it possible to obtain code coverage from a full Chromium build?
200
201Yes, with some important caveats. It is possible to build `chrome` target with
202code coverage instrumentation enabled. However, there are some inconveniences
203involved:
204
205* Linking may take a while
206* The binary is huge (~4GB)
207* The browser "works", but is noticeably slow and laggy
208* The sandbox needs to be disabled (`--no-sandbox`)
Max Moroz63cd04d2018-05-02 16:40:23209
210For more information, please see [crbug.com/834781].
211
Max Moroz3a928902018-05-15 14:39:50212### Why do we see significantly different coverage reported on different revisions?
213
214There can be two possible scenarios:
215
216* It can be a one time flakiness due to a broken build or failing tests.
217* It can be caused by extension of the test suite used for generating code
218coverage reports. When we add new tests to the suite, the aggregate coverage
219reported usually grows after that.
220
221### How can I improve [coverage dashboard]?
222
223Source code of the dashboard is not open sourced at the moment, but if you are a
224Googler, you should have access to the code-coverage repository. There is a
225documentation and scripts for running it locally. To get access and report
226issues, ping chrome-code-coverage@ list.
227
228### Why is coverage for X not reported or unreasonably low, even though there is a test for X?
229
230There are several reasons why coverage reports can be incomplete or incorrect:
231
232* A particular test is not used for code coverage report generation. Please
233check the [test suite], and if the test is missing, upload a CL to add it.
234* A test may have a build failure or a runtime crash. Please check [the logs]
235for that particular test target (rightmost column on the [coverage dashboard]).
236If there is any failure, please upload a CL with the fix. If you can't fix it,
237feel free to [file a bug].
238* A particular test may not be available on a particular platform. As of now,
239only reports generated on Linux are available on the [coverage dashboard].
240
Max Moroz3a928902018-05-15 14:39:50241### Is coverage reported for the code executed inside the sandbox?
242
243Not at the moment until [crbug.com/842424] is resolved. We do not disable the
244sandbox when running the tests. However, if there are any other non-sandbox'ed
245tests for the same code, the coverage should be reported from those. For more
246information, see [crbug.com/842424].
247
Max Morozd73e45f2018-04-24 18:32:47248
Max Moroza5a95272018-08-31 16:20:55249[assert]: http://man7.org/linux/man-pages/man3/assert.3.html
Yuke Liaobc35726b2018-10-31 22:16:21250[code-coverage group]: https://groups.google.com/a/chromium.org/forum/#!forum/code-coverage
Max Moroz3a928902018-05-15 14:39:50251[code-coverage repository]: https://chrome-internal.googlesource.com/chrome/tools/code-coverage
252[coverage dashboard]: https://chromium-coverage.appspot.com/
Yuke Liao1ffc8cb62018-04-06 19:09:07253[coverage script]: https://cs.chromium.org/chromium/src/tools/code_coverage/coverage.py
254[code coverage report directory view]: images/code_coverage_directory_view.png
255[code coverage report component view]: images/code_coverage_component_view.png
Abhishek Aryaaf9811f22018-05-11 22:17:48256[code coverage source view]: images/code_coverage_source_view.png
Max Moroz3a928902018-05-15 14:39:50257[crbug.com/821617]: https://crbug.com/821617
Max Morozc5e364a2018-04-25 23:19:49258[crbug.com/831939]: https://crbug.com/831939
Max Moroz63cd04d2018-05-02 16:40:23259[crbug.com/834781]: https://crbug.com/834781
Max Moroz3a928902018-05-15 14:39:50260[crbug.com/842424]: https://crbug.com/842424
Max Moroza5a95272018-08-31 16:20:55261[crrev.com/c/1172932]: https://crrev.com/c/1172932
Max Moroz3a928902018-05-15 14:39:50262[clang roll]: https://crbug.com/841908
Abhishek Aryab23b1a72018-05-17 20:11:09263[dead code example]: https://chromium.googlesource.com/chromium/src/+/ac6e09311fcc7e734be2ef21a9ccbbe04c4c4706
Max Morozc5e364a2018-04-25 23:19:49264[documentation]: https://clang.llvm.org/docs/SourceBasedCodeCoverage.html
Yuke Liao1ffc8cb62018-04-06 19:09:07265[file a bug]: https://bugs.chromium.org/p/chromium/issues/entry?components=Tools%3ECodeCoverage
Max Morozc5e364a2018-04-25 23:19:49266[file a new issue]: https://bugs.chromium.org/p/chromium/issues/entry?components=Tools%3ECodeCoverage
267[guide]: http://llvm.org/docs/CommandGuide/llvm-cov.html
Max Moroza5a95272018-08-31 16:20:55268[How do crashes affect code coverage?]: #how-do-crashes-affect-code-coverage
Max Moroz3a928902018-05-15 14:39:50269[https://chromium-coverage.appspot.com/]: https://chromium-coverage.appspot.com/
Max Morozc5e364a2018-04-25 23:19:49270[known issues]: https://bugs.chromium.org/p/chromium/issues/list?q=component:Tools%3ECodeCoverage
271[link]: https://storage.googleapis.com/chromium-browser-clang-staging/
Max Moroz3a928902018-05-15 14:39:50272[test suite]: https://cs.chromium.org/chromium/src/tools/code_coverage/test_suite.txt
273[the logs]: https://chromium-coverage.appspot.com/reports/latest/linux/metadata/index.html