From 8c05e40caefe2d63b53437a50245fd4b45e51b79 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Mon, 5 Oct 2026 17:44:51 +0200 Subject: [PATCH] Split the Visual Studio 2017 AppVeyor jobs in two The VS 2017 jobs hit AppVeyor's 60-minute limit per job while still compiling the tests (77 of about 108 test targets after 58 minutes). They pass /std:c++17 for everything anyway, so build only the C++17 variant of each test (JSON_TestStandards=17), and split the unit test files across two jobs each with the new JSON_TestShard=/ option, which keeps every -th test file starting at . The extra variants of single test files are built in shard 0 only. CMAKE_OPTIONS is no longer quoted in appveyor.yml, so that it can hold more than one option. Signed-off-by: Niels Lohmann --- .github/external_ci/appveyor.yml | 21 +++++++++++++++++--- tests/CMakeLists.txt | 33 ++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/.github/external_ci/appveyor.yml b/.github/external_ci/appveyor.yml index 805195742..4f0d3f5e3 100644 --- a/.github/external_ci/appveyor.yml +++ b/.github/external_ci/appveyor.yml @@ -16,6 +16,9 @@ only_commits: environment: matrix: + # The Visual Studio 2017 jobs compile everything with /std:c++17, so they + # only build the C++17 variant of each test, split into two jobs each to + # stay below AppVeyor's 60-minute limit per job. - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 configuration: Debug platform: x86 @@ -34,7 +37,13 @@ environment: configuration: Release platform: x86 CXX_FLAGS: "/permissive- /std:c++17 /utf-8 /W4 /WX" - CMAKE_OPTIONS: "" + CMAKE_OPTIONS: "-DJSON_TestStandards=17 -DJSON_TestShard=0/2" + GENERATOR: Visual Studio 15 2017 + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + configuration: Release + platform: x86 + CXX_FLAGS: "/permissive- /std:c++17 /utf-8 /W4 /WX" + CMAKE_OPTIONS: "-DJSON_TestStandards=17 -DJSON_TestShard=1/2" GENERATOR: Visual Studio 15 2017 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 @@ -55,7 +64,13 @@ environment: configuration: Release platform: x64 CXX_FLAGS: "/permissive- /std:c++17 /Zc:__cplusplus /utf-8 /W4 /WX" - CMAKE_OPTIONS: "" + CMAKE_OPTIONS: "-DJSON_TestStandards=17 -DJSON_TestShard=0/2" + GENERATOR: Visual Studio 15 2017 + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + configuration: Release + platform: x64 + CXX_FLAGS: "/permissive- /std:c++17 /Zc:__cplusplus /utf-8 /W4 /WX" + CMAKE_OPTIONS: "-DJSON_TestStandards=17 -DJSON_TestShard=1/2" GENERATOR: Visual Studio 15 2017 init: @@ -66,7 +81,7 @@ install: - if "%platform%"=="x86" set GENERATOR_PLATFORM=Win32 before_build: - - cmake . -G "%GENERATOR%" -A "%GENERATOR_PLATFORM%" -DCMAKE_CXX_FLAGS="%CXX_FLAGS%" -DCMAKE_IGNORE_PATH="C:/Program Files/Git/usr/bin" -DJSON_BuildTests=On "%CMAKE_OPTIONS%" + - cmake . -G "%GENERATOR%" -A "%GENERATOR_PLATFORM%" -DCMAKE_CXX_FLAGS="%CXX_FLAGS%" -DCMAKE_IGNORE_PATH="C:/Program Files/Git/usr/bin" -DJSON_BuildTests=On %CMAKE_OPTIONS% build_script: - cmake --build . --config "%configuration%" --parallel 2 diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index aac6fee5e..8735934de 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -8,6 +8,7 @@ set(JSON_SIMDUTF_VERSION 9.1.0 CACHE STRING "The simdutf version used by JSON_Te set(JSON_32bitTest AUTO CACHE STRING "Enable the 32bit unit test (ON/OFF/AUTO/ONLY).") set(JSON_TestStandards "" CACHE STRING "The list of standards to test explicitly.") +set(JSON_TestShard "" CACHE STRING "Build only a part of the unit tests, given as / (e.g. 0/2), to split them across CI jobs with a time limit.") # using an env var, since this will also affect targets executing cmake (such as "ci_test_compiler_default") if (NOT "" STREQUAL "$ENV{JSON_FORCED_GLOBAL_COMPILE_OPTIONS}") @@ -288,6 +289,33 @@ elseif(NOT json_32bit_test) list(FILTER files EXCLUDE REGEX src/unit-32bit.cpp) endif() +# with JSON_TestShard=/, keep every -th unit test file, +# starting at (the glob is sorted, so the split is stable) +set(test_shard_index 0) +if(NOT "${JSON_TestShard}" STREQUAL "") + if(NOT JSON_TestShard MATCHES "^([0-9]+)/([1-9][0-9]*)$") + message(FATAL_ERROR "JSON_TestShard must be /, e.g. 0/2, not '${JSON_TestShard}'.") + endif() + set(test_shard_index ${CMAKE_MATCH_1}) + set(test_shard_count ${CMAKE_MATCH_2}) + if(NOT test_shard_index LESS test_shard_count) + message(FATAL_ERROR "JSON_TestShard: the index must be less than the count, not '${JSON_TestShard}'.") + endif() + list(LENGTH files test_file_count) + set(shard_files "") + set(file_position 0) + foreach(file ${files}) + math(EXPR file_shard "${file_position} % ${test_shard_count}") + if(file_shard EQUAL test_shard_index) + list(APPEND shard_files ${file}) + endif() + math(EXPR file_position "${file_position} + 1") + endforeach() + set(files ${shard_files}) + list(LENGTH files shard_file_count) + message(STATUS "Test shard ${JSON_TestShard}: ${shard_file_count} of ${test_file_count} unit test files") +endif() + foreach(file ${files}) json_test_add_test_for(${file} MAIN test_main CXX_STANDARDS ${test_cxx_standards} ${test_force}) endforeach() @@ -305,6 +333,9 @@ if(json_32bit_test_only) return() endif() +# the following variants of single test files are only built in the first shard +if(test_shard_index EQUAL 0) + # test legacy comparison of discarded values json_test_set_test_options(test-comparison_legacy COMPILE_DEFINITIONS JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON=1 @@ -332,6 +363,8 @@ json_test_add_test_for(src/unit-diagnostic-positions.cpp MAIN test_main CXX_STANDARDS ${test_cxx_standards} ${test_force} ) +endif() + # *DO NOT* use json_test_set_test_options() below this line #############################################################################