rules.gni 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633
  1. # Copyright 2018 The Chromium Authors. All rights reserved.
  2. # Use of this source code is governed by a BSD-style license that can be
  3. # found in the LICENSE file.
  4. import("//build/config/chrome_build.gni")
  5. import("//build/config/chromeos/args.gni")
  6. import("//build/config/chromeos/ui_mode.gni")
  7. import("//build/config/dcheck_always_on.gni")
  8. import("//build/config/gclient_args.gni")
  9. import("//build/config/python.gni")
  10. import("//build/util/generate_wrapper.gni")
  11. assert(is_chromeos && is_chromeos_device)
  12. # Determine the real paths for various items in the SDK, which may be used
  13. # in the 'generate_runner_script' template below. We do so outside the template
  14. # to confine exec_script to a single invocation.
  15. if (cros_sdk_version != "") {
  16. # Ideally these should be maps, however, gn doesn't support map, so using a
  17. # list of list to simulate a map:
  18. # [key1, [value1, value2, ...]], [key2, [value1, value2, ...]], where
  19. # the keys are boards and values are symlinks or symlink targets, and the
  20. # mapping shouldn't be used for anything else.
  21. #
  22. # A sample usage is:
  23. # foreach(m, _symlink_targets_map) {
  24. # if(m[0] == target_key) {
  25. # target_value = m[1]
  26. # }
  27. # }
  28. #
  29. _symlink_map = []
  30. _symlink_targets_map = []
  31. if (is_chromeos_ash) {
  32. _potential_test_boards = [ cros_board ]
  33. } else {
  34. _potential_test_boards = []
  35. if (cros_boards != "") {
  36. _potential_test_boards += string_split(cros_boards, ":")
  37. }
  38. if (cros_boards_with_qemu_images != "") {
  39. _potential_test_boards += string_split(cros_boards_with_qemu_images, ":")
  40. }
  41. }
  42. foreach(b, _potential_test_boards) {
  43. _cache_path_prefix =
  44. "//build/cros_cache/chrome-sdk/symlinks/${b}+${cros_sdk_version}"
  45. _cros_is_vm = false
  46. foreach(b1, string_split(cros_boards_with_qemu_images, ":")) {
  47. if (b == b1) {
  48. _cros_is_vm = true
  49. }
  50. }
  51. _symlinks = []
  52. _symlinks = [
  53. # Tast harness & test data.
  54. rebase_path("${_cache_path_prefix}+autotest_server_package.tar.bz2"),
  55. rebase_path("${_cache_path_prefix}+chromeos-base/tast-cmd"),
  56. rebase_path("${_cache_path_prefix}+chromeos-base/tast-remote-tests-cros"),
  57. # Binutils (and other toolchain tools) used to deploy Chrome to the device.
  58. rebase_path(
  59. "${_cache_path_prefix}+environment_chromeos-base_chromeos-chrome.tar.xz"),
  60. rebase_path("${_cache_path_prefix}+target_toolchain"),
  61. ]
  62. if (_cros_is_vm) {
  63. # VM-related tools.
  64. _symlinks += [
  65. rebase_path("${_cache_path_prefix}+sys-firmware/seabios"),
  66. rebase_path("${_cache_path_prefix}+chromiumos_test_image.tar.xz"),
  67. rebase_path("${_cache_path_prefix}+app-emulation/qemu"),
  68. ]
  69. }
  70. _symlink_map += [ [
  71. b,
  72. _symlinks,
  73. ] ]
  74. }
  75. _all_symlinks = []
  76. foreach(m, _symlink_map) {
  77. _all_symlinks += m[1]
  78. }
  79. _all_symlink_targets =
  80. exec_script("//build/get_symlink_targets.py", _all_symlinks, "list lines")
  81. _index = 0
  82. foreach(m, _symlink_map) {
  83. _symlink_targets = []
  84. foreach(_, m[1]) {
  85. _symlink_targets += [ _all_symlink_targets[_index] ]
  86. _index += 1
  87. }
  88. _symlink_targets_map += [ [
  89. m[0],
  90. _symlink_targets,
  91. ] ]
  92. }
  93. }
  94. # Creates dependencies required by skylab testing. If passed the
  95. # generated_script and test_exe this will generate the skylab runner script.
  96. # If passed tast_attr_expr, tast_tests or tast_disabled_tests this will
  97. # generate a filter file containing the expression for running tests in skylab.
  98. # Args:
  99. # generated_script: Name of the generated runner script created for test_exe
  100. # test_exe: Name of the executable to run with the generated script.
  101. # tast_attr_expr: Tast expression to determine tests to run. This creates the
  102. # initial set of tests that can be further filtered..
  103. # tast_tests: Names of tests to enable in tast. All other tests will be
  104. # disabled that are not listed.
  105. # tast_disabled_tests: Names of tests to disable in tast. All other tests that
  106. # match the tast expression will still run.
  107. # tast_control: gni file with collections of tests to be used for specific
  108. # filters (e.g. "//chromeos/tast_control.gni"). Any lists of strings in
  109. # this file will be used to generate additional tast expressions with
  110. # those strings expanded into tests to disable (i.e. as && !"name:test").
  111. # The name of those lists are then intended to be used to specify in
  112. # test_suites.pyl which collection to be used on specific test suites.
  113. template("generate_skylab_deps") {
  114. forward_variables_from(invoker,
  115. [
  116. "generated_script",
  117. "test_exe",
  118. "tast_attr_expr",
  119. "tast_tests",
  120. "tast_disabled_tests",
  121. "tast_control",
  122. ])
  123. if (defined(test_exe) || defined(generated_script)) {
  124. assert(defined(test_exe) && defined(generated_script),
  125. "The test_exe and generated_script must both be defined when " +
  126. "generating the skylab runner script")
  127. action(target_name) {
  128. script = "//build/chromeos/generate_skylab_deps.py"
  129. outputs = [ generated_script ]
  130. args = [
  131. "generate-runner",
  132. "--test-exe",
  133. test_exe,
  134. "--output",
  135. rebase_path(generated_script, root_build_dir),
  136. ]
  137. deps = [ "//testing/buildbot/filters:chromeos_filters" ]
  138. if (defined(invoker.deps)) {
  139. deps += invoker.deps
  140. }
  141. data = [ generated_script ]
  142. if (defined(invoker.data)) {
  143. data += invoker.data
  144. }
  145. data_deps = [ "//testing:test_scripts_shared" ]
  146. if (defined(invoker.data_deps)) {
  147. data_deps += invoker.data_deps
  148. }
  149. }
  150. }
  151. if (defined(tast_attr_expr) || defined(tast_tests) ||
  152. defined(tast_disabled_tests)) {
  153. if (defined(tast_disabled_tests)) {
  154. assert(defined(tast_attr_expr),
  155. "tast_attr_expr must be used when specifying tast_disabled_tests.")
  156. }
  157. _generated_filter = "$root_build_dir/bin/${target_name}.filter"
  158. _skylab_args = [
  159. "generate-filter",
  160. "--output",
  161. rebase_path(_generated_filter),
  162. ]
  163. if (defined(tast_control)) {
  164. _skylab_args += [
  165. "--tast-control",
  166. rebase_path(tast_control),
  167. ]
  168. }
  169. if (defined(tast_attr_expr)) {
  170. _skylab_args += [
  171. "--tast-expr",
  172. tast_attr_expr,
  173. ]
  174. }
  175. if (defined(tast_tests)) {
  176. foreach(_test, tast_tests) {
  177. _skylab_args += [
  178. "--enabled-tests",
  179. _test,
  180. ]
  181. }
  182. }
  183. if (defined(tast_disabled_tests)) {
  184. foreach(_test, tast_disabled_tests) {
  185. _skylab_args += [
  186. "--disabled-tests",
  187. _test,
  188. ]
  189. }
  190. }
  191. action(target_name) {
  192. script = "//build/chromeos/generate_skylab_deps.py"
  193. if (defined(tast_control)) {
  194. sources = [ tast_control ]
  195. }
  196. outputs = [ _generated_filter ]
  197. args = _skylab_args
  198. if (defined(invoker.data_deps)) {
  199. data_deps = invoker.data_deps
  200. }
  201. data = [ _generated_filter ]
  202. if (defined(invoker.data)) {
  203. data += invoker.data
  204. }
  205. if (defined(invoker.deps)) {
  206. deps = invoker.deps
  207. }
  208. }
  209. }
  210. }
  211. # Creates a script at $generated_script that can be used to launch a cros VM
  212. # and optionally run a test within it.
  213. # Args:
  214. # test_exe: Name of test binary located in the out dir. This will get copied
  215. # to the VM and executed there.
  216. # tast_attr_expr: Tast expression to pass to local_test_runner on the VM.
  217. # tast_tests: List of Tast tests to run on the VM. Note that when this is
  218. # specified, the target name used to invoke this template will be
  219. # designated as the "name" of this test and will primarly used for test
  220. # results tracking and displaying (eg: flakiness dashboard).
  221. # generated_script: Path to place the generated script.
  222. # deploy_chrome: If true, deploys a locally built chrome located in the root
  223. # build dir to the VM or DUT after launching it.
  224. # deploy_lacros: If true, deploys a locally built Lacros located in the root
  225. # build dir to the VM or DUT after launching it.
  226. # runtime_deps_file: Path to file listing runtime deps for the test. If set,
  227. # all files listed will be copied to the VM before testing.
  228. # skip_generating_board_args: By default, this template generates an '--board'
  229. # arg with corresponding '--flash' or '--use-vm' args for device and vm
  230. # respectively. This argument instructs the template to skip generating
  231. # them, and it's designed for use cases where one builds for one board
  232. # (e.g. amd64-generic), but tests on a different board (e.g. eve).
  233. # tast_vars: A list of "key=value" runtime variable pairs to pass to invoke
  234. # strip_chrome: If true, strips Chrome before deploying it for non-Tast tests.
  235. # the Tast tests. For more details, please see:
  236. # https://chromium.googlesource.com/chromiumos/platform/tast/+/HEAD/docs/writing_tests.md#Runtime-variables
  237. template("generate_runner_script") {
  238. forward_variables_from(invoker,
  239. [
  240. "deploy_chrome",
  241. "deploy_lacros",
  242. "generated_script",
  243. "runtime_deps_file",
  244. "skip_generating_board_args",
  245. "strip_chrome",
  246. "tast_attr_expr",
  247. "tast_tests",
  248. "tast_vars",
  249. "testonly",
  250. "test_exe",
  251. ])
  252. if (!defined(skip_generating_board_args)) {
  253. skip_generating_board_args = false
  254. }
  255. if (skip_generating_board_args) {
  256. # cros_board is not needed, so setting it to empty to avoid being used
  257. # accidentally below.
  258. cros_board = ""
  259. not_needed([ cros_board ])
  260. }
  261. if (!defined(deploy_chrome)) {
  262. deploy_chrome = false
  263. }
  264. if (!defined(deploy_lacros)) {
  265. deploy_lacros = false
  266. }
  267. if (!defined(strip_chrome)) {
  268. strip_chrome = false
  269. }
  270. assert(!(deploy_chrome && deploy_lacros),
  271. "deploy_chrome and deploy_lacros are exclusive.")
  272. is_tast = defined(tast_attr_expr) || defined(tast_tests)
  273. assert(!(is_tast && defined(test_exe)),
  274. "Tast tests are invoked from binaries shipped with the VM image. " +
  275. "There should be no locally built binary needed.")
  276. assert(is_tast || !defined(tast_vars),
  277. "tast_vars is only support for Tast tests")
  278. if (is_tast) {
  279. not_needed([ "strip_chrome" ])
  280. }
  281. # If we're in the cros chrome-sdk (and not the raw ebuild), the test will
  282. # need some additional runtime data located in the SDK cache.
  283. _sdk_data = []
  284. if (cros_sdk_version != "") {
  285. assert(defined(generated_script),
  286. "Must specify where to place generated test launcher script via " +
  287. "'generated_script'")
  288. foreach(b, _potential_test_boards) {
  289. _cros_is_vm = false
  290. foreach(b1, string_split(cros_boards_with_qemu_images, ":")) {
  291. if (b == b1) {
  292. _cros_is_vm = true
  293. }
  294. }
  295. # Determine the real paths for various items in the SDK, which may be used
  296. # in the 'generate_runner_script' template below.
  297. if (is_tast || _cros_is_vm || deploy_chrome) {
  298. _symlink_targets = []
  299. foreach(m, _symlink_targets_map) {
  300. if (b == m[0]) {
  301. _symlink_targets = []
  302. _symlink_targets = m[1]
  303. }
  304. }
  305. if (is_tast) {
  306. # Add tast sdk items.
  307. _sdk_data += [
  308. _symlink_targets[0],
  309. _symlink_targets[1],
  310. _symlink_targets[2],
  311. ]
  312. }
  313. if (deploy_chrome) {
  314. # To deploy chrome to the VM, it needs to be stripped down to fit into
  315. # the VM. This is done by using binutils in the toolchain. So add the
  316. # toolchain to the data.
  317. _sdk_data += [
  318. _symlink_targets[3],
  319. _symlink_targets[4],
  320. ]
  321. }
  322. if (_cros_is_vm) {
  323. # Add vm sdk items.
  324. _sdk_data += [
  325. _symlink_targets[5],
  326. _symlink_targets[6],
  327. _symlink_targets[7],
  328. ]
  329. }
  330. }
  331. }
  332. }
  333. generate_wrapper(target_name) {
  334. executable = "//build/chromeos/test_runner.py"
  335. wrapper_script = generated_script
  336. executable_args = []
  337. if (defined(runtime_deps_file)) {
  338. write_runtime_deps = runtime_deps_file
  339. }
  340. # Build executable_args for the three different test types: GTest, Tast,
  341. # and host-side commands (eg telemetry).
  342. if (defined(test_exe)) {
  343. executable_args += [
  344. "gtest",
  345. "--test-exe",
  346. test_exe,
  347. ]
  348. if (defined(runtime_deps_file)) {
  349. executable_args += [
  350. "--runtime-deps-path",
  351. rebase_path(runtime_deps_file, root_build_dir),
  352. ]
  353. }
  354. } else if (is_tast) {
  355. # When --tast-tests is specified, test_runner.py will call
  356. # local_test_runner on the VM to run the set of tests.
  357. executable_args += [
  358. "tast",
  359. "--suite-name",
  360. target_name,
  361. ]
  362. if (defined(tast_attr_expr)) {
  363. executable_args += [
  364. "--attr-expr",
  365. tast_attr_expr,
  366. ]
  367. } else {
  368. foreach(test, tast_tests) {
  369. executable_args += [
  370. "-t",
  371. test,
  372. ]
  373. }
  374. }
  375. if (defined(tast_vars)) {
  376. foreach(var, tast_vars) {
  377. executable_args += [
  378. "--tast-var",
  379. var,
  380. ]
  381. }
  382. }
  383. if (dcheck_always_on) {
  384. executable_args += [
  385. "--tast-extra-use-flags",
  386. "chrome_dcheck",
  387. ]
  388. }
  389. } else {
  390. executable_args += [ "host-cmd" ]
  391. }
  392. executable_args += [
  393. "--cros-cache",
  394. "build/cros_cache/",
  395. "--path-to-outdir",
  396. rebase_path(root_out_dir, "//"),
  397. "-v",
  398. ]
  399. if (!is_tast && strip_chrome) {
  400. executable_args += [ "--strip-chrome" ]
  401. }
  402. if (!skip_generating_board_args) {
  403. executable_args += [
  404. "--board",
  405. cros_board,
  406. ]
  407. _cros_is_vm = false
  408. foreach(b, string_split(cros_boards_with_qemu_images, ":")) {
  409. if (cros_board == b) {
  410. _cros_is_vm = true
  411. }
  412. }
  413. if (_cros_is_vm) {
  414. executable_args += [ "--use-vm" ]
  415. } else {
  416. executable_args += [ "--flash" ]
  417. }
  418. }
  419. # If we have public Chromium builds, use public Chromium OS images when
  420. # flashing the test device.
  421. if (!is_chrome_branded) {
  422. executable_args += [ "--public-image" ]
  423. }
  424. if (deploy_lacros) {
  425. executable_args += [ "--deploy-lacros" ]
  426. }
  427. if (deploy_chrome && !defined(test_exe) && !is_tast) {
  428. executable_args += [ "--deploy-chrome" ]
  429. }
  430. # executable_args should be finished, now build the data and deps lists.
  431. deps = [ "//testing/buildbot/filters:chromeos_filters" ]
  432. if (defined(invoker.deps)) {
  433. deps += invoker.deps
  434. }
  435. data = [
  436. "//.vpython3",
  437. # We use android test-runner's results libs to construct gtest output
  438. # json.
  439. "//build/android/pylib/__init__.py",
  440. "//build/android/pylib/base/",
  441. "//build/android/pylib/results/",
  442. "//build/chromeos/",
  443. "//build/util/",
  444. # Needed for various SDK components used below.
  445. "//build/cros_cache/chrome-sdk/misc/",
  446. "//build/cros_cache/chrome-sdk/symlinks/",
  447. "//chrome/VERSION",
  448. # The LKGM file controls what version of the VM image to download. Add it
  449. # as data here so that changes to it will trigger analyze.
  450. "//chromeos/CHROMEOS_LKGM",
  451. "//third_party/chromite/",
  452. ]
  453. data += _sdk_data
  454. if (defined(invoker.data)) {
  455. data += invoker.data
  456. }
  457. data_deps = [ "//testing:test_scripts_shared" ]
  458. if (defined(invoker.data_deps)) {
  459. data_deps += invoker.data_deps
  460. }
  461. }
  462. }
  463. template("tast_test") {
  464. forward_variables_from(invoker, "*")
  465. # Default the expression to match any chrome-related test.
  466. if (!defined(tast_attr_expr) && !defined(tast_tests)) {
  467. # The following expression filters out all non-critical tests. See the link
  468. # below for more details:
  469. # https://chromium.googlesource.com/chromiumos/platform/tast/+/main/docs/test_attributes.md
  470. tast_attr_expr = "\"group:mainline\" && \"dep:chrome\""
  471. if (defined(enable_tast_informational_tests) &&
  472. enable_tast_informational_tests) {
  473. tast_attr_expr += " && informational"
  474. } else {
  475. tast_attr_expr += " && !informational"
  476. }
  477. if (!is_chrome_branded) {
  478. tast_attr_expr += " && !\"dep:chrome_internal\""
  479. }
  480. } else {
  481. assert(defined(tast_attr_expr) != defined(tast_tests),
  482. "Specify one of tast_tests or tast_attr_expr.")
  483. }
  484. # Append any disabled tests to the expression.
  485. if (defined(tast_disabled_tests)) {
  486. assert(defined(tast_attr_expr),
  487. "tast_attr_expr must be used when specifying tast_disabled_tests.")
  488. foreach(test, tast_disabled_tests) {
  489. tast_attr_expr += " && !\"name:${test}\""
  490. }
  491. }
  492. if (defined(tast_attr_expr)) {
  493. tast_attr_expr = "( " + tast_attr_expr + " )"
  494. }
  495. generate_runner_script(target_name) {
  496. testonly = true
  497. generated_script = "$root_build_dir/bin/run_${target_name}"
  498. runtime_deps_file = "$root_out_dir/${target_name}.runtime_deps"
  499. deploy_chrome = true
  500. data_deps = [
  501. "//:chromiumos_preflight", # Builds the browser.
  502. "//chromeos:cros_chrome_deploy", # Adds additional browser run-time deps.
  503. # Tools used to symbolize Chrome crash dumps.
  504. # TODO(crbug.com/1156772): Remove these if/when all tests pick them up by
  505. # default.
  506. "//third_party/breakpad:dump_syms",
  507. "//third_party/breakpad:minidump_dump",
  508. "//third_party/breakpad:minidump_stackwalk",
  509. ]
  510. data = [ "//components/crash/content/tools/generate_breakpad_symbols.py" ]
  511. }
  512. }
  513. template("lacros_tast_tests") {
  514. forward_variables_from(invoker,
  515. [
  516. "tast_attr_expr",
  517. "tast_disabled_tests",
  518. "tast_tests",
  519. "tast_control",
  520. ])
  521. assert(defined(tast_attr_expr) != defined(tast_tests),
  522. "Specify one of tast_tests or tast_attr_expr.")
  523. _lacros_data_deps = [
  524. "//chrome", # Builds the browser.
  525. # Tools used to symbolize Chrome crash dumps.
  526. # TODO(crbug.com/1156772): Remove these if/when all tests pick them up by
  527. # default.
  528. "//third_party/breakpad:dump_syms",
  529. "//third_party/breakpad:minidump_dump",
  530. "//third_party/breakpad:minidump_stackwalk",
  531. ]
  532. _lacros_data = [
  533. "//components/crash/content/tools/generate_breakpad_symbols.py",
  534. # A script needed to launch Lacros in Lacros Tast tests.
  535. "//build/lacros/mojo_connection_lacros_launcher.py",
  536. ]
  537. if (is_skylab) {
  538. generate_skylab_deps(target_name) {
  539. data = _lacros_data
  540. data_deps = _lacros_data_deps
  541. # To disable a test on specific milestones, add it to the appropriate
  542. # collection in the following file
  543. tast_control = "//chromeos/tast_control.gni"
  544. }
  545. } else {
  546. # Append any disabled tests to the expression.
  547. if (defined(tast_disabled_tests)) {
  548. assert(defined(tast_attr_expr),
  549. "tast_attr_expr must be used when specifying tast_disabled_tests.")
  550. foreach(test, tast_disabled_tests) {
  551. tast_attr_expr += " && !\"name:${test}\""
  552. }
  553. }
  554. if (defined(tast_attr_expr)) {
  555. tast_attr_expr = "( " + tast_attr_expr + " )"
  556. }
  557. generate_runner_script(target_name) {
  558. testonly = true
  559. deploy_lacros = true
  560. generated_script = "$root_build_dir/bin/run_${target_name}"
  561. runtime_deps_file = "$root_out_dir/${target_name}.runtime_deps"
  562. # At build time, Lacros tests don't know whether they'll run on VM or HW,
  563. # and instead, these flags are specified at runtime when invoking the
  564. # generated runner script.
  565. skip_generating_board_args = true
  566. # By default, tast tests download a lacros-chrome from a gcs location and
  567. # use it for testing. To support running lacros tast tests from Chromium CI,
  568. # a Var is added to support pointing the tast tests to use a specified
  569. # pre-deployed lacros-chrome. The location is decided by:
  570. # https://source.chromium.org/chromium/chromium/src/+/main:third_party/chromite/scripts/deploy_chrome.py;l=80;drc=86f1234a4be8e9574442e076cdc835897f7bea61
  571. tast_vars = [ "lacros.DeployedBinary=/usr/local/lacros-chrome" ]
  572. data_deps = _lacros_data_deps
  573. data = _lacros_data
  574. }
  575. }
  576. }