blob: 5b6b603310998139b3c6b731c58fc817c516e859 [file] [log] [blame]
aizatskycb1a43932015-12-14 20:59:141# 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
aizatsky7dfb57342015-12-21 04:02:525# Defines fuzzer_test.
6#
aizatsky43d459a52016-02-13 01:22:187import("//build/config/features.gni")
8import("//build/config/sanitizers/sanitizers.gni")
aizatskycb1a43932015-12-14 20:59:149import("//testing/test.gni")
10
11# fuzzer_test is used to define individual libfuzzer tests.
12#
13# Supported attributes:
14# - (required) sources - fuzzer test source files
aizatskycb1a43932015-12-14 20:59:1415# - deps - test dependencies
16# - additional_configs - additional configs to be used for compilation
17# - dict - a dictionary file for the fuzzer.
mmoroz344a75ae2016-03-02 16:57:1718# - libfuzzer_options - options for the fuzzer (e.g. -max_len or -timeout).
aizatsky198e3022016-03-08 21:33:4619# - seed_corpus - a directory with seed corpus.
aizatskycb1a43932015-12-14 20:59:1420#
aizatsky43d459a52016-02-13 01:22:1821# If use_libfuzzer gn flag is defined, then proper fuzzer would be build.
metzman8c9ed0e2016-06-21 20:37:2022# Without use_libfuzzer or use_afl a unit-test style binary would be built on
23# linux and the whole target is a no-op otherwise.
aizatsky43d459a52016-02-13 01:22:1824#
aizatskycb1a43932015-12-14 20:59:1425# The template wraps test() target with appropriate dependencies.
mmoroz344a75ae2016-03-02 16:57:1726# If any test run-time options are present (dict or libfuzzer_options), then a
27# config (.options file) file would be generated or modified in root output
aizatskycb1a43932015-12-14 20:59:1428# dir (next to test).
29template("fuzzer_test") {
Jonathan Metzmand901d1b2017-10-09 23:07:2830 if (!disable_libfuzzer && (use_fuzzing_engine || use_drfuzz || is_linux)) {
aizatsky43d459a52016-02-13 01:22:1831 assert(defined(invoker.sources), "Need sources in $target_name.")
aizatskycb1a43932015-12-14 20:59:1432
aizatsky43d459a52016-02-13 01:22:1833 test_deps = [ "//testing/libfuzzer:libfuzzer_main" ]
aizatskycb1a43932015-12-14 20:59:1434
aizatsky43d459a52016-02-13 01:22:1835 if (defined(invoker.deps)) {
36 test_deps += invoker.deps
37 }
aizatskycb1a43932015-12-14 20:59:1438
mmoroz902ef432017-02-07 17:03:3739 if (defined(invoker.seed_corpus) || defined(invoker.seed_corpuses)) {
40 assert(!(defined(invoker.seed_corpus) && defined(invoker.seed_corpuses)),
41 "Do not use both seed_corpus and seed_corpuses for $target_name.")
42
aizatsky198e3022016-03-08 21:33:4643 out = "$root_build_dir/$target_name" + "_seed_corpus.zip"
44
45 action(target_name + "_seed_corpus") {
46 script = "//testing/libfuzzer/archive_corpus.py"
mmoroz902ef432017-02-07 17:03:3747
aizatsky198e3022016-03-08 21:33:4648 args = [
aizatsky198e3022016-03-08 21:33:4649 "--output",
wychen5e1f7252017-05-30 08:05:1050 rebase_path(out, root_build_dir),
aizatsky198e3022016-03-08 21:33:4651 ]
52
mmoroz902ef432017-02-07 17:03:3753 if (defined(invoker.seed_corpus)) {
wychen5e1f7252017-05-30 08:05:1054 args += [ rebase_path(invoker.seed_corpus, root_build_dir) ]
mmoroz902ef432017-02-07 17:03:3755 }
56
57 if (defined(invoker.seed_corpuses)) {
58 foreach(seed_corpus_path, invoker.seed_corpuses) {
wychen5e1f7252017-05-30 08:05:1059 args += [ rebase_path(seed_corpus_path, root_build_dir) ]
mmoroz902ef432017-02-07 17:03:3760 }
61 }
62
aizatsky198e3022016-03-08 21:33:4663 outputs = [
64 out,
65 ]
mmoroz902ef432017-02-07 17:03:3766
aizatsky7951d34f2016-03-11 00:09:4567 deps = [
68 "//testing/libfuzzer:seed_corpus",
69 ]
aizatsky198e3022016-03-08 21:33:4670 }
71
72 test_deps += [ ":" + target_name + "_seed_corpus" ]
73 }
74
mmoroz062a4a62016-04-12 09:02:3375 if (defined(invoker.dict) || defined(invoker.libfuzzer_options)) {
76 if (defined(invoker.dict)) {
77 # Copy dictionary to output.
78 copy(target_name + "_dict_copy") {
79 sources = [
80 invoker.dict,
81 ]
82 outputs = [
83 "$root_build_dir/" + target_name + ".dict",
84 ]
85 }
86 test_deps += [ ":" + target_name + "_dict_copy" ]
aizatsky43d459a52016-02-13 01:22:1887 }
88
mmoroz062a4a62016-04-12 09:02:3389 # Generate .options file.
mmoroz344a75ae2016-03-02 16:57:1790 config_name = target_name + ".options"
91 action(config_name) {
92 script = "//testing/libfuzzer/gen_fuzzer_config.py"
93 args = [
94 "--config",
wychen5e1f7252017-05-30 08:05:1095 rebase_path("$root_build_dir/" + config_name, root_build_dir),
mmoroz344a75ae2016-03-02 16:57:1796 ]
97
mmoroz062a4a62016-04-12 09:02:3398 if (defined(invoker.dict)) {
mmoroz344a75ae2016-03-02 16:57:1799 args += [
mmoroz062a4a62016-04-12 09:02:33100 "--dict",
wychen5e1f7252017-05-30 08:05:10101 rebase_path("$root_build_dir/" + invoker.target_name + ".dict",
102 root_build_dir),
mmoroz344a75ae2016-03-02 16:57:17103 ]
104 }
mmoroz062a4a62016-04-12 09:02:33105
106 if (defined(invoker.libfuzzer_options)) {
107 args += [ "--libfuzzer_options" ]
108 args += invoker.libfuzzer_options
109 }
110
mmoroz344a75ae2016-03-02 16:57:17111 outputs = [
112 "$root_build_dir/$config_name",
113 ]
114 }
115 test_deps += [ ":" + config_name ]
aizatskycb1a43932015-12-14 20:59:14116 }
117
aizatsky43d459a52016-02-13 01:22:18118 test(target_name) {
119 forward_variables_from(invoker,
120 [
[email protected]419d0f92017-09-14 12:07:47121 "cflags",
122 "cflags_cc",
brettw6b0712a2016-07-15 17:48:20123 "check_includes",
wfhdee978f2016-09-01 22:18:18124 "defines",
aizatsky43d459a52016-02-13 01:22:18125 "include_dirs",
brettw6b0712a2016-07-15 17:48:20126 "sources",
aizatsky43d459a52016-02-13 01:22:18127 ])
128 deps = test_deps
aizatsky43d459a52016-02-13 01:22:18129
130 if (defined(invoker.additional_configs)) {
131 configs += invoker.additional_configs
132 }
aizatsky345732a2016-04-14 22:30:44133 configs += [ "//testing/libfuzzer:fuzzer_test_config" ]
katrielc2bfe70482016-06-16 13:43:00134
135 # Used by WebRTC to suppress some Clang warnings in their codebase.
136 if (defined(invoker.suppressed_configs)) {
137 configs -= invoker.suppressed_configs
138 }
aizatskycb1a43932015-12-14 20:59:14139 }
aizatsky43d459a52016-02-13 01:22:18140 } else {
141 # noop on unsupported platforms.
142 # mark attributes as used.
143 assert(invoker.sources == [] || invoker.sources != [])
aizatskycb1a43932015-12-14 20:59:14144 if (defined(invoker.additional_configs)) {
aizatsky43d459a52016-02-13 01:22:18145 assert(
146 invoker.additional_configs == [] || invoker.additional_configs != [])
147 }
148 if (defined(invoker.deps)) {
149 assert(invoker.deps == [] || invoker.deps != [])
150 }
151 if (defined(invoker.dict)) {
152 assert(invoker.dict == [] || invoker.dict != [])
153 }
mmoroz344a75ae2016-03-02 16:57:17154 if (defined(invoker.libfuzzer_options)) {
155 assert(invoker.libfuzzer_options == [] || invoker.libfuzzer_options != [])
156 }
aizatsky198e3022016-03-08 21:33:46157 if (defined(invoker.seed_corpus)) {
158 assert(invoker.seed_corpus == [] || invoker.seed_corpus != [])
159 }
mmoroz2d9411b2017-02-09 12:01:37160 if (defined(invoker.seed_corpuses)) {
161 assert(invoker.seed_corpuses == [] || invoker.seed_corpuses != [])
162 }
brettw6b0712a2016-07-15 17:48:20163 assert(!defined(invoker.check_includes) || invoker.check_includes != [])
wfhdee978f2016-09-01 22:18:18164 assert(!defined(invoker.include_dirs) || invoker.include_dirs != [])
165 assert(!defined(invoker.defines) || invoker.defines != [])
aizatsky43d459a52016-02-13 01:22:18166
167 group(target_name) {
aizatskycb1a43932015-12-14 20:59:14168 }
169 }
170}