Skip to content

Commit 50ae54d

Browse files
authored
[fuzzing] Run fuzzers a little bit as a test (grpc#29919)
* [fuzzer] Add a script to sample fuzzers * remember the script * add ci * bleh * fix * Update sample_fuzzers.sh * tweak * tweak * tweak * tweak * tweak * fix fuzzer found bug * add explainer * make it bold af * limit max fuzzing time in addition to runs
1 parent df3ce20 commit 50ae54d

11 files changed

+188
-13
lines changed

bazel/grpc_build_system.bzl

+9-8
Original file line numberDiff line numberDiff line change
@@ -378,14 +378,15 @@ def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data
378378
"linkstatic": linkstatic,
379379
}
380380

381-
ios_cc_test(
382-
name = name,
383-
srcs = srcs,
384-
tags = tags,
385-
deps = core_deps,
386-
args = args,
387-
**test_args
388-
)
381+
if "grpc-fuzzer" not in tags:
382+
ios_cc_test(
383+
name = name,
384+
srcs = srcs,
385+
tags = tags,
386+
deps = core_deps,
387+
args = args,
388+
**test_args
389+
)
389390
if not uses_polling:
390391
# the test behavior doesn't depend on polling, just generate the test
391392
native.cc_test(

src/core/lib/channel/promise_based_filter.cc

+7-1
Original file line numberDiff line numberDiff line change
@@ -591,7 +591,13 @@ void ClientCallData::StartBatch(grpc_transport_stream_op_batch* b) {
591591
batch.CancelWith(GRPC_ERROR_REF(cancelled_error_), &flusher);
592592
}
593593

594-
if (batch.is_captured()) batch.ResumeWith(&flusher);
594+
if (batch.is_captured()) {
595+
if (!is_last()) {
596+
batch.ResumeWith(&flusher);
597+
} else {
598+
batch.CancelWith(GRPC_ERROR_CANCELLED, &flusher);
599+
}
600+
}
595601
}
596602

597603
// Handle cancellation.

src/core/lib/channel/promise_based_filter.h

