diff options
author | Craig Tiller <ctiller@google.com> | 2017-09-29 11:10:14 -0700 |
---|---|---|
committer | Craig Tiller <ctiller@google.com> | 2017-09-29 11:10:14 -0700 |
commit | 2c357bc62e795affe6a9278193b579960aaf56ec (patch) | |
tree | c2a9d4a0e4ac386b5bf7ac7c4bd3d3e39db8a4a4 | |
parent | 1c9ef7c5ef8a42b5d02bdd55146d8346d87034b1 (diff) |
Moving to allow fuzzer test to run entire corpora under bazel
-rw-r--r-- | test/core/util/BUILD | 8 | ||||
-rw-r--r-- | test/core/util/fuzzer_corpus_test.cc | 139 | ||||
-rw-r--r-- | test/core/util/grpc_fuzzer.bzl | 20 | ||||
-rw-r--r-- | test/core/util/one_corpus_entry_fuzzer.c | 39 |
4 files changed, 154 insertions, 52 deletions
diff --git a/test/core/util/BUILD b/test/core/util/BUILD index 10eefe159a..abb50a0c99 100644 --- a/test/core/util/BUILD +++ b/test/core/util/BUILD @@ -89,12 +89,16 @@ grpc_cc_library( ) grpc_cc_library( - name = "one_corpus_entry_fuzzer", - srcs = ["one_corpus_entry_fuzzer.c"], + name = "fuzzer_corpus_test", + srcs = ["fuzzer_corpus_test.cc"], deps = [ ":gpr_test_util", "//:grpc", ], + external_deps = [ + "gtest", + "gflags", + ], ) sh_library( diff --git a/test/core/util/fuzzer_corpus_test.cc b/test/core/util/fuzzer_corpus_test.cc new file mode 100644 index 0000000000..75c6846cd7 --- /dev/null +++ b/test/core/util/fuzzer_corpus_test.cc @@ -0,0 +1,139 @@ +/* + * + * Copyright 2016 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include <stdbool.h> + +#include <dirent.h> +#include <gflags/gflags.h> +#include <grpc/support/log.h> +#include <gtest/gtest.h> +#include <stdio.h> +#include <sys/types.h> + +#include "src/core/lib/iomgr/load_file.h" +#include "test/core/util/test_config.h" + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size); +extern "C" bool squelch; +extern "C" bool leak_check; + +DEFINE_string(file, "", "Use this file as test data"); +DEFINE_string(directory, "", "Use this directory as test data"); + +class FuzzerCorpusTest : public ::testing::TestWithParam<std::string> {}; + +TEST_P(FuzzerCorpusTest, RunOneExample) { + grpc_slice buffer; + squelch = false; + leak_check = false; + GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file", + grpc_load_file(GetParam().c_str(), 0, &buffer))); + LLVMFuzzerTestOneInput(GRPC_SLICE_START_PTR(buffer), + GRPC_SLICE_LENGTH(buffer)); + grpc_slice_unref(buffer); +} + +class ExampleGenerator + : public ::testing::internal::ParamGeneratorInterface<std::string> { + public: + virtual ::testing::internal::ParamIteratorInterface<std::string>* Begin() + const; + virtual ::testing::internal::ParamIteratorInterface<std::string>* End() const; + + private: + void Materialize() const { + if (examples_.empty()) { + if (!FLAGS_file.empty()) examples_.push_back(FLAGS_file); + if (!FLAGS_directory.empty()) { + DIR* dp; + struct dirent* ep; + dp = opendir("./"); + + if (dp != NULL) { + while ((ep = readdir(dp)) != nullptr) examples_.push_back(ep->d_name); + + (void)closedir(dp); + } else { + perror("Couldn't open the directory"); + abort(); + } + } + } + } + + mutable std::vector<std::string> examples_; +}; + +class ExampleIterator + : public ::testing::internal::ParamIteratorInterface<std::string> { + public: + ExampleIterator(const ExampleGenerator& base_, + std::vector<std::string>::const_iterator begin) + : base_(base_), begin_(begin), current_(begin), current_string_(NULL) {} + + ~ExampleIterator() { delete current_string_; } + virtual const ExampleGenerator* BaseGenerator() const { return &base_; } + + virtual void Advance() { + current_++; + delete current_string_; + current_string_ = NULL; + } + virtual ExampleIterator* Clone() const { return new ExampleIterator(*this); } + virtual const std::string* Current() const; + + virtual bool Equals(const ParamIteratorInterface<std::string>& other) const { + return &base_ == other.BaseGenerator() && + current_ == dynamic_cast<const ExampleIterator*>(&other)->current_; + } + + private: + ExampleIterator(const ExampleIterator& other) + : base_(other.base_), + begin_(other.begin_), + current_(other.current_), + current_string_(NULL) {} + + const ExampleGenerator& base_; + const std::vector<std::string>::const_iterator begin_; + std::vector<std::string>::const_iterator current_; + mutable const std::string* current_string_; +}; + +::testing::internal::ParamIteratorInterface<std::string>* +ExampleGenerator::Begin() const { + Materialize(); + return new ExampleIterator(*this, examples_.begin()); +} + +::testing::internal::ParamIteratorInterface<std::string>* +ExampleGenerator::End() const { + Materialize(); + return new ExampleIterator(*this, examples_.end()); +} + +INSTANTIATE_TEST_CASE_P( + CorpusExamples, FuzzerCorpusTest, + ::testing::internal::ParamGenerator<std::string>(new ExampleGenerator)); + +int main(int argc, char** argv) { + grpc_test_init(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} diff --git a/test/core/util/grpc_fuzzer.bzl b/test/core/util/grpc_fuzzer.bzl index 41f6cdc8ba..55b6f1c1a5 100644 --- a/test/core/util/grpc_fuzzer.bzl +++ b/test/core/util/grpc_fuzzer.bzl @@ -12,19 +12,17 @@ # See the License for the specific language governing permissions and # limitations under the License. -load("//bazel:grpc_build_system.bzl", "grpc_cc_binary") +load("//bazel:grpc_build_system.bzl", "grpc_cc_test") def grpc_fuzzer(name, corpus, srcs = [], deps = [], **kwargs): - grpc_cc_binary( - name = '%s/one_entry.bin' % name, + grpc_cc_test( + name = name, srcs = srcs, - deps = deps + ["//test/core/util:one_corpus_entry_fuzzer"], + deps = deps + ["//test/core/util:fuzzer_corpus_test"], + data = [corpus], + args = ['--directory', '$(location %s)' % corpus], + external_deps = [ + 'gtest', + ], **kwargs ) - for entry in native.glob(['%s/*' % corpus]): - native.sh_test( - name = '%s/one_entry/%s' % (name, entry), - data = [':%s/one_entry.bin' % name, entry], - srcs = ['//test/core/util:fuzzer_one_entry_runner'], - args = ['$(location :%s/one_entry.bin)' % name, '$(location %s)' % entry] - ) diff --git a/test/core/util/one_corpus_entry_fuzzer.c b/test/core/util/one_corpus_entry_fuzzer.c deleted file mode 100644 index 42467390f2..0000000000 --- a/test/core/util/one_corpus_entry_fuzzer.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * - * Copyright 2016 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include <stdbool.h> - -#include <grpc/support/log.h> -#include "src/core/lib/iomgr/load_file.h" - -extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); - -extern bool squelch; -extern bool leak_check; - -int main(int argc, char **argv) { - grpc_slice buffer; - squelch = false; - leak_check = false; - GPR_ASSERT( - GRPC_LOG_IF_ERROR("load_file", grpc_load_file(argv[1], 0, &buffer))); - LLVMFuzzerTestOneInput(GRPC_SLICE_START_PTR(buffer), - GRPC_SLICE_LENGTH(buffer)); - grpc_slice_unref(buffer); - return 0; -} |