Specify cmake tests, benchmarks and tools idiomatically

This commit is contained in:
John Keiser 2020-04-06 08:24:54 -07:00
parent 54b7291c34
commit 10b7556a37
9 changed files with 66 additions and 82 deletions

View File

@ -46,7 +46,6 @@ option(SIMDJSON_EXCEPTIONS "Enable simdjson's exception-throwing interface" ON)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/tools/cmake")
find_package(CTargets)
find_package(Options)
#
@ -63,13 +62,15 @@ set (TEST_DATA_DIR "${CMAKE_CURRENT_SOURCE_DIR}/jsonchecker/")
set (BENCHMARK_DATA_DIR "${CMAKE_CURRENT_SOURCE_DIR}/jsonexamples/")
add_definitions(-DSIMDJSON_TEST_DATA_DIR="${TEST_DATA_DIR}")
add_definitions(-DSIMDJSON_BENCHMARK_DATA_DIR="${TEST_DATA_DIR}")
add_definitions(-DJSON_TEST_PATH="${BENCHMARK_DATA_DIR}/twitter.json")
add_definitions(-DSIMDJSON_AMAZON_CELLPHONES_NDJSON_PATH="${PROJECT_SOURCE_DIR}/jsonexamples/amazon_cellphones.ndjson")
enable_testing()
add_subdirectory(tools)
add_subdirectory(tests)
add_subdirectory(benchmark)
if (SIMDJSON_GOOGLE_BENCHMARKS)
if(NOT EXISTS dependencies/benchmark/CMakeLists.txt)
# message(STATUS "Unable to find dependencies/benchmark/CMakeLists.txt")

View File

@ -1,16 +1,14 @@
include_directories( . linux )
add_cpp_benchmark(parse)
add_cpp_benchmark(statisticalmodel)
add_cpp_benchmark(parse_stream)
add_cpp_benchmark(get_corpus_benchmark)
link_libraries(simdjson)
add_executable(parse parse.cpp)
add_executable(statisticalmodel statisticalmodel.cpp)
add_executable(parse_stream parse_stream.cpp)
add_executable(get_corpus_benchmark get_corpus_benchmark.cpp)
add_executable(perfdiff perfdiff.cpp)
# Google Benchmarks
if (SIMDJSON_GOOGLE_BENCHMARKS)
add_cpp_benchmark(bench_parse_call)
target_link_libraries(bench_parse_call benchmark::benchmark)
add_cpp_benchmark(bench_dom_api)
target_link_libraries(bench_dom_api benchmark::benchmark)
target_compile_definitions(bench_dom_api PRIVATE JSON_TEST_PATH="${PROJECT_SOURCE_DIR}/jsonexamples/twitter.json")
link_libraries(benchmark::benchmark)
add_executable(bench_parse_call bench_parse_call.cpp)
add_executable(bench_dom_api bench_dom_api.cpp)
endif()

View File

