Skip to content

Commit

Permalink
try
Browse files Browse the repository at this point in the history
  • Loading branch information
rui-mo committed Apr 12, 2024
1 parent 273955f commit 2faad2f
Show file tree
Hide file tree
Showing 10 changed files with 196 additions and 154 deletions.
3 changes: 1 addition & 2 deletions velox/expression/tests/ArgGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@ class DecimalArgGeneratorBase : public ArgGenerator {

// Return randomly selected pair of input types that produce the specified
// result type.
Inputs findInputs(const TypePtr& returnType, FuzzerGenerator& rng)
const;
Inputs findInputs(const TypePtr& returnType, FuzzerGenerator& rng) const;

const std::vector<TypePtr>& getAllTypes() const;

Expand Down
144 changes: 5 additions & 139 deletions velox/expression/tests/ExpressionFuzzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,134 +32,6 @@
namespace facebook::velox::test {
namespace {

class PlusMinusArgGenerator : public DecimalArgGeneratorBase {
public:
PlusMinusArgGenerator() {
initialize();
}

protected:
std::optional<std::pair<int, int>> toReturnType(int count, ...) override {
VELOX_CHECK_EQ(count, 4);
va_list args;
va_start(args, count);
int p1 = va_arg(args, int);
int s1 = va_arg(args, int);
int p2 = va_arg(args, int);
int s2 = va_arg(args, int);
va_end(args);

auto s = std::max(s1, s2);
auto p = std::min(38, std::max(p1 - s1, p2 - s2) + 1 + s);
return {{p, s}};
}
};

class MultiplyArgGenerator : public DecimalArgGeneratorBase {
public:
MultiplyArgGenerator() {
initialize();
}

protected:
std::optional<std::pair<int, int>> toReturnType(int count, ...) override {
VELOX_CHECK_EQ(count, 4);
va_list args;
va_start(args, count);
int p1 = va_arg(args, int);
int s1 = va_arg(args, int);
int p2 = va_arg(args, int);
int s2 = va_arg(args, int);
va_end(args);

if (s1 + s2 > 38) {
return std::nullopt;
}

auto p = std::min(38, p1 + p2);
auto s = s1 + s2;
return {{p, s}};
}
};

class DivideArgGenerator : public DecimalArgGeneratorBase {
public:
DivideArgGenerator() {
initialize();
}

protected:
std::optional<std::pair<int, int>> toReturnType(int count, ...) override {
VELOX_CHECK_EQ(count, 4);
va_list args;
va_start(args, count);
int p1 = va_arg(args, int);
int s1 = va_arg(args, int);
int p2 = va_arg(args, int);
int s2 = va_arg(args, int);
va_end(args);

if (s1 + s2 > 38) {
return std::nullopt;
}

auto p = std::min(38, p1 + s2 + std::max(0, s2 - s1));
auto s = std::max(s1, s2);
return {{p, s}};
}
};

class FloorAndRoundArgGenerator : public ArgGenerator {
public:
std::vector<TypePtr> generateArgs(
const exec::FunctionSignature& signature,
const TypePtr& returnType,
FuzzerGenerator& rng) override {
if (signature.argumentTypes().size() == 1) {
return generateSingleArg(returnType, rng);
} else {
VELOX_CHECK_EQ(2, signature.argumentTypes().size())
return generateTwoArgs(returnType);
}
}

private:
std::vector<TypePtr> generateSingleArg(
const TypePtr& returnType,
FuzzerGenerator& rng) {
auto [p, s] = getDecimalPrecisionScale(*returnType);

// p = p1 - s1 + min(s1, 1)
// s = 0
if (s != 0) {
return {};
}

const auto rand32 = [](FuzzerGenerator& rng) {
return boost::random::uniform_int_distribution<int32_t>()(rng);
};

auto s1 = rand32(rng) % (38 - p + 1);
if (s1 == 0) {
return {DECIMAL(p, 0)};
}

return {DECIMAL(p - 1 + s1, s1)};
}

std::vector<TypePtr> generateTwoArgs(const TypePtr& returnType) {
auto [p, s] = getDecimalPrecisionScale(*returnType);

// p = p1 + 1
// s = s1
if (p == 1 || p == s) {
return {};
}

return {DECIMAL(p - 1, s), INTEGER()};
}
};

using exec::SignatureBinder;
using exec::SignatureBinderBase;

Expand Down Expand Up @@ -658,22 +530,16 @@ ExpressionFuzzer::ExpressionFuzzer(
FunctionSignatureMap signatureMap,
size_t initialSeed,
const std::shared_ptr<VectorFuzzer>& vectorFuzzer,
const std::optional<ExpressionFuzzer::Options>& options)
const std::optional<ExpressionFuzzer::Options>& options,
const std::unordered_map<std::string, std::shared_ptr<ArgGenerator>>&
argGenerators)
: options_(options.value_or(Options())),
vectorFuzzer_(vectorFuzzer),
state{rng_, std::max(1, options_.maxLevelOfNesting)} {
state{rng_, std::max(1, options_.maxLevelOfNesting)},
argGenerators_(argGenerators) {
VELOX_CHECK(vectorFuzzer, "Vector fuzzer must be provided");
seed(initialSeed);

argGenerators_.emplace("plus", std::make_shared<PlusMinusArgGenerator>());
argGenerators_.emplace("minus", std::make_shared<PlusMinusArgGenerator>());
argGenerators_.emplace("multiply", std::make_shared<MultiplyArgGenerator>());
argGenerators_.emplace("divide", std::make_shared<DivideArgGenerator>());
argGenerators_.emplace(
"floor", std::make_shared<FloorAndRoundArgGenerator>());
argGenerators_.emplace(
"round", std::make_shared<FloorAndRoundArgGenerator>());

appendSpecialForms(signatureMap, options_.specialForms);
filterSignatures(
signatureMap, options_.useOnlyFunctions, options_.skipFunctions);
Expand Down
6 changes: 4 additions & 2 deletions velox/expression/tests/ExpressionFuzzer.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@
#include "velox/core/ITypedExpr.h"
#include "velox/core/QueryCtx.h"
#include "velox/expression/Expr.h"
#include "velox/expression/tests/ArgGenerator.h"
#include "velox/expression/tests/ExpressionVerifier.h"
#include "velox/expression/tests/utils/FuzzerToolkit.h"
#include "velox/functions/FunctionRegistry.h"
#include "velox/vector/fuzzer/VectorFuzzer.h"
#include "velox/vector/tests/utils/VectorMaker.h"
#include "velox/expression/tests/ArgGenerator.h"

namespace facebook::velox::test {

Expand Down Expand Up @@ -108,7 +108,9 @@ class ExpressionFuzzer {
FunctionSignatureMap signatureMap,
size_t initialSeed,
const std::shared_ptr<VectorFuzzer>& vectorFuzzer,
const std::optional<ExpressionFuzzer::Options>& options = std::nullopt);
const std::optional<ExpressionFuzzer::Options>& options = std::nullopt,
const std::unordered_map<std::string, std::shared_ptr<ArgGenerator>>&
argGenerators = {});

template <typename TFunc>
void registerFuncOverride(TFunc func, const std::string& name);
Expand Down
12 changes: 11 additions & 1 deletion velox/expression/tests/ExpressionFuzzerTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
#include <gtest/gtest.h>
#include <unordered_set>

#include "velox/expression/tests/ArgGenerator.h"
#include "velox/expression/tests/FuzzerRunner.h"
#include "velox/functions/prestosql/fuzzer/PlusMinusArgGenerator.h"
#include "velox/functions/prestosql/registration/RegistrationFunctions.h"

DEFINE_int64(
Expand All @@ -27,6 +29,8 @@ DEFINE_int64(
"Initial seed for random number generator used to reproduce previous "
"results (0 means start with random seed).");

using facebook::velox::exec::test;
using facebook::velox::test::ArgGenerator;
using facebook::velox::test::FuzzerRunner;

int main(int argc, char** argv) {
Expand Down Expand Up @@ -65,6 +69,12 @@ int main(int argc, char** argv) {
"regexp_extract_all",
"regexp_like",
};
std::unordered_map<std::string, std::shared_ptr<ArgGenerator>> argGenerators =
{std::make_shared<PlusMinusArgGenerator>(),
std::make_shared<MultiplyArgGenerator>(),
std::make_shared<DivideArgGenerator>(),
std::make_shared<FloorAndRoundArgGenerator>()};

size_t initialSeed = FLAGS_seed == 0 ? std::time(nullptr) : FLAGS_seed;
return FuzzerRunner::run(initialSeed, skipFunctions, {{}});
return FuzzerRunner::run(initialSeed, skipFunctions, {{}}, argGenerators);
}
7 changes: 5 additions & 2 deletions velox/expression/tests/ExpressionFuzzerVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,9 @@ RowVectorPtr wrapChildren(
ExpressionFuzzerVerifier::ExpressionFuzzerVerifier(
const FunctionSignatureMap& signatureMap,
size_t initialSeed,
const ExpressionFuzzerVerifier::Options& options)
const ExpressionFuzzerVerifier::Options& options,
const std::unordered_map<std::string, std::shared_ptr<ArgGenerator>>&
argGenerators)
: options_(options),
queryCtx_(std::make_shared<core::QueryCtx>(
nullptr,
Expand All @@ -98,7 +100,8 @@ ExpressionFuzzerVerifier::ExpressionFuzzerVerifier(
signatureMap,
initialSeed,
vectorFuzzer_,
options.expressionFuzzerOptions) {
options.expressionFuzzerOptions,
argGenerators) {
seed(initialSeed);

// Init stats and register listener.
Expand Down
4 changes: 3 additions & 1 deletion velox/expression/tests/ExpressionFuzzerVerifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ class ExpressionFuzzerVerifier {
ExpressionFuzzerVerifier(
const FunctionSignatureMap& signatureMap,
size_t initialSeed,
const Options& options);
const Options& options,
const std::unordered_map<std::string, std::shared_ptr<ArgGenerator>>&
argGenerators);

// This function starts the test that is performed by the
// ExpressionFuzzerVerifier which is generating random expressions and
Expand Down
13 changes: 9 additions & 4 deletions velox/expression/tests/FuzzerRunner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,22 +210,27 @@ ExpressionFuzzerVerifier::Options getExpressionFuzzerVerifierOptions(
int FuzzerRunner::run(
size_t seed,
const std::unordered_set<std::string>& skipFunctions,
const std::unordered_map<std::string, std::string>& queryConfigs) {
runFromGtest(seed, skipFunctions, queryConfigs);
const std::unordered_map<std::string, std::string>& queryConfigs,
const std::unordered_map<std::string, std::shared_ptr<ArgGenerator>>&
argGenerators) {
runFromGtest(seed, skipFunctions, queryConfigs, argGenerators);
return RUN_ALL_TESTS();
}

// static
void FuzzerRunner::runFromGtest(
size_t seed,
const std::unordered_set<std::string>& skipFunctions,
const std::unordered_map<std::string, std::string>& queryConfigs) {
const std::unordered_map<std::string, std::string>& queryConfigs,
const std::unordered_map<std::string, std::shared_ptr<ArgGenerator>>&
argGenerators) {
memory::MemoryManager::testingSetInstance({});
auto signatures = facebook::velox::getFunctionSignatures();
ExpressionFuzzerVerifier(
signatures,
seed,
getExpressionFuzzerVerifierOptions(skipFunctions, queryConfigs))
getExpressionFuzzerVerifierOptions(skipFunctions, queryConfigs),
argGenerators)
.go();
}
} // namespace facebook::velox::test
8 changes: 6 additions & 2 deletions velox/expression/tests/FuzzerRunner.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,16 @@ class FuzzerRunner {
static int run(
size_t seed,
const std::unordered_set<std::string>& skipFunctions,
const std::unordered_map<std::string, std::string>& queryConfigs);
const std::unordered_map<std::string, std::string>& queryConfigs,
const std::unordered_map<std::string, std::shared_ptr<ArgGenerator>>&
argGenerators);

static void runFromGtest(
size_t seed,
const std::unordered_set<std::string>& skipFunctions,
const std::unordered_map<std::string, std::string>& queryConfigs);
const std::unordered_map<std::string, std::string>& queryConfigs,
const std::unordered_map<std::string, std::shared_ptr<ArgGenerator>>&
argGenerators);
};

} // namespace facebook::velox::test
2 changes: 1 addition & 1 deletion velox/expression/tests/SparkExpressionFuzzerTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,5 +60,5 @@ int main(int argc, char** argv) {
std::unordered_map<std::string, std::string> queryConfigs = {
{facebook::velox::core::QueryConfig::kSparkPartitionId, "123"}};

return FuzzerRunner::run(FLAGS_seed, skipFunctions, queryConfigs);
return FuzzerRunner::run(FLAGS_seed, skipFunctions, queryConfigs, {});
}
Loading

0 comments on commit 2faad2f

Please sign in to comment.