Add test for out-of-order parse asserts

This commit is contained in:
John Keiser
2020-12-11 17:28:24 -08:00
parent 73c7b7db3d
commit f9c6dedca1
32 changed files with 302 additions and 97 deletions
+2 -2
View File
@@ -19,7 +19,7 @@ environment:
- job_name: VS2017 (Static, No Threads)
image: Visual Studio 2017
CMAKE_ARGS: -A %Platform% -DSIMDJSON_BUILD_STATIC=ON -DSIMDJSON_ENABLE_THREADS=OFF
CTEST_ARGS: -E checkperf
CTEST_ARGS: -LE explicitonly
- job_name: VS2019 (Win32)
platform: Win32
CMAKE_ARGS: -A %Platform% -DSIMDJSON_BUILD_STATIC=OFF -DSIMDJSON_ENABLE_THREADS=ON # This should be the default. Testing anyway.
@@ -31,7 +31,7 @@ environment:
- job_name: VS2015
image: Visual Studio 2015
CMAKE_ARGS: -A %Platform% -DSIMDJSON_BUILD_STATIC=ON -DSIMDJSON_ENABLE_THREADS=OFF
CTEST_ARGS: -E checkperf
CTEST_ARGS: -LE explicitonly
build_script:
- mkdir build
+32 -10
View File
@@ -103,7 +103,15 @@ commands:
cd build &&
tools/json2json -h &&
ctest $CTEST_FLAGS -L acceptance &&
ctest $CTEST_FLAGS -LE acceptance -E checkperf
ctest $CTEST_FLAGS -LE acceptance -LE explicitonly
cmake_test:
steps:
- run: |
cd build &&
tools/json2json -h &&
ctest $CTEST_FLAGS -L assert &&
ctest $CTEST_FLAGS -LE acceptance -LE explicitonly
cmake_test_all:
steps:
@@ -112,9 +120,9 @@ commands:
cd build &&
tools/json2json -h &&
ctest $CTEST_FLAGS -DSIMDJSON_IMPLEMENTATION="haswell;westmere;fallback" -L acceptance -LE per_implementation &&
SIMDJSON_FORCE_IMPLEMENTATION=haswell ctest $CTEST_FLAGS -L per_implementation -E checkperf &&
SIMDJSON_FORCE_IMPLEMENTATION=westmere ctest $CTEST_FLAGS -L per_implementation -E checkperf &&
SIMDJSON_FORCE_IMPLEMENTATION=fallback ctest $CTEST_FLAGS -L per_implementation -E checkperf &&
SIMDJSON_FORCE_IMPLEMENTATION=haswell ctest $CTEST_FLAGS -L per_implementation -LE explicitonly &&
SIMDJSON_FORCE_IMPLEMENTATION=westmere ctest $CTEST_FLAGS -L per_implementation -LE explicitonly &&
SIMDJSON_FORCE_IMPLEMENTATION=fallback ctest $CTEST_FLAGS -L per_implementation -LE explicitonly &&
ctest $CTEST_FLAGS -LE "acceptance|per_implementation" # Everything we haven't run yet, run now.
@@ -144,6 +152,16 @@ jobs:
executor: gcc10
environment: { CMAKE_FLAGS: -DSIMDJSON_JUST_LIBRARY=ON }
steps: [ cmake_build, cmake_install_test, cmake_installed_test_cxx20 ]
assert-gcc10:
description: Build the library with asserts on, install it and run tests
executor: gcc10
environment: { CMAKE_FLAGS: -DSIMDJSON_GOOGLE_BENCHMARKS=OFF -DCXX_CMAKE_FLAGS_RELEASE=-O3 }
steps: [ cmake_test, cmake_assert_test ]
assert-clang10:
description: Build just the library, install it and do a basic test
executor: clang10
environment: { CMAKE_FLAGS: -DSIMDJSON_GOOGLE_BENCHMARKS=OFF -DCXX_CMAKE_FLAGS_RELEASE=-O3 }
steps: [ cmake_test, cmake_assert_test ]
gcc10-perftest:
description: Build and run performance tests on GCC 10 and AVX 2 with a cmake static build, this test performance regression
executor: gcc10
@@ -174,22 +192,22 @@ jobs:
sanitize-gcc10:
description: Build and run tests on GCC 10 and AVX 2 with a cmake sanitize build
executor: gcc10
environment: { CMAKE_FLAGS: -DSIMDJSON_BUILD_STATIC=OFF -DSIMDJSON_SANITIZE=ON, BUILD_FLAGS: "", CTEST_FLAGS: --output-on-failure -E checkperf }
environment: { CMAKE_FLAGS: -DSIMDJSON_BUILD_STATIC=OFF -DSIMDJSON_SANITIZE=ON, BUILD_FLAGS: "", CTEST_FLAGS: --output-on-failure -LE explicitonly }
steps: [ cmake_test ]
sanitize-clang10:
description: Build and run tests on clang 10 and AVX 2 with a cmake sanitize build
executor: clang10
environment: { CMAKE_FLAGS: -DSIMDJSON_BUILD_STATIC=OFF -DSIMDJSON_SANITIZE=ON, CTEST_FLAGS: --output-on-failure -E checkperf }
environment: { CMAKE_FLAGS: -DSIMDJSON_BUILD_STATIC=OFF -DSIMDJSON_SANITIZE=ON, CTEST_FLAGS: --output-on-failure -LE explicitonly }
steps: [ cmake_test ]
threadsanitize-gcc10:
description: Build and run tests on GCC 10 and AVX 2 with a cmake sanitize build
executor: gcc10
environment: { CMAKE_FLAGS: -DSIMDJSON_BUILD_STATIC=OFF -DSIMDJSON_SANITIZE_THREADS=ON, BUILD_FLAGS: "", CTEST_FLAGS: --output-on-failure -E checkperf }
environment: { CMAKE_FLAGS: -DSIMDJSON_BUILD_STATIC=OFF -DSIMDJSON_SANITIZE_THREADS=ON, BUILD_FLAGS: "", CTEST_FLAGS: --output-on-failure -LE explicitonly }
steps: [ cmake_test ]
threadsanitize-clang10:
description: Build and run tests on clang 10 and AVX 2 with a cmake sanitize build
executor: clang10
environment: { CMAKE_FLAGS: -DSIMDJSON_BUILD_STATIC=OFF -DSIMDJSON_SANITIZE_THREADS=ON, CTEST_FLAGS: --output-on-failure -E checkperf }
environment: { CMAKE_FLAGS: -DSIMDJSON_BUILD_STATIC=OFF -DSIMDJSON_SANITIZE_THREADS=ON, CTEST_FLAGS: --output-on-failure -LE explicitonly }
steps: [ cmake_test ]
# dynamic
dynamic-gcc10:
@@ -245,12 +263,12 @@ jobs:
sanitize-haswell-gcc10:
description: Build and run tests on GCC 10 and AVX 2 with a cmake sanitize build
executor: gcc10
environment: { CXXFLAGS: -march=haswell, CMAKE_FLAGS: -DSIMDJSON_BUILD_STATIC=OFF -DSIMDJSON_SANITIZE=ON, BUILD_FLAGS: "", CTEST_FLAGS: --output-on-failure -E checkperf }
environment: { CXXFLAGS: -march=haswell, CMAKE_FLAGS: -DSIMDJSON_BUILD_STATIC=OFF -DSIMDJSON_SANITIZE=ON, BUILD_FLAGS: "", CTEST_FLAGS: --output-on-failure -LE explicitonly }
steps: [ cmake_test ]
sanitize-haswell-clang10:
description: Build and run tests on clang 10 and AVX 2 with a cmake sanitize build
executor: clang10
environment: { CXXFLAGS: -march=haswell, CMAKE_FLAGS: -DSIMDJSON_BUILD_STATIC=OFF -DSIMDJSON_SANITIZE=ON, CTEST_FLAGS: --output-on-failure -E checkperf }
environment: { CXXFLAGS: -march=haswell, CMAKE_FLAGS: -DSIMDJSON_BUILD_STATIC=OFF -DSIMDJSON_SANITIZE=ON, CTEST_FLAGS: --output-on-failure -LE explicitonly }
steps: [ cmake_test ]
workflows:
@@ -292,4 +310,8 @@ workflows:
# testing "just the library"
- justlib-gcc10
# testing asserts
- assert-gcc10
- assert-clang10
# TODO add windows: https://circleci.com/docs/2.0/configuration-reference/#windows
+1 -1
View File
@@ -23,4 +23,4 @@ task:
- make
test_script:
- cd build
- ctest --output-on-failure -E checkperf
- ctest --output-on-failure -LE explicitonly
+19 -19
View File
@@ -9,7 +9,7 @@ steps:
CXX: g++
BUILD_FLAGS: -- -j
CMAKE_FLAGS: -DSIMDJSON_BUILD_STATIC=ON
CTEST_FLAGS: -j4 --output-on-failure -E checkperf
CTEST_FLAGS: -j4 --output-on-failure -LE explicitonly
commands:
- scripts/addcmakeppa.sh "$(env -i sh -c '. /etc/os-release; echo $VERSION_CODENAME')"
- apt-get install -y g++ cmake gcc git
@@ -30,7 +30,7 @@ steps:
CXX: clang++-6.0
BUILD_FLAGS: -- -j
CMAKE_FLAGS: -DSIMDJSON_BUILD_STATIC=ON
CTEST_FLAGS: -j4 --output-on-failure -E checkperf
CTEST_FLAGS: -j4 --output-on-failure -LE explicitonly
commands:
- scripts/addcmakeppa.sh "$(env -i sh -c '. /etc/os-release; echo $VERSION_CODENAME')"
- apt-get install -y clang++-6.0 cmake git
@@ -51,7 +51,7 @@ steps:
CXX: g++
BUILD_FLAGS: -- -j
CMAKE_FLAGS: -DSIMDJSON_BUILD_STATIC=ON -DSIMDJSON_IMPLEMENTATION=haswell;westmere;fallback
CTEST_FLAGS: -j4 --output-on-failure -E checkperf
CTEST_FLAGS: -j4 --output-on-failure -LE explicitonly
commands:
- echo "deb http://deb.debian.org/debian buster-backports main" >> /etc/apt/sources.list
- apt-get update -qq
@@ -78,7 +78,7 @@ steps:
CXX: clang++-6.0
BUILD_FLAGS: -- -j
CMAKE_FLAGS: -DSIMDJSON_BUILD_STATIC=ON -DSIMDJSON_IMPLEMENTATION=haswell;westmere;fallback
CTEST_FLAGS: -j4 --output-on-failure -E checkperf
CTEST_FLAGS: -j4 --output-on-failure -LE explicitonly
commands:
- mkdir build
- cd build
@@ -101,7 +101,7 @@ steps:
CXX: g++
BUILD_FLAGS: -- -j
CMAKE_FLAGS: -DSIMDJSON_BUILD_STATIC=OFF
CTEST_FLAGS: -j4 --output-on-failure -E checkperf
CTEST_FLAGS: -j4 --output-on-failure -LE explicitonly
commands:
- echo "deb http://deb.debian.org/debian buster-backports main" >> /etc/apt/sources.list
- apt-get update -qq
@@ -124,7 +124,7 @@ steps:
CXX: clang++-9
CMAKE_FLAGS: -DSIMDJSON_BUILD_STATIC=OFF
BUILD_FLAGS: -- -j
CTEST_FLAGS: -j4 --output-on-failure -E checkperf
CTEST_FLAGS: -j4 --output-on-failure -LE explicitonly
commands:
- mkdir build
- cd build
@@ -143,7 +143,7 @@ steps:
CXX: g++
BUILD_FLAGS: -- -j
CMAKE_FLAGS: -DSIMDJSON_BUILD_STATIC=ON -DSIMDJSON_IMPLEMENTATION=haswell;westmere;fallback
CTEST_FLAGS: -j4 --output-on-failure -E checkperf
CTEST_FLAGS: -j4 --output-on-failure -LE explicitonly
commands:
- echo "deb http://deb.debian.org/debian buster-backports main" >> /etc/apt/sources.list
- apt-get update -qq
@@ -170,7 +170,7 @@ steps:
CXX: clang++-9
CMAKE_FLAGS: -DSIMDJSON_SANITIZE=ON -DSIMDJSON_IMPLEMENTATION=haswell;westmere;fallback
BUILD_FLAGS: -- -j
CTEST_FLAGS: -j4 --output-on-failure -E checkperf
CTEST_FLAGS: -j4 --output-on-failure -LE explicitonly
commands:
- mkdir build
- cd build
@@ -194,7 +194,7 @@ steps:
CXX: clang++-11
CMAKE_FLAGS: -GNinja
BUILD_FLAGS:
CTEST_FLAGS: -j4 --output-on-failure -E checkperf
CTEST_FLAGS: -j4 --output-on-failure -LE explicitonly
CXXFLAGS: -std=c++20 -stdlib=libc++
commands:
- mkdir build
@@ -214,7 +214,7 @@ steps:
CXX: g++
BUILD_FLAGS: -- -j
CMAKE_FLAGS: -DSIMDJSON_BUILD_STATIC=ON -DSIMDJSON_IMPLEMENTATION=arm64;fallback
CTEST_FLAGS: -j4 --output-on-failure -E checkperf
CTEST_FLAGS: -j4 --output-on-failure -LE explicitonly
commands:
- echo "deb http://deb.debian.org/debian buster-backports main" >> /etc/apt/sources.list
- apt-get update -qq
@@ -239,7 +239,7 @@ steps:
CXX: clang++-6.0
CMAKE_FLAGS: -DSIMDJSON_BUILD_STATIC=OFF
BUILD_FLAGS: -- -j
CTEST_FLAGS: -j4 --output-on-failure -E checkperf
CTEST_FLAGS: -j4 --output-on-failure -LE explicitonly
commands:
- apt-get -qq update
- apt-get -t buster-backports install -y cmake
@@ -261,7 +261,7 @@ steps:
CXX: g++
BUILD_FLAGS: -- -j
CMAKE_FLAGS: -DSIMDJSON_BUILD_STATIC=OFF
CTEST_FLAGS: -j4 --output-on-failure -E checkperf
CTEST_FLAGS: -j4 --output-on-failure -LE explicitonly
commands:
- echo "deb http://deb.debian.org/debian buster-backports main" >> /etc/apt/sources.list
- apt-get update -qq
@@ -283,7 +283,7 @@ steps:
CXX: clang++-6.0
CMAKE_FLAGS: -DSIMDJSON_BUILD_STATIC=OFF
BUILD_FLAGS: -- -j
CTEST_FLAGS: -j4 --output-on-failure -E checkperf
CTEST_FLAGS: -j4 --output-on-failure -LE explicitonly
commands:
- apt-get -qq update
- apt-get -t buster-backports install -y cmake
@@ -303,7 +303,7 @@ steps:
environment:
BUILD_FLAGS: -- -j
CMAKE_FLAGS: -DSIMDJSON_BUILD_STATIC=ON -DSIMDJSON_IMPLEMENTATION=arm64;fallback
CTEST_FLAGS: -j4 --output-on-failure -E checkperf
CTEST_FLAGS: -j4 --output-on-failure -LE explicitonly
CC: gcc
CXX: g++
commands:
@@ -331,7 +331,7 @@ steps:
CXX: clang++-6.0
CMAKE_FLAGS: -DSIMDJSON_SANITIZE=ON -DSIMDJSON_IMPLEMENTATION=arm64;fallback
BUILD_FLAGS: -- -j
CTEST_FLAGS: -j4 --output-on-failure -E checkperf
CTEST_FLAGS: -j4 --output-on-failure -LE explicitonly
commands:
- apt-get -qq update
- apt-get -t buster-backports install -y cmake
@@ -357,7 +357,7 @@ steps:
CXX: clang++-9
BUILD_FLAGS: -- -j 4
CMAKE_FLAGS: -GNinja -DSIMDJSON_BUILD_STATIC=ON
CTEST_FLAGS: -j4 --output-on-failure -E checkperf
CTEST_FLAGS: -j4 --output-on-failure -LE explicitonly
CXXFLAGS: -stdlib=libc++
commands:
- mkdir build
@@ -378,7 +378,7 @@ steps:
CXX: clang++-9
BUILD_FLAGS: -- -j
CMAKE_FLAGS: -DSIMDJSON_BUILD_STATIC=ON
CTEST_FLAGS: -j4 --output-on-failure -E checkperf
CTEST_FLAGS: -j4 --output-on-failure -LE explicitonly
CXXFLAGS: -stdlib=libc++
commands:
- mkdir build
@@ -399,7 +399,7 @@ steps:
CXX: clang++-7
BUILD_FLAGS: -- -j
CMAKE_FLAGS: -DSIMDJSON_BUILD_STATIC=ON
CTEST_FLAGS: -j4 --output-on-failure -E checkperf
CTEST_FLAGS: -j4 --output-on-failure -LE explicitonly
CXXFLAGS: -stdlib=libc++
commands:
- mkdir build
@@ -419,7 +419,7 @@ steps:
CXX: g++
BUILD_FLAGS: -- -j
CMAKE_FLAGS: -DSIMDJSON_EXCEPTIONS=OFF
CTEST_FLAGS: -j4 --output-on-failure -E checkperf
CTEST_FLAGS: -j4 --output-on-failure -LE explicitonly
commands:
- echo "deb http://deb.debian.org/debian buster-backports main" >> /etc/apt/sources.list
- apt-get update -qq
+1 -1
View File
@@ -34,4 +34,4 @@ jobs:
./alpine.sh cmake --build build_for_alpine
- name: test
run: |
./alpine.sh bash -c "cd build_for_alpine && ctest -E checkperf"
./alpine.sh bash -c "cd build_for_alpine && ctest -LE explicitonly"
+1 -1
View File
@@ -51,4 +51,4 @@ jobs:
cd build
cmake -DCMAKE_BUILD_TYPE=${{ matrix.type }} -DSIMDJSON_BUILD_STATIC=ON -DSIMDJSON_DO_NOT_USE_THREADS_NO_MATTER_WHAT=ON ..
cmake --build . --verbose
ctest -j4 --output-on-failure -E checkperf
ctest -j4 --output-on-failure -LE explicitonly
+1 -1
View File
@@ -23,6 +23,6 @@ jobs:
cd build &&
cmake -DSIMDJSON_GOOGLE_BENCHMARKS=ON -DSIMDJSON_BUILD_STATIC=ON -DCMAKE_INSTALL_PREFIX:PATH=destination .. &&
cmake --build . &&
ctest -j --output-on-failure -E checkperf &&
ctest -j --output-on-failure -LE explicitonly &&
make install &&
echo -e '#include <simdjson.h>\nint main(int argc,char**argv) {simdjson::dom::parser parser;simdjson::dom::element tweets = parser.load(argv[1]); }' > tmp.cpp && c++ -Idestination/include -Ldestination/lib -std=c++17 -Wl,-rpath,destination/lib -o linkandrun tmp.cpp -lsimdjson && ./linkandrun jsonexamples/twitter.json
+1 -1
View File
@@ -23,6 +23,6 @@ jobs:
cd build &&
cmake -DSIMDJSON_GOOGLE_BENCHMARKS=ON -DSIMDJSON_BUILD_STATIC=ON -DCMAKE_INSTALL_PREFIX:PATH=destination .. &&
cmake --build . &&
ctest -j --output-on-failure -E checkperf &&
ctest -j --output-on-failure -LE explicitonly &&
make install &&
echo -e '#include <simdjson.h>\nint main(int argc,char**argv) {simdjson::dom::parser parser;simdjson::dom::element tweets = parser.load(argv[1]); }' > tmp.cpp && c++ -Idestination/include -Ldestination/lib -std=c++17 -Wl,-rpath,destination/lib -o linkandrun tmp.cpp -lsimdjson && ./linkandrun jsonexamples/twitter.json
+1 -1
View File
@@ -31,6 +31,6 @@ jobs:
buildWithCMakeArgs: --config Release
- name: 'Run CTest'
run: ctest -C Release -E checkperf --output-on-failure
run: ctest -C Release -LE explicitonly --output-on-failure
working-directory: "${{ github.workspace }}/../../_temp/windows"
+1 -1
View File
@@ -31,5 +31,5 @@ jobs:
buildWithCMakeArgs: --config Release
- name: 'Run CTest'
run: ctest -C Release -E checkperf --output-on-failure
run: ctest -C Release -LE explicitonly --output-on-failure
working-directory: "${{ github.workspace }}/../../_temp/windows"
+1 -1
View File
@@ -31,6 +31,6 @@ jobs:
buildWithCMakeArgs: --config Release
- name: 'Run CTest'
run: ctest -C Release -E checkperf --output-on-failure
run: ctest -C Release -LE explicitonly --output-on-failure
working-directory: "${{ github.workspace }}/../../_temp/windows"
+1 -1
View File
@@ -176,7 +176,7 @@ install:
- if [[ "${STATIC}" == "on" ]]; then
export CMAKE_FLAGS="${CMAKE_FLAGS} -DSIMDJSON_BUILD_STATIC=ON";
fi
- export CTEST_FLAGS="-j4 --output-on-failure -E checkperf"
- export CTEST_FLAGS="-j4 --output-on-failure -LE explicitonly"
script:
- mkdir build
+1 -1
View File
@@ -41,7 +41,7 @@
#
# Next you can test it as follows:
#
# docker run -it -v $(pwd):/project:Z simdjson sh -c "cd dockerbuild && ctest . --output-on-failure -E checkperf"
# docker run -it -v $(pwd):/project:Z simdjson sh -c "cd dockerbuild && ctest . --output-on-failure -LE explicitonly"
#
# The run the complete tests requires you to have built all of simdjson.
#
+1 -1
View File
@@ -89,7 +89,7 @@ if (Git_FOUND AND (GIT_VERSION_STRING VERSION_GREATER "2.1.4") AND (NOT CMAKE_G
# COMMAND ECHO $<TARGET_FILE:perfdiff> \"$<TARGET_FILE:parse> -t ${SIMDJSON_CHECKPERF_ARGS}\" \"${CHECKPERF_PARSE} -t ${SIMDJSON_CHECKPERF_ARGS}\" }
COMMAND $<TARGET_FILE:perfdiff> $<TARGET_FILE:parse> ${CHECKPERF_PARSE} -H -t ${SIMDJSON_CHECKPERF_ARGS}
)
set_property(TEST checkperf APPEND PROPERTY LABELS per_implementation)
set_property(TEST checkperf APPEND PROPERTY LABELS per_implementation explicitonly)
set_property(TEST checkperf APPEND PROPERTY DEPENDS parse perfdiff ${SIMDJSON_USER_CMAKECACHE})
set_property(TEST checkperf PROPERTY RUN_SERIAL TRUE)
else()
+17 -13
View File
@@ -72,24 +72,24 @@ set(THREADS_PREFER_PTHREAD_FLAG ON)
option(SIMDJSON_VISUAL_STUDIO_BUILD_WITH_DEBUG_INFO_FOR_PROFILING "Under Visual Studio, add Zi to the compile flag and DEBUG to the link file to add debugging information to the release build for easier profiling inside tools like VTune" OFF)
if(MSVC)
if("${MSVC_TOOLSET_VERSION}" STREQUAL "140")
# Visual Studio 2015 issues warnings and we tolerate it, cmake -G"Visual Studio 14" ..
target_compile_options(simdjson-internal-flags INTERFACE /W0 /sdl)
else()
# Recent version of Visual Studio expected (2017, 2019...). Prior versions are unsupported.
target_compile_options(simdjson-internal-flags INTERFACE /WX /W3 /sdl /w34714) # https://docs.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-4-c4714?view=vs-2019
endif()
if(SIMDJSON_VISUAL_STUDIO_BUILD_WITH_DEBUG_INFO_FOR_PROFILING)
target_link_options(simdjson-flags INTERFACE /DEBUG )
target_compile_options(simdjson-flags INTERFACE /Zi)
endif()
else()
if("${MSVC_TOOLSET_VERSION}" STREQUAL "140")
# Visual Studio 2015 issues warnings and we tolerate it, cmake -G"Visual Studio 14" ..
target_compile_options(simdjson-internal-flags INTERFACE /W0 /sdl)
else()
# Recent version of Visual Studio expected (2017, 2019...). Prior versions are unsupported.
target_compile_options(simdjson-internal-flags INTERFACE /WX /W3 /sdl /w34714) # https://docs.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-4-c4714?view=vs-2019
endif()
if(SIMDJSON_VISUAL_STUDIO_BUILD_WITH_DEBUG_INFO_FOR_PROFILING)
target_link_options(simdjson-flags INTERFACE /DEBUG )
target_compile_options(simdjson-flags INTERFACE /Zi)
endif(SIMDJSON_VISUAL_STUDIO_BUILD_WITH_DEBUG_INFO_FOR_PROFILING)
else(MSVC)
if(NOT WIN32)
target_compile_options(simdjson-internal-flags INTERFACE -fPIC)
endif()
target_compile_options(simdjson-internal-flags INTERFACE -Werror -Wall -Wextra -Weffc++)
target_compile_options(simdjson-internal-flags INTERFACE -Wsign-compare -Wshadow -Wwrite-strings -Wpointer-arith -Winit-self -Wconversion -Wno-sign-conversion)
endif()
endif(MSVC)
#
# Optional flags
@@ -232,5 +232,9 @@ if(${CMAKE_C_COMPILER_ID} MATCHES "Intel") # icc / icpc
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-intel")
endif()
include (CheckSymbolExists)
CHECK_SYMBOL_EXISTS(fork unistd.h HAVE_POSIX_FORK)
CHECK_SYMBOL_EXISTS(wait sys/wait.h HAVE_POSIX_WAIT)
install(TARGETS simdjson-flags EXPORT simdjson-config)
install(TARGETS simdjson-internal-flags EXPORT simdjson-config)
@@ -47,16 +47,6 @@ struct implementation_simdjson_result_base {
*/
simdjson_really_inline implementation_simdjson_result_base(T &&value, error_code error) noexcept;
/**
* Move a result.
*/
simdjson_really_inline implementation_simdjson_result_base(implementation_simdjson_result_base<T> &&value) noexcept = default;
/**
* Copy a result.
*/
simdjson_really_inline implementation_simdjson_result_base(const implementation_simdjson_result_base<T> &value) = default;
/**
* Create a new empty result with error = UNINITIALIZED.
*/
@@ -8,9 +8,6 @@ simdjson_really_inline document::document(ondemand::json_iterator &&_iter) noexc
logger::log_start_value(iter, "document");
}
simdjson_really_inline void document::assert_at_root() const noexcept {
iter.assert_at_root();
}
simdjson_really_inline document document::start(json_iterator &&iter) noexcept {
return document(std::forward<json_iterator>(iter));
}
@@ -19,8 +16,11 @@ simdjson_really_inline value document::as_value() noexcept {
return as_value_iterator();
}
simdjson_really_inline value_iterator document::as_value_iterator() noexcept {
assert_at_root();
return value_iterator(&iter, 1, iter.token.checkpoint());
iter.assert_at_root();
return value_iterator(&iter, 1, iter.root_checkpoint());
}
simdjson_really_inline value_iterator document::as_non_root_value_iterator() noexcept {
return value_iterator(&iter, 1, iter.root_checkpoint());
}
simdjson_really_inline simdjson_result<array> document::get_array() & noexcept {
@@ -90,10 +90,20 @@ simdjson_really_inline simdjson_result<array_iterator> document::end() & noexcep
return {};
}
simdjson_really_inline simdjson_result<value> document::operator[](std::string_view key) & noexcept {
return get_object()[key];
if (iter.at_root()) {
return get_object()[key];
} else {
// If we're not at the root, this is not the first key we've grabbed
return object::resume(as_non_root_value_iterator())[key];
}
}
simdjson_really_inline simdjson_result<value> document::operator[](const char *key) & noexcept {
return get_object()[key];
if (iter.at_root()) {
return get_object()[key];
} else {
// If we're not at the root, this is not the first key we've grabbed
return object::resume(as_non_root_value_iterator())[key];
}
}
} // namespace ondemand
+1 -5
View File
@@ -230,10 +230,9 @@ protected:
simdjson_really_inline value as_value() noexcept;
simdjson_really_inline value_iterator as_value_iterator() noexcept;
simdjson_really_inline value_iterator as_non_root_value_iterator() noexcept;
static simdjson_really_inline document start(ondemand::json_iterator &&iter) noexcept;
simdjson_really_inline void assert_at_root() const noexcept;
//
// Fields
//
@@ -261,10 +260,7 @@ struct simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document> : public SIM
public:
simdjson_really_inline simdjson_result(SIMDJSON_IMPLEMENTATION::ondemand::document &&value) noexcept; ///< @private
simdjson_really_inline simdjson_result(error_code error) noexcept; ///< @private
simdjson_really_inline simdjson_result() noexcept = default;
simdjson_really_inline simdjson_result(simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document> &&a) noexcept = default;
simdjson_really_inline ~simdjson_result() noexcept = default; ///< @private
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array> get_array() & noexcept;
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object> get_object() & noexcept;
@@ -91,7 +91,11 @@ simdjson_warn_unused simdjson_really_inline error_code json_iterator::skip_child
}
simdjson_really_inline bool json_iterator::at_root() const noexcept {
return token.index == parser->dom_parser.structural_indexes.get();
return token.checkpoint() == root_checkpoint();
}
simdjson_really_inline const uint32_t *json_iterator::root_checkpoint() const noexcept {
return parser->dom_parser.structural_indexes.get();
}
simdjson_really_inline void json_iterator::assert_at_root() const noexcept {
@@ -62,6 +62,11 @@ public:
*/
simdjson_really_inline bool at_root() const noexcept;
/**
* Get the root value iterator
*/
simdjson_really_inline const uint32_t *root_checkpoint() const noexcept;
/**
* Assert if the iterator is not at the start
*/
@@ -184,8 +189,6 @@ public:
simdjson_really_inline simdjson_result(error_code error) noexcept; ///< @private
simdjson_really_inline simdjson_result() noexcept = default;
simdjson_really_inline simdjson_result(simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::json_iterator> &&a) noexcept = default;
simdjson_really_inline ~simdjson_result() noexcept = default; ///< @private
};
} // namespace simdjson
@@ -71,9 +71,12 @@ simdjson_really_inline object object::started(value_iterator &iter) noexcept {
simdjson_unused bool has_value = iter.started_object();
return iter;
}
simdjson_really_inline object object::resume(const value_iterator &iter) noexcept {
return { iter, false };
}
simdjson_really_inline object::object(const value_iterator &_iter) noexcept
: iter{_iter}
simdjson_really_inline object::object(const value_iterator &_iter, bool _at_start) noexcept
: iter{_iter, _at_start}
{
}
+2 -1
View File
@@ -49,7 +49,8 @@ protected:
static simdjson_really_inline simdjson_result<object> start(value_iterator &iter) noexcept;
static simdjson_really_inline simdjson_result<object> try_start(value_iterator &iter) noexcept;
static simdjson_really_inline object started(value_iterator &iter) noexcept;
simdjson_really_inline object(const value_iterator &_iter) noexcept;
static simdjson_really_inline object resume(const value_iterator &iter) noexcept;
simdjson_really_inline object(const value_iterator &iter, bool at_start = true) noexcept;
simdjson_warn_unused simdjson_really_inline error_code find_field_raw(const std::string_view key) noexcept;
@@ -6,9 +6,9 @@ namespace ondemand {
// object_iterator
//
simdjson_really_inline object_iterator::object_iterator(const value_iterator &_iter) noexcept
simdjson_really_inline object_iterator::object_iterator(const value_iterator &_iter, bool _at_start) noexcept
: iter{_iter},
at_start{true}
at_start{_at_start}
{}
simdjson_really_inline simdjson_result<field> object_iterator::operator*() noexcept {
@@ -52,7 +52,7 @@ private:
*/
bool at_start{};
simdjson_really_inline object_iterator(const value_iterator &iter) noexcept;
simdjson_really_inline object_iterator(const value_iterator &iter, bool at_start = true) noexcept;
friend struct simdjson_result<object_iterator>;
friend class object;
};
@@ -130,10 +130,7 @@ struct simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::parser> : public SIMDJ
public:
simdjson_really_inline simdjson_result(SIMDJSON_IMPLEMENTATION::ondemand::parser &&value) noexcept; ///< @private
simdjson_really_inline simdjson_result(error_code error) noexcept; ///< @private
simdjson_really_inline simdjson_result() noexcept = default;
simdjson_really_inline simdjson_result(simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::parser> &&a) noexcept = default;
simdjson_really_inline ~simdjson_result() noexcept = default; ///< @private
};
} // namespace simdjson
@@ -109,9 +109,7 @@ struct simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string> : pub
public:
simdjson_really_inline simdjson_result(SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string &&value) noexcept; ///< @private
simdjson_really_inline simdjson_result(error_code error) noexcept; ///< @private
simdjson_really_inline simdjson_result() noexcept = default;
simdjson_really_inline simdjson_result(const simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string> &a) noexcept = default;
simdjson_really_inline ~simdjson_result() noexcept = default; ///< @private
simdjson_really_inline simdjson_result<const char *> raw() const noexcept;
@@ -97,9 +97,7 @@ struct simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::token_iterator> : publ
public:
simdjson_really_inline simdjson_result(SIMDJSON_IMPLEMENTATION::ondemand::token_iterator &&value) noexcept; ///< @private
simdjson_really_inline simdjson_result(error_code error) noexcept; ///< @private
simdjson_really_inline simdjson_result() noexcept = default;
simdjson_really_inline simdjson_result(simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::token_iterator> &&a) noexcept = default;
simdjson_really_inline ~simdjson_result() noexcept = default; ///< @private
};
@@ -80,7 +80,6 @@ simdjson_warn_unused simdjson_really_inline simdjson_result<bool> value_iterator
}
simdjson_warn_unused simdjson_really_inline simdjson_result<raw_json_string> value_iterator::field_key() noexcept {
logger::log_event(*this, "hi");
assert_at_child();
const uint8_t *key = _json_iter->advance();
@@ -23,7 +23,11 @@ protected:
json_iterator *_json_iter{};
/** The depth of this value */
depth_t _depth{};
/** The starting token index for this value */
/**
* The starting token index for this value
*
* PERF NOTE: this is a safety check; we expect this to be elided in release builds.
*/
const uint32_t *_start_index{};
public:
+3 -1
View File
@@ -2,4 +2,6 @@
link_libraries(simdjson)
include_directories(..)
add_cpp_test(ondemand_basictests LABELS acceptance per_implementation)
if(HAVE_POSIX_FORK AND HAVE_POSIX_WAIT) # assert tests use fork and wait, which aren't on MSVC
add_cpp_test(ondemand_assert_out_of_order_values LABELS per_implementation explicitonly assert)
endif()
@@ -0,0 +1,46 @@
#include <iostream>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
#include "simdjson.h"
using namespace simdjson;
using namespace simdjson::builtin;
// This ensures the compiler can't rearrange them into the proper order (which causes it to work!)
simdjson_never_inline int check_point(simdjson_result<ondemand::value> xval, simdjson_result<ondemand::value> yval) {
// Verify the expected release behavior
error_code error;
uint64_t x = 0;
if ((error = xval.get(x))) { std::cerr << "error getting x: " << error << std::endl; }
else if (x != 2) { std::cerr << "expected x to (wrongly) be 2, was " << x << std::endl; }
uint64_t y = 0;
if ((error = yval.get(y))) { std::cerr << "error getting y: " << error << std::endl; }
else if (y != 3) { std::cerr << "expected y to (wrongly) be 3, was " << y << std::endl; }
return 0;
}
int main(void) {
pid_t pid = fork();
if (pid == -1) { std::cerr << "fork failed" << std::endl; return 1; }
if (pid) {
// Parent - wait child and interpret its result
int status = 0;
wait(&status);
if(!WIFSIGNALED(status)) {
std::cerr << "Expected program to abort, but it exited successfully with status " << status << std::endl;
return 1;
}
return 0; // Signal-terminated means success
} else {
auto json = R"(
{
"x": 1,
"y": 2 3
)"_padded;
ondemand::parser parser;
auto doc = parser.iterate(json);
return check_point(doc["x"], doc["y"]);
}
}
+129 -1
View File
@@ -887,6 +887,116 @@ namespace dom_api_tests {
return true;
}));
SUBTEST("simdjson_result<ondemand::document>", test_ondemand_doc(json, [&](auto doc_result) {
ASSERT_SUCCESS( doc_result["scalar_ignore"] );
std::cout << " - After ignoring empty scalar ..." << std::endl;
ASSERT_SUCCESS( doc_result["empty_array_ignore"] );
std::cout << " - After ignoring empty array ..." << std::endl;
ASSERT_SUCCESS( doc_result["empty_object_ignore"] );
std::cout << " - After ignoring empty doc_result ..." << std::endl;
// Break after using first value in child object
{
auto value = doc_result["object_break"];
for (auto [ child_field, error ] : value.get_object()) {
ASSERT_SUCCESS(error);
ASSERT_EQUAL(child_field.key(), "x");
uint64_t x;
ASSERT_SUCCESS( child_field.value().get(x) );
ASSERT_EQUAL(x, 3);
break; // Break after the first value
}
std::cout << " - After using first value in child object ..." << std::endl;
}
// Break without using first value in child object
{
auto value = doc_result["object_break_unused"];
for (auto [ child_field, error ] : value.get_object()) {
ASSERT_SUCCESS(error);
ASSERT_EQUAL(child_field.key(), "x");
break;
}
std::cout << " - After reaching (but not using) first value in child object ..." << std::endl;
}
// Only look up one field in child object
{
auto value = doc_result["object_index"];
uint64_t x;
ASSERT_SUCCESS( value["x"].get(x) );
ASSERT_EQUAL( x, 5 );
std::cout << " - After looking up one field in child object ..." << std::endl;
}
// Only look up one field in child object, but don't use it
{
auto value = doc_result["object_index_unused"];
ASSERT_SUCCESS( value["x"] );
std::cout << " - After looking up (but not using) one field in child object ..." << std::endl;
}
// Break after first value in child array
{
auto value = doc_result["array_break"];
for (auto child_value : value) {
uint64_t x;
ASSERT_SUCCESS( child_value.get(x) );
ASSERT_EQUAL( x, 7 );
break;
}
std::cout << " - After using first value in child array ..." << std::endl;
}
// Break without using first value in child array
{
auto value = doc_result["array_break_unused"];
for (auto child_value : value) {
ASSERT_SUCCESS(child_value);
break;
}
std::cout << " - After reaching (but not using) first value in child array ..." << std::endl;
}
// Break out of multiple child loops
{
auto value = doc_result["quadruple_nested_break"];
for (auto child1 : value.get_object()) {
for (auto child2 : child1.value().get_array()) {
for (auto child3 : child2.get_object()) {
for (auto child4 : child3.value().get_array()) {
uint64_t x;
ASSERT_SUCCESS( child4.get(x) );
ASSERT_EQUAL( x, 9 );
break;
}
break;
}
break;
}
break;
}
std::cout << " - After breaking out of quadruply-nested arrays and objects ..." << std::endl;
}
// Test the actual value
{
auto value = doc_result["actual_value"];
uint64_t actual_value;
ASSERT_SUCCESS( value.get(actual_value) );
ASSERT_EQUAL( actual_value, 10 );
}
return true;
}));
return true;
}
@@ -1061,17 +1171,35 @@ namespace dom_api_tests {
return true;
}));
SUBTEST("simdjson_result<ondemand::object>", test_ondemand_doc(json, [&](auto doc_result) {
ASSERT_EQUAL( doc_result.get_object()["a"].get_uint64().first, 1 );
simdjson_result<ondemand::object> object;
object = doc_result.get_object();
ASSERT_EQUAL( object["a"].get_uint64().first, 1 );
ASSERT_EQUAL( object["b"].get_uint64().first, 2 );
ASSERT_EQUAL( object["c/d"].get_uint64().first, 3 );
ASSERT_ERROR( object["a"], NO_SUCH_FIELD );
ASSERT_ERROR( object["d"], NO_SUCH_FIELD );
return true;
}));
SUBTEST("ondemand::document", test_ondemand_doc(json, [&](auto doc_result) {
ondemand::document doc;
ASSERT_SUCCESS( std::move(doc_result).get(doc) );
ASSERT_EQUAL( doc["a"].get_uint64().first, 1 );
ASSERT_EQUAL( doc["b"].get_uint64().first, 2 );
ASSERT_EQUAL( doc["c/d"].get_uint64().first, 3 );
ASSERT_ERROR( doc["a"], NO_SUCH_FIELD );
ASSERT_ERROR( doc["d"], NO_SUCH_FIELD );
return true;
}));
SUBTEST("simdjson_result<ondemand::document>", test_ondemand_doc(json, [&](auto doc_result) {
ASSERT_EQUAL( doc_result["a"].get_uint64().first, 1 );
ASSERT_EQUAL( doc_result["b"].get_uint64().first, 2 );
ASSERT_EQUAL( doc_result["c/d"].get_uint64().first, 3 );
ASSERT_ERROR( doc_result["a"], NO_SUCH_FIELD );
ASSERT_ERROR( doc_result["d"], NO_SUCH_FIELD );
return true;
}));
TEST_SUCCEED();