Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ wdk_add_driver(kf-test WINVER NTDDI_WIN10 STL
AutoSpinLockTest.cpp
EResourceSharedLockTest.cpp
RecursiveAutoSpinLockTest.cpp
TimerThreadTest.cpp
)

target_link_libraries(kf-test kf::kf kmtest::kmtest)
Expand Down
84 changes: 84 additions & 0 deletions test/TimerThreadTest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#include "pch.h"
#include <kf/TimerThread.h>

namespace
{
void delay(LONGLONG time)
{
LARGE_INTEGER interval;
interval.QuadPart = -time;
KeDelayExecutionThread(KernelMode, FALSE, &interval);
}
}

SCENARIO("TimerThread callback execution")
{
constexpr auto k100Microsecond = 1'000; // 100 microseconds
constexpr auto kMillisecond = 10'000;

GIVEN("TimerThread and a callback incrementing a counter")
{
kf::TimerThread timer;
LONG counter = 0;

LARGE_INTEGER period;
period.QuadPart = k100Microsecond;

REQUIRE_NT_SUCCESS(timer.start(period, [&counter]() {
InterlockedIncrement(&counter);
}));

WHEN("Waiting enough time for multiple callbacks")
{
delay(5 * kMillisecond); // 5ms

THEN("Counter should have been incremented at least greater than 1")
{
REQUIRE(counter > 1);
}
}

WHEN("Stopping the TimerThread via join")
{
delay(5 * kMillisecond); // 5 ms
timer.join();
int valueAfterJoin = counter;
delay(10 * kMillisecond); // 10 ms

THEN("Counter should not increase after join")
{
REQUIRE(counter == valueAfterJoin);
}
}
}

GIVEN("TimerThread in a scope and a callback incrementing a counter")
{
LONG counter = 0;

{
kf::TimerThread timer;
LARGE_INTEGER period;
period.QuadPart = k100Microsecond;

REQUIRE_NT_SUCCESS(timer.start(period, [&counter]() {
InterlockedIncrement(&counter);
}));

delay(5 * kMillisecond);
REQUIRE(counter > 1);
}

int valueAfterScope = counter;

WHEN("TimerThread goes out of scope")
{
delay(10 * kMillisecond); // 10 ms

THEN("Counter should not increase any more")
{
REQUIRE(counter == valueAfterScope);
}
}
}
}