// Copyright (c) 2020 - 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/testing/watch_dog.hpp" #include "iceoryx_posh/internal/popo/building_blocks/condition_listener.hpp" #include "iceoryx_posh/internal/popo/building_blocks/condition_variable_data.hpp" #include "iceoryx_posh/popo/trigger_handle.hpp" #include "test.hpp" #include namespace { using namespace iox; using namespace iox::popo; using namespace ::testing; class TriggerHandle_test : public Test { public: void resetCallback(const uint64_t id) { m_resetCallbackId = id; } void SetUp() { m_watchdog.watchAndActOnFailure([] { std::terminate(); }); } uint64_t m_resetCallbackId = 0U; ConditionVariableData m_condVar{"Horscht"}; TriggerHandle_test* m_self = this; Watchdog m_watchdog{units::Duration::fromSeconds(2U)}; TriggerHandle m_sut{m_condVar, {*this, &TriggerHandle_test::resetCallback}, 12U}; }; TEST_F(TriggerHandle_test, IsValidWhenConditionVariableIsNotNull) { ::testing::Test::RecordProperty("TEST_ID", "3b2ece7a-bd79-45c9-85e6-7868f82bd0f4"); EXPECT_TRUE(m_sut.isValid()); EXPECT_TRUE(m_sut); } TEST_F(TriggerHandle_test, DefaultCTorConstructsInvalidHandle) { ::testing::Test::RecordProperty("TEST_ID", "9910af97-c47a-4048-8c06-13402e02b1ee"); TriggerHandle sut2; EXPECT_FALSE(sut2.isValid()); EXPECT_THAT(sut2.getUniqueId(), Eq(Trigger::INVALID_TRIGGER_ID)); EXPECT_FALSE(sut2); } TEST_F(TriggerHandle_test, InvalidateCreatesInvalidTriggerHandle) { ::testing::Test::RecordProperty("TEST_ID", "3fdd92d9-d598-443c-b71e-708cf12b874c"); m_sut.invalidate(); EXPECT_FALSE(m_sut.isValid()); EXPECT_FALSE(m_sut); EXPECT_THAT(m_sut.getUniqueId(), Eq(Trigger::INVALID_TRIGGER_ID)); } TEST_F(TriggerHandle_test, ResetCreatesInvalidTriggerHandle) { ::testing::Test::RecordProperty("TEST_ID", "1d977b12-75ce-4374-88bc-d7e814db4fad"); m_sut.reset(); EXPECT_FALSE(m_sut.isValid()); EXPECT_FALSE(m_sut); EXPECT_THAT(m_sut.getUniqueId(), Eq(Trigger::INVALID_TRIGGER_ID)); } TEST_F(TriggerHandle_test, ResetCallsResetCallbackWhenHandleIsValid) { ::testing::Test::RecordProperty("TEST_ID", "2f4b5803-de4a-42f5-afc2-7953a211158d"); m_sut.reset(); EXPECT_EQ(m_resetCallbackId, 12U); EXPECT_THAT(m_sut.getUniqueId(), Eq(Trigger::INVALID_TRIGGER_ID)); } TEST_F(TriggerHandle_test, ResetDoesNotCallResetCallbackWhenHandleIsInvalid) { ::testing::Test::RecordProperty("TEST_ID", "900c0fb5-81a7-46dd-bf5f-1df6072bcb53"); m_sut.invalidate(); m_sut.reset(); EXPECT_EQ(m_resetCallbackId, 0U); EXPECT_THAT(m_sut.getUniqueId(), Eq(Trigger::INVALID_TRIGGER_ID)); } TEST_F(TriggerHandle_test, getConditionVariableDataReturnsCorrectVar) { ::testing::Test::RecordProperty("TEST_ID", "d5722115-2624-4f19-992e-52afb98b9dd5"); EXPECT_EQ(m_sut.getConditionVariableData(), &m_condVar); } TEST_F(TriggerHandle_test, getUniqueIdReturnsCorrectId) { ::testing::Test::RecordProperty("TEST_ID", "856e38a0-c5eb-461c-9445-efb5b21cc5db"); TriggerHandle sut2{m_condVar, {*m_self, &TriggerHandle_test::resetCallback}, 8912U}; EXPECT_EQ(sut2.getUniqueId(), 8912U); } TEST_F(TriggerHandle_test, triggerNotifiesConditionVariable) { ::testing::Test::RecordProperty("TEST_ID", "11e752c8-d473-4bfd-b973-869c3b2d9fbc"); std::atomic_int stage{0}; std::thread t([&] { ConditionListener(m_condVar).wait(); stage.store(1); }); std::this_thread::sleep_for(std::chrono::milliseconds(100)); EXPECT_EQ(stage.load(), 0); m_sut.trigger(); std::this_thread::sleep_for(std::chrono::milliseconds(100)); EXPECT_EQ(stage.load(), 1); t.join(); } TEST_F(TriggerHandle_test, wasTriggeredReturnsFalseAfterCreation) { ::testing::Test::RecordProperty("TEST_ID", "4a40fead-103f-4f3a-a4db-4b8aacae1b57"); EXPECT_FALSE(m_sut.wasTriggered()); } TEST_F(TriggerHandle_test, wasTriggeredReturnsFalseWhenHandleIsInvalid) { ::testing::Test::RecordProperty("TEST_ID", "46f36789-894a-4aba-b17e-d844e4cb90ee"); m_sut.reset(); EXPECT_FALSE(m_sut.wasTriggered()); } TEST_F(TriggerHandle_test, wasTriggeredReturnsTrueAfterItWasTriggered) { ::testing::Test::RecordProperty("TEST_ID", "afc27579-011b-4879-82e4-0377a3bfb68d"); m_sut.trigger(); EXPECT_TRUE(m_sut.wasTriggered()); } TEST_F(TriggerHandle_test, wasTriggeredReturnsFalseAfterItWasTriggeredAndTheListenerResetIt) { ::testing::Test::RecordProperty("TEST_ID", "7d44c016-4abd-4897-bd7a-0a9ce41ffa1f"); m_sut.trigger(); ConditionListener(m_condVar).timedWait(units::Duration::fromSeconds(0U)); EXPECT_FALSE(m_sut.wasTriggered()); } } // namespace