Skip to content

Commit f05f29a

Browse files
author
Vlada Kanivets
committed
add tests for Thread
1 parent bf56e1b commit f05f29a

File tree

2 files changed

+156
-0
lines changed

2 files changed

+156
-0
lines changed

test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ wdk_add_driver(kf-test WINVER NTDDI_WIN10 STL
5959
AutoSpinLockTest.cpp
6060
EResourceSharedLockTest.cpp
6161
RecursiveAutoSpinLockTest.cpp
62+
ThreadTest.cpp
6263
)
6364

6465
target_link_libraries(kf-test kf::kf kmtest::kmtest)

test/ThreadTest.cpp

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
#include "pch.h"
2+
#include <kf/Thread.h>
3+
4+
namespace
5+
{
6+
struct TestObject
7+
{
8+
NTSTATUS run()
9+
{
10+
value = 123;
11+
return STATUS_SUCCESS;
12+
}
13+
14+
int value = 0;
15+
};
16+
}
17+
18+
SCENARIO("kf::Thread")
19+
{
20+
GIVEN("Default-constructed thread")
21+
{
22+
kf::Thread thread;
23+
24+
WHEN("Starting a thread with lambda")
25+
{
26+
int value = 0;
27+
NTSTATUS status = thread.start([](void* context) {
28+
auto p = static_cast<int*>(context);
29+
*p = 123;
30+
}, &value);
31+
32+
THEN("Status is successful")
33+
{
34+
REQUIRE(NT_SUCCESS(status));
35+
}
36+
37+
thread.join();
38+
39+
THEN("Thread changed the given value")
40+
{
41+
REQUIRE(value == 123);
42+
}
43+
}
44+
45+
WHEN("Thread is not started and joined")
46+
{
47+
thread.join();
48+
49+
THEN("Does nothing and no crash occurs")
50+
{
51+
}
52+
}
53+
54+
WHEN("Calling join twice after start")
55+
{
56+
REQUIRE_NT_SUCCESS(thread.start([](void*) { }, nullptr));
57+
58+
thread.join();
59+
thread.join();
60+
61+
THEN("Does nothing and no crash occurs")
62+
{
63+
}
64+
}
65+
}
66+
67+
GIVEN("Thread with a member routine")
68+
{
69+
kf::Thread thread;
70+
TestObject obj;
71+
72+
WHEN("Starting a thread with member function")
73+
{
74+
NTSTATUS status = thread.start<&TestObject::run>(&obj);
75+
76+
THEN("Status is successful")
77+
{
78+
REQUIRE(NT_SUCCESS(status));
79+
}
80+
81+
thread.join();
82+
83+
THEN("Thread called the function")
84+
{
85+
REQUIRE(obj.value == 123);
86+
}
87+
}
88+
}
89+
90+
GIVEN("Thread with long working function")
91+
{
92+
kf::Thread thread;
93+
int value = 0;
94+
95+
WHEN("Starting a thread with long working function and joined")
96+
{
97+
REQUIRE_NT_SUCCESS(thread.start([](void* context) {
98+
auto p = static_cast<int*>(context);
99+
LARGE_INTEGER interval;
100+
interval.QuadPart = -10'000;
101+
KeDelayExecutionThread(KernelMode, FALSE, &interval);
102+
*p = 246;
103+
}, &value));
104+
105+
thread.join();
106+
107+
THEN("Main thread execution contimued after given thread finished it's work")
108+
{
109+
REQUIRE(value == 246);
110+
}
111+
}
112+
}
113+
114+
GIVEN("Thread that goes out of scope")
115+
{
116+
int value = 0;
117+
{
118+
kf::Thread thread;
119+
REQUIRE_NT_SUCCESS(thread.start([](void* context) {
120+
auto p = static_cast<int*>(context);
121+
*p = 777;
122+
}, &value));
123+
}
124+
125+
THEN("Destructor joined and work was finished")
126+
{
127+
REQUIRE(value == 777);
128+
}
129+
}
130+
131+
GIVEN("Woring thread")
132+
{
133+
kf::Thread thread;
134+
int value = 0;
135+
136+
REQUIRE_NT_SUCCESS(thread.start([](void* context) {
137+
auto p = static_cast<int*>(context);
138+
LARGE_INTEGER interval;
139+
interval.QuadPart = -10'000;
140+
KeDelayExecutionThread(KernelMode, FALSE, &interval);
141+
*p = 999;
142+
}, &value));
143+
144+
WHEN("Thread is moved to another instance")
145+
{
146+
kf::Thread thread2 = std::move(thread);
147+
thread2.join();
148+
149+
THEN("Function form thread is completed")
150+
{
151+
REQUIRE(value == 999);
152+
}
153+
}
154+
}
155+
}

0 commit comments

Comments
 (0)