Browse Source

test: add all cases ffi test

master
Dnomd343 1 year ago
parent
commit
9e11872178
  1. 11
      src/core/ffi/all_cases.cc
  2. 13
      src/core_test/CMakeLists.txt
  3. 5
      src/core_test/cases/all_cases.cc
  4. 183
      src/core_test/ffi/all_cases.cc
  5. 8
      third_party/third_party.cmake

11
src/core/ffi/all_cases.cc

@ -3,7 +3,6 @@
using klotski::cases::AllCases;
using klotski::cases::BasicRanges;
using klotski::cases::ALL_CASES_NUM;
void all_cases_prebuild() {
@ -11,9 +10,9 @@ void all_cases_prebuild() {
}
void all_cases_prebuild_async(executor_t executor, notifier_t callback) {
executor([](void *cb) {
executor([](void *fn) {
all_cases_prebuild();
((notifier_t)cb)();
((notifier_t)fn)();
}, (void*)callback);
}
@ -30,9 +29,9 @@ void all_cases_build() {
}
void all_cases_build_async(executor_t executor, notifier_t callback) {
executor([](void *cb) {
executor([](void *fn) {
all_cases_build();
((notifier_t)cb)();
((notifier_t)fn)();
}, (void*)callback);
}
@ -68,7 +67,7 @@ int all_cases_available() {
}
int all_cases_num(int head) {
if (head < 0 || head > 15) {
if (head < 0 || head >= (int)ALL_CASES_NUM.size()) {
return -1;
}
return ALL_CASES_NUM[head];

13
src/core_test/CMakeLists.txt

@ -2,12 +2,13 @@ cmake_minimum_required(VERSION 3.0)
set(CMAKE_CXX_STANDARD 20)
set(KLOTSKI_TEST_DEPS klotski-core gtest gtest_main xxHash::xxhash)
set(KLOTSKI_TEST_DEPS klotski-core gtest gtest_main md5sum xxHash::xxhash)
###############################################################################################
include_directories(utils)
include_directories(${KLOTSKI_ROOT}/src/core/ffi)
include_directories(${KLOTSKI_ROOT}/src/core/utils)
include_directories(${KLOTSKI_ROOT}/src/core/all_cases)
@ -22,3 +23,13 @@ target_link_libraries(test_klotski_cases PRIVATE ${KLOTSKI_TEST_DEPS})
add_test(NAME klotski_cases COMMAND test_klotski_cases)
###############################################################################################
set(KLOTSKI_TEST_FFI_SRC
ffi/all_cases.cc
)
add_executable(test_klotski_ffi ${KLOTSKI_TEST_FFI_SRC})
target_link_libraries(test_klotski_ffi PRIVATE ${KLOTSKI_TEST_DEPS})
add_test(NAME klotski_ffi COMMAND test_klotski_ffi)
###############################################################################################

5
src/core_test/cases/all_cases.cc

@ -21,11 +21,6 @@ static const auto TEST_THREAD_NUM = 256;
static const std::string ALL_CASES_XXHASH = "d589c8a45983ebb6";
static const std::string BASIC_RANGES_XXHASH = "5e7f633b7bd8af37";
/// 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";
//static const std::string BASIC_RANGES_MD5 = "6f385dc171e201089ff96bb010b47212";
/// Forcibly modify private variables to reset state.
PRIVATE_ACCESS(AllCases, available_, bool)
PRIVATE_ACCESS(BasicRanges, available_, bool)

183
src/core_test/ffi/all_cases.cc

@ -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);
}

8
third_party/third_party.cmake

@ -4,10 +4,10 @@ set(ABSL_PROPAGATE_CXX_STD ON)
include_directories(abseil-cpp)
add_subdirectory(${KLOTSKI_THIRD_PARTY}/abseil-cpp EXCLUDE_FROM_ALL)
#if (KLOTSKI_UNIT_TEST)
# include_directories(${KLOTSKI_THIRD_PARTY}/md5sum)
# add_subdirectory(${KLOTSKI_THIRD_PARTY}/md5sum EXCLUDE_FROM_ALL)
#endif (KLOTSKI_UNIT_TEST)
if (KLOTSKI_UNIT_TEST)
include_directories(${KLOTSKI_THIRD_PARTY}/md5sum)
add_subdirectory(${KLOTSKI_THIRD_PARTY}/md5sum EXCLUDE_FROM_ALL)
endif (KLOTSKI_UNIT_TEST)
if (KLOTSKI_UNIT_TEST)
include_directories(${KLOTSKI_THIRD_PARTY}/googletest/googletest/include)

Loading…
Cancel
Save