@ -6,8 +6,8 @@ using namespace simdjson;
using namespace benchmark;
using namespace std;
#ifndef JSON_TEST_PATH
#define JSON_TEST_PATH "jsonexamples/twitter.json"
#ifndef SIMDJSON_TWITTER_JSON_PATH
#define SIMDJSON_TWITTER_JSON_PATH "jsonexamples/twitter.json"
#endif
const padded_string EMPTY_ARRAY("[]", 2);
@ -17,7 +17,7 @@ const padded_string EMPTY_ARRAY("[]", 2);
static void twitter_count(State& state) {
// Prints the number of results in twitter.json
dom::parser parser;
dom::element doc = parser.load(JSON_TEST_PATH);
dom::element doc = parser.load(SIMDJSON_TWITTER_JSON_PATH);
for (auto _ : state) {
uint64_t result_count = doc["search_metadata"]["count"];
if (result_count != 100) { return; }
@ -29,7 +29,7 @@ SIMDJSON_PUSH_DISABLE_WARNINGS
SIMDJSON_DISABLE_DEPRECATED_WARNING
static void iterator_twitter_count(State& state) {
// Prints the number of results in twitter.json
padded_string json = padded_string::load(JSON_TEST_PATH);
padded_string json = padded_string::load(SIMDJSON_TWITTER_JSON_PATH);
ParsedJson pj = build_parsed_json(json);
for (auto _ : state) {
ParsedJson::Iterator iter(pj);
@ -48,7 +48,7 @@ SIMDJSON_POP_DISABLE_WARNINGS
static void twitter_default_profile(State& state) {
// Count unique users with a default profile.
dom::parser parser;
dom::element doc = parser.load(JSON_TEST_PATH);
dom::element doc = parser.load(SIMDJSON_TWITTER_JSON_PATH);
for (auto _ : state) {
set<string_view> default_users;
for (dom::object tweet : doc["statuses"].get<dom::array>()) {
@ -65,7 +65,7 @@ BENCHMARK(twitter_default_profile);
static void twitter_image_sizes(State& state) {
// Count unique image sizes
dom::parser parser;
dom::element doc = parser.load(JSON_TEST_PATH);
dom::element doc = parser.load(SIMDJSON_TWITTER_JSON_PATH);
for (auto _ : state) {
set<tuple<uint64_t, uint64_t>> image_sizes;
for (dom::object tweet : doc["statuses"].get<dom::array>()) {
@ -88,7 +88,7 @@ BENCHMARK(twitter_image_sizes);
static void error_code_twitter_count(State& state) noexcept {
// Prints the number of results in twitter.json
dom::parser parser;
dom::element doc = parser.load(JSON_TEST_PATH);
dom::element doc = parser.load(SIMDJSON_TWITTER_JSON_PATH);
for (auto _ : state) {
auto [value, error] = doc["search_metadata"]["count"].get<uint64_t>();
if (error) { return; }
@ -100,7 +100,7 @@ BENCHMARK(error_code_twitter_count);
static void error_code_twitter_default_profile(State& state) noexcept {
// Count unique users with a default profile.
dom::parser parser;
dom::element doc = parser.load(JSON_TEST_PATH);
dom::element doc = parser.load(SIMDJSON_TWITTER_JSON_PATH);
for (auto _ : state) {
set<string_view> default_users;
@ -127,7 +127,7 @@ SIMDJSON_PUSH_DISABLE_WARNINGS
SIMDJSON_DISABLE_DEPRECATED_WARNING
static void iterator_twitter_default_profile(State& state) {
// Count unique users with a default profile.
padded_string json = padded_string::load(JSON_TEST_PATH);
padded_string json = padded_string::load(SIMDJSON_TWITTER_JSON_PATH);
ParsedJson pj = build_parsed_json(json);
for (auto _ : state) {
set<string_view> default_users;
@ -167,7 +167,7 @@ BENCHMARK(iterator_twitter_default_profile);
static void error_code_twitter_image_sizes(State& state) noexcept {
// Count unique image sizes
dom::parser parser;
dom::element doc = parser.load(JSON_TEST_PATH);
dom::element doc = parser.load(SIMDJSON_TWITTER_JSON_PATH);
for (auto _ : state) {
set<tuple<uint64_t, uint64_t>> image_sizes;
auto [statuses, error] = doc["statuses"].get<dom::array>();
@ -196,7 +196,7 @@ SIMDJSON_PUSH_DISABLE_WARNINGS
SIMDJSON_DISABLE_DEPRECATED_WARNING
static void iterator_twitter_image_sizes(State& state) {
// Count unique image sizes
padded_string json = padded_string::load(JSON_TEST_PATH);
padded_string json = padded_string::load(SIMDJSON_TWITTER_JSON_PATH);
ParsedJson pj = build_parsed_json(json);
for (auto _ : state) {
set<tuple<uint64_t, uint64_t>> image_sizes;
@ -254,7 +254,7 @@ BENCHMARK(iterator_twitter_image_sizes);
static void print_json(State& state) noexcept {
// Prints the number of results in twitter.json
padded_string json = get_corpus(JSON_TEST_PATH);
padded_string json = get_corpus(SIMDJSON_TWITTER_JSON_PATH);
dom::parser parser;
if (int error = json_parse(json, parser); error != SUCCESS) { cerr << error_message(error) << endl; return; }
for (auto _ : state) {

View File

@ -1,33 +1,21 @@
if(MSVC)
target_include_directories(simdjson
INTERFACE $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/windows>
)
endif()
# Helper so we don't have to repeat ourselves so much
function(add_cpp_test TEST_NAME)
add_executable(${TEST_NAME} ${TEST_NAME}.cpp)
add_test(${TEST_NAME} ${TEST_NAME})
endfunction(add_cpp_test)
link_libraries(simdjson)
add_cpp_test(basictests)
add_cpp_test(errortests)
## Next bit should not be needed!
#if(CMAKE_INTERPROCEDURAL_OPTIMIZATION)
# next line is a workaround for an odr-violation in basictests regarding the globals 0x432a40 and 0x52045c under clang
#set_tests_properties(basictests PROPERTIES
# ENVIRONMENT ASAN_OPTIONS="detect_odr_violation=0")
#endif()
add_cpp_test(jsoncheck)
add_cpp_test(parse_many_test)
add_cpp_test(pointercheck)
add_cpp_test(integer_tests)
target_compile_definitions(basictests PRIVATE JSON_TEST_PATH="${PROJECT_SOURCE_DIR}/jsonexamples/twitter.json" NDJSON_TEST_PATH="${PROJECT_SOURCE_DIR}/jsonexamples/amazon_cellphones.ndjson")
target_compile_definitions(errortests PRIVATE JSON_TEST_PATH="${PROJECT_SOURCE_DIR}/jsonexamples/twitter.json")
## This causes problems
# add_executable(singleheader ./singleheadertest.cpp ${PROJECT_SOURCE_DIR}/singleheader/simdjson.cpp)
# target_link_libraries(singleheader simdjson)
# add_test(singleheader singleheader)
if(MSVC)
include_directories($<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/windows>)
add_custom_command(TARGET basictests POST_BUILD # Adds a post-build event
COMMAND ${CMAKE_COMMAND} -E echo "$<TARGET_FILE:simdjson>"
COMMAND ${CMAKE_COMMAND} -E echo "$<TARGET_FILE_DIR:basictests>"
@ -36,3 +24,14 @@ if(MSVC)
"$<TARGET_FILE_DIR:basictests>") # <--this is out-file path
endif()
## Next bit should not be needed!
#if(CMAKE_INTERPROCEDURAL_OPTIMIZATION)
# next line is a workaround for an odr-violation in basictests regarding the globals 0x432a40 and 0x52045c under clang
#set_tests_properties(basictests PROPERTIES
# ENVIRONMENT ASAN_OPTIONS="detect_odr_violation=0")
#endif()
## This causes problems
# add_executable(singleheader ./singleheadertest.cpp ${PROJECT_SOURCE_DIR}/singleheader/simdjson.cpp)
# target_link_libraries(singleheader simdjson)
# add_test(singleheader singleheader)

View File

@ -17,11 +17,11 @@
#include "simdjson.h"
#ifndef JSON_TEST_PATH
#define JSON_TEST_PATH "jsonexamples/twitter.json"
#ifndef SIMDJSON_TWITTER_JSON_PATH
#define SIMDJSON_TWITTER_JSON_PATH "jsonexamples/twitter.json"
#endif
#ifndef NDJSON_TEST_PATH
#define NDJSON_TEST_PATH "jsonexamples/amazon_cellphones.ndjson"
#ifndef SIMDJSON_AMAZON_CELLPHONES_NDJSON_PATH
#define SIMDJSON_AMAZON_CELLPHONES_NDJSON_PATH "jsonexamples/amazon_cellphones.ndjson"
#endif
#define ASSERT_EQUAL(ACTUAL, EXPECTED) if ((ACTUAL) != (EXPECTED)) { std::cerr << "Expected " << #ACTUAL << " to be " << (EXPECTED) << ", got " << (ACTUAL) << " instead!" << std::endl; return false; }
@ -495,7 +495,7 @@ namespace parse_api_tests {
bool parser_load() {
std::cout << "Running " << __func__ << std::endl;
dom::parser parser;
auto [doc, error] = parser.load(JSON_TEST_PATH);
auto [doc, error] = parser.load(SIMDJSON_TWITTER_JSON_PATH);
if (error) { cerr << error << endl; return false; }
if (!doc.is<dom::object>()) { cerr << "Document did not parse as an object" << endl; return false; }
return true;
@ -504,7 +504,7 @@ namespace parse_api_tests {
std::cout << "Running " << __func__ << std::endl;
dom::parser parser;
int count = 0;
for (auto [doc, error] : parser.load_many(NDJSON_TEST_PATH)) {
for (auto [doc, error] : parser.load_many(SIMDJSON_AMAZON_CELLPHONES_NDJSON_PATH)) {
if (error) { cerr << error << endl; return false; }
if (!doc.is<dom::array>()) { cerr << "Document did not parse as an array" << endl; return false; }
count++;
@ -537,7 +537,7 @@ namespace parse_api_tests {
bool parser_load_exception() {
std::cout << "Running " << __func__ << std::endl;
dom::parser parser;
const element doc = parser.load(JSON_TEST_PATH);
const element doc = parser.load(SIMDJSON_TWITTER_JSON_PATH);
if (!doc.is<dom::object>()) { cerr << "Document did not parse as an object" << endl; return false; }
return true;
}
@ -545,7 +545,7 @@ namespace parse_api_tests {
std::cout << "Running " << __func__ << std::endl;
dom::parser parser;
int count = 0;
for (const element doc : parser.load_many(NDJSON_TEST_PATH)) {
for (const element doc : parser.load_many(SIMDJSON_AMAZON_CELLPHONES_NDJSON_PATH)) {
if (!doc.is<dom::array>()) { cerr << "Document did not parse as an array" << endl; return false; }
count++;
}
@ -869,7 +869,7 @@ namespace dom_api_tests {
std::cout << "Running " << __func__ << std::endl;
// Prints the number of results in twitter.json
dom::parser parser;
auto [result_count, error] = parser.load(JSON_TEST_PATH)["search_metadata"]["count"].get<uint64_t>();
auto [result_count, error] = parser.load(SIMDJSON_TWITTER_JSON_PATH)["search_metadata"]["count"].get<uint64_t>();
if (error) { cerr << "Error: " << error << endl; return false; }
if (result_count != 100) { cerr << "Expected twitter.json[metadata_count][count] = 100, got " << result_count << endl; return false; }
return true;
@ -880,7 +880,7 @@ namespace dom_api_tests {
// Print users with a default profile.
set<string_view> default_users;
dom::parser parser;
auto [tweets, error] = parser.load(JSON_TEST_PATH)["statuses"].get<dom::array>();
auto [tweets, error] = parser.load(SIMDJSON_TWITTER_JSON_PATH)["statuses"].get<dom::array>();
if (error) { cerr << "Error: " << error << endl; return false; }
for (auto tweet : tweets) {
object user;
@ -905,7 +905,7 @@ namespace dom_api_tests {
// Print image names and sizes
set<pair<uint64_t, uint64_t>> image_sizes;
dom::parser parser;
auto [tweets, error] = parser.load(JSON_TEST_PATH)["statuses"].get<dom::array>();
auto [tweets, error] = parser.load(SIMDJSON_TWITTER_JSON_PATH)["statuses"].get<dom::array>();
if (error) { cerr << "Error: " << error << endl; return false; }
for (auto tweet : tweets) {
auto [media, not_found] = tweet["entities"]["media"].get<dom::array>();
@ -1043,7 +1043,7 @@ namespace dom_api_tests {
std::cout << "Running " << __func__ << std::endl;
// Prints the number of results in twitter.json
dom::parser parser;
element doc = parser.load(JSON_TEST_PATH);
element doc = parser.load(SIMDJSON_TWITTER_JSON_PATH);
uint64_t result_count = doc["search_metadata"]["count"];
if (result_count != 100) { cerr << "Expected twitter.json[metadata_count][count] = 100, got " << result_count << endl; return false; }
return true;
@ -1054,7 +1054,7 @@ namespace dom_api_tests {
// Print users with a default profile.
set<string_view> default_users;
dom::parser parser;
element doc = parser.load(JSON_TEST_PATH);
element doc = parser.load(SIMDJSON_TWITTER_JSON_PATH);
for (object tweet : doc["statuses"].get<dom::array>()) {
object user = tweet["user"];
if (user["default_profile"]) {
@ -1070,7 +1070,7 @@ namespace dom_api_tests {
// Print image names and sizes
set<pair<uint64_t, uint64_t>> image_sizes;
dom::parser parser;
element doc = parser.load(JSON_TEST_PATH);
element doc = parser.load(SIMDJSON_TWITTER_JSON_PATH);
for (object tweet : doc["statuses"].get<dom::array>()) {
auto [media, not_found] = tweet["entities"]["media"];
if (!not_found) {

View File

@ -14,8 +14,8 @@
using namespace simdjson;
using namespace std;
#ifndef JSON_TEST_PATH
#define JSON_TEST_PATH "jsonexamples/twitter.json"
#ifndef SIMDJSON_TWITTER_JSON_PATH
#define SIMDJSON_TWITTER_JSON_PATH "jsonexamples/twitter.json"
#endif
#define TEST_START() { cout << "Running " << __func__ << " ..." << endl; }
@ -27,14 +27,14 @@ namespace parser_load {
bool parser_load_capacity() {
TEST_START();
dom::parser parser(1); // 1 byte max capacity
auto [doc, error] = parser.load(JSON_TEST_PATH);
auto [doc, error] = parser.load(SIMDJSON_TWITTER_JSON_PATH);
ASSERT_ERROR(error, CAPACITY);
TEST_SUCCEED();
}
bool parser_load_many_capacity() {
TEST_START();
dom::parser parser(1); // 1 byte max capacity
for (auto [doc, error] : parser.load_many(JSON_TEST_PATH)) {
for (auto [doc, error] : parser.load_many(SIMDJSON_TWITTER_JSON_PATH)) {
ASSERT_ERROR(error, CAPACITY);
TEST_SUCCEED();
}

View File

@ -5,7 +5,7 @@
using namespace simdjson;
int main() {
const char *filename = JSON_TEST_PATH;
const char *filename = SIMDJSON_TWITTER_JSON_PATH;
padded_string p = get_corpus(filename);
dom::parser parser;
auto [doc, error] = parser.parse(p);

View File

@ -1,3 +1,4 @@
add_cpp_tool(json2json)
add_cpp_tool(jsonstats)
add_cpp_tool(minify)
link_libraries(simdjson)
add_executable(json2json json2json.cpp)
add_executable(jsonstats jsonstats.cpp)
add_executable(minify minify.cpp)

View File

@ -1,15 +0,0 @@
function(add_cpp_test TEST_NAME)
add_executable(${TEST_NAME} ${TEST_NAME}.cpp)
target_link_libraries(${TEST_NAME} ${SIMDJSON_LIB_NAME})
add_test(${TEST_NAME} ${TEST_NAME})
endfunction(add_cpp_test)
function(add_cpp_benchmark BENCH_NAME)
add_executable(${BENCH_NAME} ${BENCH_NAME}.cpp)
target_link_libraries(${BENCH_NAME} ${SIMDJSON_LIB_NAME})
endfunction(add_cpp_benchmark)
function(add_cpp_tool TOOL_NAME)
add_executable(${TOOL_NAME} ${TOOL_NAME}.cpp)
target_link_libraries(${TOOL_NAME} ${SIMDJSON_LIB_NAME})
endfunction(add_cpp_tool)