LCOV - code coverage report
Current view: top level - tests/core - t_threadpool.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 86 86 100.0 %
Date: 2024-05-13 05:06:06 Functions: 63 64 98.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : #include <chrono>
       2             : #include <gtest/gtest.h>
       3             : #include <iostream>
       4             : #include <openGPMP/core/threads.hpp>
       5             : #include <random>
       6             : #include <vector>
       7             : 
       8             : using namespace std::chrono_literals;
       9             : 
      10             : namespace {
      11           4 : TEST(ThreadPoolTest, EnqueueSingleTask) {
      12           1 :     gpmp::core::ThreadPool pool(1);
      13           2 :     std::future<int> result = pool.enqueue([]() { return 42; });
      14           1 :     ASSERT_EQ(result.get(), 42);
      15           1 : }
      16             : 
      17           4 : TEST(ThreadPoolTest, TestSingleTask) {
      18           1 :     gpmp::core::ThreadPool pool(2);
      19             : 
      20             :     std::future<int> result =
      21           2 :         pool.enqueue([](int x, int y) { return x + y; }, 3, 4);
      22             : 
      23           1 :     EXPECT_EQ(result.get(), 7);
      24           1 : }
      25             : 
      26           4 : TEST(ThreadPoolTest, EnqueueMultipleTasks) {
      27           1 :     gpmp::core::ThreadPool pool(4);
      28           1 :     std::vector<std::future<int>> results;
      29         101 :     for (int i = 0; i < 100; ++i) {
      30         200 :         results.emplace_back(pool.enqueue([i]() { return i * 2; }));
      31             :     }
      32         101 :     for (int i = 0; i < 100; ++i) {
      33         100 :         ASSERT_EQ(results[i].get(), i * 2);
      34             :     }
      35           1 : }
      36             : 
      37           4 : TEST(ThreadPoolTest, EnqueueException) {
      38           1 :     gpmp::core::ThreadPool pool(2);
      39             :     std::future<void> result =
      40           2 :         pool.enqueue([]() { throw std::runtime_error("test error"); });
      41           1 :     ASSERT_THROW(result.get(), std::runtime_error);
      42           1 : }
      43             : 
      44           4 : TEST(ThreadPoolTest, TestException) {
      45           1 :     gpmp::core::ThreadPool pool(1);
      46             : 
      47           3 :     EXPECT_THROW(
      48             :         pool.enqueue([]() { throw std::runtime_error("test exception"); })
      49             :             .get(),
      50           1 :         std::runtime_error);
      51           1 : }
      52             : 
      53           4 : TEST(ThreadPoolTest, TestDynamicAllocation) {
      54             :     // Create a new ThreadPool with 4 threads
      55           1 :     gpmp::core::ThreadPool *pool = new gpmp::core::ThreadPool(4);
      56             : 
      57             :     // Enqueue a task and wait for it to complete
      58           2 :     std::future<int> result = pool->enqueue([]() { return 42; });
      59           1 :     EXPECT_EQ(result.get(), 42);
      60             : 
      61             :     // Delete the ThreadPool
      62           1 :     delete pool;
      63           1 : }
      64             : 
      65           4 : TEST(ThreadPoolTest, TestEnqueueOnStoppedThreadPool) {
      66             :     // Create a new ThreadPool with 2 threads
      67           1 :     gpmp::core::ThreadPool *pool = new gpmp::core::ThreadPool(2);
      68             : 
      69             :     // Stop the ThreadPool explicitly
      70           1 :     delete pool; // pool.~ThreadPool();
      71             : 
      72             :     // Try to enqueue a task on the stopped ThreadPool
      73           1 :     EXPECT_THROW(pool->enqueue([]() { return 42; }), std::runtime_error);
      74           1 : }
      75             : 
      76           4 : TEST(ThreadPoolTest, TestEnqueueWithDifferentReturnTypes) {
      77           1 :     gpmp::core::ThreadPool pool(2);
      78             : 
      79           1 :     auto task1 = []() { /* do something */ };
      80           1 :     auto task2 = []() -> int { return 42; };
      81           1 :     auto task3 = []() -> std::string { return "hello world"; };
      82             : 
      83           1 :     auto res1 = pool.enqueue(task1);
      84           1 :     auto res2 = pool.enqueue(task2);
      85           1 :     auto res3 = pool.enqueue(task3);
      86             : 
      87           1 :     res1.wait();
      88           1 :     EXPECT_EQ(res2.get(), 42);
      89           2 :     EXPECT_EQ(res3.get(), "hello world");
      90           1 : }
      91             : 
      92           4 : TEST(ThreadPoolTest, TestEnqueueWithDifferentArgumentTypes) {
      93           1 :     gpmp::core::ThreadPool pool(2);
      94             : 
      95           1 :     auto task1 = [](int x, int y) { /* do something */ };
      96           1 :     auto task2 = [](const std::string &str) { /* do something */ };
      97           1 :     auto task3 = [](bool flag, float value) { /* do something */ };
      98             : 
      99           1 :     auto res1 = pool.enqueue(task1, 2, 3);
     100           1 :     auto res2 = pool.enqueue(task2, "hello world");
     101           1 :     auto res3 = pool.enqueue(task3, true, 3.14f);
     102             : 
     103           1 :     res1.wait();
     104           1 :     res2.wait();
     105           1 :     res3.wait();
     106           1 : }
     107             : 
     108           4 : TEST(ThreadPoolTest, TestEnqueueWithLargeNumberOfTasks) {
     109           1 :     const int numTasks = 1000;
     110           1 :     gpmp::core::ThreadPool pool(4);
     111             : 
     112        1001 :     for (int i = 0; i < numTasks; ++i) {
     113        1000 :         auto task = []() { /* do something */ };
     114        1000 :         auto task2 = pool.enqueue(task);
     115        1000 :         task2.wait();
     116        1000 :     }
     117           1 : }
     118             : 
     119           4 : TEST(ThreadPoolTest, DispatchFunction) {
     120           1 :     gpmp::core::ThreadPool pool(2);
     121             :     gpmp::core::ThreadDispatch dispatch;
     122             : 
     123             :     // fefine a lambda function to be dispatched to the thread pool
     124           1 :     auto task = []() -> int { return 42; };
     125             : 
     126             :     // dispatch the task to the thread pool using
     127             :     // ThreadDispatch::dispatch()
     128           1 :     auto future_result = dispatch.dispatch(pool, task);
     129             : 
     130             :     // wait for the task to complete and get the result
     131           1 :     auto result = future_result.get();
     132             : 
     133             :     // check if the result is correct
     134           1 :     EXPECT_EQ(result, 42);
     135           1 : }
     136             : 
     137           4 : TEST(ThreadPoolTest, DispatchFunctionWithArgs) {
     138           1 :     gpmp::core::ThreadPool pool(2);
     139             :     gpmp::core::ThreadDispatch dispatch;
     140             : 
     141             :     // define a lambda function to be dispatched to the thread pool, which
     142             :     // takes an integer argument and returns its square
     143           1 :     auto task = [](int x) -> int { return x * x; };
     144             : 
     145           1 :     auto future_result = dispatch.dispatch(pool, task, 5);
     146             : 
     147           1 :     auto result = future_result.get();
     148             : 
     149           1 :     EXPECT_EQ(result, 25);
     150           1 : }
     151             : 
     152             : } // namespace

Generated by: LCOV version 1.14