ST_engine  0.3-ALPHA
task_manager_tests.cpp
1 /* This file is part of the "ST" project.
2  * You may use, distribute or modify this code under the terms
3  * of the GNU General Public License version 2.
4  * See LICENCE.txt in the root directory of the project.
5  *
6  * Author: Maxim Atanasov
7  * E-mail: maxim.atanasov@protonmail.com
8  */
9 
10 #include <gtest/gtest.h>
11 #include <task_manager.hpp>
12 #include <thread>
13 
14 class task_manager_tests : public ::testing::TestWithParam<int> {
15 };
16 
17 static void test_task_function(void *arg) {
18  auto val = static_cast<uint8_t *>(arg);
19  ++*val;
20 }
21 
22 static void test_task_function2(void *arg) {
23  auto val = static_cast<uint8_t *>(arg);
24  std::this_thread::sleep_for(std::chrono::milliseconds(500));
25  ++*val;
26 }
27 
28 TEST_F(task_manager_tests, test_start_task_without_dependency) {
29  //Set up
30  task_manager test_subject;
31  uint8_t test_value = 10;
32 
33  //Test
34  task_id id = test_subject.start_task(new ST::task(test_task_function, &test_value, nullptr));
35  test_subject.wait_for_task(id);
36  ASSERT_EQ(test_value, 11);
37 }
38 
39 TEST_F(task_manager_tests, test_start_tasks_with_dependency) {
40  //Set up
41  task_manager test_subject;
42  uint8_t test_value = 10;
43 
44  //Test
45  task_id id1 = test_subject.start_task(new ST::task(test_task_function2, &test_value, nullptr));
46  task_id id2 = test_subject.start_task(new ST::task(test_task_function, &test_value, id1));
47 
48  test_subject.wait_for_task(id2);
49  ASSERT_EQ(test_value, 12);
50 }
51 
52 TEST_F(task_manager_tests, test_start_task_lockfree_without_dependency) {
53  //Set up
54  task_manager test_subject;
55  uint8_t test_value = 10;
56 
57  //Test
58  test_subject.start_task_lockfree(new ST::task(test_task_function, &test_value, nullptr));
59 
60  //Wait a suffecent amount of time
61  std::this_thread::sleep_for(std::chrono::milliseconds(500));
62  ASSERT_EQ(test_value, 11);
63 }
64 
65 TEST_F(task_manager_tests, test_start_task_lockfree_with_dependency) {
66  //Set up
67  task_manager test_subject;
68  uint8_t test_value = 10;
69 
70  //Test
71  task_id id1 = test_subject.start_task(new ST::task(test_task_function2, &test_value, nullptr));
72  test_subject.start_task_lockfree(new ST::task(test_task_function, &test_value, id1));
73 
74  std::this_thread::sleep_for(std::chrono::seconds(2));
75  ASSERT_EQ(test_value, 12);
76 }
77 
78 //With only one task thread running the test will take about 2 seconds to complete if
79 //the waiter isn't doing any work
80 TEST_P(task_manager_tests, test_do_work_while_waiting) {
81  //Set up
82  task_manager test_subject(1);
83  uint8_t test_value1 = 10;
84  uint8_t test_value2 = 20;
85 
86  //Test
87  auto start = std::chrono::duration_cast<std::chrono::milliseconds>(
88  std::chrono::high_resolution_clock::now().time_since_epoch());
89 
90  task_id id1 = test_subject.start_task(new ST::task(test_task_function2, &test_value1, nullptr));
91  task_id id2 = test_subject.start_task(new ST::task(test_task_function2, &test_value2, nullptr));
92 
93  test_subject.work_wait_for_task(id1);
94  test_subject.work_wait_for_task(id2);
95  auto end = std::chrono::duration_cast<std::chrono::milliseconds>(
96  std::chrono::high_resolution_clock::now().time_since_epoch());
97 
98  ASSERT_NEAR(static_cast<double>(end.count() - start.count()), 515, 200);
99  ASSERT_EQ(test_value1, 11);
100  ASSERT_EQ(test_value2, 21);
101 }
102 
103 INSTANTIATE_TEST_CASE_P(test_do_work_while_waiting, task_manager_tests, ::testing::Range(0, 15));
104 
105 int main(int argc, char **argv) {
106  ::testing::InitGoogleTest(&argc, argv);
107  return RUN_ALL_TESTS();
108 }
An object representing a task to be run by the task manager.
Definition: task.hpp:24
The Task Manager handles all things multi-threaded in the engine.
void start_task_lockfree(ST::task *arg)
void wait_for_task(task_id id)
void work_wait_for_task(task_id id)
task_id start_task(ST::task *arg)