#include "../lib/Utilities.hpp" #include #include #include #include #include #include void test_lock_free_queue() { std::cout << "Testing lock-free queue...\n"; reactor::LockFreeQueueTyped queue; assert(queue.empty()); queue.enqueue(1); queue.enqueue(2); queue.enqueue(3); assert(!queue.empty()); int val; assert(queue.dequeue(val) && val == 1); assert(queue.dequeue(val) && val == 2); assert(queue.dequeue(val) && val == 3); assert(queue.empty()); assert(!queue.dequeue(val)); std::cout << "✓ Lock-free queue basic operations passed\n"; } void test_lock_free_queue_concurrent() { std::cout << "Testing lock-free queue concurrency...\n"; reactor::LockFreeQueueTyped queue; constexpr int num_items = 50; // Reduced further constexpr int num_producers = 1; // Simplified to 1 producer constexpr int num_consumers = 1; // Simplified to 1 consumer std::vector producers; std::vector consumers; std::atomic consumed_count{0}; std::atomic stop_consumers{false}; for (int p = 0; p < num_producers; ++p) { producers.emplace_back([&queue, p, num_items]() { for (int i = 0; i < num_items; ++i) { queue.enqueue(p * num_items + i); std::this_thread::sleep_for(std::chrono::milliseconds(1)); } }); } for (int c = 0; c < num_consumers; ++c) { consumers.emplace_back([&queue, &consumed_count, &stop_consumers]() { int val; while (!stop_consumers) { if (queue.dequeue(val)) { consumed_count++; } else { std::this_thread::sleep_for(std::chrono::milliseconds(1)); } } }); } for (auto& p : producers) { p.join(); } // Wait longer for all items to be consumed auto start = std::chrono::steady_clock::now(); while (consumed_count < num_producers * num_items) { std::this_thread::sleep_for(std::chrono::milliseconds(10)); auto now = std::chrono::steady_clock::now(); if (std::chrono::duration_cast(now - start).count() > 5) { break; // Timeout after 5 seconds } } stop_consumers = true; for (auto& c : consumers) { c.join(); } assert(consumed_count == num_producers * num_items); std::cout << "✓ Lock-free queue concurrency passed\n"; } void test_object_pool() { std::cout << "Testing object pool...\n"; struct TestObject { int value = 42; TestObject() { std::cout << "TestObject constructed\n"; } ~TestObject() { std::cout << "TestObject destructed\n"; } }; auto pool = std::make_shared>(); { auto obj1 = pool->getObject(); auto obj2 = pool->getObject(); assert(obj1->value == 42); assert(obj2->value == 42); assert(obj1.get() != obj2.get()); } { auto obj3 = pool->getObject(); assert(obj3->value == 42); } std::cout << "✓ Object pool passed\n"; } void test_logger() { std::cout << "Testing logger...\n"; reactor::Logger::setLevel(reactor::LogLevel::DEBUG); reactor::Logger(reactor::LogLevel::DEBUG) << "Debug message"; reactor::Logger(reactor::LogLevel::INFO) << "Info message with number: " << 42; reactor::Logger(reactor::LogLevel::WARN) << "Warning message"; reactor::Logger(reactor::LogLevel::ERROR) << "Error message"; reactor::Logger::setLevel(reactor::LogLevel::ERROR); reactor::Logger(reactor::LogLevel::DEBUG) << "This should not appear"; reactor::Logger(reactor::LogLevel::INFO) << "This should not appear"; reactor::Logger(reactor::LogLevel::ERROR) << "This should appear"; reactor::Logger::setLevel(reactor::LogLevel::DEBUG); std::cout << "✓ Logger passed\n"; } void test_concurrent_task_queue() { std::cout << "Testing concurrent task queue...\n"; reactor::ConcurrentTaskQueue queue(2, "TestQueue"); assert(queue.getName() == "TestQueue"); std::atomic counter{0}; std::promise all_done; auto future = all_done.get_future(); for (int i = 0; i < 10; ++i) { queue.runTaskInQueue([&counter, i, &all_done]() { std::this_thread::sleep_for(std::chrono::milliseconds(10)); if (++counter == 10) { all_done.set_value(); } }); } future.wait(); assert(counter == 10); std::cout << "✓ Concurrent task queue passed\n"; } void test_sync_task() { std::cout << "Testing sync task execution...\n"; reactor::ConcurrentTaskQueue queue(1, "SyncTest"); // Use shared_ptr to avoid move issues auto executed_flag = std::make_shared(false); queue.syncTaskInQueue([executed_flag]() { std::this_thread::sleep_for(std::chrono::milliseconds(50)); *executed_flag = true; }); assert(*executed_flag); std::cout << "✓ Sync task execution passed\n"; } void test_utility_functions() { std::cout << "Testing utility functions...\n"; std::size_t seed = 0; reactor::hashCombine(seed, 42); reactor::hashCombine(seed, std::string("test")); assert(seed != 0); std::string text = "hello,world,test,data"; auto parts = reactor::splitString(text, ","); assert(parts.size() == 4); assert(parts[0] == "hello"); assert(parts[1] == "world"); assert(parts[2] == "test"); assert(parts[3] == "data"); auto single = reactor::splitString("single", ","); assert(single.size() == 1); assert(single[0] == "single"); std::cout << "✓ Utility functions passed\n"; } void test_network_utilities() { std::cout << "Testing network utilities...\n"; uint64_t original = 0x123456789ABCDEF0ULL; uint64_t network = reactor::hton64(original); uint64_t back = reactor::ntoh64(network); assert(back == original); std::cout << "✓ Network utilities passed\n"; } void test_non_copyable() { std::cout << "Testing NonCopyable...\n"; class TestClass : public reactor::NonCopyable { public: int value = 42; TestClass() = default; TestClass(TestClass&& other) noexcept : value(other.value) { other.value = 0; } }; TestClass obj1; TestClass obj2 = std::move(obj1); assert(obj2.value == 42); assert(obj1.value == 0); std::cout << "✓ NonCopyable passed\n"; } int main() { std::cout << "=== Utilities Tests ===\n"; test_lock_free_queue(); test_lock_free_queue_concurrent(); test_object_pool(); test_logger(); test_concurrent_task_queue(); test_sync_task(); test_utility_functions(); test_network_utilities(); test_non_copyable(); std::cout << "All utilities tests passed! ✓\n"; return 0; }