Browse Source

test: optimize AllCases test suites

master
Dnomd343 2 months ago
parent
commit
92398275b1
  1. 63
      src/core_test/cases/all_cases.cc
  2. 24
      src/core_test/cases/basic_ranges.cc
  3. 40
      src/core_test/cases/cases_helper.h
  4. 2
      src/core_test/cases/helper/block_num.cc
  5. 41
      src/core_test/cases/helper/cases.h
  6. 2
      src/core_test/cases/ranges.cc

63
src/core_test/cases/all_cases.cc

@ -1,11 +1,26 @@
#include "hash.h" #include <gtest/gtest.h>
#include "cases_helper.h"
#include "helper/cases.h"
#include "utility/hash.h"
#include "utility/exposer.h"
#include "short_code/short_code.h"
#include "common_code/common_code.h" #include "common_code/common_code.h"
using klotski::array_sum;
using klotski::cases::Ranges; using klotski::cases::Ranges;
using klotski::cases::AllCases;
using klotski::cases::BasicRanges;
using klotski::codec::ShortCode;
using klotski::codec::CommonCode; using klotski::codec::CommonCode;
static constexpr auto ALL_CASES_XXH3 = std::to_array<uint64_t>({ using klotski::cases::ALL_CASES_NUM_;
using klotski::codec::SHORT_CODE_LIMIT;
/// Forcibly modify private variables to reset state.
EXPOSE_VAR(AllCases, bool, available_)
constexpr auto ALL_CASES_XXH3 = std::to_array<uint64_t>({
0x71c8ff7a71c93da0, 0x2a5247ee8bfed666, 0xf4efc8fc692d58e2, 0x2d06800538d394c2, 0x71c8ff7a71c93da0, 0x2a5247ee8bfed666, 0xf4efc8fc692d58e2, 0x2d06800538d394c2,
0xb3f7cc1b962d6944, 0x7e2792f8ab777faa, 0x4b8e78026cca8a27, 0x2d06800538d394c2, 0xb3f7cc1b962d6944, 0x7e2792f8ab777faa, 0x4b8e78026cca8a27, 0x2d06800538d394c2,
0x8acd688c5ab93c42, 0xedca5101ed81cc77, 0xe8dc9d30c91ce682, 0x2d06800538d394c2, 0x8acd688c5ab93c42, 0xedca5101ed81cc77, 0xe8dc9d30c91ce682, 0x2d06800538d394c2,
@ -40,31 +55,24 @@ protected:
}; };
TEST_FF(AllCases, content) { TEST_FF(AllCases, content) {
auto verify = [](const uint64_t head) { for (auto head : Heads) {
auto &cases = AllCases::instance().fetch()[head]; auto &cases = AllCases::instance().fetch()[head];
EXPECT_SORTED_AND_UNIQUE(cases);
EXPECT_EQ(cases.size(), ALL_CASES_NUM[head]); // size verify EXPECT_EQ(cases.size(), ALL_CASES_NUM[head]); // size verify
EXPECT_EQ(hash::xxh3(cases), ALL_CASES_XXH3[head]); // checksum verify EXPECT_EQ(hash::xxh3(cases), ALL_CASES_XXH3[head]); // checksum verify
EXPECT_SUBSET(BasicRanges::instance().fetch(), cases); // subset verify
EXPECT_TRUE(std::ranges::is_sorted(cases.begin(), cases.end())); EXPECT_COMMON_CODES(head, cases); // release verify
const auto match = std::ranges::adjacent_find(cases.begin(), cases.end());
EXPECT_EQ(match, cases.end()); // no duplicates
auto &all = BasicRanges::instance().fetch(); // subset verify
EXPECT_TRUE(std::ranges::includes(all.begin(), all.end(), cases.begin(), cases.end()));
for (const auto range : cases) {
CommonCode::check(head << 32 | range); // release verify
} }
};
for (int head = 0; head < 16; ++head) { ShortCode::speed_up(true);
if (head % 4 != 3) { std::vector<uint32_t> short_codes;
verify(head); short_codes.reserve(ALL_CASES_NUM_);
continue; for (const auto code : AllCases::instance().fetch().codes()) {
} short_codes.emplace_back(code.to_short_code().unwrap());
EXPECT_EQ(AllCases::instance().fetch()[head].size(), 0);
} }
EXPECT_EQ(short_codes.front(), 0);
EXPECT_SORTED_AND_UNIQUE(short_codes);
EXPECT_EQ(short_codes.back(), SHORT_CODE_LIMIT - 1);
} }
TEST_FF(AllCases, constant) { TEST_FF(AllCases, constant) {
@ -72,13 +80,14 @@ TEST_FF(AllCases, constant) {
EXPECT_EQ(ALL_CASES_NUM.size(), 16); EXPECT_EQ(ALL_CASES_NUM.size(), 16);
EXPECT_EQ(array_sum(ALL_CASES_NUM), ALL_CASES_NUM_); EXPECT_EQ(array_sum(ALL_CASES_NUM), ALL_CASES_NUM_);
EXPECT_EQ(ALL_CASES_NUM[3], 0);
EXPECT_EQ(ALL_CASES_NUM[7], 0);
EXPECT_EQ(ALL_CASES_NUM[11], 0);
EXPECT_EQ(ALL_CASES_NUM[15], 0);
auto ranges = BasicRanges::instance().fetch(); auto ranges = BasicRanges::instance().fetch();
ranges.reverse(); ranges.reverse();
for (int head = 0; head < 16; ++head) { for (const auto head : Heads) {
if (head % 4 == 3) {
EXPECT_EQ(ALL_CASES_NUM[head], 0);
continue;
}
Ranges release; Ranges release;
ranges.derive(head, release); ranges.derive(head, release);
EXPECT_EQ(release.size(), ALL_CASES_NUM[head]); EXPECT_EQ(release.size(), ALL_CASES_NUM[head]);

24
src/core_test/cases/basic_ranges.cc

@ -1,12 +1,22 @@
#include "hash.h" #include <gtest/gtest.h>
#include "group/group.h" #include "group/group.h"
#include "cases_helper.h" #include "helper/cases.h"
#include "utility/hash.h"
#include "utility/exposer.h"
using klotski::array_sum;
using klotski::cases::Ranges; using klotski::cases::Ranges;
using klotski::cases::AllCases;
using klotski::cases::BasicRanges;
using klotski::cases::BLOCK_NUM; using klotski::cases::BLOCK_NUM;
using klotski::cases::TYPE_ID_LIMIT; using klotski::cases::TYPE_ID_LIMIT;
static constexpr uint64_t BASIC_RANGES_XXH3 = 0x34fce9da6a052533; /// Forcibly modify private variables to reset state.
EXPOSE_VAR(BasicRanges, bool, available_)
constexpr uint64_t BASIC_RANGES_XXH3 = 0x34fce9da6a052533;
class BasicRangesTest : public testing::Test, public Concurrent { class BasicRangesTest : public testing::Test, public Concurrent {
protected: protected:
@ -35,11 +45,7 @@ protected:
TEST_FF(BasicRanges, content) { TEST_FF(BasicRanges, content) {
auto &ranges = BasicRanges::instance().fetch(); auto &ranges = BasicRanges::instance().fetch();
EXPECT_SORTED_AND_UNIQUE(ranges);
EXPECT_TRUE(std::ranges::is_sorted(ranges.begin(), ranges.end()));
const auto match = std::ranges::adjacent_find(ranges.begin(), ranges.end());
EXPECT_EQ(match, ranges.end()); // no duplicates
EXPECT_EQ(ranges.size(), BASIC_RANGES_NUM_); // size verify EXPECT_EQ(ranges.size(), BASIC_RANGES_NUM_); // size verify
EXPECT_EQ(hash::xxh3(ranges), BASIC_RANGES_XXH3); // checksum verify EXPECT_EQ(hash::xxh3(ranges), BASIC_RANGES_XXH3); // checksum verify
} }
@ -50,7 +56,7 @@ TEST_FF(BasicRanges, constant) {
EXPECT_EQ(array_sum(BASIC_RANGES_NUM), BASIC_RANGES_NUM_); EXPECT_EQ(array_sum(BASIC_RANGES_NUM), BASIC_RANGES_NUM_);
for (uint32_t type_id = 0; type_id < TYPE_ID_LIMIT; ++type_id) { for (uint32_t type_id = 0; type_id < TYPE_ID_LIMIT; ++type_id) {
auto [n, n_2x1, n_1x1] = BLOCK_NUM[type_id]; const auto [n, n_2x1, n_1x1] = BLOCK_NUM[type_id];
Ranges ranges; Ranges ranges;
ranges.spawn(n, n_2x1, n_1x1); ranges.spawn(n, n_2x1, n_1x1);
EXPECT_EQ(ranges.size(), BASIC_RANGES_NUM[type_id]); EXPECT_EQ(ranges.size(), BASIC_RANGES_NUM[type_id]);

40
src/core_test/cases/cases_helper.h

@ -1,40 +0,0 @@
#pragma once
#include <algorithm>
#include <gtest/gtest.h>
#include "exposer.h"
#include "concurrent.h"
#include "all_cases/all_cases.h"
using klotski::array_sum;
using klotski::cases::AllCases;
using klotski::cases::BasicRanges;
using klotski::cases::ALL_CASES_NUM;
using klotski::cases::ALL_CASES_NUM_;
using klotski::cases::BASIC_RANGES_NUM;
using klotski::cases::BASIC_RANGES_NUM_;
/// Test fixture wrapper with concurrency tools.
class Concurrent {
protected:
co::Racer racer_ {256};
co::Executor serial_ {1};
co::Executor executor_ {0};
std::atomic<int> counter_ {0};
std::atomic_flag condition_ {false};
};
/// Forcibly modify private variables to reset state.
EXPOSE_VAR(AllCases, bool, available_)
EXPOSE_VAR(BasicRanges, bool, available_)
/// Test fixture macro with custom test suite name.
#define TEST_FF(test_suite_name, test_name) \
GTEST_TEST_(test_suite_name, test_name, test_suite_name##Test, \
::testing::internal::GetTypeId<test_suite_name##Test>())

2
src/core_test/cases/helper/block_num.cc

@ -4,6 +4,8 @@
#include "cases.h" #include "cases.h"
using klotski::range_reverse;
/// Build the sequence list of all block numbers. /// Build the sequence list of all block numbers.
static std::vector<block_num_t> build_block_nums() { static std::vector<block_num_t> build_block_nums() {
std::vector<std::pair<uint32_t, block_num_t>> nums; std::vector<std::pair<uint32_t, block_num_t>> nums;

41
src/core_test/cases/helper/cases.h

@ -4,7 +4,9 @@
#include <algorithm> #include <algorithm>
#include "group/group.h" #include "group/group.h"
#include "all_cases/all_cases.h" #include "utility/concurrent.h"
// ----------------------------------------------------------------------------------------- //
using klotski::cases::Ranges; using klotski::cases::Ranges;
using klotski::cases::AllCases; using klotski::cases::AllCases;
@ -12,9 +14,6 @@ using klotski::codec::CommonCode;
using klotski::cases::BasicRanges; using klotski::cases::BasicRanges;
using klotski::cases::RangesUnion; using klotski::cases::RangesUnion;
using klotski::array_sum;
using klotski::range_reverse;
using klotski::cases::BLOCK_NUM; using klotski::cases::BLOCK_NUM;
using klotski::cases::ALL_CASES_NUM; using klotski::cases::ALL_CASES_NUM;
using klotski::cases::ALL_CASES_NUM; using klotski::cases::ALL_CASES_NUM;
@ -26,7 +25,31 @@ constexpr auto Heads = std::to_array({
0, 1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14 0, 1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14
}); });
// ------------------------------------------------------------------------------------- // // ----------------------------------------------------------------------------------------- //
/// Test fixture wrapper with concurrency tools.
class Concurrent {
protected:
// Execute same task concurrently.
co::Racer racer_ {256};
// Execute assigned tasks one by one.
co::Executor serial_ {1};
// Execute assigned tasks on all cores.
co::Executor executor_ {0};
// Atomic helpers for multi-thread testing.
std::atomic<int> counter_ {0};
std::atomic_flag condition_ {false};
};
/// Test fixture macro with custom test suite name.
#define TEST_FF(test_suite_name, test_name) \
GTEST_TEST_(test_suite_name, test_name, test_suite_name##Test, \
::testing::internal::GetTypeId<test_suite_name##Test>())
// ----------------------------------------------------------------------------------------- //
/// Assert that Ranges are sorted and unique. /// Assert that Ranges are sorted and unique.
#define EXPECT_SORTED_AND_UNIQUE(R) \ #define EXPECT_SORTED_AND_UNIQUE(R) \
@ -42,7 +65,7 @@ constexpr auto Heads = std::to_array({
for (const auto range : ranges) \ for (const auto range : ranges) \
EXPECT_TRUE(CommonCode::check(static_cast<uint64_t>(head) << 32 | range)) EXPECT_TRUE(CommonCode::check(static_cast<uint64_t>(head) << 32 | range))
// ------------------------------------------------------------------------------------- // // ----------------------------------------------------------------------------------------- //
/// The number of blocks in one klotski layout. /// The number of blocks in one klotski layout.
struct block_num_t { struct block_num_t {
@ -62,7 +85,7 @@ constexpr bool operator==(const block_num_t &lhs, const block_num_t &rhs) {
return lhs.n_1x1 == rhs.n_1x1 && lhs.n_1x2 == rhs.n_1x2 && lhs.n_2x1 == rhs.n_2x1; return lhs.n_1x1 == rhs.n_1x1 && lhs.n_1x2 == rhs.n_1x2 && lhs.n_2x1 == rhs.n_2x1;
} }
// ------------------------------------------------------------------------------------- // // ----------------------------------------------------------------------------------------- //
/// Calculate the block number from Range. /// Calculate the block number from Range.
block_num_t cal_block_num(uint32_t range); block_num_t cal_block_num(uint32_t range);
@ -76,7 +99,7 @@ block_num_t to_block_num(uint32_t type_id);
/// Get all block number combinations without dependencies. /// Get all block number combinations without dependencies.
const std::vector<block_num_t>& block_nums(); const std::vector<block_num_t>& block_nums();
// ------------------------------------------------------------------------------------- // // ----------------------------------------------------------------------------------------- //
// TODO: get cases with type id (filter from AllCases) // TODO: get cases with type id (filter from AllCases)
@ -87,3 +110,5 @@ const std::vector<CommonCode>& group_union_cases(uint32_t type_id);
std::vector<CommonCode> group_cases(uint32_t type_id, uint32_t group_id); std::vector<CommonCode> group_cases(uint32_t type_id, uint32_t group_id);
// TODO: always return ref of `std::vector` here // TODO: always return ref of `std::vector` here
// ----------------------------------------------------------------------------------------- //

2
src/core_test/cases/ranges.cc

@ -4,6 +4,8 @@
#include "helper/cases.h" #include "helper/cases.h"
#include "ranges/ranges.h" #include "ranges/ranges.h"
using klotski::range_reverse;
static_assert(std::is_base_of_v<std::vector<uint32_t>, Ranges>); static_assert(std::is_base_of_v<std::vector<uint32_t>, Ranges>);
TEST(Ranges, check) { TEST(Ranges, check) {

Loading…
Cancel
Save