+1
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ class BaseCallData : public Activity, private Wakeable {
171171
~Flusher();
172172

173173
void Resume(grpc_transport_stream_op_batch* batch) {
174+
GPR_ASSERT(!call_->is_last());
174175
release_.push_back(batch);
175176
}
176177

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
actions {
2+
create_channel {
3+
channel_actions {
4+
}
5+
}
6+
}
7+
actions {
8+
create_call {
9+
method {
10+
value: "contenttype"
11+
}
12+
}
13+
}
14+
actions {
15+
queue_batch {
16+
operations {
17+
receive_initial_metadata {
18+
}
19+
}
20+
}
21+
}

test/core/slice/BUILD

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ grpc_fuzzer(
2727
tags = ["no_windows"],
2828
deps = [
2929
"//:grpc",
30+
"//test/core/util:grpc_suppressions",
3031
],
3132
)
3233

@@ -38,6 +39,7 @@ grpc_fuzzer(
3839
tags = ["no_windows"],
3940
deps = [
4041
"//:grpc",
42+
"//test/core/util:grpc_suppressions",
4143
],
4244
)
4345

test/core/util/grpc_fuzzer.bzl

+8-4
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ load("//bazel:grpc_build_system.bzl", "grpc_cc_test")
2020
load("@rules_proto//proto:defs.bzl", "proto_library")
2121
load("@rules_cc//cc:defs.bzl", "cc_proto_library")
2222

23-
def grpc_fuzzer(name, corpus, srcs = [], deps = [], data = [], size = "large", **kwargs):
23+
def grpc_fuzzer(name, corpus, srcs = [], tags = [], deps = [], data = [], size = "large", **kwargs):
2424
"""Instantiates a fuzzer test.
2525
2626
Args:
@@ -30,12 +30,14 @@ def grpc_fuzzer(name, corpus, srcs = [], deps = [], data = [], size = "large", *
3030
deps: The dependencies of the test.
3131
data: The data dependencies of the test.
3232
size: The size of the test.
33+
tags: The tags for the test.
3334
**kwargs: Other arguments to supply to the test.
3435
"""
3536
CORPUS_DIR = native.package_name() + "/" + corpus
3637
grpc_cc_test(
3738
name = name,
3839
srcs = srcs,
40+
tags = tags + ["grpc-fuzzer", "no-cache"],
3941
deps = deps + select({
4042
"//:grpc_build_fuzzers": [],
4143
"//conditions:default": ["//test/core/util:fuzzer_corpus_test"],
@@ -46,13 +48,13 @@ def grpc_fuzzer(name, corpus, srcs = [], deps = [], data = [], size = "large", *
4648
],
4749
size = size,
4850
args = select({
49-
"//:grpc_build_fuzzers": [CORPUS_DIR],
51+
"//:grpc_build_fuzzers": [CORPUS_DIR, "-runs=5000", "-max_total_time=300"],
5052
"//conditions:default": ["--directory=" + CORPUS_DIR],
5153
}),
5254
**kwargs
5355
)
5456

55-
def grpc_proto_fuzzer(name, corpus, proto, srcs = [], deps = [], data = [], size = "large", **kwargs):
57+
def grpc_proto_fuzzer(name, corpus, proto, srcs = [], tags = [], deps = [], data = [], size = "large", **kwargs):
5658
"""Instantiates a protobuf mutator fuzzer test.
5759
5860
Args:
@@ -63,6 +65,7 @@ def grpc_proto_fuzzer(name, corpus, proto, srcs = [], deps = [], data = [], size
6365
deps: The dependencies of the test.
6466
data: The data dependencies of the test.
6567
size: The size of the test.
68+
tags: The tags for the test.
6669
**kwargs: Other arguments to supply to the test.
6770
"""
6871
PROTO_LIBRARY = "_%s_proto" % name
@@ -82,6 +85,7 @@ def grpc_proto_fuzzer(name, corpus, proto, srcs = [], deps = [], data = [], size
8285
grpc_cc_test(
8386
name = name,
8487
srcs = srcs,
88+
tags = tags + ["grpc-fuzzer", "no-cache"],
8589
deps = deps + [
8690
"@com_google_libprotobuf_mutator//:libprotobuf_mutator",
8791
CC_PROTO_LIBRARY,
@@ -95,7 +99,7 @@ def grpc_proto_fuzzer(name, corpus, proto, srcs = [], deps = [], data = [], size
9599
],
96100
size = size,
97101
args = select({
98-
"//:grpc_build_fuzzers": [CORPUS_DIR],
102+
"//:grpc_build_fuzzers": [CORPUS_DIR, "-runs=5000", "-max_total_time=300"],
99103
"//conditions:default": ["--directory=" + CORPUS_DIR],
100104
}),
101105
**kwargs

tools/fuzzing/sample_fuzzers.sh

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#! /bin/bash -ex
2+
# Copyright 2022 The gRPC Authors
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
dir=$(dirname "${0}")
17+
cd "${dir}/../.."
18+
tools/bazel test `tools/bazel query "attr(tags, '\\bgrpc-fuzzer\\b', //test/...)"` \
19+
-c dbg --config fuzzer_asan --test_output=errors
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#!/usr/bin/env bash
2+
# Copyright 2017 gRPC authors.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
set -ex
17+
18+
# Enter the gRPC repo root
19+
cd $(dirname $0)/../../..
20+
21+
cat tools/internal_ci/linux/grpc_sample_fuzzers_failure_explanation.txt
22+
23+
source tools/internal_ci/helper_scripts/prepare_build_linux_rc
24+
25+
export DOCKERFILE_DIR=tools/dockerfile/test/cxx_debian11_x64
26+
export DOCKER_RUN_SCRIPT=tools/internal_ci/linux/grpc_sample_fuzzers_in_docker.sh
27+
exec tools/run_tests/dockerize/build_and_run_docker.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
*******************************************************************************
2+
*******************************************************************************
3+
*******************************************************************************
4+
*******************************************************************************
5+
*******************************************************************************
6+
7+
8+
HEY THIS TEST IS FAILING AND I DONT KNOW HOW TO REPRODUCE IT??
9+
10+
At the point when this file was authored, I had no idea how to get the crash
11+
artifacts out of bazel/the fuzzer/kokoro/somewhere and onto your machine.
12+
13+
Without that this seemed like a problem - why check whether fuzzers pass if
14+
we can't debug them?
15+
16+
My thinking is this: if we can find an example that fails within a few minutes
17+
in CI, we can probably do likewise on your machine.
18+
19+
Try:
20+
21+
bazel build path/to/fuzzer --config=fuzzer_asan -c dbg
22+
bazel-bin/path/to/fuzzer path/to/fuzzer_corpus -jobs=$CPUS -workers=$CPUS
23+
24+
You should see whatever failure this CI job found before terribly long.
25+
26+
27+
*******************************************************************************
28+
*******************************************************************************
29+
*******************************************************************************
30+
*******************************************************************************
31+
*******************************************************************************
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/usr/bin/env bash
2+
# Copyright 2022 The gRPC Authors
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
set -ex
17+
18+
# Enter the gRPC repo root
19+
cd $(dirname $0)/../../..
20+
21+
# some extra pip packages are needed for the check_on_pr.py script to work
22+
# TODO(jtattermusch): avoid needing to install these pip packages each time
23+
time python3 -m pip install --user -r tools/internal_ci/helper_scripts/requirements.linux_perf.txt
24+
25+
tools/run_tests/start_port_server.py
26+
27+
tools/internal_ci/linux/run_if_c_cpp_modified.sh tools/fuzzing/sample_fuzzers.sh \
28+
-d "origin/$KOKORO_GITHUB_PULL_REQUEST_TARGET_BRANCH"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Copyright 2022 The 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+
# Config file for the internal CI (in protobuf text format)
16+
17+
# Location of the continuous shell script in repository.
18+
build_file: "grpc/tools/internal_ci/linux/grpc_sample_fuzzers.sh"
19+
timeout_mins: 120
20+
before_action {
21+
fetch_keystore {
22+
keystore_resource {
23+
keystore_config_id: 73836
24+
keyname: "grpc_checks_private_key"
25+
}
26+
}
27+
}
28+
action {
29+
define_artifacts {
30+
regex: "**/*sponge_log.*"
31+
regex: "**/test.log"
32+
regex: "github/grpc/reports/**"
33+
regex: "**/crash-*"
34+
}
35+
}

0 commit comments

Comments
 (0)