This manual provides information on how to develop the Chromium Updater, including tips and tricks.
Where possible, cross-platform code is preferred to other alternatives. This means that the source code of the updater is organized in sub-directories, first by functionality (or feature), and second by platform name. For example, the source code contains updater\net instead of updater\mac\net.
NOTE: Knowledge in this section may become out-of-date as LUCI evolves quickly.
There are two sets of configuration files for our builders/testers. One is for chromium-branded and locates in src. The other one is for chrome-branded and locates in src-internal.
src)tools/mb/mb_config.pyl: specifies GN args.testing/buildbot/gn_isolate_map.pyl: maps a GN label to GN targets, and provides test arguments, for example test timeout values.testing/buildbot/test_suites.pyl: maps test suite name to GN label, and provides optional swarming dimensions.testing/buildbot/waterfalls.pyl: maps tester to test suites names, and specifies OS, architecture etc.infra/config/subprojects/chromium/ci/chromium.updater.star: defines our testers and builders and how they appear on the console.Command to update json files after configure update:
tools\mb\mb train (if mb_config.pyl is changed).lucicfg generate .\infra\config\main.star (if chromium.updater.star is changed).vpython3 .\testing\buildbot\generate_buildbot_json.pyReference CLs:
src-internal)tools/mb/mb_config.pyl: specifies GN args.testing/buildbot/gn_isolate_map.pyl: maps a GN label to GN targets, and provides test arguments, for example test timeout values.testing/buildbot/test_suites.pyl: maps test suite name to GN label, and provides optional swarming dimensions.testing/buildbot/waterfalls.pyl: maps tester to test suites names, and specifies OS, architecture etc.infra/config/subprojects/chrome/ci/chrome.updater.star: defines our testers and builders and how they appear on the console.Command to update json files after configure update:
..\src\tools\mb\mb train -f tools\mb\mb_config.pyl (if mb_config.pyl is changed).lucicfg generate .\infra\config\main.star (if chrome.updater.star is changed).vpython3 .\testing\buildbot\generate_testing_json.pyPlease note changes in src-internal needs to roll into chromium/src to take effect. This could take hours until a CL authored by chromium-internal-autoroll@ lands. During transition, the configure files could be in inconsistent state and leads to infra error.
mb tool can upload your private build target (and all the dependencies, based on build rule) to swarming server and run the target on bots. The upload may take quite some time if the target changed a lot since the last upload and/or your network is slow.
.\tools\mb\mb.bat run -v --swarmed .\out\Default updater_tests -- --gtest_filter=*Integration*
-d. Remember --no-default-dimensions is necessary to avoid dimension value conflict. Example:.\tools\mb\mb.bat run --swarmed --no-default-dimensions -d pool chromium.win.uac -d os Windows-10 .\out\Default updater_tests_system -- --gtest_filter=*Install*
mb can schedule tests in the pools managed by different swarming servers. The default server is chromium-swarm.appspot.com. To schedule tests to pools managed by chrome-swarming.appspot.com, for example chrome.tests, add --internal flag in the command line:tools/mb/mb run -v --swarmed --internal --no-default-dimensions -d pool chrome.tests -d os Windows-10 out/WinDefault updater_tests
mb command failed with error isolate: original error: interactive login is required, you need to login:tools/luci-go/isolate login
mb tool know so it can correctly figure out the dependency. Example: https://crrev.com/c/3470143.Arm64, the mb tool needs to be invoked as follows:.\tools\mb\mb run -v --swarmed --no-default-dimensions --internal -d pool chrome.tests.arm64 out\Default updater_tests_system -- --gtest_filter=LegacyAppCommandWebImplTest.FailedToLaunchStatus
TODO(crbug.com/1327486): Document how to remote into bots for debugging.
An older version of the updater is checked in under //third_party/updater. This version of the updater is used in some integration tests. The updater is pulled from CIPD based on the versions specified in //DEPS. A system called 3pp periodically updates the packages in CIPD, based on a combination of the Chromium build output and what is actually released through Omaha servers. The configuration for 3pp can be found in //third_party/updater/*/3pp.
To update these copies of the updaters:
fetch.py scripts for 3pp. For Chrome builds, make sure the build has been released in Omaha then update the fetch script with the desired version number. For Chromium, make sure the build exists in GCS (the chromium-browser-snapshots bucket), then update the min version in the script. The min version usually is different per-platform, since Chromium does not archive a version at every CL. After making these changes, 3pp will import the new versions within a few hours.After creating your build configuration directory via gn gen (this step is equivalent across all platforms), you will need to use gn args to configure the build appropriately.
As of 2023-05-24, the updater cannot be built in component mode. It is also not specifically designed to be built without the updater being enabled. You must specify these options to gn via gn args:
is_component_build=false enable_updater=true
Depending on other configuration options, the default symbol_level, 2, might produce object files too large for the linker to handle (in debug builds). Partial symbols, via symbol_level=1, fix this. Omitting almost all symbols via symbol_level=0 reuslts in a smaller and faster build but makes debugging nearly impossible (call stacks will not be symbolicated).
Building on Goma is typically much faster than your workstation. After you've set up Goma, specify it in gn args with use_goma=true.
To get started on Goma, and for more information on how to use it, review its public documentation or its Google-internal documentation.
Chromium projects build in debug mode by default. Release builds (also called “opt”, or “optimized”, builds) are faster to link and run more efficiently; they are, of course, much harder to debug. For a release build, add the following to the build configuration's gn args:
is_debug=false
With a Google src-internal checkout, you can create a Chrome-branded build:
is_chrome_branded=true include_branded_entitlements=false
Updater branding affects the path the updater installs itself to, among other things. Differently-branded copies of Chromium Updater are intended to coexist on a machine, operating independently from each other.
Running ninja with t clean cleans the build out directory. For example:
ninja -C out\Default chrome/updater:all -t clean
6 different build flavors need to be built in sequence. If you see errors similar to the following:
midl.exe output different from files in gen/chrome/updater/app/server/win, see C:\src\temp\tmppbfwi0ds To rebaseline: copy /y C:\src\temp\tmppbfwi0ds\* c:\src\chromium\src\third_party\win_build_output\midl\chrome\updater\app\server\win\x64 ninja: build stopped: subcommand failed.
You can then run the following command to update IDL COM files for all flavors:
python3 tools/win/update_idl.py
Build outputs will land in the directory created by gn gen that you have been providing to assorted gn, ninja, and autoninja commands. updater.zip contains copies of the “final” outputs created by the build. UpdaterSetup is probably what you want for installing the updater you have built.
TODO(crbug.com/1448700): list the relevant/interesting outputs here and what they are, why they're relevant/interesting, etc.
Gerrit now down-votes the changes that do not have enough coverage. And it's nice to have good coverage regardless. To improve code-coverage, we need to know what are already covered and what are not.
It's automatically generated. But the coverage shown is the combined result from all OS platforms.
The updater code coverage dashboard supports breakdown by OS platform or test type. But it is only for the code in trunk.
We can quickly get OS-specific coverage result with the local changes:
gn gen out/coverage --args="use_clang_coverage=true is_component_build=false is_chrome_branded=true is_debug=true use_debug_fission=true use_goma=true symbol_level=2" vpython3 tools/code_coverage/coverage.py updater_tests -b out/coverage -o out/report -c 'out/coverage/updater_tests' -f chrome/updater
gn gen out\coverage --args="use_clang_coverage=true is_component_build=false is_chrome_branded=true is_debug=true use_debug_fission=true use_goma=true symbol_level=2" vpython3 tools\code_coverage\coverage.py updater_tests -b out\coverage -o out\report -c out\coverage\updater_tests.exe -f chrome/updater
The last command outputs an HTML file and you can open it in browser to see the coverages.
UpdaterSetup.exe --install [--system]TIP: Debugger may have trouble to find the symbols at the service side even if you add your build output directory to the symbol paths. To workaournd the issue, you can copy
updater.exe*to the versioned installation directory.
update_service_proxy.*.--server (user-level server) or --system --windows-service (system-level server). Start another debugger and attach the server process. Then set a server-side breakpoint at the place you want to debug.Both the updater and the unit tests can create program logs.
The updater itself logs in the product directory.
The unit tests log into a directory defined by the environment variable ${ISOLATED_OUTDIR}. When run by Swarming, the updater logs are copied into ${ISOLATED_OUTDIR} too, so that after the swarming task has completed, both types of logs are available as CAS outputs. The logs for updater_tests_system and integration_test_helper are merged into updater_tests_system.log.
Non-bot systems can set up this environment variable to collect logs for debugging when the tests are run locally.
In some cases, you will want to test the changes you make within chromium/src on specific builders/testers before landing these changes. It is possible to do this with the use of the trybots available on the tryserver.chromium.updater waterfall. The steps are as follows:
git cl uploadgit cl try -B luci.chromium.try -b {TRYBOT_NAME} with the name of the trybot you found.origin/main since your last successful build, or have never successfully built on your current branch, and the build errors you‘re seeing aren’t obviously related to any changes you've made, check the tree status. Did you pull down a broken version? If so, and the revert is in, pull again and see if it works better. Or skip checking the tree status and just try this as your first debugging step for build breaks after a pull.gclient sync -D after every pull from origin/main and every branch change. If you aren‘t sure whether you ran it, just run it, it’s fast if you don't need it.goma_ctl ensure_start and try again.gn args to verify that symbol_level=1 (or 0) is present. If it‘s not, you’re running into a known issue where the default symbol level, 2, outputs symbols too large for the linker to comprehend.