mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-28 08:52:19 -07:00
[Client] Unit test LagMonitor stall recording
Drives recordGap() directly to cover the threshold, plausibility cap, trim, and clear behavior without timing-dependent waits. Took 36 seconds
This commit is contained in:
parent
fa823e4b1c
commit
218f89df72
3 changed files with 110 additions and 1 deletions
|
|
@ -41,7 +41,8 @@ public:
|
||||||
struct StallRecord
|
struct StallRecord
|
||||||
{
|
{
|
||||||
qint64 timestampMsSinceEpoch = 0; ///< when the stalled period ended
|
qint64 timestampMsSinceEpoch = 0; ///< when the stalled period ended
|
||||||
qint64 durationMs = 0; ///< approximate length of the freeze; measured tick to tick, so it can exceed the true stall by up to TICK_INTERVAL_MS
|
qint64 durationMs = 0; ///< approximate length of the freeze; measured tick to tick, so it can exceed the true
|
||||||
|
///< stall by up to TICK_INTERVAL_MS
|
||||||
};
|
};
|
||||||
|
|
||||||
static constexpr int TICK_INTERVAL_MS = 500;
|
static constexpr int TICK_INTERVAL_MS = 500;
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ add_test(NAME server_card_counter_test COMMAND server_card_counter_test)
|
||||||
add_test(NAME server_counter_test COMMAND server_counter_test)
|
add_test(NAME server_counter_test COMMAND server_counter_test)
|
||||||
add_test(NAME server_rate_limiter_test COMMAND server_rate_limiter_test)
|
add_test(NAME server_rate_limiter_test COMMAND server_rate_limiter_test)
|
||||||
add_test(NAME warning_categories_test COMMAND warning_categories_test)
|
add_test(NAME warning_categories_test COMMAND warning_categories_test)
|
||||||
|
add_test(NAME lag_monitor_test COMMAND lag_monitor_test)
|
||||||
add_test(NAME latency_tracker_test COMMAND latency_tracker_test)
|
add_test(NAME latency_tracker_test COMMAND latency_tracker_test)
|
||||||
|
|
||||||
add_test(NAME deck_hash_performance_test COMMAND deck_hash_performance_test)
|
add_test(NAME deck_hash_performance_test COMMAND deck_hash_performance_test)
|
||||||
|
|
@ -30,6 +31,8 @@ add_executable(server_card_counter_test server_card_counter_test.cpp)
|
||||||
add_executable(server_counter_test server_counter_test.cpp)
|
add_executable(server_counter_test server_counter_test.cpp)
|
||||||
add_executable(server_rate_limiter_test server_rate_limiter_test.cpp)
|
add_executable(server_rate_limiter_test server_rate_limiter_test.cpp)
|
||||||
add_executable(warning_categories_test warning_categories_test.cpp)
|
add_executable(warning_categories_test warning_categories_test.cpp)
|
||||||
|
add_executable(lag_monitor_test ${CMAKE_SOURCE_DIR}/cockatrice/src/client/lag_monitor.cpp lag_monitor_test.cpp)
|
||||||
|
target_include_directories(lag_monitor_test PRIVATE ${CMAKE_SOURCE_DIR}/cockatrice/src)
|
||||||
add_executable(latency_tracker_test latency_tracker_test.cpp)
|
add_executable(latency_tracker_test latency_tracker_test.cpp)
|
||||||
|
|
||||||
find_package(GTest)
|
find_package(GTest)
|
||||||
|
|
@ -68,6 +71,7 @@ if(NOT GTEST_FOUND)
|
||||||
add_dependencies(server_counter_test gtest)
|
add_dependencies(server_counter_test gtest)
|
||||||
add_dependencies(server_rate_limiter_test gtest)
|
add_dependencies(server_rate_limiter_test gtest)
|
||||||
add_dependencies(warning_categories_test gtest)
|
add_dependencies(warning_categories_test gtest)
|
||||||
|
add_dependencies(lag_monitor_test gtest)
|
||||||
add_dependencies(latency_tracker_test gtest)
|
add_dependencies(latency_tracker_test gtest)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
@ -103,6 +107,7 @@ target_link_libraries(
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
warning_categories_test libcockatrice_utility Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES}
|
warning_categories_test libcockatrice_utility Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES}
|
||||||
)
|
)
|
||||||
|
target_link_libraries(lag_monitor_test Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES})
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
latency_tracker_test libcockatrice_network Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES}
|
latency_tracker_test libcockatrice_network Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES}
|
||||||
)
|
)
|
||||||
|
|
|
||||||
103
tests/lag_monitor_test.cpp
Normal file
103
tests/lag_monitor_test.cpp
Normal file
|
|
@ -0,0 +1,103 @@
|
||||||
|
#include "client/lag_monitor.h"
|
||||||
|
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QEvent>
|
||||||
|
#include <QLoggingCategory>
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
/// Timestamps are taken at recording time; allow generous scheduler slack.
|
||||||
|
constexpr qint64 TIMESTAMP_SLACK_MS = 10000;
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
class LagMonitorTest : public ::testing::Test
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
LagMonitor monitor;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(LagMonitorTest, GapAtOrBelowThresholdIsIgnored)
|
||||||
|
{
|
||||||
|
monitor.recordGap(0);
|
||||||
|
monitor.recordGap(LagMonitor::TICK_INTERVAL_MS);
|
||||||
|
monitor.recordGap(LagMonitor::STALL_THRESHOLD_MS);
|
||||||
|
|
||||||
|
EXPECT_TRUE(monitor.recentStalls().isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(LagMonitorTest, GapAboveThresholdIsRecorded)
|
||||||
|
{
|
||||||
|
monitor.recordGap(LagMonitor::STALL_THRESHOLD_MS + 1);
|
||||||
|
|
||||||
|
const QList<LagMonitor::StallRecord> stalls = monitor.recentStalls();
|
||||||
|
ASSERT_EQ(1, stalls.size());
|
||||||
|
EXPECT_EQ(LagMonitor::STALL_THRESHOLD_MS + 1, stalls.first().durationMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(LagMonitorTest, RecordedTimestampIsFresh)
|
||||||
|
{
|
||||||
|
monitor.recordGap(LagMonitor::STALL_THRESHOLD_MS + 1);
|
||||||
|
|
||||||
|
const qint64 now = QDateTime::currentMSecsSinceEpoch();
|
||||||
|
ASSERT_EQ(1, monitor.recentStalls().size());
|
||||||
|
EXPECT_LE(qAbs(monitor.recentStalls().first().timestampMsSinceEpoch - now), TIMESTAMP_SLACK_MS);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(LagMonitorTest, RecordsAreTrimmedToMaxOldestFirst)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < LagMonitor::MAX_RECORDED_STALLS + 5; ++i) {
|
||||||
|
monitor.recordGap(LagMonitor::STALL_THRESHOLD_MS + 1 + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
const QList<LagMonitor::StallRecord> stalls = monitor.recentStalls();
|
||||||
|
ASSERT_EQ(LagMonitor::MAX_RECORDED_STALLS, stalls.size());
|
||||||
|
EXPECT_EQ(LagMonitor::STALL_THRESHOLD_MS + 6, stalls.first().durationMs);
|
||||||
|
EXPECT_EQ(LagMonitor::STALL_THRESHOLD_MS + 5 + LagMonitor::MAX_RECORDED_STALLS, stalls.last().durationMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(LagMonitorTest, GapAtPlausibilityCapIsKept)
|
||||||
|
{
|
||||||
|
monitor.recordGap(LagMonitor::MAX_PLAUSIBLE_STALL_MS);
|
||||||
|
|
||||||
|
ASSERT_EQ(1, monitor.recentStalls().size());
|
||||||
|
EXPECT_EQ(LagMonitor::MAX_PLAUSIBLE_STALL_MS, monitor.recentStalls().first().durationMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(LagMonitorTest, GapBeyondPlausibilityCapIsDropped)
|
||||||
|
{
|
||||||
|
monitor.recordGap(LagMonitor::MAX_PLAUSIBLE_STALL_MS + 1);
|
||||||
|
|
||||||
|
EXPECT_TRUE(monitor.recentStalls().isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(LagMonitorTest, ClearStallsEmptiesList)
|
||||||
|
{
|
||||||
|
monitor.recordGap(LagMonitor::STALL_THRESHOLD_MS + 1);
|
||||||
|
ASSERT_EQ(1, monitor.recentStalls().size());
|
||||||
|
|
||||||
|
monitor.clearStalls();
|
||||||
|
|
||||||
|
EXPECT_TRUE(monitor.recentStalls().isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(LagMonitorTest, ApplicationStateChangeDoesNotRecordAStall)
|
||||||
|
{
|
||||||
|
QObject probe;
|
||||||
|
QEvent event(QEvent::ApplicationStateChange);
|
||||||
|
|
||||||
|
QCoreApplication::sendEvent(&probe, &event);
|
||||||
|
|
||||||
|
EXPECT_TRUE(monitor.recentStalls().isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
QLoggingCategory::setFilterRules("lag_monitor.*=false");
|
||||||
|
QCoreApplication app(argc, argv);
|
||||||
|
::testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue