#include #include "LockableDObject.h" #include #include /** * @file LockableDObjectTest.cpp * @brief Unit tests for the LockableDObject class. */ /** * @brief Test suite for the LockableDObject class. */ class LockableDObjectTest : public ::testing::Test { protected: LockableDObject lockableObject; void SetUp() override { // Initialize the LockableDObject for tests DObject& obj = lockableObject.get(); obj.setData(42); // Set initial data } }; /** * @test Verify the default construction of LockableDObject. */ TEST_F(LockableDObjectTest, DefaultConstruction) { EXPECT_NO_THROW(LockableDObject obj); } /** * @test Verify access to the underlying DObject. */ TEST_F(LockableDObjectTest, AccessDObject) { DObject& obj = lockableObject.get(); EXPECT_EQ(std::get(obj.getData()), 42); // Ensure the data is accessible } /** * @test Verify locking and unlocking. */ TEST_F(LockableDObjectTest, LockAndUnlock) { EXPECT_NO_THROW(lockableObject.lock()); EXPECT_NO_THROW(lockableObject.unlock()); } /** * @test Verify thread safety with multiple threads. */ TEST_F(LockableDObjectTest, ThreadSafety) { const int numThreads = 10; std::vector threads; std::atomic successCount{0}; // Each thread tries to update the data for (int i = 0; i < numThreads; ++i) { threads.emplace_back([this, i, &successCount]() { lockableObject.lock(); DObject& obj = lockableObject.get(); obj.setData(i); if (std::get(obj.getData()) == i) { successCount++; } lockableObject.unlock(); }); } for (auto& t : threads) { t.join(); } EXPECT_EQ(successCount, numThreads); } /** * @test Verify that the DObject remains consistent when accessed via LockableDObject. */ TEST_F(LockableDObjectTest, ConsistentState) { lockableObject.lock(); DObject& obj = lockableObject.get(); obj.setData(100); EXPECT_EQ(std::get(obj.getData()), 100); lockableObject.unlock(); lockableObject.lock(); EXPECT_EQ(std::get(lockableObject.get().getData()), 100); lockableObject.unlock(); }