Skip to content

Commit

Permalink
test: Add InputGenerator for TimestampWithTimeZone (facebookincubator…
Browse files Browse the repository at this point in the history
…#12481)

Summary:

This diff adds an implementation of AbstractInputGenerator for the TimestampWithTimeZone 
type.  It uses a random int64_t for the number of milliseconds (there may be overflow since we
only have 52 bits for the milliseconds but that doesn't matter since it's random anyway) and
selects a random time zone ID from a list of valid time zone IDs provided by TimeZoneMap.

Differential Revision: D70362561
  • Loading branch information
Kevin Wilfong authored and facebook-github-bot committed Feb 28, 2025
1 parent 27cb3c6 commit 06250b5
Show file tree
Hide file tree
Showing 9 changed files with 208 additions and 3 deletions.
5 changes: 4 additions & 1 deletion velox/functions/prestosql/types/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,11 @@ velox_link_libraries(
velox_functions_util
velox_functions_json
velox_functions_lib_date_time_formatter
velox_constrained_input_generators)
velox_constrained_input_generators
velox_presto_types_fuzzer_utils)

if(${VELOX_BUILD_TESTING})
add_subdirectory(tests)
endif()

add_subdirectory(fuzzer_utils)
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "velox/expression/CastExpr.h"
#include "velox/functions/lib/DateTimeFormatter.h"
#include "velox/functions/prestosql/types/TimestampWithTimeZoneType.h"
#include "velox/functions/prestosql/types/fuzzer_utils/TimestampWithTimeZoneInputGenerator.h"
#include "velox/type/tz/TimeZoneMap.h"

namespace facebook::velox {
Expand Down Expand Up @@ -287,8 +288,9 @@ class TimestampWithTimeZoneTypeFactories : public CustomTypeFactories {
}

AbstractInputGeneratorPtr getInputGenerator(
const InputGeneratorConfig& /*config*/) const override {
return nullptr;
const InputGeneratorConfig& config) const override {
return std::make_shared<fuzzer::TimestampWithTimeZoneInputGenerator>(
config.seed_, config.nullRatio_);
}
};
} // namespace
Expand Down
26 changes: 26 additions & 0 deletions velox/functions/prestosql/types/fuzzer_utils/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Copyright (c) Facebook, Inc. and its affiliates.
#
# 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.
velox_add_library(velox_presto_types_fuzzer_utils
TimestampWithTimeZoneInputGenerator.cpp)

velox_link_libraries(
velox_presto_types_fuzzer_utils
velox_type
velox_common_fuzzer_util
velox_presto_types
velox_type_tz)

if(${VELOX_BUILD_TESTING})
add_subdirectory(tests)
endif()
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* 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 "velox/functions/prestosql/types/fuzzer_utils/TimestampWithTimeZoneInputGenerator.h"

#include "velox/common/fuzzer/Utils.h"
#include "velox/functions/prestosql/types/TimestampWithTimeZoneType.h"
#include "velox/type/Variant.h"
#include "velox/type/tz/TimeZoneMap.h"

namespace facebook::velox::fuzzer {
TimestampWithTimeZoneInputGenerator::TimestampWithTimeZoneInputGenerator(
const size_t seed,
const double nullRatio)
: AbstractInputGenerator(
seed,
TIMESTAMP_WITH_TIME_ZONE(),
nullptr,
nullRatio),
timeZoneIds_(tz::getTimeZoneIDs()) {}

variant TimestampWithTimeZoneInputGenerator::generate() {
if (coinToss(rng_, nullRatio_)) {
return variant::null(type_->kind());
}

int16_t timeZoneId = timeZoneIds_
[boost::random::uniform_int_distribution<size_t>()(rng_) %
timeZoneIds_.size()];

return pack(
boost::random::uniform_int_distribution<int64_t>()(rng_), timeZoneId);
}
} // namespace facebook::velox::fuzzer
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* 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.
*/

#pragma once

#include "velox/type/Type.h"

namespace facebook::velox::fuzzer {
class TimestampWithTimeZoneInputGenerator : public AbstractInputGenerator {
public:
TimestampWithTimeZoneInputGenerator(
const size_t seed,
const double nullRatio);

variant generate() override;

private:
const std::vector<int16_t> timeZoneIds_;
};
} // namespace facebook::velox::fuzzer
28 changes: 28 additions & 0 deletions velox/functions/prestosql/types/fuzzer_utils/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copyright (c) Facebook, Inc. and its affiliates.
#
# 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.

add_executable(velox_presto_types_fuzzer_utils_test
TimestampWithTimeZoneInputGeneratorTest.cpp)

add_test(velox_presto_types_fuzzer_utils_test
velox_presto_types_fuzzer_utils_test)

target_link_libraries(
velox_presto_types_fuzzer_utils_test
velox_presto_types_fuzzer_utils
velox_presto_types
velox_type
velox_type_tz
GTest::gtest
GTest::gtest_main)
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* 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 "velox/functions/prestosql/types/fuzzer_utils/TimestampWithTimeZoneInputGenerator.h"

#include <gtest/gtest.h>

#include "velox/functions/prestosql/types/TimestampWithTimeZoneType.h"
#include "velox/type/Variant.h"
#include "velox/type/tz/TimeZoneMap.h"

namespace facebook::velox::fuzzer::test {

TEST(TimestampWithTimeZoneInputGeneratorTest, generate) {
TimestampWithTimeZoneInputGenerator generator(123456, 0.1);

size_t numTrials = 100;
for (size_t i = 0; i < numTrials; ++i) {
variant generated = generator.generate();

if (generated.isNull()) {
continue;
}

generated.checkIsKind(TypeKind::BIGINT);
const auto value = generated.value<TypeKind::BIGINT>();

// The value can be any random int64_t with the one restriction that the
// time zone should be valid.
auto zoneKey = unpackZoneKeyId(value);
EXPECT_NE(tz::locateZone(zoneKey), nullptr);
}
}
} // namespace facebook::velox::fuzzer::test
15 changes: 15 additions & 0 deletions velox/type/tz/TimeZoneMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,21 @@ int16_t getTimeZoneID(int32_t offsetMinutes) {
}
}

std::vector<int16_t> getTimeZoneIDs() {
const auto& timeZoneDatabase = getTimeZoneDatabase();

std::vector<int16_t> ids;
ids.reserve(timeZoneDatabase.size());

for (int16_t i = 0; i < timeZoneDatabase.size(); ++i) {
if (timeZoneDatabase[i] != nullptr) {
ids.push_back(i);
}
}

return ids;
}

TimeZone::seconds TimeZone::to_sys(
TimeZone::seconds timestamp,
TimeZone::TChoose choose) const {
Expand Down
4 changes: 4 additions & 0 deletions velox/type/tz/TimeZoneMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include <chrono>
#include <string>
#include <vector>

namespace facebook::velox::date {
class time_zone;
Expand Down Expand Up @@ -63,6 +64,9 @@ int16_t getTimeZoneID(std::string_view timeZone, bool failOnError = true);
/// [-14:00, +14:00] range.
int16_t getTimeZoneID(int32_t offsetMinutes);

/// Returns all valid time zone IDs.
std::vector<int16_t> getTimeZoneIDs();

// Validates that the time point can be safely used by the external date
// library.
template <typename T>
Expand Down

0 comments on commit 06250b5

Please sign in to comment.