66 lines
2.1 KiB
C++
66 lines
2.1 KiB
C++
#include <gtest/gtest.h>
|
|
#include <web_server/src/detail/Gallery_Frame_Clock.hpp>
|
|
#include <asio/thread_pool.hpp>
|
|
#include <chrono>
|
|
#include <condition_variable>
|
|
#include <exception>
|
|
#include <mutex>
|
|
#include <thread>
|
|
#include <vector>
|
|
|
|
namespace aethera::web::detail {
|
|
TEST(Gallery_Frame_Clock, Produces_One_Monotonic_Absolute_Timeline) {
|
|
asio::thread_pool pool(1);
|
|
std::mutex mutex;
|
|
std::condition_variable condition;
|
|
std::vector<Plot_Render_Tick> ticks;
|
|
std::exception_ptr failure;
|
|
{
|
|
Gallery_Frame_Clock clock(
|
|
pool.get_executor(), 100.0,
|
|
[&](Plot_Render_Tick tick) {
|
|
std::lock_guard lock(mutex);
|
|
ticks.push_back(tick);
|
|
condition.notify_all();
|
|
},
|
|
[&](std::exception_ptr value) {
|
|
std::lock_guard lock(mutex);
|
|
failure = std::move(value);
|
|
condition.notify_all();
|
|
});
|
|
clock.start();
|
|
clock.start();
|
|
{
|
|
std::unique_lock lock(mutex);
|
|
ASSERT_TRUE(condition.wait_for(lock, std::chrono::seconds(2), [&] {
|
|
return ticks.size() >= 8 || failure;
|
|
}));
|
|
ASSERT_FALSE(failure);
|
|
ASSERT_GE(ticks.size(), 8U);
|
|
for (std::size_t index = 1; index < ticks.size(); ++index) {
|
|
EXPECT_GT(ticks[index].sequence, ticks[index - 1].sequence);
|
|
EXPECT_GT(ticks[index].time_milliseconds,
|
|
ticks[index - 1].time_milliseconds);
|
|
}
|
|
EXPECT_NEAR(ticks.front().time_milliseconds,
|
|
static_cast<double>(ticks.front().sequence) * 10.0,
|
|
0.001);
|
|
}
|
|
clock.stop();
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(30));
|
|
std::size_t stopped_count{};
|
|
{
|
|
std::lock_guard lock(mutex);
|
|
stopped_count = ticks.size();
|
|
}
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(30));
|
|
{
|
|
std::lock_guard lock(mutex);
|
|
EXPECT_EQ(ticks.size(), stopped_count);
|
|
}
|
|
}
|
|
pool.stop();
|
|
pool.join();
|
|
}
|
|
}
|