blob: ccd9bd275e49a1c9e4a02360e8c8805387101ed6 [file] [log] [blame]
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/sys/fuzzing/common/options.h"
#include <gtest/gtest.h>
namespace fuzzing {
namespace {
TEST(OptionsTest, Set) {
// To ensure this test doesn't miss any options, it defines variables with the same name as the
// "snake_case" column in options.inc and then uses the `FUCHSIA_FUZZER_OPTIONS` macro.
uint32_t runs = 1000;
int64_t max_total_time = zx::sec(300).get();
uint32_t seed = 42;
uint64_t max_input_size = 1ULL << 10;
uint16_t mutation_depth = 8;
uint16_t dictionary_level = 2;
bool detect_exits = true;
bool detect_leaks = false;
int64_t run_limit = zx::sec(20).get();
uint64_t malloc_limit = 64ULL << 10;
uint64_t oom_limit = 1ULL << 20;
int64_t purge_interval = zx::sec(10).get();
int32_t malloc_exitcode = 1000;
int32_t death_exitcode = 1001;
int32_t leak_exitcode = 1002;
int32_t oom_exitcode = 1003;
int64_t pulse_interval = zx::sec(3).get();
bool debug = true;
bool print_final_stats = true;
bool use_value_profile = true;
SanitizerOptions sanitizer_options = {.name = "MYSAN_OPTIONS", .value = "key1=val1:key2=val2"};
OutputFlags output_flags = OutputFlags::LIBFUZZER;
Options options1;
#define FUCHSIA_FUZZER_OPTION(type, option, Option, default_value) options1.set_##option(option);
#include "src/sys/fuzzing/common/options.inc"
#undef FUCHSIA_FUZZER_OPTION
Options options2;
SetOptions(&options2, options1);
#define FUCHSIA_FUZZER_OPTION(type, option, Option, default_value) \
EXPECT_EQ(options2.option(), option);
#include "src/sys/fuzzing/common/options-literal.inc"
#undef FUCHSIA_FUZZER_OPTION
EXPECT_EQ(options2.sanitizer_options().name, sanitizer_options.name);
EXPECT_EQ(options2.sanitizer_options().value, sanitizer_options.value);
// Special case: sanitizer_options.name must end in "...SAN_OPTIONS" or it is ignored.
Options invalid;
SanitizerOptions bad_options = {.name = "BAD_OPTIONS", .value = "key3=val3:key4=val4"};
invalid.set_sanitizer_options(bad_options);
SetOptions(&options2, invalid);
EXPECT_EQ(options2.sanitizer_options().name, sanitizer_options.name);
EXPECT_EQ(options2.sanitizer_options().value, sanitizer_options.value);
}
TEST(OptionsTest, Copy) {
// Start with default values.
#define FUCHSIA_FUZZER_OPTION(type, option, Option, default_value) type option = default_value;
#include "src/sys/fuzzing/common/options.inc"
#undef FUCHSIA_FUZZER_OPTION
// Change some of the values, and set those.
runs = 1000;
seed = 42;
mutation_depth = 8;
detect_leaks = false;
malloc_limit = 64ULL << 10;
purge_interval = 10;
death_exitcode = 1001;
oom_exitcode = 1003;
debug = true;
sanitizer_options = {.name = "MYSAN_OPTIONS", .value = "key1=val1:key2=val2"};
Options options1;
options1.set_runs(runs);
options1.set_seed(seed);
options1.set_mutation_depth(mutation_depth);
options1.set_detect_leaks(detect_leaks);
options1.set_malloc_limit(malloc_limit);
options1.set_purge_interval(purge_interval);
options1.set_death_exitcode(death_exitcode);
options1.set_oom_exitcode(oom_exitcode);
options1.set_debug(debug);
options1.set_sanitizer_options(sanitizer_options);
// Copy, and verify the set values are copied and the missing values are defaulted.
auto options2 = CopyOptions(options1);
#define FUCHSIA_FUZZER_OPTION(type, option, Option, default_value) \
EXPECT_EQ(options2.option(), option);
#include "src/sys/fuzzing/common/options-literal.inc"
#undef FUCHSIA_FUZZER_OPTION
EXPECT_EQ(options2.sanitizer_options().name, sanitizer_options.name);
EXPECT_EQ(options2.sanitizer_options().value, sanitizer_options.value);
EXPECT_EQ(options2.output_flags(), output_flags);
}
TEST(OptionsTest, AddDefaults) {
// |AddDefaults| should add anything that is missing.
Options options1;
AddDefaults(&options1);
#define FUCHSIA_FUZZER_OPTION(type, option, Option, default_value) \
EXPECT_EQ(options1.option(), kDefault##Option);
#include "src/sys/fuzzing/common/options-literal.inc"
#undef FUCHSIA_FUZZER_OPTION
EXPECT_TRUE(options1.sanitizer_options().name.empty());
EXPECT_TRUE(options1.sanitizer_options().value.empty());
EXPECT_EQ(options1.output_flags(), OutputFlags());
// ...but it should not overwrite anything already there.
#define FUCHSIA_FUZZER_OPTION(type, option, Option, default_value) type option = default_value;
#include "src/sys/fuzzing/common/options.inc"
#undef FUCHSIA_FUZZER_OPTION
runs = 1000;
seed = 42;
mutation_depth = 8;
detect_leaks = false;
malloc_limit = 64ULL << 10;
purge_interval = 10;
death_exitcode = 1001;
oom_exitcode = 1003;
debug = true;
sanitizer_options = {.name = "MYSAN_OPTIONS", .value = "key1=val1:key2=val2"};
Options options2;
options2.set_runs(runs);
options2.set_seed(seed);
options2.set_mutation_depth(mutation_depth);
options2.set_detect_leaks(detect_leaks);
options2.set_malloc_limit(malloc_limit);
options2.set_purge_interval(purge_interval);
options2.set_death_exitcode(death_exitcode);
options2.set_oom_exitcode(oom_exitcode);
options2.set_debug(debug);
options2.set_sanitizer_options(sanitizer_options);
AddDefaults(&options2);
#define FUCHSIA_FUZZER_OPTION(type, option, Option, default_value) \
EXPECT_EQ(options2.option(), option);
#include "src/sys/fuzzing/common/options-literal.inc"
#undef FUCHSIA_FUZZER_OPTION
EXPECT_EQ(options2.sanitizer_options().name, sanitizer_options.name);
EXPECT_EQ(options2.sanitizer_options().value, sanitizer_options.value);
EXPECT_EQ(options1.output_flags(), output_flags);
}
} // namespace
} // namespace fuzzing