Compare commits

..

12 Commits

Author SHA1 Message Date
Martin Hořeňovský
c1968b3114 More tsan builds 2025-11-09 23:13:57 +01:00
Martin Hořeňovský
5ed9c45e5f Verbose ctest 2025-11-09 22:53:55 +01:00
Martin Hořeňovský
950ad70f4c Fix 2025-11-09 21:34:41 +01:00
Martin Hořeňovský
d7c67270af Disable werror 2025-11-09 21:32:03 +01:00
Martin Hořeňovský
c748569310 Test tsan on mac 2025-11-09 21:28:25 +01:00
Martin Hořeňovský
cd7e43489e Fewer assertions so that msvc debug build doesn't timeout 2025-11-09 15:18:09 +01:00
Martin Hořeňovský
f6fd079aa3 back to 4 threads 2025-11-09 15:03:54 +01:00
Martin Hořeňovský
22d54b36e0 Just 2 threads for a test 2025-11-09 14:58:10 +01:00
Martin Hořeňovský
a9116c2142 Serial run, CAPTURE back 2025-11-09 13:14:14 +01:00
Martin Hořeňovský
2e3214709a Remove captures 2025-11-09 11:41:27 +01:00
Martin Hořeňovský
41ed8b702a Fix initialization for older standards 2025-11-09 11:19:44 +01:00
Martin Hořeňovský
93ef2b4cb8 Add tests for assertion thread safety 2025-11-09 11:07:32 +01:00
4 changed files with 98 additions and 4 deletions

36
.github/workflows/mac-other-builds.yml vendored Normal file
View File

@@ -0,0 +1,36 @@
name: Mac Sanitizer Builds
on: [push, pull_request]
env:
CXXFLAGS: -fsanitize=thread,undefined
jobs:
build:
# From macos-14 forward, the baseline "macos-X" image is Arm based,
# and not Intel based.
runs-on: ${{matrix.image}}
strategy:
fail-fast: false
matrix:
image: [macos-13, macos-14]
build_type: [Debug, Release]
std: [14, 17]
steps:
- uses: actions/checkout@v4
- name: Configure
run: |
cmake --preset all-tests -GNinja \
-DCMAKE_BUILD_TYPE=${{matrix.build_type}} \
-DCMAKE_CXX_STANDARD=${{matrix.std}} \
-DCATCH_BUILD_EXTRA_TESTS=ON \
-DCATCH_ENABLE_WERROR=OFF
- name: Build
run: cmake --build build
- name: Test
run: ctest --test-dir build -R ThreadSafetyTests --timeout 21600 --verbose

View File

@@ -23,10 +23,10 @@ namespace Catch {
using Mutex = std::mutex;
using LockGuard = std::lock_guard<std::mutex>;
struct AtomicCounts {
std::atomic<std::uint64_t> passed = 0;
std::atomic<std::uint64_t> failed = 0;
std::atomic<std::uint64_t> failedButOk = 0;
std::atomic<std::uint64_t> skipped = 0;
std::atomic<std::uint64_t> passed{ 0 };
std::atomic<std::uint64_t> failed{ 0 };
std::atomic<std::uint64_t> failedButOk{ 0 };
std::atomic<std::uint64_t> skipped{ 0 };
};
#else // ^^ Use actual mutex, lock and atomics
// vv Dummy implementations for single-thread performance

View File

@@ -553,3 +553,17 @@ set_tests_properties(AmalgamatedFileTest
PROPERTIES
PASS_REGULAR_EXPRESSION "All tests passed \\(14 assertions in 3 test cases\\)"
)
add_executable(ThreadSafetyTests
${TESTS_DIR}/X94-ThreadSafetyTests.cpp
)
target_link_libraries(ThreadSafetyTests Catch2_buildall_interface)
target_compile_definitions(ThreadSafetyTests PUBLIC CATCH_CONFIG_EXPERIMENTAL_THREAD_SAFE_ASSERTIONS)
add_test(NAME ThreadSafetyTests
COMMAND ThreadSafetyTests -r compact
)
set_tests_properties(ThreadSafetyTests
PROPERTIES
PASS_REGULAR_EXPRESSION "assertions: 801 | 400 passed | 401 failed"
RUN_SERIAL ON
)

View File

@@ -0,0 +1,44 @@
// Copyright Catch2 Authors
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
// SPDX-License-Identifier: BSL-1.0
/**\file
* Test that assertions and messages are thread-safe.
*
* This is done by spamming assertions and messages on multiple subthreads.
* In manual, this reliably causes segfaults if the test is linked against
* a non-thread-safe version of Catch2.
*
* The CTest test definition should also verify that the final assertion
* count is correct.
*/
#include <catch2/catch_test_macros.hpp>
#include <atomic>
#include <thread>
#include <vector>
TEST_CASE( "Failed REQUIRE in the main thread is fine" ) {
std::vector<std::thread> threads;
for ( size_t t = 0; t < 4; ++t) {
threads.emplace_back( [t]() {
CAPTURE(t);
for (size_t i = 0; i < 100; ++i) {
CAPTURE(i);
CHECK( false );
CHECK( true );
}
} );
}
for (auto& t : threads) {
t.join();
}
REQUIRE( false );
}