1# Copyright 2016 gRPC authors. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15""" 16Includes fuzzer rules. 17 18Now that we are at C++17, please prefer grpc_fuzz_test over the 19grpc_fuzzer/grpc_proto_fuzzer older rules for new fuzzers - the former is 20simpler and better maintained, and we'll eventually replace existing fuzzers 21with grpc_fuzz_test. 22""" 23 24load("//bazel:grpc_build_system.bzl", "grpc_cc_proto_library", "grpc_cc_test", "grpc_internal_proto_library") 25 26def grpc_fuzzer(name, corpus, owner = "grpc", srcs = [], tags = [], external_deps = [], deps = [], data = [], size = "large", **kwargs): 27 """Instantiates a fuzzer test. 28 29 Args: 30 name: The name of the test. 31 corpus: The corpus for the test. 32 srcs: The source files for the test. 33 external_deps: External deps. 34 deps: The dependencies of the test. 35 data: The data dependencies of the test. 36 size: The size of the test. 37 tags: The tags for the test. 38 owner: The owning team of the test (for auto-bug-filing). 39 **kwargs: Other arguments to supply to the test. 40 """ 41 CORPUS_DIR = native.package_name() + "/" + corpus 42 grpc_cc_test( 43 name = name, 44 srcs = srcs, 45 tags = tags + ["grpc-fuzzer", "no-cache"], 46 deps = deps + select({ 47 "//:grpc_build_fuzzers": [], 48 "//conditions:default": ["//test/core/test_util:fuzzer_corpus_test"], 49 }), 50 data = data + native.glob([corpus + "/**"]), 51 external_deps = external_deps + [ 52 "gtest", 53 ], 54 size = size, 55 args = select({ 56 "//:grpc_build_fuzzers": [CORPUS_DIR, "-runs=20000", "-max_total_time=300"], 57 "//conditions:default": ["--directory=" + CORPUS_DIR], 58 }), 59 **kwargs 60 ) 61 62def grpc_proto_fuzzer( 63 name, 64 corpus, 65 proto, 66 owner = "grpc", # @unused 67 proto_deps = [], 68 external_deps = [], 69 srcs = [], 70 tags = [], 71 deps = [], 72 end2end_fuzzer = False, # @unused 73 data = [], 74 size = "large", 75 **kwargs): 76 """Instantiates a protobuf mutator fuzzer test. 77 78 Args: 79 name: The name of the test. 80 corpus: The corpus for the test. 81 proto: The proto for the test. If empty, it assumes the proto dependency 82 is already included in the target deps. Otherwise it creates a 83 new proto_library with name "_{name}_proto" and 84 cc_proto_library with name "_{name}_cc_proto" and makes the 85 fuzz target depend on the latter. 86 proto_deps: Deps for proto. Only used if proto is not empty. 87 external_deps: External deps. 88 srcs: The source files for the test. 89 deps: The dependencies of the test. 90 data: The data dependencies of the test. 91 size: The size of the test. 92 tags: The tags for the test. 93 owner: The owning team of the test (for auto-bug-filing). 94 end2end_fuzzer: Flag to enable end2end fuzzers. 95 This is currently False and ignored 96 **kwargs: Other arguments to supply to the test. 97 """ 98 99 CORPUS_DIR = native.package_name() + "/" + corpus 100 deps = deps + ["@com_google_libprotobuf_mutator//:libprotobuf_mutator"] 101 102 if "gtest" not in external_deps: 103 external_deps = external_deps + ["gtest"] 104 105 if proto != None: 106 PROTO_LIBRARY = "_%s_proto" % name 107 grpc_internal_proto_library( 108 name = PROTO_LIBRARY, 109 srcs = [proto], 110 deps = proto_deps, 111 ) 112 CC_PROTO_LIBRARY = "_%s_cc_proto" % name 113 grpc_cc_proto_library( 114 name = CC_PROTO_LIBRARY, 115 deps = [PROTO_LIBRARY], 116 ) 117 deps = deps + [CC_PROTO_LIBRARY] 118 119 grpc_cc_test( 120 name = name, 121 srcs = srcs, 122 tags = tags + ["grpc-fuzzer", "no-cache"], 123 deps = deps + select({ 124 "//:grpc_build_fuzzers": [], 125 "//conditions:default": ["//test/core/test_util:fuzzer_corpus_test"], 126 }), 127 data = data + native.glob([corpus + "/**"]), 128 external_deps = external_deps, 129 size = size, 130 args = select({ 131 "//:grpc_build_fuzzers": [CORPUS_DIR, "-runs=20000", "-max_total_time=300"], 132 "//conditions:default": ["--directory=" + CORPUS_DIR], 133 }), 134 **kwargs 135 ) 136 137def grpc_fuzz_test(name, srcs = [], deps = [], tags = [], external_deps = []): 138 """Instantiates a fuzztest based test. 139 140 This is the preferred method of writing fuzzers. 141 142 Args: 143 name: The name of the test. 144 srcs: The source files for the test. 145 deps: The dependencies of the test. 146 tags: The tags for the test. 147 external_deps: External deps. 148 """ 149 grpc_cc_test( 150 name = name, 151 srcs = srcs, 152 tags = tags + [ 153 "grpc-fuzzer", 154 "grpc-fuzztest", 155 "no-cache", 156 "no_windows", 157 "bazel_only", 158 ], 159 deps = deps, 160 external_deps = external_deps, 161 ) 162