Browse Source

test: more elegant parallelism

master
Dnomd343 2 months ago
parent
commit
1fc7d35c5e
  1. 78
      src/core_test/codec/common_code.cc
  2. 3
      src/core_test/codec/helper/codec.cc
  3. 20
      src/core_test/codec/helper/codec.h
  4. 40
      src/core_test/codec/raw_code.cc
  5. 41
      src/core_test/codec/short_code.cc

78
src/core_test/codec/common_code.cc

@ -147,59 +147,53 @@ TEST(CommonCode, initialize) {
} }
TEST(CommonCode, code_verify) { TEST(CommonCode, code_verify) {
common_code_parallel([](std::span<CommonCode> codes) { COMMON_CODE_PARALLEL({
for (auto code : codes) { EXPECT_TRUE(CommonCode::check(code.unwrap())); // verify all cases
EXPECT_TRUE(CommonCode::check(code.unwrap())); // verify all cases
}
}); });
} }
TEST(CommonCode, code_mirror) { TEST(CommonCode, code_mirror) {
common_code_parallel([](std::span<CommonCode> codes) { COMMON_CODE_PARALLEL({
for (auto code : codes) { const auto mirror_v = code.to_vertical_mirror();
const auto mirror_v = code.to_vertical_mirror(); EXPECT_TRUE(CommonCode::check(mirror_v.unwrap()));
EXPECT_TRUE(CommonCode::check(mirror_v.unwrap())); EXPECT_EQ(mirror_v.to_vertical_mirror(), code);
EXPECT_EQ(mirror_v.to_vertical_mirror(), code); EXPECT_FALSE(mirror_v.is_vertical_mirror()); // not exist
EXPECT_FALSE(mirror_v.is_vertical_mirror()); // not exist EXPECT_NE(mirror_v, code);
EXPECT_NE(mirror_v, code);
const auto mirror_h = code.to_horizontal_mirror();
const auto mirror_h = code.to_horizontal_mirror(); EXPECT_TRUE(CommonCode::check(mirror_h.unwrap()));
EXPECT_TRUE(CommonCode::check(mirror_h.unwrap())); EXPECT_EQ(mirror_h.to_horizontal_mirror(), code);
EXPECT_EQ(mirror_h.to_horizontal_mirror(), code); if (mirror_h.is_horizontal_mirror()) {
if (mirror_h.is_horizontal_mirror()) { EXPECT_EQ(mirror_h, code);
EXPECT_EQ(mirror_h, code); } else {
} else { EXPECT_NE(mirror_h, code);
EXPECT_NE(mirror_h, code);
}
} }
}); });
} }
TEST(CommonCode, code_string) { TEST(CommonCode, code_string) {
common_code_parallel([](std::span<CommonCode> codes) { COMMON_CODE_PARALLEL({
for (auto code : codes) { auto code_shorten = code.to_string(true); // with shorten
auto code_shorten = code.to_string(true); // with shorten auto code_normal = code.to_string(false); // without shorten
auto code_normal = code.to_string(false); // without shorten EXPECT_TRUE(code_normal.starts_with(code_shorten));
EXPECT_TRUE(code_normal.starts_with(code_shorten)); EXPECT_EQ(std::format("{:09X}", code.unwrap()), code_normal);
EXPECT_EQ(std::format("{:09X}", code.unwrap()), code_normal);
EXPECT_LE(code_shorten.size(), 9); // length -> (0, 9]
EXPECT_LE(code_shorten.size(), 9); // length -> (0, 9] EXPECT_NE(code_shorten.size(), 0);
EXPECT_NE(code_shorten.size(), 0); if (code != 0) { // skip special code string `0`
if (code != 0) { // skip special code string `0` EXPECT_NE(code_shorten.back(), '0');
EXPECT_NE(code_shorten.back(), '0'); }
} EXPECT_EQ(CommonCode::from_string(code_shorten), code); // test upper cases
EXPECT_EQ(CommonCode::from_string(code_shorten), code); // test upper cases std::transform(code_shorten.begin(), code_shorten.end(), code_shorten.begin(), ::tolower);
std::transform(code_shorten.begin(), code_shorten.end(), code_shorten.begin(), ::tolower); EXPECT_EQ(CommonCode::from_string(code_shorten), code); // test lower cases
EXPECT_EQ(CommonCode::from_string(code_shorten), code); // test lower cases
EXPECT_EQ(code_normal.size(), 9); // length = 9 EXPECT_EQ(code_normal.size(), 9); // length = 9
for (auto c : code_normal) { for (auto c : code_normal) {
EXPECT_TRUE((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F')); EXPECT_TRUE((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F'));
}
EXPECT_EQ(CommonCode::from_string(code_normal), code); // test upper cases
std::transform(code_normal.begin(), code_normal.end(), code_normal.begin(), ::tolower);
EXPECT_EQ(CommonCode::from_string(code_normal), code); // test lower cases
} }
EXPECT_EQ(CommonCode::from_string(code_normal), code); // test upper cases
std::transform(code_normal.begin(), code_normal.end(), code_normal.begin(), ::tolower);
EXPECT_EQ(CommonCode::from_string(code_normal), code); // test lower cases
}); });
} }

