Add tests for fuzzers::RandomGenerator
BUG=tint:1019 Change-Id: Ia462080877a97348c5589bfa71231a832a7ebfd3 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/70081 Auto-Submit: Ryan Harrison <rharrison@chromium.org> Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Ryan Harrison <rharrison@chromium.org> Reviewed-by: Antonio Maiorano <amaiorano@google.com>
This commit is contained in:
parent
066c175852
commit
1c1b9762ce
|
@ -54,7 +54,7 @@ if (build_with_chromium) {
|
||||||
# fuzzer_test doesn't have configs members, so need to define them in an empty
|
# fuzzer_test doesn't have configs members, so need to define them in an empty
|
||||||
# source_set.
|
# source_set.
|
||||||
|
|
||||||
source_set("tint_fuzzer_common") {
|
source_set("tint_fuzzer_common_src") {
|
||||||
public_configs = [
|
public_configs = [
|
||||||
"${tint_root_dir}/src:tint_config",
|
"${tint_root_dir}/src:tint_config",
|
||||||
"${tint_root_dir}/src:tint_common_config",
|
"${tint_root_dir}/src:tint_common_config",
|
||||||
|
@ -67,8 +67,12 @@ if (build_with_chromium) {
|
||||||
|
|
||||||
sources = [
|
sources = [
|
||||||
"data_builder.h",
|
"data_builder.h",
|
||||||
|
"mersenne_twister_engine.cc",
|
||||||
|
"mersenne_twister_engine.h",
|
||||||
"random_generator.cc",
|
"random_generator.cc",
|
||||||
"random_generator.h",
|
"random_generator.h",
|
||||||
|
"random_generator_engine.cc",
|
||||||
|
"random_generator_engine.h",
|
||||||
"tint_common_fuzzer.cc",
|
"tint_common_fuzzer.cc",
|
||||||
"tint_common_fuzzer.h",
|
"tint_common_fuzzer.h",
|
||||||
"tint_reader_writer_fuzzer.h",
|
"tint_reader_writer_fuzzer.h",
|
||||||
|
@ -76,8 +80,8 @@ if (build_with_chromium) {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
source_set("tint_fuzzer_common_with_init") {
|
source_set("tint_fuzzer_common_with_init_src") {
|
||||||
public_deps = [ ":tint_fuzzer_common" ]
|
public_deps = [ ":tint_fuzzer_common_src" ]
|
||||||
|
|
||||||
sources = [
|
sources = [
|
||||||
"cli.cc",
|
"cli.cc",
|
||||||
|
@ -90,7 +94,7 @@ if (build_with_chromium) {
|
||||||
if (tint_build_wgsl_reader && tint_build_wgsl_writer) {
|
if (tint_build_wgsl_reader && tint_build_wgsl_writer) {
|
||||||
fuzzer_test("tint_ast_clone_fuzzer") {
|
fuzzer_test("tint_ast_clone_fuzzer") {
|
||||||
sources = [ "tint_ast_clone_fuzzer.cc" ]
|
sources = [ "tint_ast_clone_fuzzer.cc" ]
|
||||||
deps = [ ":tint_fuzzer_common_with_init" ]
|
deps = [ ":tint_fuzzer_common_with_init_src" ]
|
||||||
dict = "dictionary.txt"
|
dict = "dictionary.txt"
|
||||||
libfuzzer_options = tint_fuzzer_common_libfuzzer_options
|
libfuzzer_options = tint_fuzzer_common_libfuzzer_options
|
||||||
seed_corpus = fuzzer_corpus_wgsl_dir
|
seed_corpus = fuzzer_corpus_wgsl_dir
|
||||||
|
@ -115,7 +119,7 @@ if (build_with_chromium) {
|
||||||
|
|
||||||
fuzzer_test("tint_wgsl_reader_wgsl_writer_fuzzer") {
|
fuzzer_test("tint_wgsl_reader_wgsl_writer_fuzzer") {
|
||||||
sources = [ "tint_wgsl_reader_wgsl_writer_fuzzer.cc" ]
|
sources = [ "tint_wgsl_reader_wgsl_writer_fuzzer.cc" ]
|
||||||
deps = [ ":tint_fuzzer_common_with_init" ]
|
deps = [ ":tint_fuzzer_common_with_init_src" ]
|
||||||
dict = "dictionary.txt"
|
dict = "dictionary.txt"
|
||||||
libfuzzer_options = tint_fuzzer_common_libfuzzer_options
|
libfuzzer_options = tint_fuzzer_common_libfuzzer_options
|
||||||
seed_corpus = fuzzer_corpus_wgsl_dir
|
seed_corpus = fuzzer_corpus_wgsl_dir
|
||||||
|
@ -126,7 +130,7 @@ if (build_with_chromium) {
|
||||||
if (tint_build_wgsl_reader && tint_build_spv_writer) {
|
if (tint_build_wgsl_reader && tint_build_spv_writer) {
|
||||||
fuzzer_test("tint_all_transforms_fuzzer") {
|
fuzzer_test("tint_all_transforms_fuzzer") {
|
||||||
sources = [ "tint_all_transforms_fuzzer.cc" ]
|
sources = [ "tint_all_transforms_fuzzer.cc" ]
|
||||||
deps = [ ":tint_fuzzer_common_with_init" ]
|
deps = [ ":tint_fuzzer_common_with_init_src" ]
|
||||||
dict = "dictionary.txt"
|
dict = "dictionary.txt"
|
||||||
libfuzzer_options = tint_fuzzer_common_libfuzzer_options
|
libfuzzer_options = tint_fuzzer_common_libfuzzer_options
|
||||||
seed_corpus = fuzzer_corpus_wgsl_dir
|
seed_corpus = fuzzer_corpus_wgsl_dir
|
||||||
|
@ -143,7 +147,7 @@ if (build_with_chromium) {
|
||||||
|
|
||||||
fuzzer_test("tint_binding_remapper_fuzzer") {
|
fuzzer_test("tint_binding_remapper_fuzzer") {
|
||||||
sources = [ "tint_binding_remapper_fuzzer.cc" ]
|
sources = [ "tint_binding_remapper_fuzzer.cc" ]
|
||||||
deps = [ ":tint_fuzzer_common_with_init" ]
|
deps = [ ":tint_fuzzer_common_with_init_src" ]
|
||||||
dict = "dictionary.txt"
|
dict = "dictionary.txt"
|
||||||
libfuzzer_options = tint_fuzzer_common_libfuzzer_options
|
libfuzzer_options = tint_fuzzer_common_libfuzzer_options
|
||||||
seed_corpus = fuzzer_corpus_wgsl_dir
|
seed_corpus = fuzzer_corpus_wgsl_dir
|
||||||
|
@ -152,7 +156,7 @@ if (build_with_chromium) {
|
||||||
|
|
||||||
fuzzer_test("tint_first_index_offset_fuzzer") {
|
fuzzer_test("tint_first_index_offset_fuzzer") {
|
||||||
sources = [ "tint_first_index_offset_fuzzer.cc" ]
|
sources = [ "tint_first_index_offset_fuzzer.cc" ]
|
||||||
deps = [ ":tint_fuzzer_common_with_init" ]
|
deps = [ ":tint_fuzzer_common_with_init_src" ]
|
||||||
dict = "dictionary.txt"
|
dict = "dictionary.txt"
|
||||||
libfuzzer_options = tint_fuzzer_common_libfuzzer_options
|
libfuzzer_options = tint_fuzzer_common_libfuzzer_options
|
||||||
seed_corpus = fuzzer_corpus_wgsl_dir
|
seed_corpus = fuzzer_corpus_wgsl_dir
|
||||||
|
@ -169,7 +173,7 @@ if (build_with_chromium) {
|
||||||
|
|
||||||
fuzzer_test("tint_renamer_fuzzer") {
|
fuzzer_test("tint_renamer_fuzzer") {
|
||||||
sources = [ "tint_renamer_fuzzer.cc" ]
|
sources = [ "tint_renamer_fuzzer.cc" ]
|
||||||
deps = [ ":tint_fuzzer_common_with_init" ]
|
deps = [ ":tint_fuzzer_common_with_init_src" ]
|
||||||
dict = "dictionary.txt"
|
dict = "dictionary.txt"
|
||||||
libfuzzer_options = tint_fuzzer_common_libfuzzer_options
|
libfuzzer_options = tint_fuzzer_common_libfuzzer_options
|
||||||
seed_corpus = fuzzer_corpus_wgsl_dir
|
seed_corpus = fuzzer_corpus_wgsl_dir
|
||||||
|
@ -178,7 +182,7 @@ if (build_with_chromium) {
|
||||||
|
|
||||||
fuzzer_test("tint_robustness_fuzzer") {
|
fuzzer_test("tint_robustness_fuzzer") {
|
||||||
sources = [ "tint_robustness_fuzzer.cc" ]
|
sources = [ "tint_robustness_fuzzer.cc" ]
|
||||||
deps = [ ":tint_fuzzer_common_with_init" ]
|
deps = [ ":tint_fuzzer_common_with_init_src" ]
|
||||||
dict = "dictionary.txt"
|
dict = "dictionary.txt"
|
||||||
libfuzzer_options = tint_fuzzer_common_libfuzzer_options
|
libfuzzer_options = tint_fuzzer_common_libfuzzer_options
|
||||||
seed_corpus = fuzzer_corpus_wgsl_dir
|
seed_corpus = fuzzer_corpus_wgsl_dir
|
||||||
|
@ -187,7 +191,7 @@ if (build_with_chromium) {
|
||||||
|
|
||||||
fuzzer_test("tint_single_entry_point_fuzzer") {
|
fuzzer_test("tint_single_entry_point_fuzzer") {
|
||||||
sources = [ "tint_single_entry_point_fuzzer.cc" ]
|
sources = [ "tint_single_entry_point_fuzzer.cc" ]
|
||||||
deps = [ ":tint_fuzzer_common_with_init" ]
|
deps = [ ":tint_fuzzer_common_with_init_src" ]
|
||||||
dict = "dictionary.txt"
|
dict = "dictionary.txt"
|
||||||
libfuzzer_options = tint_fuzzer_common_libfuzzer_options
|
libfuzzer_options = tint_fuzzer_common_libfuzzer_options
|
||||||
seed_corpus = fuzzer_corpus_wgsl_dir
|
seed_corpus = fuzzer_corpus_wgsl_dir
|
||||||
|
@ -196,7 +200,7 @@ if (build_with_chromium) {
|
||||||
|
|
||||||
fuzzer_test("tint_vertex_pulling_fuzzer") {
|
fuzzer_test("tint_vertex_pulling_fuzzer") {
|
||||||
sources = [ "tint_vertex_pulling_fuzzer.cc" ]
|
sources = [ "tint_vertex_pulling_fuzzer.cc" ]
|
||||||
deps = [ ":tint_fuzzer_common_with_init" ]
|
deps = [ ":tint_fuzzer_common_with_init_src" ]
|
||||||
dict = "dictionary.txt"
|
dict = "dictionary.txt"
|
||||||
libfuzzer_options = tint_fuzzer_common_libfuzzer_options
|
libfuzzer_options = tint_fuzzer_common_libfuzzer_options
|
||||||
seed_corpus = fuzzer_corpus_wgsl_dir
|
seed_corpus = fuzzer_corpus_wgsl_dir
|
||||||
|
@ -205,7 +209,7 @@ if (build_with_chromium) {
|
||||||
|
|
||||||
fuzzer_test("tint_wgsl_reader_spv_writer_fuzzer") {
|
fuzzer_test("tint_wgsl_reader_spv_writer_fuzzer") {
|
||||||
sources = [ "tint_wgsl_reader_spv_writer_fuzzer.cc" ]
|
sources = [ "tint_wgsl_reader_spv_writer_fuzzer.cc" ]
|
||||||
deps = [ ":tint_fuzzer_common_with_init" ]
|
deps = [ ":tint_fuzzer_common_with_init_src" ]
|
||||||
dict = "dictionary.txt"
|
dict = "dictionary.txt"
|
||||||
libfuzzer_options = tint_fuzzer_common_libfuzzer_options
|
libfuzzer_options = tint_fuzzer_common_libfuzzer_options
|
||||||
seed_corpus = fuzzer_corpus_wgsl_dir
|
seed_corpus = fuzzer_corpus_wgsl_dir
|
||||||
|
@ -232,7 +236,7 @@ if (build_with_chromium) {
|
||||||
|
|
||||||
fuzzer_test("tint_wgsl_reader_hlsl_writer_fuzzer") {
|
fuzzer_test("tint_wgsl_reader_hlsl_writer_fuzzer") {
|
||||||
sources = [ "tint_wgsl_reader_hlsl_writer_fuzzer.cc" ]
|
sources = [ "tint_wgsl_reader_hlsl_writer_fuzzer.cc" ]
|
||||||
deps = [ ":tint_fuzzer_common_with_init" ]
|
deps = [ ":tint_fuzzer_common_with_init_src" ]
|
||||||
dict = "dictionary.txt"
|
dict = "dictionary.txt"
|
||||||
libfuzzer_options = tint_fuzzer_common_libfuzzer_options
|
libfuzzer_options = tint_fuzzer_common_libfuzzer_options
|
||||||
seed_corpus = fuzzer_corpus_wgsl_dir
|
seed_corpus = fuzzer_corpus_wgsl_dir
|
||||||
|
@ -259,7 +263,7 @@ if (build_with_chromium) {
|
||||||
|
|
||||||
fuzzer_test("tint_wgsl_reader_msl_writer_fuzzer") {
|
fuzzer_test("tint_wgsl_reader_msl_writer_fuzzer") {
|
||||||
sources = [ "tint_wgsl_reader_msl_writer_fuzzer.cc" ]
|
sources = [ "tint_wgsl_reader_msl_writer_fuzzer.cc" ]
|
||||||
deps = [ ":tint_fuzzer_common_with_init" ]
|
deps = [ ":tint_fuzzer_common_with_init_src" ]
|
||||||
dict = "dictionary.txt"
|
dict = "dictionary.txt"
|
||||||
libfuzzer_options = tint_fuzzer_common_libfuzzer_options
|
libfuzzer_options = tint_fuzzer_common_libfuzzer_options
|
||||||
seed_corpus = fuzzer_corpus_wgsl_dir
|
seed_corpus = fuzzer_corpus_wgsl_dir
|
||||||
|
@ -272,7 +276,7 @@ if (build_with_chromium) {
|
||||||
tint_build_wgsl_writer) {
|
tint_build_wgsl_writer) {
|
||||||
executable("tint_black_box_fuzz_target") {
|
executable("tint_black_box_fuzz_target") {
|
||||||
sources = [ "tint_black_box_fuzz_target.cc" ]
|
sources = [ "tint_black_box_fuzz_target.cc" ]
|
||||||
deps = [ ":tint_fuzzer_common" ]
|
deps = [ ":tint_fuzzer_common_src" ]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,12 @@ function(add_tint_fuzzer NAME)
|
||||||
data_builder.h
|
data_builder.h
|
||||||
fuzzer_init.cc
|
fuzzer_init.cc
|
||||||
fuzzer_init.h
|
fuzzer_init.h
|
||||||
|
mersenne_twister_engine.cc
|
||||||
|
mersenne_twister_engine.h
|
||||||
random_generator.cc
|
random_generator.cc
|
||||||
random_generator.h
|
random_generator.h
|
||||||
|
random_generator_engine.cc
|
||||||
|
random_generator_engine.h
|
||||||
tint_common_fuzzer.cc
|
tint_common_fuzzer.cc
|
||||||
tint_common_fuzzer.h
|
tint_common_fuzzer.h
|
||||||
tint_reader_writer_fuzzer.h
|
tint_reader_writer_fuzzer.h
|
||||||
|
@ -93,9 +97,13 @@ if (${TINT_BUILD_WGSL_READER}
|
||||||
AND ${TINT_BUILD_SPV_WRITER}
|
AND ${TINT_BUILD_SPV_WRITER}
|
||||||
AND ${TINT_BUILD_WGSL_WRITER})
|
AND ${TINT_BUILD_WGSL_WRITER})
|
||||||
add_executable(tint_black_box_fuzz_target
|
add_executable(tint_black_box_fuzz_target
|
||||||
|
mersenne_twister_engine.cc
|
||||||
|
mersenne_twister_engine.h
|
||||||
random_generator.cc
|
random_generator.cc
|
||||||
random_generator.h
|
random_generator.h
|
||||||
tint_black_box_fuzz_target
|
random_generator_engine.cc
|
||||||
|
random_generator_engine.h
|
||||||
|
tint_black_box_fuzz_target.cc
|
||||||
tint_common_fuzzer.cc
|
tint_common_fuzzer.cc
|
||||||
tint_common_fuzzer.h
|
tint_common_fuzzer.h
|
||||||
)
|
)
|
||||||
|
|
|
@ -36,7 +36,7 @@ class DataBuilder {
|
||||||
/// @param data - data fuzzer to calculate seed from
|
/// @param data - data fuzzer to calculate seed from
|
||||||
/// @param size - size of data buffer
|
/// @param size - size of data buffer
|
||||||
explicit DataBuilder(const uint8_t* data, size_t size)
|
explicit DataBuilder(const uint8_t* data, size_t size)
|
||||||
: generator_(data, size) {
|
: generator_(RandomGenerator::CalculateSeed(data, size)) {
|
||||||
assert(data != nullptr && "|data| must be !nullptr");
|
assert(data != nullptr && "|data| must be !nullptr");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
// Copyright 2021 The Tint 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 "fuzzers/mersenne_twister_engine.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
#include "src/utils/hash.h"
|
||||||
|
|
||||||
|
namespace tint {
|
||||||
|
namespace fuzzers {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
/// Generate integer from uniform distribution
|
||||||
|
/// @tparam I - integer type
|
||||||
|
/// @param engine - random number engine to use
|
||||||
|
/// @param lower - Lower bound of integer generated
|
||||||
|
/// @param upper - Upper bound of integer generated
|
||||||
|
/// @returns i, where lower <= i < upper
|
||||||
|
template <typename I>
|
||||||
|
I RandomInteger(std::mt19937_64* engine, I lower, I upper) {
|
||||||
|
assert(lower < upper && "|lower| must be strictly less than |upper|");
|
||||||
|
return std::uniform_int_distribution<I>(lower, upper - 1)(*engine);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
MersenneTwisterEngine::MersenneTwisterEngine(uint64_t seed) : engine_(seed) {}
|
||||||
|
|
||||||
|
uint32_t MersenneTwisterEngine::RandomUInt32(uint32_t lower, uint32_t upper) {
|
||||||
|
return RandomInteger(&engine_, lower, upper);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t MersenneTwisterEngine::RandomUInt64(uint64_t lower, uint64_t upper) {
|
||||||
|
return RandomInteger(&engine_, lower, upper);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MersenneTwisterEngine::RandomNBytes(uint8_t* dest, size_t n) {
|
||||||
|
assert(dest && "|dest| must not be nullptr");
|
||||||
|
std::generate(
|
||||||
|
dest, dest + n,
|
||||||
|
std::independent_bits_engine<std::mt19937_64, 8, uint8_t>(engine_));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace fuzzers
|
||||||
|
} // namespace tint
|
|
@ -0,0 +1,62 @@
|
||||||
|
// Copyright 2021 The Tint 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.
|
||||||
|
|
||||||
|
#ifndef FUZZERS_MERSENNE_TWISTER_ENGINE_H_
|
||||||
|
#define FUZZERS_MERSENNE_TWISTER_ENGINE_H_
|
||||||
|
|
||||||
|
#include <random>
|
||||||
|
|
||||||
|
#include "fuzzers/random_generator_engine.h"
|
||||||
|
|
||||||
|
namespace tint {
|
||||||
|
namespace fuzzers {
|
||||||
|
|
||||||
|
/// Standard MT based random number generation
|
||||||
|
class MersenneTwisterEngine : public RandomGeneratorEngine {
|
||||||
|
public:
|
||||||
|
/// @brief Initializes using provided seed
|
||||||
|
/// @param seed - seed value to use
|
||||||
|
explicit MersenneTwisterEngine(uint64_t seed);
|
||||||
|
~MersenneTwisterEngine() override = default;
|
||||||
|
|
||||||
|
/// Generate random uint32_t value from uniform distribution.
|
||||||
|
/// @param lower - lower bound of integer generated
|
||||||
|
/// @param upper - upper bound of integer generated
|
||||||
|
/// @returns i, where lower <= i < upper
|
||||||
|
uint32_t RandomUInt32(uint32_t lower, uint32_t upper) override;
|
||||||
|
|
||||||
|
/// Get random uint64_t value from uniform distribution.
|
||||||
|
/// @param lower - lower bound of integer generated
|
||||||
|
/// @param upper - upper bound of integer generated
|
||||||
|
/// @returns i, where lower <= i < upper
|
||||||
|
uint64_t RandomUInt64(uint64_t lower, uint64_t upper) override;
|
||||||
|
|
||||||
|
/// Get N bytes of pseudo-random data
|
||||||
|
/// @param dest - memory location to store data
|
||||||
|
/// @param n - number of bytes of data to generate
|
||||||
|
void RandomNBytes(uint8_t* dest, size_t n) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Disallow copy & assign
|
||||||
|
MersenneTwisterEngine(const MersenneTwisterEngine&) = delete;
|
||||||
|
MersenneTwisterEngine& operator=(const MersenneTwisterEngine&) = delete;
|
||||||
|
|
||||||
|
std::mt19937_64 engine_;
|
||||||
|
|
||||||
|
}; // class MersenneTwisterEngine
|
||||||
|
|
||||||
|
} // namespace fuzzers
|
||||||
|
} // namespace tint
|
||||||
|
|
||||||
|
#endif // FUZZERS_MERSENNE_TWISTER_ENGINE_H_
|
|
@ -16,8 +16,10 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <vector>
|
#include <utility>
|
||||||
|
|
||||||
|
#include "fuzzers/mersenne_twister_engine.h"
|
||||||
|
#include "fuzzers/random_generator_engine.h"
|
||||||
#include "src/utils/hash.h"
|
#include "src/utils/hash.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
|
@ -25,19 +27,6 @@ namespace fuzzers {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
/// Generate integer from uniform distribution
|
|
||||||
/// @tparam I - integer type
|
|
||||||
/// @param engine - random number engine to use
|
|
||||||
/// @param lower - Lower bound of integer generated
|
|
||||||
/// @param upper - Upper bound of integer generated
|
|
||||||
/// @returns i, where lower <= i < upper
|
|
||||||
template <typename I>
|
|
||||||
I RandomUInt(std::mt19937_64* engine, I lower, I upper) {
|
|
||||||
assert(lower < upper && "|lower| must be stictly less than |upper|");
|
|
||||||
|
|
||||||
return std::uniform_int_distribution<I>(lower, upper - 1)(*engine);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Calculate the hash for the contents of a c-style data buffer
|
/// Calculate the hash for the contents of a c-style data buffer
|
||||||
/// This is intentionally not implemented as a generic override of HashCombine
|
/// This is intentionally not implemented as a generic override of HashCombine
|
||||||
/// in "src/utils/hash.h", because it conflicts with the vardiac override for
|
/// in "src/utils/hash.h", because it conflicts with the vardiac override for
|
||||||
|
@ -56,55 +45,58 @@ size_t HashBuffer(const uint8_t* data, const size_t size) {
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
RandomGenerator::RandomGenerator(uint64_t seed) : engine_(seed) {}
|
RandomGenerator::RandomGenerator(std::unique_ptr<RandomGeneratorEngine> engine)
|
||||||
|
: engine_(std::move(engine)) {}
|
||||||
|
|
||||||
RandomGenerator::RandomGenerator(const uint8_t* data, size_t size)
|
RandomGenerator::RandomGenerator(uint64_t seed)
|
||||||
: engine_(RandomGenerator::CalculateSeed(data, size)) {
|
: RandomGenerator(std::make_unique<MersenneTwisterEngine>(seed)) {}
|
||||||
assert(data != nullptr && "|data| must be !nullptr");
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t RandomGenerator::GetUInt32(uint32_t lower, uint32_t upper) {
|
uint32_t RandomGenerator::GetUInt32(uint32_t lower, uint32_t upper) {
|
||||||
return RandomUInt(&engine_, lower, upper);
|
assert(lower < upper && "|lower| must be strictly less than |upper|");
|
||||||
|
return engine_->RandomUInt32(lower, upper);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t RandomGenerator::GetUInt32(uint32_t bound) {
|
uint32_t RandomGenerator::GetUInt32(uint32_t bound) {
|
||||||
assert(bound > 0 && "|bound| must be greater than 0");
|
assert(bound > 0 && "|bound| must be greater than 0");
|
||||||
return RandomUInt(&engine_, 0u, bound);
|
return engine_->RandomUInt32(0u, bound);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t RandomGenerator::GetUInt64(uint64_t lower, uint64_t upper) {
|
uint64_t RandomGenerator::GetUInt64(uint64_t lower, uint64_t upper) {
|
||||||
return RandomUInt(&engine_, lower, upper);
|
assert(lower < upper && "|lower| must be strictly less than |upper|");
|
||||||
|
return engine_->RandomUInt64(lower, upper);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t RandomGenerator::GetUInt64(uint64_t bound) {
|
uint64_t RandomGenerator::GetUInt64(uint64_t bound) {
|
||||||
assert(bound > 0 && "|bound| must be greater than 0");
|
assert(bound > 0 && "|bound| must be greater than 0");
|
||||||
return RandomUInt(&engine_, static_cast<uint64_t>(0), bound);
|
return engine_->RandomUInt64(static_cast<uint64_t>(0), bound);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t RandomGenerator::GetByte() {
|
uint8_t RandomGenerator::GetByte() {
|
||||||
return std::independent_bits_engine<std::mt19937_64, 8, uint8_t>(engine_)();
|
uint8_t result;
|
||||||
|
engine_->RandomNBytes(&result, 1);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t RandomGenerator::Get4Bytes() {
|
uint32_t RandomGenerator::Get4Bytes() {
|
||||||
return std::independent_bits_engine<std::mt19937_64, 32, uint32_t>(engine_)();
|
uint32_t result;
|
||||||
|
engine_->RandomNBytes(reinterpret_cast<uint8_t*>(&result), 4);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RandomGenerator::GetNBytes(uint8_t* dest, size_t n) {
|
void RandomGenerator::GetNBytes(uint8_t* dest, size_t n) {
|
||||||
assert(dest && "|dest| must not be nullptr");
|
assert(dest && "|dest| must not be nullptr");
|
||||||
std::generate(
|
engine_->RandomNBytes(dest, n);
|
||||||
dest, dest + n,
|
|
||||||
std::independent_bits_engine<std::mt19937_64, 8, uint8_t>(engine_));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RandomGenerator::GetBool() {
|
bool RandomGenerator::GetBool() {
|
||||||
return RandomUInt(&engine_, 0u, 2u);
|
return engine_->RandomUInt32(0u, 2u);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RandomGenerator::GetWeightedBool(uint32_t percentage) {
|
bool RandomGenerator::GetWeightedBool(uint32_t percentage) {
|
||||||
static const uint32_t kMaxPercentage = 100;
|
static const uint32_t kMaxPercentage = 100;
|
||||||
assert(percentage <= kMaxPercentage &&
|
assert(percentage <= kMaxPercentage &&
|
||||||
"|percentage| needs to be within [0, 100]");
|
"|percentage| needs to be within [0, 100]");
|
||||||
return RandomUInt(&engine_, 0u, kMaxPercentage) < percentage;
|
return engine_->RandomUInt32(0u, kMaxPercentage) < percentage;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t RandomGenerator::CalculateSeed(const uint8_t* data, size_t size) {
|
uint64_t RandomGenerator::CalculateSeed(const uint8_t* data, size_t size) {
|
||||||
|
@ -119,16 +111,14 @@ uint64_t RandomGenerator::CalculateSeed(const uint8_t* data, size_t size) {
|
||||||
static const int64_t kHashDesiredMinBytes = 4;
|
static const int64_t kHashDesiredMinBytes = 4;
|
||||||
// Maximum number of bytes we want to use in the hash.
|
// Maximum number of bytes we want to use in the hash.
|
||||||
static const int64_t kHashDesiredMaxBytes = 32;
|
static const int64_t kHashDesiredMaxBytes = 32;
|
||||||
int64_t size_i64 = static_cast<int64_t>(size);
|
auto size_i64 = static_cast<int64_t>(size);
|
||||||
int64_t hash_begin_i64 =
|
auto hash_begin_i64 =
|
||||||
std::min(kHashDesiredLeadingSkipBytes,
|
std::min(kHashDesiredLeadingSkipBytes,
|
||||||
std::max<int64_t>(size_i64 - kHashDesiredMinBytes, 0));
|
std::max<int64_t>(size_i64 - kHashDesiredMinBytes, 0));
|
||||||
int64_t hash_end_i64 =
|
auto hash_end_i64 = std::min(hash_begin_i64 + kHashDesiredMaxBytes, size_i64);
|
||||||
std::min(hash_begin_i64 + kHashDesiredMaxBytes, size_i64);
|
auto hash_begin = static_cast<size_t>(hash_begin_i64);
|
||||||
size_t hash_begin = static_cast<size_t>(hash_begin_i64);
|
auto hash_size = static_cast<size_t>(hash_end_i64) - hash_begin;
|
||||||
size_t hash_size = static_cast<size_t>(hash_end_i64) - hash_begin;
|
|
||||||
return HashBuffer(data + hash_begin, hash_size);
|
return HashBuffer(data + hash_begin, hash_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace fuzzers
|
} // namespace fuzzers
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
|
@ -15,23 +15,25 @@
|
||||||
#ifndef FUZZERS_RANDOM_GENERATOR_H_
|
#ifndef FUZZERS_RANDOM_GENERATOR_H_
|
||||||
#define FUZZERS_RANDOM_GENERATOR_H_
|
#define FUZZERS_RANDOM_GENERATOR_H_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <random>
|
#include <random>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "fuzzers/random_generator_engine.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace fuzzers {
|
namespace fuzzers {
|
||||||
|
|
||||||
/// Pseudo random generator utility class for fuzzing
|
/// Pseudo random generator utility class for fuzzing
|
||||||
class RandomGenerator {
|
class RandomGenerator {
|
||||||
public:
|
public:
|
||||||
/// @brief Initializes the internal engine
|
/// @brief Initializes using provided engine
|
||||||
/// @param seed - seed value passed to engine
|
/// @param engine - engine implementation to use
|
||||||
explicit RandomGenerator(uint64_t seed);
|
explicit RandomGenerator(std::unique_ptr<RandomGeneratorEngine> engine);
|
||||||
|
|
||||||
/// @brief Wrapper that invokes CalculateSeed for caller
|
/// @brief Creates a MersenneTwisterEngine and initializes using that
|
||||||
/// @param data - data fuzzer to calculate seed from
|
/// @param seed - seed value to use for engine
|
||||||
/// @param size - size of data buffer
|
explicit RandomGenerator(uint64_t seed);
|
||||||
explicit RandomGenerator(const uint8_t* data, size_t size);
|
|
||||||
|
|
||||||
~RandomGenerator() = default;
|
~RandomGenerator() = default;
|
||||||
RandomGenerator(RandomGenerator&&) = default;
|
RandomGenerator(RandomGenerator&&) = default;
|
||||||
|
@ -70,7 +72,7 @@ class RandomGenerator {
|
||||||
|
|
||||||
/// Get N bytes of pseudo-random data
|
/// Get N bytes of pseudo-random data
|
||||||
/// @param dest - memory location to store data
|
/// @param dest - memory location to store data
|
||||||
/// @param n - number of bytes of data to generate
|
/// @param n - number of bytes of data to get
|
||||||
void GetNBytes(uint8_t* dest, size_t n);
|
void GetNBytes(uint8_t* dest, size_t n);
|
||||||
|
|
||||||
/// Get random bool with even odds
|
/// Get random bool with even odds
|
||||||
|
@ -83,6 +85,14 @@ class RandomGenerator {
|
||||||
/// of the time.
|
/// of the time.
|
||||||
bool GetWeightedBool(uint32_t percentage);
|
bool GetWeightedBool(uint32_t percentage);
|
||||||
|
|
||||||
|
/// Returns a randomly-chosen element from vector v.
|
||||||
|
/// @param v - the vector from which the random element will be selected.
|
||||||
|
/// @return a random element of vector v.
|
||||||
|
template <typename T>
|
||||||
|
inline T GetRandomElement(const std::vector<T>& v) {
|
||||||
|
return v[GetUInt64(0, v.size())];
|
||||||
|
}
|
||||||
|
|
||||||
/// Calculate a seed value based on a blob of data.
|
/// Calculate a seed value based on a blob of data.
|
||||||
/// Currently hashes bytes near the front of the buffer, after skipping N
|
/// Currently hashes bytes near the front of the buffer, after skipping N
|
||||||
/// bytes.
|
/// bytes.
|
||||||
|
@ -90,21 +100,13 @@ class RandomGenerator {
|
||||||
/// @param size - number of elements in |data|, must be > 0
|
/// @param size - number of elements in |data|, must be > 0
|
||||||
static uint64_t CalculateSeed(const uint8_t* data, size_t size);
|
static uint64_t CalculateSeed(const uint8_t* data, size_t size);
|
||||||
|
|
||||||
/// Returns a randomly-chosen element from vector v.
|
|
||||||
/// @param v - the vector from which the random element will be selected.
|
|
||||||
/// @return a random element of vector v.
|
|
||||||
template <typename T>
|
|
||||||
inline T GetRandomElement(const std::vector<T>& v) {
|
|
||||||
return v[GetUInt64(0, v.size() - 1)];
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::mt19937_64 engine_;
|
|
||||||
|
|
||||||
// Disallow copy & assign
|
// Disallow copy & assign
|
||||||
RandomGenerator(const RandomGenerator&) = delete;
|
RandomGenerator(const RandomGenerator&) = delete;
|
||||||
RandomGenerator& operator=(const RandomGenerator&) = delete;
|
RandomGenerator& operator=(const RandomGenerator&) = delete;
|
||||||
|
|
||||||
|
std::unique_ptr<RandomGeneratorEngine> engine_;
|
||||||
|
|
||||||
}; // class RandomGenerator
|
}; // class RandomGenerator
|
||||||
|
|
||||||
} // namespace fuzzers
|
} // namespace fuzzers
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
// Copyright 2021 The Tint 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 "fuzzers/random_generator_engine.h"
|
||||||
|
|
||||||
|
namespace tint {
|
||||||
|
namespace fuzzers {
|
||||||
|
|
||||||
|
// Not in header to avoid weak vtable warnings from clang
|
||||||
|
RandomGeneratorEngine::RandomGeneratorEngine() = default;
|
||||||
|
RandomGeneratorEngine::~RandomGeneratorEngine() = default;
|
||||||
|
RandomGeneratorEngine::RandomGeneratorEngine(RandomGeneratorEngine&&) = default;
|
||||||
|
|
||||||
|
} // namespace fuzzers
|
||||||
|
} // namespace tint
|
|
@ -0,0 +1,58 @@
|
||||||
|
// Copyright 2021 The Tint 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.
|
||||||
|
|
||||||
|
#ifndef FUZZERS_RANDOM_GENERATOR_ENGINE_H_
|
||||||
|
#define FUZZERS_RANDOM_GENERATOR_ENGINE_H_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <random>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace tint {
|
||||||
|
namespace fuzzers {
|
||||||
|
|
||||||
|
/// Wrapper interface around STL random number engine
|
||||||
|
class RandomGeneratorEngine {
|
||||||
|
public:
|
||||||
|
RandomGeneratorEngine();
|
||||||
|
virtual ~RandomGeneratorEngine();
|
||||||
|
RandomGeneratorEngine(RandomGeneratorEngine&&);
|
||||||
|
|
||||||
|
/// Generate random uint32_t value from uniform distribution.
|
||||||
|
/// @param lower - lower bound of integer generated
|
||||||
|
/// @param upper - upper bound of integer generated
|
||||||
|
/// @returns i, where lower <= i < upper
|
||||||
|
virtual uint32_t RandomUInt32(uint32_t lower, uint32_t upper) = 0;
|
||||||
|
|
||||||
|
/// Get random uint64_t value from uniform distribution.
|
||||||
|
/// @param lower - lower bound of integer generated
|
||||||
|
/// @param upper - upper bound of integer generated
|
||||||
|
/// @returns i, where lower <= i < upper
|
||||||
|
virtual uint64_t RandomUInt64(uint64_t lower, uint64_t upper) = 0;
|
||||||
|
|
||||||
|
/// Get N bytes of pseudo-random data
|
||||||
|
/// @param dest - memory location to store data
|
||||||
|
/// @param n - number of bytes of data to generate
|
||||||
|
virtual void RandomNBytes(uint8_t* dest, size_t n) = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Disallow copy & assign
|
||||||
|
RandomGeneratorEngine(const RandomGeneratorEngine&) = delete;
|
||||||
|
RandomGeneratorEngine& operator=(const RandomGeneratorEngine&) = delete;
|
||||||
|
}; // class RandomGeneratorEngine
|
||||||
|
|
||||||
|
} // namespace fuzzers
|
||||||
|
} // namespace tint
|
||||||
|
|
||||||
|
#endif // FUZZERS_RANDOM_GENERATOR_ENGINE_H_
|
|
@ -0,0 +1,202 @@
|
||||||
|
// Copyright 2021 The Tint 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 "fuzzers/random_generator.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
#include "fuzzers/mersenne_twister_engine.h"
|
||||||
|
|
||||||
|
namespace tint {
|
||||||
|
namespace fuzzers {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
/// Implementation of RandomGeneratorEngine that just returns a stream of
|
||||||
|
/// monotonically increasing numbers.
|
||||||
|
class MonotonicEngine : public RandomGeneratorEngine {
|
||||||
|
public:
|
||||||
|
uint32_t RandomUInt32(uint32_t, uint32_t) override { return next_++; }
|
||||||
|
|
||||||
|
uint64_t RandomUInt64(uint64_t, uint64_t) override { return next_++; }
|
||||||
|
|
||||||
|
void RandomNBytes(uint8_t*, size_t) override {
|
||||||
|
assert(false && "MonotonicDelegate does not implement RandomNBytes");
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t next_ = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RandomGeneratorTest : public testing::Test {
|
||||||
|
public:
|
||||||
|
void SetUp() override { rng_ = std::make_unique<RandomGenerator>(0); }
|
||||||
|
|
||||||
|
void TearDown() override {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::unique_ptr<RandomGenerator> rng_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
TEST_F(RandomGeneratorTest, GetUInt32ReversedBoundsCrashes) {
|
||||||
|
EXPECT_DEATH(rng_->GetUInt32(10, 5), ".*");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RandomGeneratorTest, GetUInt32EmptyBoundsCrashes) {
|
||||||
|
EXPECT_DEATH(rng_->GetUInt32(5, 5), ".*");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RandomGeneratorTest, GetUInt32ZeroBoundCrashes) {
|
||||||
|
EXPECT_DEATH(rng_->GetUInt32(0u), ".*");
|
||||||
|
}
|
||||||
|
#endif // NDEBUG
|
||||||
|
|
||||||
|
TEST_F(RandomGeneratorTest, GetUInt32SingularReturnsOneValue) {
|
||||||
|
{
|
||||||
|
uint32_t result = rng_->GetUInt32(5u, 6u);
|
||||||
|
ASSERT_EQ(5u, result);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
uint32_t result = rng_->GetUInt32(1u);
|
||||||
|
ASSERT_EQ(0u, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RandomGeneratorTest, GetUInt32StaysInBounds) {
|
||||||
|
{
|
||||||
|
uint32_t result = rng_->GetUInt32(5u, 10u);
|
||||||
|
ASSERT_LE(5u, result);
|
||||||
|
ASSERT_GT(10u, result);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
uint32_t result = rng_->GetUInt32(10u);
|
||||||
|
ASSERT_LE(0u, result);
|
||||||
|
ASSERT_GT(10u, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
TEST_F(RandomGeneratorTest, GetUInt64ReversedBoundsCrashes) {
|
||||||
|
EXPECT_DEATH(rng_->GetUInt64(10, 5), ".*");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RandomGeneratorTest, GetUInt64EmptyBoundsCrashes) {
|
||||||
|
EXPECT_DEATH(rng_->GetUInt64(5, 5), ".*");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RandomGeneratorTest, GetUInt64ZeroBoundCrashes) {
|
||||||
|
EXPECT_DEATH(rng_->GetUInt64(0u), ".*");
|
||||||
|
}
|
||||||
|
#endif // NDEBUG
|
||||||
|
|
||||||
|
TEST_F(RandomGeneratorTest, GetUInt64SingularReturnsOneValue) {
|
||||||
|
{
|
||||||
|
uint64_t result = rng_->GetUInt64(5u, 6u);
|
||||||
|
ASSERT_EQ(5u, result);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
uint64_t result = rng_->GetUInt64(1u);
|
||||||
|
ASSERT_EQ(0u, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RandomGeneratorTest, GetUInt64StaysInBounds) {
|
||||||
|
{
|
||||||
|
uint64_t result = rng_->GetUInt64(5u, 10u);
|
||||||
|
ASSERT_LE(5u, result);
|
||||||
|
ASSERT_GT(10u, result);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
uint64_t result = rng_->GetUInt64(10u);
|
||||||
|
ASSERT_LE(0u, result);
|
||||||
|
ASSERT_GT(10u, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RandomGeneratorTest, GetByte) {
|
||||||
|
rng_->GetByte();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
TEST_F(RandomGeneratorTest, GetNBytesNullDataBufferCrashes) {
|
||||||
|
EXPECT_DEATH(rng_->GetNBytes(nullptr, 5), ".*");
|
||||||
|
}
|
||||||
|
#endif // NDEBUG
|
||||||
|
|
||||||
|
TEST_F(RandomGeneratorTest, GetNBytes) {
|
||||||
|
std::vector<uint8_t> data;
|
||||||
|
for (uint32_t i = 25; i < 1000u; i = i + 25) {
|
||||||
|
data.resize(i);
|
||||||
|
rng_->GetNBytes(data.data(), data.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RandomGeneratorTest, GetBool) {
|
||||||
|
rng_->GetBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RandomGeneratorTest, GetWeightedBoolZeroAlwaysFalse) {
|
||||||
|
ASSERT_FALSE(rng_->GetWeightedBool(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RandomGeneratorTest, GetWeightedBoolHundredAlwaysTrue) {
|
||||||
|
ASSERT_TRUE(rng_->GetWeightedBool(100));
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
TEST_F(RandomGeneratorTest, GetWeightedBoolAboveHundredCrashes) {
|
||||||
|
EXPECT_DEATH(rng_->GetWeightedBool(101), ".*");
|
||||||
|
EXPECT_DEATH(rng_->GetWeightedBool(500), ".*");
|
||||||
|
}
|
||||||
|
#endif // NDEBUG
|
||||||
|
|
||||||
|
TEST_F(RandomGeneratorTest, GetWeightedBool) {
|
||||||
|
for (uint32_t i = 0; i <= 100; i++) {
|
||||||
|
rng_ =
|
||||||
|
std::make_unique<RandomGenerator>(std::make_unique<MonotonicEngine>());
|
||||||
|
for (uint32_t j = 0; j <= 100; j++) {
|
||||||
|
if (j < i) {
|
||||||
|
ASSERT_TRUE(rng_->GetWeightedBool(i));
|
||||||
|
} else {
|
||||||
|
ASSERT_FALSE(rng_->GetWeightedBool(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
TEST_F(RandomGeneratorTest, GetRandomElementEmptyVectorCrashes) {
|
||||||
|
std::vector<uint8_t> v;
|
||||||
|
EXPECT_DEATH(rng_->GetRandomElement(v), ".*");
|
||||||
|
}
|
||||||
|
#endif // NDEBUG
|
||||||
|
|
||||||
|
TEST_F(RandomGeneratorTest, GetRandomElement) {
|
||||||
|
std::vector<uint32_t> v;
|
||||||
|
for (uint32_t i = 25; i < 100u; i = i + 25) {
|
||||||
|
rng_ =
|
||||||
|
std::make_unique<RandomGenerator>(std::make_unique<MonotonicEngine>());
|
||||||
|
v.resize(i);
|
||||||
|
std::iota(v.begin(), v.end(), 0);
|
||||||
|
for (uint32_t j = 0; j < i; j++) {
|
||||||
|
EXPECT_EQ(j, rng_->GetRandomElement(v));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
} // namespace fuzzers
|
||||||
|
} // namespace tint
|
|
@ -34,7 +34,7 @@ if (build_with_chromium) {
|
||||||
|
|
||||||
deps = [
|
deps = [
|
||||||
":tint_ast_fuzzer_proto",
|
":tint_ast_fuzzer_proto",
|
||||||
"${tint_root_dir}/fuzzers:tint_fuzzer_common",
|
"${tint_root_dir}/fuzzers:tint_fuzzer_common_src",
|
||||||
"//third_party/protobuf:protobuf_full",
|
"//third_party/protobuf:protobuf_full",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,9 @@ add_custom_command(
|
||||||
COMMENT "Generate protobuf sources from proto definition file.")
|
COMMENT "Generate protobuf sources from proto definition file.")
|
||||||
|
|
||||||
set(LIBTINT_AST_FUZZER_SOURCES
|
set(LIBTINT_AST_FUZZER_SOURCES
|
||||||
|
../mersenne_twister_engine.h
|
||||||
../random_generator.h
|
../random_generator.h
|
||||||
|
../random_generator_engine.h
|
||||||
mutation.h
|
mutation.h
|
||||||
mutation_finder.h
|
mutation_finder.h
|
||||||
mutation_finders/replace_identifiers.h
|
mutation_finders/replace_identifiers.h
|
||||||
|
@ -48,7 +50,9 @@ set(LIBTINT_AST_FUZZER_SOURCES
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/protobufs/tint_ast_fuzzer.pb.h)
|
${CMAKE_CURRENT_BINARY_DIR}/protobufs/tint_ast_fuzzer.pb.h)
|
||||||
|
|
||||||
set(LIBTINT_AST_FUZZER_SOURCES ${LIBTINT_AST_FUZZER_SOURCES}
|
set(LIBTINT_AST_FUZZER_SOURCES ${LIBTINT_AST_FUZZER_SOURCES}
|
||||||
|
../mersenne_twister_engine.cc
|
||||||
../random_generator.cc
|
../random_generator.cc
|
||||||
|
../random_generator_engine.cc
|
||||||
mutation.cc
|
mutation.cc
|
||||||
mutation_finder.cc
|
mutation_finder.cc
|
||||||
mutation_finders/replace_identifiers.cc
|
mutation_finders/replace_identifiers.cc
|
||||||
|
|
|
@ -22,7 +22,7 @@ if (build_with_chromium) {
|
||||||
"${tint_root_dir}/src:tint_common_config",
|
"${tint_root_dir}/src:tint_common_config",
|
||||||
]
|
]
|
||||||
|
|
||||||
deps = [ "${tint_root_dir}/fuzzers:tint_fuzzer_common" ]
|
deps = [ "${tint_root_dir}/fuzzers:tint_fuzzer_common_src" ]
|
||||||
|
|
||||||
sources = [
|
sources = [
|
||||||
"cli.cc",
|
"cli.cc",
|
||||||
|
|
|
@ -21,8 +21,12 @@ function(add_tint_regex_fuzzer NAME)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
set(LIBTINT_REGEX_FUZZER_SOURCES
|
set(LIBTINT_REGEX_FUZZER_SOURCES
|
||||||
|
../mersenne_twister_engine.cc
|
||||||
|
../mersenne_twister_engine.h
|
||||||
../random_generator.cc
|
../random_generator.cc
|
||||||
../random_generator.h
|
../random_generator.h
|
||||||
|
../random_generator_engine.cc
|
||||||
|
../random_generator_engine.h
|
||||||
wgsl_mutator.cc
|
wgsl_mutator.cc
|
||||||
wgsl_mutator.h)
|
wgsl_mutator.h)
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,9 @@
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
set(FUZZER_SOURCES
|
set(FUZZER_SOURCES
|
||||||
|
../mersenne_twister_engine.cc
|
||||||
../random_generator.cc
|
../random_generator.cc
|
||||||
|
../random_generator_engine.cc
|
||||||
cli.cc
|
cli.cc
|
||||||
fuzzer.cc
|
fuzzer.cc
|
||||||
mutator.cc
|
mutator.cc
|
||||||
|
@ -24,7 +26,9 @@ set(FUZZER_SOURCES
|
||||||
util.cc)
|
util.cc)
|
||||||
|
|
||||||
set(FUZZER_SOURCES ${FUZZER_SOURCES}
|
set(FUZZER_SOURCES ${FUZZER_SOURCES}
|
||||||
|
../mersenne_twister_engine.h
|
||||||
../random_generator.h
|
../random_generator.h
|
||||||
|
../random_generator_engine.h
|
||||||
cli.h
|
cli.h
|
||||||
mutator.h
|
mutator.h
|
||||||
mutator_cache.h
|
mutator_cache.h
|
||||||
|
@ -76,7 +80,9 @@ add_tint_spirv_tools_fuzzer(tint_spirv_tools_spv_writer_fuzzer)
|
||||||
add_tint_spirv_tools_fuzzer(tint_spirv_tools_wgsl_writer_fuzzer)
|
add_tint_spirv_tools_fuzzer(tint_spirv_tools_wgsl_writer_fuzzer)
|
||||||
|
|
||||||
set(DEBUGGER_SOURCES
|
set(DEBUGGER_SOURCES
|
||||||
|
../mersenne_twister_engine.cc
|
||||||
../random_generator.cc
|
../random_generator.cc
|
||||||
|
../random_generator_engine.cc
|
||||||
cli.cc
|
cli.cc
|
||||||
mutator.cc
|
mutator.cc
|
||||||
mutator_debugger.cc
|
mutator_debugger.cc
|
||||||
|
@ -86,7 +92,9 @@ set(DEBUGGER_SOURCES
|
||||||
util.cc)
|
util.cc)
|
||||||
|
|
||||||
set(DEBUGGER_SOURCES ${DEBUGGER_SOURCES}
|
set(DEBUGGER_SOURCES ${DEBUGGER_SOURCES}
|
||||||
|
../mersenne_twister_engine.h
|
||||||
../random_generator.h
|
../random_generator.h
|
||||||
|
../random_generator_engine.h
|
||||||
cli.h
|
cli.h
|
||||||
mutator.h
|
mutator.h
|
||||||
spirv_fuzz_mutator.h
|
spirv_fuzz_mutator.h
|
||||||
|
|
|
@ -409,9 +409,9 @@ libtint_source_set("libtint_core_all_src") {
|
||||||
"sem/storage_texture_type.h",
|
"sem/storage_texture_type.h",
|
||||||
"sem/switch_statement.h",
|
"sem/switch_statement.h",
|
||||||
"sem/texture_type.h",
|
"sem/texture_type.h",
|
||||||
|
"sem/type.h",
|
||||||
"sem/type_constructor.h",
|
"sem/type_constructor.h",
|
||||||
"sem/type_conversion.h",
|
"sem/type_conversion.h",
|
||||||
"sem/type.h",
|
|
||||||
"sem/type_manager.h",
|
"sem/type_manager.h",
|
||||||
"sem/type_mappings.h",
|
"sem/type_mappings.h",
|
||||||
"sem/u32_type.h",
|
"sem/u32_type.h",
|
||||||
|
@ -581,12 +581,12 @@ libtint_source_set("libtint_sem_src") {
|
||||||
"sem/switch_statement.h",
|
"sem/switch_statement.h",
|
||||||
"sem/texture_type.cc",
|
"sem/texture_type.cc",
|
||||||
"sem/texture_type.h",
|
"sem/texture_type.h",
|
||||||
|
"sem/type.cc",
|
||||||
|
"sem/type.h",
|
||||||
"sem/type_constructor.cc",
|
"sem/type_constructor.cc",
|
||||||
"sem/type_constructor.h",
|
"sem/type_constructor.h",
|
||||||
"sem/type_conversion.cc",
|
"sem/type_conversion.cc",
|
||||||
"sem/type_conversion.h",
|
"sem/type_conversion.h",
|
||||||
"sem/type.cc",
|
|
||||||
"sem/type.h",
|
|
||||||
"sem/type_manager.cc",
|
"sem/type_manager.cc",
|
||||||
"sem/type_manager.h",
|
"sem/type_manager.h",
|
||||||
"sem/type_mappings.h",
|
"sem/type_mappings.h",
|
||||||
|
|
|
@ -1083,6 +1083,18 @@ if(${TINT_BUILD_TESTS})
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (${TINT_BUILD_FUZZERS})
|
||||||
|
list(APPEND TINT_TEST_SRCS
|
||||||
|
../fuzzers/mersenne_twister_engine.cc
|
||||||
|
../fuzzers/mersenne_twister_engine.h
|
||||||
|
../fuzzers/random_generator.cc
|
||||||
|
../fuzzers/random_generator.h
|
||||||
|
../fuzzers/random_generator_engine.cc
|
||||||
|
../fuzzers/random_generator_engine.h
|
||||||
|
../fuzzers/random_generator_test.cc
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
add_executable(tint_unittests ${TINT_TEST_SRCS})
|
add_executable(tint_unittests ${TINT_TEST_SRCS})
|
||||||
|
|
||||||
if(NOT MSVC)
|
if(NOT MSVC)
|
||||||
|
|
|
@ -169,9 +169,9 @@ tint_unittests_source_set("tint_unittests_ast_src") {
|
||||||
"../src/ast/function_test.cc",
|
"../src/ast/function_test.cc",
|
||||||
"../src/ast/group_decoration_test.cc",
|
"../src/ast/group_decoration_test.cc",
|
||||||
"../src/ast/i32_test.cc",
|
"../src/ast/i32_test.cc",
|
||||||
"../src/ast/index_accessor_expression_test.cc",
|
|
||||||
"../src/ast/identifier_expression_test.cc",
|
"../src/ast/identifier_expression_test.cc",
|
||||||
"../src/ast/if_statement_test.cc",
|
"../src/ast/if_statement_test.cc",
|
||||||
|
"../src/ast/index_accessor_expression_test.cc",
|
||||||
"../src/ast/int_literal_expression_test.cc",
|
"../src/ast/int_literal_expression_test.cc",
|
||||||
"../src/ast/interpolate_decoration_test.cc",
|
"../src/ast/interpolate_decoration_test.cc",
|
||||||
"../src/ast/intrinsic_texture_helper_test.cc",
|
"../src/ast/intrinsic_texture_helper_test.cc",
|
||||||
|
@ -213,7 +213,6 @@ tint_unittests_source_set("tint_unittests_ast_src") {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
tint_unittests_source_set("tint_unittests_diagnostic_src") {
|
tint_unittests_source_set("tint_unittests_diagnostic_src") {
|
||||||
sources = [
|
sources = [
|
||||||
"../src/diagnostic/formatter_test.cc",
|
"../src/diagnostic/formatter_test.cc",
|
||||||
|
@ -269,9 +268,7 @@ tint_unittests_source_set("tint_unittests_resolver_src") {
|
||||||
"../src/resolver/var_let_test.cc",
|
"../src/resolver/var_let_test.cc",
|
||||||
"../src/resolver/var_let_validation_test.cc",
|
"../src/resolver/var_let_validation_test.cc",
|
||||||
]
|
]
|
||||||
deps = [
|
deps = [ ":tint_unittests_ast_src" ]
|
||||||
":tint_unittests_ast_src",
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tint_unittests_source_set("tint_unittests_sem_src") {
|
tint_unittests_source_set("tint_unittests_sem_src") {
|
||||||
|
@ -397,9 +394,7 @@ tint_unittests_source_set("tint_unittests_spv_reader_src") {
|
||||||
"../src/reader/spirv/usage_test.cc",
|
"../src/reader/spirv/usage_test.cc",
|
||||||
]
|
]
|
||||||
|
|
||||||
deps = [
|
deps = [ "${tint_root_dir}/src:libtint_spv_reader_src" ]
|
||||||
"${tint_root_dir}/src:libtint_spv_reader_src",
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tint_unittests_source_set("tint_unittests_spv_writer_src") {
|
tint_unittests_source_set("tint_unittests_spv_writer_src") {
|
||||||
|
@ -524,9 +519,7 @@ tint_unittests_source_set("tint_unittests_wgsl_reader_src") {
|
||||||
"../src/reader/wgsl/token_test.cc",
|
"../src/reader/wgsl/token_test.cc",
|
||||||
]
|
]
|
||||||
|
|
||||||
deps = [
|
deps = [ "${tint_root_dir}/src:libtint_wgsl_reader_src" ]
|
||||||
"${tint_root_dir}/src:libtint_wgsl_reader_src",
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tint_unittests_source_set("tint_unittests_wgsl_writer_src") {
|
tint_unittests_source_set("tint_unittests_wgsl_writer_src") {
|
||||||
|
@ -705,9 +698,18 @@ tint_unittests_source_set("tint_unittests_core_src") {
|
||||||
"../src/traits_test.cc",
|
"../src/traits_test.cc",
|
||||||
]
|
]
|
||||||
|
|
||||||
deps = [
|
deps = [ ":tint_unittests_ast_src" ]
|
||||||
":tint_unittests_ast_src",
|
}
|
||||||
]
|
|
||||||
|
if (build_with_chromium) {
|
||||||
|
tint_unittests_source_set("tint_unittests_fuzzer_src") {
|
||||||
|
sources = [ "../fuzzers/random_generator_test.cc" ]
|
||||||
|
|
||||||
|
deps = [
|
||||||
|
":tint_unittests_core_src",
|
||||||
|
"${tint_root_dir}/fuzzers:tint_fuzzer_common_src",
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
source_set("tint_unittests_src") {
|
source_set("tint_unittests_src") {
|
||||||
|
@ -755,6 +757,10 @@ source_set("tint_unittests_src") {
|
||||||
deps += [ ":tint_unittests_glsl_writer_src" ]
|
deps += [ ":tint_unittests_glsl_writer_src" ]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (build_with_chromium) {
|
||||||
|
deps += [ ":tint_unittests_fuzzer_src" ]
|
||||||
|
}
|
||||||
|
|
||||||
configs += [ ":tint_unittests_config" ]
|
configs += [ ":tint_unittests_config" ]
|
||||||
|
|
||||||
if (build_with_chromium) {
|
if (build_with_chromium) {
|
||||||
|
|
Loading…
Reference in New Issue