// Copyright (c) 2021 by Robert Bosch GmbH. All rights reserved. // Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // 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. // // SPDX-License-Identifier: Apache-2.0 #include "iceoryx_hoofs/cxx/deadline_timer.hpp" #include "iceoryx_hoofs/internal/units/duration.hpp" #include "iceoryx_hoofs/testing/timing_test.hpp" #include "test.hpp" #include #include namespace { using namespace ::testing; using namespace iox::units; using namespace iox::units::duration_literals; using Timer = iox::cxx::DeadlineTimer; class DeadlineTimer_test : public Test { public: virtual void SetUp() { numberOfCalls = 0; } virtual void TearDown() { } Duration second{1_s}; std::atomic numberOfCalls{0}; static const Duration TIMEOUT; static const int SLEEPTIME; }; const Duration DeadlineTimer_test::TIMEOUT{10_ms}; const int DeadlineTimer_test::SLEEPTIME = DeadlineTimer_test::TIMEOUT.toMilliseconds(); TIMING_TEST_F(DeadlineTimer_test, ZeroTimeoutTest, Repeat(5), [&] { Timer sut(0_s); TIMING_TEST_EXPECT_TRUE(sut.hasExpired()); }); TIMING_TEST_F(DeadlineTimer_test, DurationOfNonZeroIsExpiresAfterTimeout, Repeat(5), [&] { Timer sut(TIMEOUT); TIMING_TEST_EXPECT_FALSE(sut.hasExpired()); std::this_thread::sleep_for(std::chrono::milliseconds(2 * SLEEPTIME / 3)); TIMING_TEST_EXPECT_FALSE(sut.hasExpired()); std::this_thread::sleep_for(std::chrono::milliseconds(2 * SLEEPTIME / 3)); TIMING_TEST_EXPECT_TRUE(sut.hasExpired()); }); TIMING_TEST_F(DeadlineTimer_test, ResetWithDurationIsExpired, Repeat(5), [&] { Timer sut(TIMEOUT); std::this_thread::sleep_for(std::chrono::milliseconds(2 * SLEEPTIME)); TIMING_TEST_EXPECT_TRUE(sut.hasExpired()); sut.reset(); TIMING_TEST_EXPECT_FALSE(sut.hasExpired()); }); TIMING_TEST_F(DeadlineTimer_test, ResetWhenNotExpiredIsStillNotExpired, Repeat(5), [&] { Timer sut(TIMEOUT); std::this_thread::sleep_for(std::chrono::milliseconds(2 * SLEEPTIME / 3)); sut.reset(); std::this_thread::sleep_for(std::chrono::milliseconds(2 * SLEEPTIME / 3)); TIMING_TEST_EXPECT_FALSE(sut.hasExpired()); }); TIMING_TEST_F(DeadlineTimer_test, ResetAfterBeingExpiredIsNotExpired, Repeat(5), [&] { Timer sut(TIMEOUT); std::this_thread::sleep_for(std::chrono::milliseconds(2 * SLEEPTIME)); TIMING_TEST_ASSERT_TRUE(sut.hasExpired()); sut.reset(); TIMING_TEST_EXPECT_FALSE(sut.hasExpired()); }); TIMING_TEST_F(DeadlineTimer_test, ResetWithCustomizedTimeAfterBeingExpiredIsNotExpired, Repeat(5), [&] { Timer sut(TIMEOUT); std::this_thread::sleep_for(std::chrono::milliseconds(2 * SLEEPTIME)); TIMING_TEST_ASSERT_TRUE(sut.hasExpired()); sut.reset(20_s); std::this_thread::sleep_for(std::chrono::milliseconds(2 * SLEEPTIME)); TIMING_TEST_EXPECT_FALSE(sut.hasExpired()); }); TIMING_TEST_F(DeadlineTimer_test, ResetWithCustomizedTimeAfterBeingExpiredIsExpired, Repeat(5), [&] { Timer sut(TIMEOUT); std::this_thread::sleep_for(std::chrono::milliseconds(2 * SLEEPTIME)); TIMING_TEST_ASSERT_TRUE(sut.hasExpired()); sut.reset(TIMEOUT); std::this_thread::sleep_for(std::chrono::milliseconds(2 * SLEEPTIME)); TIMING_TEST_ASSERT_TRUE(sut.hasExpired()); }); TIMING_TEST_F(DeadlineTimer_test, RemainingTimeCheckIfExpired, Repeat(5), [&] { Timer sut(TIMEOUT); std::this_thread::sleep_for(std::chrono::milliseconds(2 * SLEEPTIME)); TIMING_TEST_ASSERT_TRUE(sut.hasExpired()); int remainingTime = sut.remainingTime().toMilliseconds(); const int EXPECTED_REMAINING_TIME = 0; // the timer is expired the remaining wait time is Zero TIMING_TEST_EXPECT_TRUE(remainingTime == EXPECTED_REMAINING_TIME); }); TIMING_TEST_F(DeadlineTimer_test, RemainingTimeCheckIfNotExpired, Repeat(5), [&] { Timer sut(2 * TIMEOUT); std::this_thread::sleep_for(std::chrono::milliseconds(SLEEPTIME)); TIMING_TEST_ASSERT_FALSE(sut.hasExpired()); int remainingTime = sut.remainingTime().toMilliseconds(); const int PASSED_TIMER_TIME = SLEEPTIME; // Already 10ms passed in sleeping out of 20ms const int RANGE_APPROX = 2; // 2ms arppoximation. This may be lost after arming the timer in execution. const int EXPECTED_REMAINING_TIME = PASSED_TIMER_TIME - RANGE_APPROX; TIMING_TEST_EXPECT_TRUE(remainingTime >= EXPECTED_REMAINING_TIME && remainingTime <= PASSED_TIMER_TIME); }); } // namespace