3
src/core_test/codec/helper/codec.cc

@ -2,6 +2,9 @@
#include "codec.h" #include "codec.h"
using klotski::cases::AllCases;
using klotski::cases::ALL_CASES_NUM_;
void head_parallel(std::function<void(uint64_t head)> &&func) { void head_parallel(std::function<void(uint64_t head)> &&func) {
constexpr auto heads = std::to_array({ 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

20
src/core_test/codec/helper/codec.h

@ -8,9 +8,6 @@
#include "short_code/short_code.h" #include "short_code/short_code.h"
#include "common_code/common_code.h" #include "common_code/common_code.h"
using klotski::cases::AllCases;
using klotski::cases::ALL_CASES_NUM_;
using klotski::codec::RawCode; using klotski::codec::RawCode;
using klotski::codec::ShortCode; using klotski::codec::ShortCode;
using klotski::codec::CommonCode; using klotski::codec::CommonCode;
@ -18,11 +15,24 @@ using klotski::codec::CommonCode;
/// Build all valid CommonCodes. /// Build all valid CommonCodes.
std::vector<uint64_t> all_common_codes(); std::vector<uint64_t> all_common_codes();
/// Spawn all valid klotski headers in parallel. // ----------------------------------------------------------------------------------------- //
void head_parallel(std::function<void(uint64_t)> &&func);
/// Spawn all valid RawCodes in parallel.
void raw_code_parallel(std::function<void(std::span<RawCode>)> &&func); void raw_code_parallel(std::function<void(std::span<RawCode>)> &&func);
/// Spawn all valid ShortCodes in parallel.
void short_code_parallel(std::function<void(std::span<ShortCode>)> &&func); void short_code_parallel(std::function<void(std::span<ShortCode>)> &&func);
/// Spawn all valid CommonCodes in parallel.
void common_code_parallel(std::function<void(std::span<CommonCode>)> &&func); void common_code_parallel(std::function<void(std::span<CommonCode>)> &&func);
#define CODE_PARALLEL(Type, type, impl) \
type##_code_parallel([](std::span<Type##Code> codes) { \
for (auto code : codes) {impl} \
})
#define RAW_CODE_PARALLEL(impl) CODE_PARALLEL(Raw, raw, impl)
#define SHORT_CODE_PARALLEL(impl) CODE_PARALLEL(Short, short, impl)
#define COMMON_CODE_PARALLEL(impl) CODE_PARALLEL(Common, common, impl)
// ----------------------------------------------------------------------------------------- //

40
src/core_test/codec/raw_code.cc

@ -119,32 +119,28 @@ TEST(RawCode, initialize) {
} }
TEST(RawCode, code_verify) { TEST(RawCode, code_verify) {
raw_code_parallel([](std::span<RawCode> codes) { RAW_CODE_PARALLEL({
for (auto code : codes) { EXPECT_TRUE(RawCode::check(code.unwrap()));
EXPECT_TRUE(RawCode::check(code.unwrap())); const auto common_code = code.to_common_code(); // RawCode::compact
const auto common_code = code.to_common_code(); // RawCode::compact EXPECT_EQ(RawCode::from_common_code(common_code), code); // RawCode::extract
EXPECT_EQ(RawCode::from_common_code(common_code), code); // RawCode::extract
}
}); });
} }
TEST(RawCode, code_mirror) { TEST(RawCode, code_mirror) {
raw_code_parallel([](std::span<RawCode> codes) { RAW_CODE_PARALLEL({
for (auto code : codes) { const auto mirror_v = code.to_vertical_mirror();
const auto mirror_v = code.to_vertical_mirror(); EXPECT_TRUE(RawCode::check(mirror_v.unwrap()));
EXPECT_TRUE(RawCode::check(mirror_v.unwrap())); EXPECT_EQ(mirror_v.to_vertical_mirror(), code);
EXPECT_EQ(mirror_v.to_vertical_mirror(), code); EXPECT_FALSE(mirror_v.is_vertical_mirror()); // not exist
EXPECT_FALSE(mirror_v.is_vertical_mirror()); // not exist EXPECT_NE(mirror_v, code);
EXPECT_NE(mirror_v, code);
const auto mirror_h = code.to_horizontal_mirror();
const auto mirror_h = code.to_horizontal_mirror(); EXPECT_TRUE(RawCode::check(mirror_h.unwrap()));
EXPECT_TRUE(RawCode::check(mirror_h.unwrap())); EXPECT_EQ(mirror_h.to_horizontal_mirror(), code);
EXPECT_EQ(mirror_h.to_horizontal_mirror(), code); if (mirror_h.is_horizontal_mirror()) {
if (mirror_h.is_horizontal_mirror()) { EXPECT_EQ(mirror_h, code);
EXPECT_EQ(mirror_h, code); } else {
} else { EXPECT_NE(mirror_h, code);
EXPECT_NE(mirror_h, code);
}
} }
}); });
} }

41
src/core_test/codec/short_code.cc

@ -31,16 +31,7 @@ EXPOSE_STATIC_VAR(ShortCode, bool, fast_)
EXPOSE_STATIC_VAR(ShortCode, const RangesUnion*, cases_) EXPOSE_STATIC_VAR(ShortCode, const RangesUnion*, cases_)
EXPOSE_STATIC_VAR(ShortCode, std::atomic<const Ranges*>, ranges_) EXPOSE_STATIC_VAR(ShortCode, std::atomic<const Ranges*>, ranges_)
/// Reset basic ranges build state, note it is thread-unsafe. /// Reset ShortCode speed up state, note it is thread-unsafe.
void basic_ranges_reset() {
exposer::BasicRanges_available_(BasicRanges::instance()) = false;
}
/// Reset all cases build state, note it is thread-unsafe.
void all_cases_reset() {
exposer::AllCases_available_(AllCases::instance()) = false;
}
void speed_up_reset() { void speed_up_reset() {
exposer::ShortCode_fast_() = false; exposer::ShortCode_fast_() = false;
exposer::ShortCode_cases_() = nullptr; exposer::ShortCode_cases_() = nullptr;
@ -208,28 +199,24 @@ TEST(ShortCode, speed_up) {
TEST(ShortCode, code_verify) { TEST(ShortCode, code_verify) {
ShortCode::speed_up(true); // enter fast mode ShortCode::speed_up(true); // enter fast mode
short_code_parallel([](std::span<ShortCode> codes) { SHORT_CODE_PARALLEL({
for (auto code : codes) { EXPECT_TRUE(ShortCode::check(code.unwrap()));
EXPECT_TRUE(ShortCode::check(code.unwrap())); auto common_code = code.to_common_code(); // ShortCode::fast_decode
auto common_code = code.to_common_code(); // ShortCode::fast_decode EXPECT_EQ(ShortCode::from_common_code(common_code), code); // ShortCode::fast_encode
EXPECT_EQ(ShortCode::from_common_code(common_code), code); // ShortCode::fast_encode
}
}); });
} }
TEST(ShortCode, code_string) { TEST(ShortCode, code_string) {
short_code_parallel([](std::span<ShortCode> codes) { SHORT_CODE_PARALLEL({
for (auto code : codes) { auto code_str = code.to_string();
auto code_str = code.to_string(); EXPECT_EQ(code_str.size(), 5); // length = 5
EXPECT_EQ(code_str.size(), 5); // length = 5 for (auto c : code_str) {
for (auto c : code_str) { EXPECT_TRUE((c >= '1' && c <= '9') || (c >= 'A' && c <= 'Z'));
EXPECT_TRUE((c >= '1' && c <= '9') || (c >= 'A' && c <= 'Z')); EXPECT_TRUE(c != 'I' && c != 'L' && c != 'O');
EXPECT_TRUE(c != 'I' && c != 'L' && c != 'O');
}
EXPECT_EQ(ShortCode::from_string(code_str), code); // test upper cases
std::transform(code_str.begin(), code_str.end(), code_str.begin(), ::tolower);
EXPECT_EQ(ShortCode::from_string(code_str), code); // test lower cases
} }
EXPECT_EQ(ShortCode::from_string(code_str), code); // test upper cases
std::transform(code_str.begin(), code_str.end(), code_str.begin(), ::tolower);
EXPECT_EQ(ShortCode::from_string(code_str), code); // test lower cases
}); });
} }

Loading…
Cancel
Save