diff options
author | 2017-09-29 11:10:14 -0700 | |
---|---|---|
committer | 2017-09-29 11:10:14 -0700 | |
commit | 2c357bc62e795affe6a9278193b579960aaf56ec (patch) | |
tree | c2a9d4a0e4ac386b5bf7ac7c4bd3d3e39db8a4a4 /test/core/util/fuzzer_corpus_test.cc | |
parent | 1c9ef7c5ef8a42b5d02bdd55146d8346d87034b1 (diff) |
Moving to allow fuzzer test to run entire corpora under bazel
Diffstat (limited to 'test/core/util/fuzzer_corpus_test.cc')
-rw-r--r-- | test/core/util/fuzzer_corpus_test.cc | 139 |
1 files changed, 139 insertions, 0 deletions
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(); +} |