test.gni 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117
  1. # Copyright 2015 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. # ==============================================================================
  5. # TEST SETUP
  6. # ==============================================================================
  7. import("//build/config/chromeos/args.gni")
  8. import("//build/config/chromeos/ui_mode.gni")
  9. import("//build/config/devtools.gni")
  10. import("//build/config/gclient_args.gni")
  11. import("//build/config/rts.gni")
  12. import("//build/rust/mixed_executable.gni")
  13. import("//build/rust/mixed_shared_library.gni")
  14. import("//build_overrides/build.gni")
  15. declare_args() {
  16. # Some component repos (e.g. ANGLE) import //testing but do not have
  17. # "location_tags.json", and so we don't want to try and upload the tags
  18. # for their tests.
  19. # And, some build configs may simply turn off generation altogether.
  20. tests_have_location_tags = generate_location_tags
  21. }
  22. # On Fuchsia, the test executable has a suffix and is a dependency of the
  23. # common |target_name| target. For `visibility`, the executable must be
  24. # specified. Cross-platform targets that include `test` targets in their
  25. # visibility lists, add `${exec_target_suffix}` immediately after the test
  26. # target name. This is not necessary when the target is a `source_set`.
  27. if (is_fuchsia) {
  28. exec_target_suffix = "__exec"
  29. } else {
  30. exec_target_suffix = ""
  31. }
  32. if (is_android) {
  33. import("//build/config/android/config.gni")
  34. import("//build/config/android/create_unwind_table.gni")
  35. import("//build/config/android/extract_unwind_tables.gni")
  36. import("//build/config/android/rules.gni")
  37. import("//build/config/sanitizers/sanitizers.gni")
  38. } else if (is_fuchsia) {
  39. import("//build/config/chromecast_build.gni")
  40. import("//build/config/fuchsia/generate_runner_scripts.gni")
  41. import("//build/config/fuchsia/package.gni")
  42. import("//third_party/fuchsia-sdk/sdk/build/cmc.gni")
  43. } else if (is_chromeos && is_chromeos_device) {
  44. import("//build/config/chromeos/rules.gni")
  45. import("//build/config/sanitizers/sanitizers.gni")
  46. import("//build/util/generate_wrapper.gni")
  47. } else if (is_ios) {
  48. import("//build/config/ios/ios_sdk.gni")
  49. import("//build/config/ios/ios_test_runner_wrapper.gni")
  50. import("//build/config/ios/rules.gni")
  51. } else {
  52. import("//build/config/sanitizers/sanitizers.gni")
  53. import("//build/util/generate_wrapper.gni")
  54. }
  55. template("mixed_test") {
  56. assert(defined(invoker.target_type) && invoker.target_type != "")
  57. target("mixed_${invoker.target_type}", target_name) {
  58. forward_variables_from(invoker,
  59. "*",
  60. TESTONLY_AND_VISIBILITY + [ "target_type" ])
  61. forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
  62. if (!defined(rs_configs)) {
  63. rs_configs = []
  64. }
  65. rs_configs += [ "//build/rust:test" ]
  66. # The crate_root is generated and should not be specified.
  67. assert(!defined(rs_crate_root))
  68. rs_generate_crate_root = true
  69. # We could automatically add `rs_deps += [ "//testing/rust_gtest_interop" ]`
  70. # if `rs_sources` is non-empty. But we don't automatically provide
  71. # //testing/gtest either so it would be asymmetric and could break in that
  72. # case. So, we act instead as if //testing/rust_gtest_interop is part of the
  73. # //testing/gtest dependency. If you add one, and have `rs_sources` listed,
  74. # you get both.
  75. _gtest_is_in_deps = false
  76. if (defined(rs_sources) && rs_sources != [] && defined(deps) &&
  77. deps != []) {
  78. foreach(dep, deps) {
  79. if (dep == "//testing/gtest") {
  80. _gtest_is_in_deps = true
  81. }
  82. }
  83. }
  84. if (_gtest_is_in_deps) {
  85. if (!defined(rs_deps)) {
  86. rs_deps = []
  87. }
  88. rs_deps += [ "//testing/rust_gtest_interop" ]
  89. }
  90. }
  91. }
  92. # Define a test as an executable (or apk on Android) with the "testonly" flag
  93. # set.
  94. # Variable:
  95. # use_xvfb: (optional) whether to run the executable under Xvfb.
  96. # use_raw_android_executable: Use mixed_executable() rather than
  97. # android_apk().
  98. # use_native_activity: Test implements ANativeActivity_onCreate().
  99. # use_cfv2: (Fuchsia, optional): build the test as a framework v2 component;
  100. # see https://fuchsia.dev/fuchsia-src/concepts/components/v2 for details.
  101. # The default value is true; set it to false explicitly to omit a .cm
  102. # manifest from the package.
  103. # use_cfv1: (Fuchsia, optional): build the test as a framework v1 component.
  104. # The default value is true; set it to false explicitly to omit a .cmx
  105. # manifest from the package.
  106. # test_runner_shard: (Fuchsia, optional): for CFv2 tests, use the given test
  107. # runner shard rather than the default shard for the ELF runner. This is
  108. # useful, for example, to use the elf_test_ambient_exec_runner for tests
  109. # that require job_policy_ambient_mark_vmo_exec.
  110. # is_xctest: (iOS, optional) whether to build the executable as XCTest.
  111. # Similar to the GN arg 'enable_run_ios_unittests_with_xctest' but
  112. # for build targets.
  113. # allow_cleartext_traffic: (Android, optional) whether to allow cleartext
  114. # network requests during the test.
  115. template("test") {
  116. # Ensures the rts file exists and if not, creates a dummy file
  117. if (use_rts) {
  118. action("${target_name}__rts_filters") {
  119. script = "//build/add_rts_filters.py"
  120. rts_file = "${root_build_dir}/gen/rts/${invoker.target_name}.filter"
  121. inverted_rts_file =
  122. "${root_build_dir}/gen/rts/${invoker.target_name}_inverted.filter"
  123. args = [
  124. rebase_path(rts_file, root_build_dir),
  125. rebase_path(inverted_rts_file, root_build_dir),
  126. ]
  127. outputs = [
  128. rts_file,
  129. inverted_rts_file,
  130. ]
  131. }
  132. }
  133. testonly = true
  134. if (!is_ios) {
  135. assert(!defined(invoker.is_xctest) || !invoker.is_xctest,
  136. "is_xctest can be set only for iOS builds")
  137. }
  138. if (!is_android) {
  139. assert(!defined(invoker.allow_cleartext_traffic),
  140. "allow_cleartext_traffic can be set only for Android tests")
  141. }
  142. if (is_android) {
  143. assert(!defined(invoker.use_xvfb) || !invoker.use_xvfb)
  144. _use_default_launcher =
  145. !defined(invoker.use_default_launcher) || invoker.use_default_launcher
  146. if (!defined(invoker.use_raw_android_executable)) {
  147. # Checkouts where build_with_chromium == false often have a custom GN
  148. # template wrapper around test() which sets use_default_launcher == false.
  149. # Set the _use_raw_android_executable default so that test() targets which
  150. # do not use the custom wrapper
  151. # (1) Do not cause "gn gen" to fail
  152. # (2) Do not need to be moved into if(build_with_chromium) block.
  153. _use_raw_android_executable =
  154. !build_with_chromium && _use_default_launcher
  155. } else {
  156. not_needed([ "_use_default_launcher" ])
  157. _use_raw_android_executable = invoker.use_raw_android_executable
  158. }
  159. # output_name is used to allow targets with the same name but in different
  160. # packages to still produce unique runner scripts.
  161. _output_name = invoker.target_name
  162. if (defined(invoker.output_name)) {
  163. _output_name = invoker.output_name
  164. }
  165. _test_runner_target = "${_output_name}__test_runner_script"
  166. _wrapper_script_vars = [
  167. "android_test_runner_script",
  168. "ignore_all_data_deps",
  169. "shard_timeout",
  170. ]
  171. assert(_use_raw_android_executable || enable_java_templates)
  172. if (_use_raw_android_executable) {
  173. not_needed(invoker, [ "add_unwind_tables_in_apk" ])
  174. _exec_target = "${target_name}__exec"
  175. _dist_target = "${target_name}__dist"
  176. _exec_output =
  177. "$target_out_dir/${invoker.target_name}/${invoker.target_name}"
  178. mixed_test(_exec_target) {
  179. target_type = "executable"
  180. # Configs will always be defined since we set_defaults in
  181. # BUILDCONFIG.gn.
  182. configs = []
  183. forward_variables_from(
  184. invoker,
  185. "*",
  186. TESTONLY_AND_VISIBILITY + _wrapper_script_vars + [
  187. "data_deps",
  188. "extra_dist_files",
  189. ])
  190. # Thanks to the set_defaults() for test(), configs are initialized with
  191. # the default shared_library configs rather than executable configs.
  192. configs -= [
  193. "//build/config:shared_library_config",
  194. "//build/config/android:hide_all_but_jni",
  195. ]
  196. configs += [ "//build/config:executable_config" ]
  197. if (defined(invoker.data_deps)) {
  198. data_deps = invoker.data_deps
  199. } else {
  200. data_deps = []
  201. }
  202. if (!defined(data)) {
  203. data = []
  204. }
  205. if (tests_have_location_tags) {
  206. data += [ "//testing/location_tags.json" ]
  207. }
  208. # Don't output to the root or else conflict with the group() below.
  209. output_name = rebase_path(_exec_output, root_out_dir)
  210. if (use_rts) {
  211. data_deps += [ ":${invoker.target_name}__rts_filters" ]
  212. }
  213. }
  214. create_native_executable_dist(_dist_target) {
  215. dist_dir = "$root_out_dir/$target_name"
  216. binary = _exec_output
  217. deps = [ ":$_exec_target" ]
  218. if (defined(invoker.extra_dist_files)) {
  219. extra_files = invoker.extra_dist_files
  220. }
  221. if (use_rts) {
  222. if (!defined(data_deps)) {
  223. data_deps = []
  224. }
  225. data_deps += [ ":${invoker.target_name}__rts_filters" ]
  226. }
  227. }
  228. } else {
  229. _library_target = "${target_name}__library"
  230. _library_crate_name = "${target_name}_library"
  231. _apk_target = "${target_name}__apk"
  232. _apk_specific_vars = [
  233. "allow_cleartext_traffic",
  234. "android_manifest",
  235. "android_manifest_dep",
  236. "android_manifest_template",
  237. "app_as_shared_lib",
  238. "enable_multidex",
  239. "generate_final_jni",
  240. "product_config_java_packages",
  241. "loadable_modules",
  242. "loadable_module_deps",
  243. "min_sdk_version",
  244. "proguard_configs",
  245. "proguard_enabled",
  246. "srcjar_deps",
  247. "target_sdk_version",
  248. "use_default_launcher",
  249. "use_native_activity",
  250. ]
  251. # Adds the unwind tables from unstripped binary as an asset file in the
  252. # apk, if |add_unwind_tables_in_apk| is specified by the test.
  253. if (defined(invoker.add_unwind_tables_in_apk) &&
  254. invoker.add_unwind_tables_in_apk) {
  255. if (use_android_unwinder_v2) {
  256. _unwind_table_asset_v2_name = "${target_name}_v2_unwind_assets"
  257. unwind_table_asset_v2(_unwind_table_asset_v2_name) {
  258. library_target = _library_target
  259. deps = [ ":$_library_target" ]
  260. }
  261. }
  262. # TODO(crbug.com/1315603): Remove generation of v1 unwind asset when
  263. # `CFIBacktraceAndroid` is replaced with `ChromeUnwinderAndroidV2`.
  264. _unwind_table_asset_name = "${target_name}_unwind_assets"
  265. unwind_table_asset(_unwind_table_asset_name) {
  266. library_target = _library_target
  267. deps = [ ":$_library_target" ]
  268. }
  269. }
  270. mixed_test(_library_target) {
  271. target_type = "shared_library"
  272. # Configs will always be defined since we set_defaults in
  273. # BUILDCONFIG.gn.
  274. configs = [] # Prevent list overwriting warning.
  275. configs = invoker.configs
  276. # Use a crate name that avoids creating a warning due to double
  277. # underscore (ie. `__`).
  278. rs_crate_name = _library_crate_name
  279. forward_variables_from(
  280. invoker,
  281. "*",
  282. [ "deps" ] + _apk_specific_vars + _wrapper_script_vars +
  283. TESTONLY_AND_VISIBILITY)
  284. # Native targets do not need to depend on java targets. Filter them out
  285. # so that the shared library can be built without needing to wait for
  286. # dependent java targets.
  287. deps = []
  288. if (defined(invoker.deps)) {
  289. foreach(_dep, invoker.deps) {
  290. _target_label = get_label_info(_dep, "label_no_toolchain")
  291. if (filter_exclude([ _target_label ], java_target_patterns) != []) {
  292. deps += [ _dep ]
  293. }
  294. }
  295. }
  296. if (_use_default_launcher) {
  297. deps += [ "//testing/android/native_test:native_test_native_code" ]
  298. }
  299. }
  300. unittest_apk(_apk_target) {
  301. forward_variables_from(invoker, _apk_specific_vars)
  302. shared_library = ":$_library_target"
  303. apk_name = invoker.target_name
  304. if (defined(invoker.output_name)) {
  305. apk_name = invoker.output_name
  306. install_script_name = "install_${invoker.output_name}"
  307. }
  308. if (defined(invoker.deps)) {
  309. deps = invoker.deps
  310. } else {
  311. deps = []
  312. }
  313. if (defined(loadable_module_deps)) {
  314. deps += loadable_module_deps
  315. }
  316. # Add the Java classes so that each target does not have to do it.
  317. if (_use_default_launcher) {
  318. deps += [ "//base/test:test_support_java" ]
  319. }
  320. if (defined(_unwind_table_asset_name)) {
  321. deps += [ ":${_unwind_table_asset_name}" ]
  322. }
  323. if (defined(_unwind_table_asset_v2_name)) {
  324. deps += [ ":${_unwind_table_asset_v2_name}" ]
  325. }
  326. if (use_rts) {
  327. data_deps = [ ":${invoker.target_name}__rts_filters" ]
  328. }
  329. }
  330. }
  331. test_runner_script(_test_runner_target) {
  332. forward_variables_from(invoker, _wrapper_script_vars)
  333. if (_use_raw_android_executable) {
  334. executable_dist_dir = "$root_out_dir/$_dist_target"
  335. data_deps = [ ":$_exec_target" ]
  336. } else {
  337. apk_target = ":$_apk_target"
  338. incremental_apk = incremental_install
  339. # Dep needed for the test runner .runtime_deps file to pick up data
  340. # deps from the forward_variables_from(invoker, "*") on the library.
  341. data_deps = [ ":$_library_target" ]
  342. }
  343. test_name = _output_name
  344. test_suite = _output_name
  345. test_type = "gtest"
  346. if (use_rts) {
  347. data_deps += [ ":${invoker.target_name}__rts_filters" ]
  348. }
  349. }
  350. # Create a wrapper script rather than using a group() in order to ensure
  351. # "ninja $target_name" always works. If this was a group(), then GN would
  352. # not create a top-level alias for it if a target exists in another
  353. # directory with the same $target_name.
  354. # Also - bots run this script directly for "components_perftests".
  355. generate_wrapper(target_name) {
  356. forward_variables_from(invoker, [ "visibility" ])
  357. executable = "$root_build_dir/bin/run_$_output_name"
  358. wrapper_script = "$root_build_dir/$_output_name"
  359. deps = [ ":$_test_runner_target" ]
  360. if (_use_raw_android_executable) {
  361. deps += [ ":$_dist_target" ]
  362. } else {
  363. # Dep needed for the swarming .isolate file to pick up data
  364. # deps from the forward_variables_from(invoker, "*") on the library.
  365. deps += [
  366. ":$_apk_target",
  367. ":$_library_target",
  368. ]
  369. }
  370. if (defined(invoker.data_deps)) {
  371. data_deps = invoker.data_deps
  372. } else {
  373. data_deps = []
  374. }
  375. data_deps += [ "//testing:test_scripts_shared" ]
  376. if (tests_have_location_tags) {
  377. data = [ "//testing/location_tags.json" ]
  378. }
  379. if (use_rts) {
  380. data_deps += [ ":${invoker.target_name}__rts_filters" ]
  381. }
  382. }
  383. } else if (is_fuchsia) {
  384. assert(!defined(invoker.use_xvfb) || !invoker.use_xvfb)
  385. # It's meaningless to omit both types of manifest from the package.
  386. assert(!defined(invoker.use_cfv2) || invoker.use_cfv2 ||
  387. !defined(invoker.use_cfv1) || invoker.use_cfv1)
  388. _output_name = invoker.target_name
  389. _pkg_target = "${_output_name}_pkg"
  390. _exec_target = "${_output_name}__exec"
  391. _program_name = get_label_info(":${_exec_target}", "name")
  392. _test_component_targets = []
  393. # Generate a CFv2 manifest unless the target opts-out via `use_cfv2=false`.
  394. if (!defined(invoker.use_cfv2) || invoker.use_cfv2) {
  395. # Generate a CML fragment that provides the program name.
  396. _test_program_fragment_target = "${target_name}_program-fragment"
  397. _test_program_fragment =
  398. "${target_out_dir}/${target_name}_program.test-cml"
  399. generated_file(_test_program_fragment_target) {
  400. contents = {
  401. program = {
  402. binary = _program_name
  403. }
  404. }
  405. outputs = [ _test_program_fragment ]
  406. output_conversion = "json"
  407. }
  408. _test_runner_shard =
  409. "//build/config/fuchsia/test/elf_test_runner.shard.test-cml"
  410. if (defined(invoker.test_runner_shard)) {
  411. _test_runner_shard = invoker.test_runner_shard
  412. }
  413. # Collate the complete set of elements to include in the test component's
  414. # manifest.
  415. _manifest_fragments = [
  416. "//build/config/fuchsia/test/chromium_test_facet.shard.test-cml",
  417. "//build/config/fuchsia/test/minimum.shard.test-cml",
  418. _test_program_fragment,
  419. _test_runner_shard,
  420. ]
  421. _test_component_manifest = "${target_out_dir}/${target_name}.cml"
  422. _merged_manifest_name = "${_output_name}.cml"
  423. if (defined(invoker.additional_manifest_fragments)) {
  424. _manifest_fragments +=
  425. filter_include(invoker.additional_manifest_fragments,
  426. [
  427. "*.cml",
  428. "*.test-cml",
  429. ])
  430. }
  431. # Generate the test component manifest from the specified elements.
  432. _test_component_manifest_target = "${target_name}_component-manifest"
  433. cmc_merge(_test_component_manifest_target) {
  434. sources = _manifest_fragments
  435. output_name = "${_merged_manifest_name}"
  436. deps = [ ":${_test_program_fragment_target}" ]
  437. }
  438. # Define the test component, dependent on the generated manifest, and the
  439. # test executable target.
  440. _test_component_target = "${target_name}_component"
  441. fuchsia_component(_test_component_target) {
  442. deps = [ ":$_test_component_manifest_target" ]
  443. data_deps = [ ":$_exec_target" ]
  444. manifest = _test_component_manifest
  445. visibility = [ ":*" ]
  446. }
  447. _test_component_targets += [ ":${_test_component_target}" ]
  448. }
  449. # Generate a CFv1 manifest unless the target opts-out via `use_cfv1=false`.
  450. if (!defined(invoker.use_cfv1) || invoker.use_cfv1) {
  451. # Generate a CMX fragment that provides the program name.
  452. _test_program_fragment_target_v1 = "${target_name}_program-fragment_v1"
  453. _test_program_fragment_v1 =
  454. "${target_out_dir}/${target_name}_program.test-cmx"
  455. generated_file(_test_program_fragment_target_v1) {
  456. contents = "{ \"program\": { \"binary\": \"${_program_name}\"}}"
  457. outputs = [ _test_program_fragment_v1 ]
  458. }
  459. # Collate the complete set of elements to include in the test component's
  460. # manifest.
  461. _manifest_fragments_v1 = [
  462. "//build/config/fuchsia/test/minimum_capabilities.test-cmx",
  463. _test_program_fragment_v1,
  464. ]
  465. _test_component_manifest_v1 = "${target_out_dir}/${target_name}.cmx"
  466. _merged_manifest_name_v1 = "${_output_name}.cmx"
  467. if (defined(invoker.additional_manifest_fragments)) {
  468. _manifest_fragments_v1 +=
  469. filter_include(invoker.additional_manifest_fragments,
  470. [
  471. "*.cmx",
  472. "*.test-cmx",
  473. ])
  474. }
  475. # Generate the test component manifest from the specified elements.
  476. _test_component_manifest_target_v1 =
  477. "${target_name}_component-manifest_v1"
  478. cmc_merge(_test_component_manifest_target_v1) {
  479. sources = _manifest_fragments_v1
  480. output_name = "${_merged_manifest_name_v1}"
  481. deps = [ ":${_test_program_fragment_target_v1}" ]
  482. }
  483. # Define the test component, dependent on the generated manifest, and the
  484. # test executable target.
  485. _test_component_target_v1 = "${target_name}_component_v1"
  486. fuchsia_component(_test_component_target_v1) {
  487. deps = [ ":$_test_component_manifest_target_v1" ]
  488. data_deps = [ ":$_exec_target" ]
  489. manifest = _test_component_manifest_v1
  490. visibility = [ ":*" ]
  491. }
  492. _test_component_targets += [ ":${_test_component_target_v1}" ]
  493. }
  494. # Define components for each entry in |additional_manifests|, if any. Since
  495. # manifests may themselves depend-on the outputs of |deps|, these components
  496. # must each individually depend on |invoker.deps|.
  497. if (defined(invoker.additional_manifests)) {
  498. foreach(filename, invoker.additional_manifests) {
  499. _additional_component_target =
  500. target_name + "_" + get_path_info(filename, "name")
  501. _test_component_targets += [ ":${_additional_component_target}" ]
  502. fuchsia_component(_additional_component_target) {
  503. forward_variables_from(invoker, [ "testonly" ])
  504. data_deps = [ ":$_exec_target" ]
  505. visibility = [ ":*" ]
  506. manifest = filename
  507. # Depend on |invoker.deps|, in case it includes a dependency that
  508. # creates this additional component's manifest.
  509. if (defined(invoker.deps)) {
  510. deps = invoker.deps
  511. }
  512. }
  513. }
  514. }
  515. # Define the package target that will bundle the test and additional
  516. # components and their data.
  517. fuchsia_package(_pkg_target) {
  518. forward_variables_from(invoker,
  519. [
  520. "excluded_files",
  521. "excluded_dirs",
  522. ])
  523. package_name = _output_name
  524. deps = _test_component_targets
  525. if (!defined(excluded_dirs)) {
  526. excluded_dirs = []
  527. }
  528. if (devtools_root_location != "") {
  529. excluded_dirs += [ devtools_root_location ]
  530. }
  531. }
  532. # |target_name| refers to the package-runner rule, so that building
  533. # "base_unittests" will build not only the executable, component, and
  534. # package, but also the script required to run them.
  535. fuchsia_test_runner(target_name) {
  536. forward_variables_from(invoker,
  537. [
  538. "data",
  539. "data_deps",
  540. "package_deps",
  541. "use_cfv2",
  542. "use_test_server",
  543. ])
  544. is_test_exe = true
  545. package = ":$_pkg_target"
  546. package_name = _output_name
  547. if (!defined(deps)) {
  548. deps = []
  549. }
  550. if (defined(invoker.deps)) {
  551. deps += invoker.deps
  552. }
  553. if (!defined(data)) {
  554. data = []
  555. }
  556. if (tests_have_location_tags) {
  557. data += [ "//testing/location_tags.json" ]
  558. }
  559. if (!defined(data_deps)) {
  560. data_deps = []
  561. }
  562. data_deps += [ "//testing:test_scripts_shared" ]
  563. if (use_rts) {
  564. data_deps += [ ":${target_name}__rts_filters" ]
  565. }
  566. }
  567. mixed_test(_exec_target) {
  568. target_type = "executable"
  569. forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY)
  570. output_name = _exec_target
  571. }
  572. } else if (is_ios) {
  573. assert(!defined(invoker.use_xvfb) || !invoker.use_xvfb)
  574. _runtime_deps_file = "$root_out_dir/${target_name}.runtime_deps"
  575. declare_args() {
  576. # Keep the unittest-as-xctest functionality defaulted to off until the
  577. # bots are updated to handle it properly.
  578. # TODO(crbug.com/1001667): Remove this arg once the iOS test runner
  579. # supports running unittests with xctest.
  580. enable_run_ios_unittests_with_xctest = false
  581. }
  582. _test_target = target_name
  583. _output_name = target_name
  584. if (defined(invoker.output_name)) {
  585. _output_name = invoker.output_name
  586. }
  587. _wrapper_output_name = "run_${target_name}"
  588. ios_test_runner_wrapper(_wrapper_output_name) {
  589. forward_variables_from(invoker,
  590. [
  591. "data",
  592. "deps",
  593. "executable_args",
  594. "output_name",
  595. "retries",
  596. "shards",
  597. ])
  598. _root_build_dir = rebase_path("${root_build_dir}", root_build_dir)
  599. if (!defined(executable_args)) {
  600. executable_args = []
  601. }
  602. executable_args += [
  603. "--app",
  604. "@WrappedPath(${_root_build_dir}/${_test_target}.app)",
  605. ]
  606. wrapper_output_name = "${_wrapper_output_name}"
  607. if (!defined(data)) {
  608. data = []
  609. }
  610. if (tests_have_location_tags) {
  611. data += [ "//testing/location_tags.json" ]
  612. }
  613. }
  614. _resources_bundle_data = target_name + "_resources_bundle_data"
  615. bundle_data(_resources_bundle_data) {
  616. visibility = [ ":$_test_target" ]
  617. sources = [ "//testing/gtest_ios/Default.png" ]
  618. outputs = [ "{{bundle_resources_dir}}/{{source_file_part}}" ]
  619. }
  620. force_xctest = enable_run_ios_unittests_with_xctest ||
  621. (defined(invoker.is_xctest) && invoker.is_xctest)
  622. if (force_xctest) {
  623. ios_test_target_type = "ios_xctest_test"
  624. } else {
  625. ios_test_target_type = "ios_app_bundle"
  626. }
  627. target(ios_test_target_type, _test_target) {
  628. testonly = true
  629. if (force_xctest && build_with_chromium) {
  630. xctest_module_target = "//base/test:google_test_runner"
  631. }
  632. forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY)
  633. # Provide sensible defaults in case invoker did not define any of those
  634. # required variables.
  635. if (!defined(info_plist) && !defined(info_plist_target)) {
  636. info_plist = "//testing/gtest_ios/unittest-Info.plist"
  637. }
  638. if (ios_use_shared_bundle_id_for_test_apps) {
  639. bundle_identifier = shared_bundle_id_for_test_apps
  640. not_needed([ "_output_name" ])
  641. } else {
  642. bundle_identifier = "$ios_app_bundle_id_prefix.chrome." +
  643. string_replace(_output_name, "_", "-")
  644. }
  645. if (!defined(bundle_deps)) {
  646. bundle_deps = []
  647. }
  648. bundle_deps += [ ":$_resources_bundle_data" ]
  649. if (!defined(data_deps)) {
  650. data_deps = []
  651. }
  652. data_deps += [ "//testing:test_scripts_shared" ]
  653. # Include the generate_wrapper as part of data_deps
  654. data_deps += [ ":${_wrapper_output_name}" ]
  655. write_runtime_deps = _runtime_deps_file
  656. if (use_rts) {
  657. data_deps += [ ":${invoker.target_name}__rts_filters" ]
  658. }
  659. }
  660. } else if ((is_chromeos_ash || (is_chromeos_lacros && is_chromeos_device)) &&
  661. cros_board != "") {
  662. assert(!defined(invoker.use_xvfb) || !invoker.use_xvfb)
  663. # Building for a cros board (ie: not linux-chromeos or linux-lacros).
  664. _gen_runner_target = "${target_name}__runner"
  665. _runtime_deps_file =
  666. "$root_out_dir/gen.runtime/" + get_label_info(target_name, "dir") +
  667. "/" + get_label_info(target_name, "name") + ".runtime_deps"
  668. _generated_script = "$root_build_dir/bin/run_" + invoker.target_name
  669. if (is_skylab) {
  670. generate_skylab_deps(_gen_runner_target) {
  671. generated_script = _generated_script
  672. test_exe = invoker.target_name
  673. }
  674. } else {
  675. generate_runner_script(_gen_runner_target) {
  676. generated_script = _generated_script
  677. test_exe = invoker.target_name
  678. runtime_deps_file = _runtime_deps_file
  679. if (is_chromeos_lacros) {
  680. # At build time, Lacros tests don't know whether they'll run on VM or
  681. # HW, and instead, these flags are specified at runtime when invoking
  682. # the generated runner script.
  683. skip_generating_board_args = true
  684. }
  685. if (tests_have_location_tags) {
  686. data = [ "//testing/location_tags.json" ]
  687. }
  688. if (use_rts) {
  689. data_deps = [ ":${invoker.target_name}__rts_filters" ]
  690. }
  691. }
  692. }
  693. mixed_test(target_name) {
  694. target_type = "executable"
  695. forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY)
  696. forward_variables_from(invoker, [ "visibility" ])
  697. if (!defined(deps)) {
  698. deps = []
  699. }
  700. if (!defined(data)) {
  701. data = []
  702. }
  703. # We use a special trigger script for CrOS hardware tests.
  704. data += [ "//testing/trigger_scripts/chromeos_device_trigger.py" ]
  705. output_name = target_name
  706. write_runtime_deps = _runtime_deps_file
  707. data += [ _runtime_deps_file ]
  708. deps += [ ":$_gen_runner_target" ]
  709. if (!defined(data_deps)) {
  710. data_deps = []
  711. }
  712. data_deps += [ "//testing:test_scripts_shared" ]
  713. if (use_rts) {
  714. data_deps += [ ":${invoker.target_name}__rts_filters" ]
  715. }
  716. }
  717. } else if (is_chromeos_lacros && !is_chromeos_device) {
  718. _runtime_deps_file = "$root_out_dir/${target_name}.runtime_deps"
  719. _executable = target_name
  720. _gen_runner_target = "${target_name}__runner"
  721. if (defined(invoker.use_xvfb)) {
  722. _use_xvfb = invoker.use_xvfb
  723. } else {
  724. _use_xvfb = false
  725. }
  726. # When use_xvfb is set by the invoker, it indicates that running this test
  727. # target requires a window, and in lacros build, ash-chrome serves as the
  728. # display server. Note that even though the tests themselves do not require
  729. # xvfb anymore, xvfb.py is still needed to invoke the lacros test runner
  730. # because ash-chrome is based on x11.
  731. _use_ash_chrome = _use_xvfb
  732. generate_wrapper(_gen_runner_target) {
  733. wrapper_script = "$root_build_dir/bin/run_" + _executable
  734. data = []
  735. data_deps = [ "//testing:test_scripts_shared" ]
  736. if (_use_xvfb) {
  737. executable = "//testing/xvfb.py"
  738. data += [ "//.vpython3" ]
  739. } else {
  740. executable = "//testing/test_env.py"
  741. }
  742. if (tests_have_location_tags) {
  743. data += [ "//testing/location_tags.json" ]
  744. }
  745. executable_args = [
  746. "@WrappedPath(../../build/lacros/test_runner.py)",
  747. "test",
  748. "@WrappedPath(./${_executable})",
  749. "--test-launcher-bot-mode",
  750. ]
  751. if (_use_ash_chrome) {
  752. executable_args += [ "--ash-chrome-path" ]
  753. # Can't use --ash-chrome-path=path because WrappedPath
  754. # won't be expanded for that usage.
  755. executable_args += [ "@WrappedPath(./ash_clang_x64/test_ash_chrome)" ]
  756. }
  757. if (is_asan) {
  758. executable_args += [ "--asan=true" ]
  759. }
  760. if (is_msan) {
  761. executable_args += [ "--msan=true" ]
  762. }
  763. if (is_tsan) {
  764. executable_args += [ "--tsan=true" ]
  765. }
  766. if (use_cfi_diag) {
  767. executable_args += [ "--cfi-diag=true" ]
  768. }
  769. data += [ "//build/lacros/test_runner.py" ]
  770. if (use_rts) {
  771. data_deps += [ ":${invoker.target_name}__rts_filters" ]
  772. }
  773. }
  774. mixed_test(target_name) {
  775. target_type = "executable"
  776. forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY)
  777. forward_variables_from(invoker, [ "visibility" ])
  778. if (!defined(deps)) {
  779. deps = []
  780. }
  781. if (!defined(data_deps)) {
  782. data_deps = []
  783. }
  784. data_deps += [ "//testing:test_scripts_shared" ]
  785. write_runtime_deps = _runtime_deps_file
  786. deps += [ ":$_gen_runner_target" ]
  787. if (_use_ash_chrome && also_build_ash_chrome) {
  788. data_deps += [ "//chrome/test:test_ash_chrome(//build/toolchain/linux:ash_clang_x64)" ]
  789. }
  790. if (use_rts) {
  791. data_deps += [ ":${invoker.target_name}__rts_filters" ]
  792. }
  793. }
  794. } else if (!is_nacl) {
  795. if (is_mac || is_win) {
  796. assert(!defined(invoker.use_xvfb) || !invoker.use_xvfb)
  797. }
  798. _runtime_deps_file = "$root_out_dir/${target_name}.runtime_deps"
  799. _executable = target_name
  800. _gen_runner_target = "${target_name}__runner"
  801. if ((is_linux || is_chromeos) && defined(invoker.use_xvfb)) {
  802. _use_xvfb = invoker.use_xvfb
  803. } else {
  804. _use_xvfb = false
  805. }
  806. generate_wrapper(_gen_runner_target) {
  807. wrapper_script = "$root_build_dir/bin/run_" + _executable
  808. data = []
  809. data_deps = [ "//testing:test_scripts_shared" ]
  810. if (_use_xvfb) {
  811. executable = "//testing/xvfb.py"
  812. } else {
  813. executable = "//testing/test_env.py"
  814. }
  815. if (tests_have_location_tags) {
  816. data += [ "//testing/location_tags.json" ]
  817. }
  818. executable_args = [
  819. "@WrappedPath(./${_executable})",
  820. "--test-launcher-bot-mode",
  821. ]
  822. if (is_asan) {
  823. executable_args += [ "--asan=true" ]
  824. }
  825. if (is_msan) {
  826. executable_args += [ "--msan=true" ]
  827. }
  828. if (is_tsan) {
  829. executable_args += [ "--tsan=true" ]
  830. }
  831. if (use_cfi_diag) {
  832. executable_args += [ "--cfi-diag=true" ]
  833. }
  834. if (use_rts) {
  835. data_deps += [ ":${invoker.target_name}__rts_filters" ]
  836. }
  837. }
  838. mixed_test(target_name) {
  839. target_type = "executable"
  840. forward_variables_from(invoker,
  841. "*",
  842. TESTONLY_AND_VISIBILITY + [ "use_xvfb" ])
  843. forward_variables_from(invoker, [ "visibility" ])
  844. if (!defined(deps)) {
  845. deps = []
  846. }
  847. deps += [
  848. # Give tests the default manifest on Windows (a no-op elsewhere).
  849. "//build/win:default_exe_manifest",
  850. ]
  851. write_runtime_deps = _runtime_deps_file
  852. deps += [ ":$_gen_runner_target" ]
  853. if (!defined(data_deps)) {
  854. data_deps = []
  855. }
  856. data_deps += [ "//testing:test_scripts_shared" ]
  857. if (use_rts) {
  858. data_deps += [ ":${invoker.target_name}__rts_filters" ]
  859. }
  860. }
  861. } else {
  862. # This is a catch-all clause for NaCl toolchains and other random
  863. # configurations that might define tests; test() in these configs
  864. # will just define the underlying executables.
  865. assert(!defined(invoker.use_xvfb) || !invoker.use_xvfb,
  866. "use_xvfb should not be defined for a non-linux configuration")
  867. mixed_test(target_name) {
  868. target_type = "executable"
  869. forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY)
  870. forward_variables_from(invoker, [ "visibility" ])
  871. if (!defined(deps)) {
  872. deps = []
  873. }
  874. if (!defined(data_deps)) {
  875. data_deps = []
  876. }
  877. data_deps += [ "//testing:test_scripts_shared" ]
  878. if (use_rts) {
  879. data_deps += [ ":${invoker.target_name}__rts_filters" ]
  880. }
  881. }
  882. }
  883. }
  884. # Defines a type of test that invokes a script to run, rather than
  885. # invoking an executable.
  886. #
  887. # The script must implement the
  888. # [test executable API](//docs/testing/test_executable_api.md).
  889. #
  890. # The template must be passed the `script` parameter, which specifies
  891. # the path to the script to run. It may optionally be passed a
  892. # `script_args` parameter, which can be used to include a list of
  893. # args to be specified by default. The template will produce
  894. # a `$root_build_dir/run_$target_name` wrapper and write the runtime_deps
  895. # for the target to $root_build_dir/${target_name}.runtime_deps, as per
  896. # the conventions listed in the
  897. # [test wrapper API](//docs/testing/test_wrapper_api.md).
  898. template("script_test") {
  899. if (use_rts) {
  900. action("${target_name}__rts_filters") {
  901. script = "//build/add_rts_filters.py"
  902. rts_file = "${root_build_dir}/gen/rts/${invoker.target_name}.filter"
  903. inverted_rts_file =
  904. "${root_build_dir}/gen/rts/${invoker.target_name}_inverted.filter"
  905. args = [
  906. rebase_path(rts_file, root_build_dir),
  907. rebase_path(inverted_rts_file, root_build_dir),
  908. ]
  909. outputs = [
  910. rts_file,
  911. inverted_rts_file,
  912. ]
  913. }
  914. }
  915. generate_wrapper(target_name) {
  916. testonly = true
  917. wrapper_script = "${root_build_dir}/bin/run_${target_name}"
  918. executable = "//testing/test_env.py"
  919. executable_args =
  920. [ "@WrappedPath(" + rebase_path(invoker.script, root_build_dir) + ")" ]
  921. if (defined(invoker.args)) {
  922. executable_args += invoker.args
  923. }
  924. data = [ invoker.script ]
  925. if (defined(invoker.data)) {
  926. data += invoker.data
  927. }
  928. if (tests_have_location_tags) {
  929. data += [ "//testing/location_tags.json" ]
  930. }
  931. data_deps = [ "//testing:test_scripts_shared" ]
  932. if (defined(invoker.data_deps)) {
  933. data_deps += invoker.data_deps
  934. }
  935. forward_variables_from(invoker,
  936. [ "*" ],
  937. TESTONLY_AND_VISIBILITY + [
  938. "data",
  939. "data_deps",
  940. "script",
  941. "script_args",
  942. ])
  943. forward_variables_from(invoker, [ "visibility" ])
  944. write_runtime_deps = "${root_build_dir}/${target_name}.runtime_deps"
  945. if (use_rts) {
  946. data_deps += [ ":${invoker.target_name}__rts_filters" ]
  947. }
  948. }
  949. }
  950. # Test defaults.
  951. set_defaults("test") {
  952. if (is_android) {
  953. configs = default_shared_library_configs
  954. configs -= [ "//build/config/android:hide_all_but_jni_onload" ]
  955. configs += [ "//build/config/android:hide_all_but_jni" ]
  956. } else {
  957. configs = default_executable_configs
  958. if (is_mac) {
  959. # TODO(lgrey): Maybe restore this.
  960. # Don't strip tests for visibility into test crashes/hangs.
  961. # https://bugs.chromium.org/p/chromium/issues/detail?id=1244047#c49
  962. configs -= [ "//build/config/mac:strip_all" ]
  963. }
  964. }
  965. }