mirror of https://github.com/dnomd343/klotski.git
Dnomd343
1 year ago
5 changed files with 204 additions and 16 deletions
@ -0,0 +1,183 @@ |
|||||
|
#include <future> |
||||
|
#include <string> |
||||
|
#include <thread> |
||||
|
|
||||
|
#include "md5sum.h" |
||||
|
#include "exposer.h" |
||||
|
#include "klotski.h" |
||||
|
#include "all_cases.h" |
||||
|
#include "gtest/gtest.h" |
||||
|
|
||||
|
using md5::md5sum; |
||||
|
|
||||
|
using klotski::cases::AllCases; |
||||
|
using klotski::cases::BasicRanges; |
||||
|
|
||||
|
using klotski::cases::ALL_CASES_NUM; |
||||
|
|
||||
|
/// The efficiency of string hashing is not very high, but there is a memorable
|
||||
|
/// story, and this scheme is still retained here.
|
||||
|
static const std::string ALL_CASES_MD5 = "3888e9fab8d3cbb50908b12b147cfb23"; |
||||
|
|
||||
|
/// Forcibly modify private variables to reset state.
|
||||
|
PRIVATE_ACCESS(AllCases, available_, bool) |
||||
|
PRIVATE_ACCESS(BasicRanges, available_, bool) |
||||
|
|
||||
|
/// Reset basic ranges build state, note it is thread-unsafe.
|
||||
|
void basic_ranges_reset() { |
||||
|
access_BasicRanges_available_(BasicRanges::Instance()) = false; |
||||
|
} |
||||
|
|
||||
|
/// Reset all cases build state, note it is thread-unsafe.
|
||||
|
void all_cases_reset() { |
||||
|
access_AllCases_available_(AllCases::Instance()) = false; |
||||
|
} |
||||
|
|
||||
|
TEST(FFI, all_cases_prebuild) { |
||||
|
basic_ranges_reset(); |
||||
|
EXPECT_FALSE(all_cases_prebuild_available()); |
||||
|
all_cases_prebuild(); |
||||
|
EXPECT_TRUE(all_cases_prebuild_available()); |
||||
|
all_cases_prebuild(); |
||||
|
EXPECT_TRUE(all_cases_prebuild_available()); |
||||
|
} |
||||
|
|
||||
|
TEST(FFI, all_cases_prebuild_async) { |
||||
|
basic_ranges_reset(); |
||||
|
static std::atomic_flag chan; |
||||
|
|
||||
|
chan.clear(); |
||||
|
all_cases_prebuild_async([](void (*fn)(void*), void *arg) { |
||||
|
std::thread worker(fn, arg); |
||||
|
worker.detach(); |
||||
|
}, []() { |
||||
|
chan.test_and_set(); |
||||
|
chan.notify_all(); |
||||
|
}); |
||||
|
EXPECT_FALSE(all_cases_prebuild_available()); |
||||
|
chan.wait(false); |
||||
|
EXPECT_TRUE(all_cases_prebuild_available()); |
||||
|
|
||||
|
chan.clear(); |
||||
|
all_cases_prebuild_async([](void (*fn)(void*), void *arg) { |
||||
|
std::thread worker(fn, arg); |
||||
|
worker.detach(); |
||||
|
}, []() { |
||||
|
chan.test_and_set(); |
||||
|
chan.notify_all(); |
||||
|
}); |
||||
|
EXPECT_TRUE(all_cases_prebuild_available()); |
||||
|
chan.wait(false); |
||||
|
EXPECT_TRUE(all_cases_prebuild_available()); |
||||
|
} |
||||
|
|
||||
|
TEST(FFI, all_cases_build) { |
||||
|
all_cases_reset(); |
||||
|
EXPECT_FALSE(all_cases_available()); |
||||
|
all_cases_build(); |
||||
|
EXPECT_TRUE(all_cases_available()); |
||||
|
all_cases_build(); |
||||
|
EXPECT_TRUE(all_cases_available()); |
||||
|
} |
||||
|
|
||||
|
TEST(FFI, all_cases_build_async) { |
||||
|
all_cases_reset(); |
||||
|
static std::atomic_flag chan; |
||||
|
|
||||
|
chan.clear(); |
||||
|
all_cases_build_async([](void (*fn)(void*), void *arg) { |
||||
|
std::thread worker(fn, arg); |
||||
|
worker.detach(); |
||||
|
}, []() { |
||||
|
chan.test_and_set(); |
||||
|
chan.notify_all(); |
||||
|
}); |
||||
|
EXPECT_FALSE(all_cases_available()); |
||||
|
chan.wait(false); |
||||
|
EXPECT_TRUE(all_cases_available()); |
||||
|
|
||||
|
chan.clear(); |
||||
|
all_cases_build_async([](void (*fn)(void*), void *arg) { |
||||
|
std::thread worker(fn, arg); |
||||
|
worker.detach(); |
||||
|
}, []() { |
||||
|
chan.test_and_set(); |
||||
|
chan.notify_all(); |
||||
|
}); |
||||
|
EXPECT_TRUE(all_cases_available()); |
||||
|
chan.wait(false); |
||||
|
EXPECT_TRUE(all_cases_available()); |
||||
|
} |
||||
|
|
||||
|
TEST(FFI, all_cases_build_parallel) { |
||||
|
all_cases_reset(); |
||||
|
EXPECT_FALSE(all_cases_available()); |
||||
|
all_cases_build_parallel([](void (*fn)(void*), void *arg) { |
||||
|
std::thread worker(fn, arg); |
||||
|
worker.detach(); |
||||
|
}); |
||||
|
EXPECT_TRUE(all_cases_available()); |
||||
|
all_cases_build_parallel([](void (*fn)(void*), void *arg) { |
||||
|
std::thread worker(fn, arg); |
||||
|
worker.detach(); |
||||
|
}); |
||||
|
EXPECT_TRUE(all_cases_available()); |
||||
|
} |
||||
|
|
||||
|
TEST(FFI, all_cases_build_parallel_async) { |
||||
|
all_cases_reset(); |
||||
|
static std::atomic_flag chan; |
||||
|
|
||||
|
chan.clear(); |
||||
|
all_cases_build_parallel_async([](void (*fn)(void*), void *arg) { |
||||
|
std::thread worker(fn, arg); |
||||
|
worker.detach(); |
||||
|
}, []() { |
||||
|
chan.test_and_set(); |
||||
|
chan.notify_all(); |
||||
|
}); |
||||
|
EXPECT_FALSE(all_cases_available()); |
||||
|
chan.wait(false); |
||||
|
EXPECT_TRUE(all_cases_available()); |
||||
|
|
||||
|
chan.clear(); |
||||
|
all_cases_build_parallel_async([](void (*fn)(void*), void *arg) { |
||||
|
std::thread worker(fn, arg); |
||||
|
worker.detach(); |
||||
|
}, []() { |
||||
|
chan.test_and_set(); |
||||
|
chan.notify_all(); |
||||
|
}); |
||||
|
EXPECT_TRUE(all_cases_available()); |
||||
|
chan.wait(false); |
||||
|
EXPECT_TRUE(all_cases_available()); |
||||
|
} |
||||
|
|
||||
|
TEST(FFI, all_cases_num) { |
||||
|
EXPECT_LT(all_cases_num(-2), 0); |
||||
|
EXPECT_LT(all_cases_num(-1), 0); |
||||
|
for (int i = 0; i < 15; ++i) { |
||||
|
EXPECT_EQ(all_cases_num(i), ALL_CASES_NUM[i]); |
||||
|
} |
||||
|
EXPECT_LT(all_cases_num(16), 0); |
||||
|
EXPECT_LT(all_cases_num(17), 0); |
||||
|
} |
||||
|
|
||||
|
TEST(FFI, all_cases_export) { |
||||
|
EXPECT_EQ(all_cases_export(-2), nullptr); |
||||
|
EXPECT_EQ(all_cases_export(-1), nullptr); |
||||
|
EXPECT_EQ(all_cases_export(16), nullptr); |
||||
|
EXPECT_EQ(all_cases_export(17), nullptr); |
||||
|
|
||||
|
std::string all_cases_str; |
||||
|
for (uint64_t head = 0; head < 15; ++head) { |
||||
|
auto num = all_cases_num((int)head); |
||||
|
auto *ranges = all_cases_export((int)head); |
||||
|
for (auto i = 0; i < num; ++i) { |
||||
|
char *tmp; |
||||
|
asprintf(&tmp, "%09llX\n", head << 32 | ranges[i]); |
||||
|
all_cases_str += tmp; |
||||
|
} |
||||
|
} |
||||
|
EXPECT_EQ(md5sum(all_cases_str), ALL_CASES_MD5); |
||||
|
} |
Loading…
Reference in new issue