From 5d50be1df553aeae04123f06d6b8f93b01ed18e3 Mon Sep 17 00:00:00 2001 From: Adam Debreceni Date: Mon, 14 Oct 2024 17:34:30 +0200 Subject: [PATCH] Fix windows test --- core/include/minifi-cpp/utils/TimeUtil.h | 58 +++++++++++++++++++ extension-utils/CMakeLists.txt | 2 +- extensions/expression-language/Expression.cpp | 2 + extensions/systemd/CMakeLists.txt | 2 +- libminifi/CMakeLists.txt | 11 +++- libminifi/src/http/HTTPClient.cpp | 24 ++++++++ libminifi/src/utils/TimeUtil.cpp | 48 +++++++++++++++ libminifi/test/unit/CronTests.cpp | 6 +- libminifi/test/unit/SchedulingAgentTests.cpp | 1 - utils/include/utils/TimeUtil.h | 36 +----------- utils/src/http/HTTPClient.cpp | 2 - utils/src/utils/TimeUtil.cpp | 14 +---- 12 files changed, 149 insertions(+), 57 deletions(-) create mode 100644 core/include/minifi-cpp/utils/TimeUtil.h create mode 100644 libminifi/src/http/HTTPClient.cpp create mode 100644 libminifi/src/utils/TimeUtil.cpp diff --git a/core/include/minifi-cpp/utils/TimeUtil.h b/core/include/minifi-cpp/utils/TimeUtil.h new file mode 100644 index 0000000000..aa16657118 --- /dev/null +++ b/core/include/minifi-cpp/utils/TimeUtil.h @@ -0,0 +1,58 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 +#include + +namespace org::apache::nifi::minifi::utils::timeutils { + +/** + * Mockable clock classes + */ +class Clock { + public: + virtual ~Clock() = default; + virtual std::chrono::milliseconds timeSinceEpoch() const = 0; + virtual bool wait_until(std::condition_variable& cv, std::unique_lock& lck, std::chrono::milliseconds time, const std::function& pred) { + return cv.wait_for(lck, time - timeSinceEpoch(), pred); + } +}; + +class SteadyClock : public Clock { + public: + std::chrono::milliseconds timeSinceEpoch() const override { + return std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()); + } + + virtual std::chrono::time_point now() const { + return std::chrono::steady_clock::now(); + } +}; + +std::shared_ptr getClock(); + +// test-only utility to specify what clock to use +void setClock(std::shared_ptr clock); + +#ifdef WIN32 +void dateSetGlobalInstall(const std::string& install); +#endif + +} // namespace org::apache::nifi::minifi::utils::timeutils + diff --git a/extension-utils/CMakeLists.txt b/extension-utils/CMakeLists.txt index c08777b667..3ba365b2c2 100644 --- a/extension-utils/CMakeLists.txt +++ b/extension-utils/CMakeLists.txt @@ -16,7 +16,7 @@ target_link_libraries(minifi-extension-utils PUBLIC minifi-core) include(RangeV3) include(Asio) include(MagicEnum) -list(APPEND CORE_LIBRARIES ZLIB::ZLIB concurrentqueue RapidJSON spdlog Threads::Threads gsl-lite range-v3 expected-lite date::date date::tz asio magic_enum OpenSSL::Crypto OpenSSL::SSL CURL::libcurl RapidJSON) +list(APPEND CORE_LIBRARIES ZLIB::ZLIB concurrentqueue RapidJSON spdlog Threads::Threads gsl-lite range-v3 expected-lite asio magic_enum OpenSSL::Crypto OpenSSL::SSL CURL::libcurl RapidJSON) if(NOT WIN32) list(APPEND CORE_LIBRARIES OSSP::libuuid++) endif() diff --git a/extensions/expression-language/Expression.cpp b/extensions/expression-language/Expression.cpp index 4bf00fa614..3f53915dd5 100644 --- a/extensions/expression-language/Expression.cpp +++ b/extensions/expression-language/Expression.cpp @@ -34,6 +34,7 @@ #include "utils/OsUtils.h" #include "expression/Expression.h" #include "utils/RegexUtils.h" +#include "utils/TimeUtil.h" #ifdef WIN32 #pragma comment(lib, "wldap32.lib" ) @@ -1634,6 +1635,7 @@ Expression Expression::make_aggregate(const std::function global_clock{std::make_shared()}; + +std::shared_ptr getClock() { + std::lock_guard lock(global_clock_mtx); + return global_clock; +} + +// test-only utility to specify what clock to use +void setClock(std::shared_ptr clock) { + std::lock_guard lock(global_clock_mtx); + global_clock = std::move(clock); +} + +#ifdef WIN32 +void dateSetGlobalInstall(const std::string& install) { + date::set_install(install); +} +#endif + + +} // namespace org::apache::nifi::minifi::utils::timeutils + diff --git a/libminifi/test/unit/CronTests.cpp b/libminifi/test/unit/CronTests.cpp index 83ff20d82a..fa70ac206d 100644 --- a/libminifi/test/unit/CronTests.cpp +++ b/libminifi/test/unit/CronTests.cpp @@ -20,10 +20,12 @@ #include "utils/Cron.h" #include "date/date.h" #include "date/tz.h" +#include "utils/TimeUtil.h" using std::chrono::system_clock; using std::chrono::seconds; using org::apache::nifi::minifi::utils::Cron; +namespace timeutils = org::apache::nifi::minifi::utils::timeutils; void checkNext(const std::string& expr, const date::zoned_time& from, const date::zoned_time& next) { @@ -160,7 +162,7 @@ TEST_CASE("Cron::calculateNextTrigger", "[cron]") { using namespace date::literals; // NOLINT(google-build-using-namespace) using namespace std::literals::chrono_literals; #ifdef WIN32 - date::set_install(TZ_DATA_DIR); + timeutils::dateSetInstall(TZ_DATA_DIR); #endif checkNext("0/15 * 1-4 * * ?", @@ -446,7 +448,7 @@ TEST_CASE("Cron::calculateNextTrigger with timezones", "[cron]") { using namespace date::literals; // NOLINT(google-build-using-namespace) using namespace std::literals::chrono_literals; #ifdef WIN32 - date::set_install(TZ_DATA_DIR); + timeutils::dateSetInstall(TZ_DATA_DIR); #endif const std::vector time_zones{ "Europe/Berlin", "Asia/Seoul", "America/Los_Angeles", "Asia/Singapore", "UTC" }; diff --git a/libminifi/test/unit/SchedulingAgentTests.cpp b/libminifi/test/unit/SchedulingAgentTests.cpp index da2cac0615..57f706015e 100644 --- a/libminifi/test/unit/SchedulingAgentTests.cpp +++ b/libminifi/test/unit/SchedulingAgentTests.cpp @@ -71,7 +71,6 @@ class SchedulingAgentTestFixture { #ifdef WIN32 minifi::utils::timeutils::dateSetInstall(TZ_DATA_DIR); - date::set_install(TZ_DATA_DIR); #endif } diff --git a/utils/include/utils/TimeUtil.h b/utils/include/utils/TimeUtil.h index 4159f089a6..b555a96c3f 100644 --- a/utils/include/utils/TimeUtil.h +++ b/utils/include/utils/TimeUtil.h @@ -33,6 +33,7 @@ #include #include "StringUtils.h" +#include "minifi-cpp/utils/TimeUtil.h" // libc++ doesn't define operator<=> on durations, and apparently the operator rewrite rules don't automagically make one #if defined(_LIBCPP_VERSION) @@ -76,41 +77,6 @@ inline uint64_t getTimeNano() { return std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); } -/** - * Mockable clock classes - */ -class Clock { - public: - virtual ~Clock() = default; - virtual std::chrono::milliseconds timeSinceEpoch() const = 0; - virtual bool wait_until(std::condition_variable& cv, std::unique_lock& lck, std::chrono::milliseconds time, const std::function& pred) { - return cv.wait_for(lck, time - timeSinceEpoch(), pred); - } -}; - -class SystemClock : public Clock { - public: - std::chrono::milliseconds timeSinceEpoch() const override { - return std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()); - } -}; - -class SteadyClock : public Clock { - public: - std::chrono::milliseconds timeSinceEpoch() const override { - return std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()); - } - - virtual std::chrono::time_point now() const { - return std::chrono::steady_clock::now(); - } -}; - -std::shared_ptr getClock(); - -// test-only utility to specify what clock to use -void setClock(std::shared_ptr clock); - inline std::string getTimeStr(std::chrono::system_clock::time_point tp) { std::ostringstream stream; date::to_stream(stream, TIME_FORMAT, std::chrono::floor(tp)); diff --git a/utils/src/http/HTTPClient.cpp b/utils/src/http/HTTPClient.cpp index 4b7a138b17..34f1279af5 100644 --- a/utils/src/http/HTTPClient.cpp +++ b/utils/src/http/HTTPClient.cpp @@ -545,6 +545,4 @@ void HTTPClient::CurlMimeFree::operator()(curl_mime* curl_mime) const { curl_mime_free(curl_mime); } -REGISTER_RESOURCE(HTTPClient, InternalResource); - } // namespace org::apache::nifi::minifi::http diff --git a/utils/src/utils/TimeUtil.cpp b/utils/src/utils/TimeUtil.cpp index 4e9be88dac..f79575bc42 100644 --- a/utils/src/utils/TimeUtil.cpp +++ b/utils/src/utils/TimeUtil.cpp @@ -25,19 +25,6 @@ namespace org::apache::nifi::minifi::utils::timeutils { using namespace std::literals::chrono_literals; -static std::mutex global_clock_mtx; -static std::shared_ptr global_clock{std::make_shared()}; - -std::shared_ptr getClock() { - std::lock_guard lock(global_clock_mtx); - return global_clock; -} - -// test-only utility to specify what clock to use -void setClock(std::shared_ptr clock) { - std::lock_guard lock(global_clock_mtx); - global_clock = std::move(clock); -} std::optional parseRfc3339(const std::string& str) { std::istringstream stream(str); @@ -76,6 +63,7 @@ std::optional parseRfc3339(const std::str // date::set_install can point to the TZDATA location, but it has to be called from each library/executable that wants to use timezones void dateSetInstall(const std::string& install) { date::set_install(install); + dateSetGlobalInstall(install); } #endif