From 8f9605bcd3320d3e5fcd999309b44b80cc6b6767 Mon Sep 17 00:00:00 2001 From: Adam Wildavsky Date: Fri, 7 Aug 2026 22:58:20 +0200 Subject: [PATCH 1/6] Removed dtest --min/--max flags. They reported minimum and maximum batch averages, not single-deal times, so they were useless. Use -r for per-board outliers instead. --- library/tests/TestTimer.cpp | 69 +---------------- library/tests/TestTimer.hpp | 33 +-------- library/tests/args.cpp | 27 +------ library/tests/args.hpp | 1 - library/tests/args_test.cpp | 45 +---------- library/tests/cst.hpp | 2 - library/tests/test_timer_test.cpp | 119 +++++------------------------- library/tests/testcommon.cpp | 2 +- 8 files changed, 34 insertions(+), 264 deletions(-) diff --git a/library/tests/TestTimer.cpp b/library/tests/TestTimer.cpp index c44c00f26..0ce169f13 100644 --- a/library/tests/TestTimer.cpp +++ b/library/tests/TestTimer.cpp @@ -8,7 +8,6 @@ */ -#include #include #include #include @@ -45,11 +44,6 @@ void TestTimer::reset() user_cum_ = 0; user_cum_old_ = 0; sys_cum_ = 0; - user_min_ = 0; - user_max_ = 0; - sys_min_ = 0; - sys_max_ = 0; - batch_count_ = 0; pending_hands_ = 0; sys_time_known_ = true; } @@ -120,52 +114,6 @@ void TestTimer::record(const int hands, const long user_ms, const long sys_ms) count_ += hands; user_cum_ += user_ms; sys_cum_ += sys_ms; - - const double user_per_hand = user_ms / static_cast(hands); - const double sys_per_hand = sys_ms / static_cast(hands); - if (batch_count_ == 0) - { - user_min_ = user_max_ = user_per_hand; - sys_min_ = sys_max_ = sys_per_hand; - } - else - { - user_min_ = std::min(user_min_, user_per_hand); - user_max_ = std::max(user_max_, user_per_hand); - sys_min_ = std::min(sys_min_, sys_per_hand); - sys_max_ = std::max(sys_max_, sys_per_hand); - } - batch_count_++; -} - - -bool TestTimer::has_batch_times() const -{ - return batch_count_ > 0; -} - - -double TestTimer::user_min_ms() const -{ - return user_min_; -} - - -double TestTimer::user_max_ms() const -{ - return user_max_; -} - - -double TestTimer::sys_min_ms() const -{ - return sys_min_; -} - - -double TestTimer::sys_max_ms() const -{ - return sys_max_; } @@ -226,10 +174,7 @@ void TestTimer::print_basic() const } -void TestTimer::print_hands( - ostream& out, - const bool show_min, - const bool show_max) const +void TestTimer::print_hands(ostream& out) const { struct StreamFormatGuard { @@ -277,12 +222,6 @@ void TestTimer::print_hands( out << setw(21) << left << "Avg user time (ms)" << setw(12) << right << fixed << setprecision(2) << user_cum_ / static_cast(count_) << "\n"; - if (show_min && has_batch_times()) - out << setw(21) << left << "Min user time (ms)" << - setw(12) << right << fixed << setprecision(2) << user_min_ << "\n"; - if (show_max && has_batch_times()) - out << setw(21) << left << "Max user time (ms)" << - setw(12) << right << fixed << setprecision(2) << user_max_ << "\n"; } if (!sys_time_known_) @@ -298,12 +237,6 @@ void TestTimer::print_hands( out << setw(21) << left << "Avg sys time (ms)" << setw(12) << right << fixed << setprecision(2) << sys_cum_ / static_cast(count_) << "\n"; - if (show_min && has_batch_times()) - out << setw(21) << left << "Min sys time (ms)" << - setw(12) << right << fixed << setprecision(2) << sys_min_ << "\n"; - if (show_max && has_batch_times()) - out << setw(21) << left << "Max sys time (ms)" << - setw(12) << right << fixed << setprecision(2) << sys_max_ << "\n"; if (user_cum_ > 0) { out << setw(21) << left << "Ratio" << setw(12) << right << fixed << setprecision(2) << diff --git a/library/tests/TestTimer.hpp b/library/tests/TestTimer.hpp index ebf936e5f..1575d9ac1 100644 --- a/library/tests/TestTimer.hpp +++ b/library/tests/TestTimer.hpp @@ -7,6 +7,7 @@ See LICENSE and README. */ + #pragma once #include @@ -40,11 +41,6 @@ class TestTimer long user_cum_; ///< Cumulative user time (milliseconds) long user_cum_old_; ///< Previous cumulative user time (milliseconds) long sys_cum_; ///< Cumulative system time (milliseconds) - double user_min_; ///< Min per-hand user time across batches (ms) - double user_max_; ///< Max per-hand user time across batches (ms) - double sys_min_; ///< Min per-hand system time across batches (ms) - double sys_max_; ///< Max per-hand system time across batches (ms) - long batch_count_; ///< Number of completed batches int pending_hands_; ///< Hands counted into the open start()/end() batch bool sys_time_known_; ///< False when clock() is unusable (e.g. wasm32) @@ -80,29 +76,13 @@ class TestTimer void end(); /// Record one completed batch without wall-clock measurement. - /// Updates cumulative totals and per-hand min/max extremes. - /// Used by end() and by unit tests for deterministic extremes. - /// Non-positive hands is ignored (no cumulative or extreme updates). + /// Updates cumulative totals. Used by end() and by unit tests. + /// Non-positive hands is ignored (no cumulative updates). /// @param hands Number of hands in the batch /// @param user_ms Batch user (wall) time in milliseconds /// @param sys_ms Batch system (CPU) time in milliseconds void record(const int hands, const long user_ms, const long sys_ms); - /// Whether at least one batch has been recorded. - bool has_batch_times() const; - - /// Minimum per-hand user time across batches (milliseconds). - double user_min_ms() const; - - /// Maximum per-hand user time across batches (milliseconds). - double user_max_ms() const; - - /// Minimum per-hand system time across batches (milliseconds). - double sys_min_ms() const; - - /// Maximum per-hand system time across batches (milliseconds). - double sys_max_ms() const; - /// Print timer status while running. /// @param reached Number of iterations completed so far /// @param number Total number of iterations @@ -115,10 +95,5 @@ class TestTimer /// Print detailed per-hand timer results. /// @param out Output stream - /// @param show_min Include min per-hand times across batches - /// @param show_max Include max per-hand times across batches - void print_hands( - std::ostream& out = std::cout, - bool show_min = false, - bool show_max = false) const; + void print_hands(std::ostream& out = std::cout) const; }; diff --git a/library/tests/args.cpp b/library/tests/args.cpp index 9480a0f5a..e4af7a388 100644 --- a/library/tests/args.cpp +++ b/library/tests/args.cpp @@ -42,7 +42,7 @@ struct optEntry unsigned numArgs; }; -#define DTEST_NUM_OPTIONS 7 +#define DTEST_NUM_OPTIONS 5 enum DtestOpt { @@ -50,9 +50,7 @@ enum DtestOpt OPT_SOLVER = 1, OPT_NUMTHR = 2, OPT_MEMORY = 3, - OPT_REPORT = 4, - OPT_MAX = 5, - OPT_MIN = 6 + OPT_REPORT = 4 }; const optEntry optList[DTEST_NUM_OPTIONS] = @@ -61,9 +59,7 @@ const optEntry optList[DTEST_NUM_OPTIONS] = {"s", "solver", 1}, {"n", "numthr", 1}, {"m", "memory", 1}, - {"r", "report", 0}, - {"", "max", 0}, - {"", "min", 0} + {"r", "report", 0} }; const vector solverList = @@ -115,10 +111,6 @@ void usage( "\n" << "-r, --report Print per-board timings sorted by longest first.\n" << "\n" << - " --max Also print max per-hand user/sys time across batches.\n" << - "\n" << - " --min Also print min per-hand user/sys time across batches.\n" << - "\n" << endl; } @@ -167,8 +159,7 @@ int GetNextArgToken( else nextToken++; - // Return 1-based option index so --max/--min do not collide with - // --memory on the shared leading 'm'. + // Return 1-based option index so 0 can mean "done". return static_cast(i) + 1; } } @@ -184,8 +175,6 @@ void SetDefaults() options.num_threads_ = 0; options.memory_mb_ = 0; options.report_slow_boards_ = false; - options.show_min_ = false; - options.show_max_ = false; } @@ -503,14 +492,6 @@ void read_args( options.report_slow_boards_ = true; break; - case OPT_MAX: - options.show_max_ = true; - break; - - case OPT_MIN: - options.show_min_ = true; - break; - default: cout << "Unknown option\n"; errFlag = true; diff --git a/library/tests/args.hpp b/library/tests/args.hpp index 529b34445..dde540226 100644 --- a/library/tests/args.hpp +++ b/library/tests/args.hpp @@ -21,7 +21,6 @@ /// - Number of threads /// - Memory allocation /// - Slow board reporting -/// - Optional min/max per-hand timing summary across batches /// Print usage information. /// @param base Command name for usage message diff --git a/library/tests/args_test.cpp b/library/tests/args_test.cpp index 2cb602b45..41aba6afa 100644 --- a/library/tests/args_test.cpp +++ b/library/tests/args_test.cpp @@ -192,17 +192,6 @@ class HandsLayoutFixture : public ::testing::Test } // namespace -TEST(Args, MaxAndMinFlagsDefaultOff) -{ - const std::string path = make_temp_input_file(); - char arg0[] = "dtest"; - char arg_f[] = "-f"; - char* argv[] = {arg0, arg_f, const_cast(path.c_str())}; - read_args(3, argv); - EXPECT_FALSE(options.show_min_); - EXPECT_FALSE(options.show_max_); -} - TEST(Args, MakeDirSucceedsWhenDirectoryAlreadyExists) { const std::string dir = @@ -222,42 +211,16 @@ TEST(Args, MakeDirFailsWhenPathIsExistingFile) EXPECT_FALSE(make_dir(path)); } -TEST(Args, MaxFlagEnablesShowMax) -{ - const std::string path = make_temp_input_file(); - char arg0[] = "dtest"; - char arg_f[] = "-f"; - char arg_max[] = "--max"; - char* argv[] = {arg0, arg_f, const_cast(path.c_str()), arg_max}; - read_args(4, argv); - EXPECT_TRUE(options.show_max_); - EXPECT_FALSE(options.show_min_); -} - -TEST(Args, MinFlagEnablesShowMin) +TEST(Args, UnknownMinMaxFlagsAreRejected) { + // Former --min/--max batch-extreme flags must not be accepted. + // read_args prints to cout and exits(0); death tests only match stderr. const std::string path = make_temp_input_file(); char arg0[] = "dtest"; char arg_f[] = "-f"; char arg_min[] = "--min"; char* argv[] = {arg0, arg_f, const_cast(path.c_str()), arg_min}; - read_args(4, argv); - EXPECT_TRUE(options.show_min_); - EXPECT_FALSE(options.show_max_); -} - -TEST(Args, MaxAndMinFlagsCanCombine) -{ - const std::string path = make_temp_input_file(); - char arg0[] = "dtest"; - char arg_f[] = "-f"; - char arg_max[] = "--max"; - char arg_min[] = "--min"; - char* argv[] = { - arg0, arg_f, const_cast(path.c_str()), arg_max, arg_min}; - read_args(5, argv); - EXPECT_TRUE(options.show_min_); - EXPECT_TRUE(options.show_max_); + EXPECT_EXIT(read_args(4, argv), ::testing::ExitedWithCode(0), ".*"); } TEST(Args, ResolvePrefersLiteralExistingPath) diff --git a/library/tests/cst.hpp b/library/tests/cst.hpp index a1c113fc6..9785284fc 100644 --- a/library/tests/cst.hpp +++ b/library/tests/cst.hpp @@ -36,7 +36,5 @@ struct OptionsType int num_threads_; ///< Number of threads to use int memory_mb_; ///< Memory allocation in MB bool report_slow_boards_; ///< Report slow-executing hands - bool show_min_; ///< Report min per-hand time across batches - bool show_max_; ///< Report max per-hand time across batches }; diff --git a/library/tests/test_timer_test.cpp b/library/tests/test_timer_test.cpp index c753bb0a0..1800d5ec5 100644 --- a/library/tests/test_timer_test.cpp +++ b/library/tests/test_timer_test.cpp @@ -1,5 +1,5 @@ /// @file test_timer_test.cpp -/// @brief Unit tests for TestTimer batch min/max tracking and optional reporting. +/// @brief Unit tests for TestTimer accumulation, printing, and clock helpers. #include #include @@ -14,13 +14,10 @@ namespace { -std::string capture_print_hands( - const TestTimer& timer, - const bool show_min, - const bool show_max) +std::string capture_print_hands(const TestTimer& timer) { std::ostringstream out; - timer.print_hands(out, show_min, show_max); + timer.print_hands(out); return out.str(); } @@ -91,45 +88,19 @@ TEST(TestTimer, ClockDeltaToMsAvoids32BitOverflowForMultiSecondBatches) EXPECT_NE(clock_delta_to_ms(ticks), wrapped_ms); } -TEST(TestTimer, RecordTracksMinAndMaxPerHandAcrossBatches) +TEST(TestTimer, RecordAccumulatesHandsAndTimes) { TestTimer timer; - - // Batch totals: (100ms / 10 hands), (300 / 10), (200 / 10) timer.record(10, 100, 50); - timer.record(10, 300, 80); - timer.record(10, 200, 40); - - EXPECT_TRUE(timer.has_batch_times()); - EXPECT_DOUBLE_EQ(timer.user_min_ms(), 10.0); - EXPECT_DOUBLE_EQ(timer.user_max_ms(), 30.0); - EXPECT_DOUBLE_EQ(timer.sys_min_ms(), 4.0); - EXPECT_DOUBLE_EQ(timer.sys_max_ms(), 8.0); -} - -TEST(TestTimer, SingleBatchMinEqualsMaxEqualsPerHand) -{ - TestTimer timer; - timer.record(5, 42, 7); + timer.record(5, 20, 10); - EXPECT_DOUBLE_EQ(timer.user_min_ms(), 8.4); - EXPECT_DOUBLE_EQ(timer.user_max_ms(), 8.4); - EXPECT_DOUBLE_EQ(timer.sys_min_ms(), 1.4); - EXPECT_DOUBLE_EQ(timer.sys_max_ms(), 1.4); -} - -TEST(TestTimer, UnevenBatchSizesUsePerHandNotBatchTotal) -{ - TestTimer timer; - // Slower per hand but smaller total: 50ms / 5 = 10.0 - timer.record(5, 50, 10); - // Faster per hand but larger total: 90ms / 30 = 3.0 - timer.record(30, 90, 30); - - EXPECT_DOUBLE_EQ(timer.user_min_ms(), 3.0); - EXPECT_DOUBLE_EQ(timer.user_max_ms(), 10.0); - EXPECT_DOUBLE_EQ(timer.sys_min_ms(), 1.0); - EXPECT_DOUBLE_EQ(timer.sys_max_ms(), 2.0); + const std::string out = capture_print_hands(timer); + EXPECT_NE(out.find("Number of hands"), std::string::npos); + EXPECT_NE(out.find("15"), std::string::npos); // 10 + 5 hands + EXPECT_NE(out.find("120"), std::string::npos); // 100 + 20 user ms + EXPECT_NE(out.find("8.00"), std::string::npos); // avg user 120/15 + EXPECT_EQ(out.find("Min user time (ms)"), std::string::npos); + EXPECT_EQ(out.find("Max user time (ms)"), std::string::npos); } TEST(TestTimer, RecordIgnoresNonPositiveHands) @@ -139,41 +110,23 @@ TEST(TestTimer, RecordIgnoresNonPositiveHands) timer.record(0, 999, 999); timer.record(-3, 999, 999); - EXPECT_TRUE(timer.has_batch_times()); - EXPECT_DOUBLE_EQ(timer.user_min_ms(), 10.0); - EXPECT_DOUBLE_EQ(timer.user_max_ms(), 10.0); - EXPECT_DOUBLE_EQ(timer.sys_min_ms(), 5.0); - EXPECT_DOUBLE_EQ(timer.sys_max_ms(), 5.0); - - const std::string out = capture_print_hands(timer, false, false); + const std::string out = capture_print_hands(timer); EXPECT_NE(out.find("Number of hands"), std::string::npos); EXPECT_NE(out.find("100"), std::string::npos); EXPECT_NE(out.find("10.00"), std::string::npos); EXPECT_EQ(out.find("999"), std::string::npos); } -TEST(TestTimer, ResetClearsBatchExtremes) +TEST(TestTimer, ResetClearsAccumulatedStats) { TestTimer timer; timer.record(1, 10, 2); timer.reset(); - EXPECT_FALSE(timer.has_batch_times()); -} - -TEST(TestTimer, PrintHandsOmitsMinMaxByDefault) -{ - TestTimer timer; - timer.set_name("Hand stats"); - timer.record(2, 20, 4); - - const std::string out = capture_print_hands(timer, false, false); - - EXPECT_NE(out.find("Avg user time (ms)"), std::string::npos); - EXPECT_EQ(out.find("Min user time (ms)"), std::string::npos); - EXPECT_EQ(out.find("Max user time (ms)"), std::string::npos); - EXPECT_EQ(out.find("Min sys time (ms)"), std::string::npos); - EXPECT_EQ(out.find("Max sys time (ms)"), std::string::npos); + const std::string out = capture_print_hands(timer); + EXPECT_NE(out.find("Number of hands"), std::string::npos); + EXPECT_NE(out.find("0"), std::string::npos); + EXPECT_EQ(out.find("User time (ms)"), std::string::npos); } TEST(TestTimer, PrintHandsShowsSysNaWhenClockUnavailable) @@ -184,45 +137,13 @@ TEST(TestTimer, PrintHandsShowsSysNaWhenClockUnavailable) timer.mark_sys_time_unavailable(); timer.record(10, 100, 0); - const std::string out = capture_print_hands(timer, false, false); + const std::string out = capture_print_hands(timer); EXPECT_NE(out.find("Sys time (ms)"), std::string::npos); EXPECT_NE(out.find("n/a"), std::string::npos); EXPECT_EQ(out.find("zero"), std::string::npos); } -TEST(TestTimer, PrintHandsShowsMinWhenRequested) -{ - TestTimer timer; - timer.record(2, 20, 4); // 10.0 user / hand, 2.0 sys / hand - timer.record(2, 10, 8); // 5.0 user / hand, 4.0 sys / hand - - const std::string out = capture_print_hands(timer, true, false); - - EXPECT_NE(out.find("Min user time (ms)"), std::string::npos); - EXPECT_NE(out.find("Min sys time (ms)"), std::string::npos); - EXPECT_EQ(out.find("Max user time (ms)"), std::string::npos); - EXPECT_EQ(out.find("Max sys time (ms)"), std::string::npos); - EXPECT_NE(out.find("5.00"), std::string::npos); - EXPECT_NE(out.find("2.00"), std::string::npos); -} - -TEST(TestTimer, PrintHandsShowsMaxWhenRequested) -{ - TestTimer timer; - timer.record(2, 20, 4); // 10.0 / 2.0 - timer.record(2, 10, 8); // 5.0 / 4.0 - - const std::string out = capture_print_hands(timer, false, true); - - EXPECT_NE(out.find("Max user time (ms)"), std::string::npos); - EXPECT_NE(out.find("Max sys time (ms)"), std::string::npos); - EXPECT_EQ(out.find("Min user time (ms)"), std::string::npos); - EXPECT_EQ(out.find("Min sys time (ms)"), std::string::npos); - EXPECT_NE(out.find("10.00"), std::string::npos); - EXPECT_NE(out.find("4.00"), std::string::npos); -} - TEST(TestTimer, PrintHandsRestoresStreamFormatState) { TestTimer timer; @@ -233,7 +154,7 @@ TEST(TestTimer, PrintHandsRestoresStreamFormatState) const auto flags_before = out.flags(); const auto precision_before = out.precision(); - timer.print_hands(out, true, true); + timer.print_hands(out); EXPECT_EQ(out.flags(), flags_before); EXPECT_EQ(out.precision(), precision_before); diff --git a/library/tests/testcommon.cpp b/library/tests/testcommon.cpp index f28bbb3b1..c093bac33 100644 --- a/library/tests/testcommon.cpp +++ b/library/tests/testcommon.cpp @@ -141,7 +141,7 @@ int real_main([[maybe_unused]] int argc, [[maybe_unused]] char * argv[]) exit(0); } - timer.print_hands(cout, options.show_min_, options.show_max_); + timer.print_hands(cout); if (options.report_slow_boards_) { From fb396762fa5260b2e691164eb1dc5f56e019e77a Mon Sep 17 00:00:00 2001 From: Adam Wildavsky Date: Fri, 7 Aug 2026 23:17:12 +0200 Subject: [PATCH 2/6] Address Copilot review: reject both --min and --max in args_test. Co-authored-by: Cursor --- library/tests/args_test.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/library/tests/args_test.cpp b/library/tests/args_test.cpp index 41aba6afa..88ec91ad5 100644 --- a/library/tests/args_test.cpp +++ b/library/tests/args_test.cpp @@ -219,8 +219,11 @@ TEST(Args, UnknownMinMaxFlagsAreRejected) char arg0[] = "dtest"; char arg_f[] = "-f"; char arg_min[] = "--min"; - char* argv[] = {arg0, arg_f, const_cast(path.c_str()), arg_min}; - EXPECT_EXIT(read_args(4, argv), ::testing::ExitedWithCode(0), ".*"); + char arg_max[] = "--max"; + char* argv_min[] = {arg0, arg_f, const_cast(path.c_str()), arg_min}; + char* argv_max[] = {arg0, arg_f, const_cast(path.c_str()), arg_max}; + EXPECT_EXIT(read_args(4, argv_min), ::testing::ExitedWithCode(0), ".*"); + EXPECT_EXIT(read_args(4, argv_max), ::testing::ExitedWithCode(0), ".*"); } TEST(Args, ResolvePrefersLiteralExistingPath) From ff0023f459e740189360137e7716b156ed700d73 Mon Sep 17 00:00:00 2001 From: Adam Wildavsky Date: Fri, 7 Aug 2026 23:27:49 +0200 Subject: [PATCH 3/6] Address Copilot review: assert reset hands count is exactly 0. Co-authored-by: Cursor --- library/tests/test_timer_test.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/library/tests/test_timer_test.cpp b/library/tests/test_timer_test.cpp index 1800d5ec5..22258e864 100644 --- a/library/tests/test_timer_test.cpp +++ b/library/tests/test_timer_test.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -124,8 +125,10 @@ TEST(TestTimer, ResetClearsAccumulatedStats) timer.reset(); const std::string out = capture_print_hands(timer); - EXPECT_NE(out.find("Number of hands"), std::string::npos); - EXPECT_NE(out.find("0"), std::string::npos); + // Require the hands count field itself to be 0 (not a substring match like + // "10", which also contains '0'). + EXPECT_TRUE(std::regex_search( + out, std::regex(R"(Number of hands\s+0\s*(?:\n|$))"))); EXPECT_EQ(out.find("User time (ms)"), std::string::npos); } From c99a2debad3b20e64c36567ac41bc3301595e2f9 Mon Sep 17 00:00:00 2001 From: Adam Wildavsky Date: Fri, 7 Aug 2026 23:40:52 +0200 Subject: [PATCH 4/6] Avoid MSAN timeout in calc_par_test. Drop the redundant ContextReusePerformance loop (reuse is already covered) and mark the target medium so the remaining suite has headroom under the MSAN small-test limit. Co-authored-by: Cursor --- library/tests/BUILD.bazel | 6 ++++-- library/tests/calc_par_test.cpp | 23 ----------------------- 2 files changed, 4 insertions(+), 25 deletions(-) diff --git a/library/tests/BUILD.bazel b/library/tests/BUILD.bazel index 2c56b3a26..61b1e2838 100644 --- a/library/tests/BUILD.bazel +++ b/library/tests/BUILD.bazel @@ -56,11 +56,13 @@ cc_test( ], ) -# Standalone calc_par API test +# Standalone calc_par API test. +# medium: MSAN can spend ~80s on the remaining suite alone (small = 120s under +# --config=msan), so keep headroom against runner load variance. cc_test( name = "calc_par_test", srcs = ["calc_par_test.cpp"], - size = "small", + size = "medium", copts = DDS_CPPOPTS, linkopts = DDS_LINKOPTS, local_defines = DDS_LOCAL_DEFINES, diff --git a/library/tests/calc_par_test.cpp b/library/tests/calc_par_test.cpp index 2d786d6d1..30cd12ca0 100644 --- a/library/tests/calc_par_test.cpp +++ b/library/tests/calc_par_test.cpp @@ -379,26 +379,3 @@ TEST_F(CalcParTest, CalcParContextOverloadMatchesNonContext) << "Hand " << hand_idx << " EW contracts differ"; } } - -// Performance test: context reuse should work efficiently -TEST_F(CalcParTest, ContextReusePerformance) -{ - SolverContext ctx; - - // Run multiple calculations with same context - const int num_iterations = 10; - for (int i = 0; i < num_iterations; i++) { - DdTableResults table; - ParResults par; - - // Alternate between different deals - DdTableDeal* deal = (i % 2 == 0) ? &deal0_ : &deal1_; - int vuln = vulnerability_[i % 2]; - - int result = calc_par(ctx, *deal, vuln, &table, &par); - ASSERT_EQ(result, RETURN_NO_FAULT) << "Iteration " << i << " should succeed"; - } - - // If we got here, context reuse is working - SUCCEED(); -} From 447c7b866457e2e1bffd70d4c495f549073150f4 Mon Sep 17 00:00:00 2001 From: Adam Wildavsky Date: Sat, 8 Aug 2026 00:08:55 +0200 Subject: [PATCH 5/6] Avoid MSAN timeout in analyse_play_consistency_test. Mark the target medium so the random-playout suite has headroom under the MSAN small-test limit. Co-authored-by: Cursor --- library/tests/solve_board/BUILD.bazel | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/library/tests/solve_board/BUILD.bazel b/library/tests/solve_board/BUILD.bazel index a8ec48b81..79015b24d 100644 --- a/library/tests/solve_board/BUILD.bazel +++ b/library/tests/solve_board/BUILD.bazel @@ -17,9 +17,11 @@ cc_test( copts = DDS_CPPOPTS, ) +# medium: MSAN can exceed the small-test limit (120s under --config=msan) on the +# random-playout consistency suite, so keep headroom against runner load variance. cc_test( name = "analyse_play_consistency_test", - size = "small", + size = "medium", srcs = [ "analyse_play_consistency.cpp", ], From ba3bccc8f59b415db2534cb21fcbf2aac733f405 Mon Sep 17 00:00:00 2001 From: Adam Wildavsky Date: Sat, 8 Aug 2026 00:36:11 +0200 Subject: [PATCH 6/6] Address Copilot review: anchor timer stats to field labels. Use label-bound regexes for hands/user/avg values so digit substrings elsewhere in the report cannot falsely pass. Co-authored-by: Cursor --- library/tests/test_timer_test.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/library/tests/test_timer_test.cpp b/library/tests/test_timer_test.cpp index 22258e864..202c19d6c 100644 --- a/library/tests/test_timer_test.cpp +++ b/library/tests/test_timer_test.cpp @@ -96,10 +96,14 @@ TEST(TestTimer, RecordAccumulatesHandsAndTimes) timer.record(5, 20, 10); const std::string out = capture_print_hands(timer); - EXPECT_NE(out.find("Number of hands"), std::string::npos); - EXPECT_NE(out.find("15"), std::string::npos); // 10 + 5 hands - EXPECT_NE(out.find("120"), std::string::npos); // 100 + 20 user ms - EXPECT_NE(out.find("8.00"), std::string::npos); // avg user 120/15 + // Anchor values to their labels so digits elsewhere in the report cannot + // satisfy the assertions (e.g. "15" matching inside "150"). + EXPECT_TRUE(std::regex_search( + out, std::regex(R"(Number of hands\s+15\s*(?:\n|$))"))); // 10 + 5 + EXPECT_TRUE(std::regex_search( + out, std::regex(R"(User time \(ms\)\s+120\s*(?:\n|$))"))); // 100 + 20 + EXPECT_TRUE(std::regex_search( + out, std::regex(R"(Avg user time \(ms\)\s+8\.00\s*(?:\n|$))"))); // 120/15 EXPECT_EQ(out.find("Min user time (ms)"), std::string::npos); EXPECT_EQ(out.find("Max user time (ms)"), std::string::npos); } @@ -112,9 +116,12 @@ TEST(TestTimer, RecordIgnoresNonPositiveHands) timer.record(-3, 999, 999); const std::string out = capture_print_hands(timer); - EXPECT_NE(out.find("Number of hands"), std::string::npos); - EXPECT_NE(out.find("100"), std::string::npos); - EXPECT_NE(out.find("10.00"), std::string::npos); + EXPECT_TRUE(std::regex_search( + out, std::regex(R"(Number of hands\s+10\s*(?:\n|$))"))); + EXPECT_TRUE(std::regex_search( + out, std::regex(R"(User time \(ms\)\s+100\s*(?:\n|$))"))); + EXPECT_TRUE(std::regex_search( + out, std::regex(R"(Avg user time \(ms\)\s+10\.00\s*(?:\n|$))"))); EXPECT_EQ(out.find("999"), std::string::npos); }