Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 0 additions & 46 deletions .github/scripts/execute-tests-under-sanitizer.sh

This file was deleted.

43 changes: 1 addition & 42 deletions .github/workflows/reusable-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,6 @@ jobs:

if: ${{ inputs.run_unit_tests }}

env:
# TODO: remove completely when we have fixed all currently existing issues with sanitizers
SANITIZER_IGNORE_ERRORS: ${{ endsWith(inputs.conan_profile, '.tsan') }}

steps:
- name: Cleanup workspace
if: ${{ runner.os == 'macOS' }}
Expand All @@ -65,46 +61,9 @@ jobs:
- name: Make clio_tests executable
run: chmod +x ./clio_tests

- name: Run clio_tests (regular)
if: ${{ env.SANITIZER_IGNORE_ERRORS == 'false' }}
- name: Run clio_tests
run: ./clio_tests

- name: Run clio_tests (sanitizer errors ignored)
if: ${{ env.SANITIZER_IGNORE_ERRORS == 'true' }}
run: ./.github/scripts/execute-tests-under-sanitizer.sh ./clio_tests

- name: Check for sanitizer report
if: ${{ env.SANITIZER_IGNORE_ERRORS == 'true' }}
id: check_report
run: |
if ls .sanitizer-report/* 1> /dev/null 2>&1; then
echo "found_report=true" >> $GITHUB_OUTPUT
else
echo "found_report=false" >> $GITHUB_OUTPUT
fi

- name: Upload sanitizer report
if: ${{ env.SANITIZER_IGNORE_ERRORS == 'true' && steps.check_report.outputs.found_report == 'true' }}
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: sanitizer_report_${{ runner.os }}_${{ inputs.build_type }}_${{ inputs.conan_profile }}
path: .sanitizer-report/*
include-hidden-files: true

- name: Create an issue
if: ${{ false && env.SANITIZER_IGNORE_ERRORS == 'true' && steps.check_report.outputs.found_report == 'true' }}
uses: ./.github/actions/create-issue
env:
GH_TOKEN: ${{ github.token }}
with:
labels: "bug"
title: "[${{ inputs.conan_profile }}] reported issues"
body: >
Clio tests failed one or more sanitizer checks when built with ${{ inputs.conan_profile }}`.

Workflow: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}/
Reports are available as artifacts.

integration_tests:
name: Integration testing
runs-on: ${{ inputs.runs_on }}
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/sanitizers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ on:
- ".github/actions/**"
- "!.github/actions/build-docker-image/**"
- "!.github/actions/create-issue/**"
- .github/scripts/execute-tests-under-sanitizer.sh

- CMakeLists.txt
- conanfile.py
Expand Down
8 changes: 6 additions & 2 deletions src/cluster/impl/RepeatedTask.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
#include <boost/asio/spawn.hpp>
#include <boost/asio/steady_timer.hpp>
#include <boost/asio/strand.hpp>
#include <boost/asio/use_future.hpp>

#include <atomic>
#include <chrono>
Expand Down Expand Up @@ -96,7 +95,12 @@ class RepeatedTask {
if (auto expected = State::Running; not state_.compare_exchange_strong(expected, State::Stopped))
return; // Already stopped or not started

boost::asio::spawn(strand_, [this](auto&&) { timer_.cancel(); }, boost::asio::use_future).wait();
std::binary_semaphore cancelSemaphore{0};
boost::asio::post(strand_, [this, &cancelSemaphore]() {
timer_.cancel();
cancelSemaphore.release();
});
cancelSemaphore.acquire();
semaphore_.acquire();
}
};
Expand Down
2 changes: 1 addition & 1 deletion src/feed/impl/SingleFeedBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ SingleFeedBase::unsub(SubscriberSharedPtr const& subscriber)
void
SingleFeedBase::pub(std::string msg)
{
[[maybe_unused]] auto task = strand_.execute([this, msg = std::move(msg)]() {
strand_.submit([this, msg = std::move(msg)] {
auto const msgPtr = std::make_shared<std::string>(msg);
signal_.emit(msgPtr);
});
Expand Down
11 changes: 8 additions & 3 deletions src/feed/impl/TrackableSignal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,15 @@ class TrackableSignal {

// This class can't hold the trackable's shared_ptr, because disconnect should be able to be called in the
// the trackable's destructor. However, the trackable can not be destroyed when the slot is being called
// either. track_foreign will hold a weak_ptr to the connection, which makes sure the connection is valid when
// the slot is called.
// either. `track_foreign` is racey because the control block can be released from some thread without a mutex
// protecting it while another one is invoking the slot. Therefore we are storing a weak_ptr of the trackable
// and explicitly checking it in the slot invocation instead. The invocation is guaranteed to happen under an
// internal mutex so it's safe.
connections->emplace(
trackable.get(), signal_.connect(typename SignalType::slot_type(slot).track_foreign(trackable))
trackable.get(), signal_.connect([slot, weakTrackable = std::weak_ptr(trackable)](Args&&... args) {
if (not weakTrackable.expired())
std::invoke(slot, std::forward<Args...>(args)...);
})
);
return true;
}
Expand Down
4 changes: 2 additions & 2 deletions tests/unit/feed/SubscriptionManagerTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,11 @@ class SubscriptionManagerBaseTest : public util::prometheus::WithPrometheus, pub
}

StrictMockAmendmentCenterSharedPtr mockAmendmentCenterPtr_;
std::shared_ptr<SubscriptionManager> subscriptionManagerPtr_ =
std::make_shared<SubscriptionManager>(Execution(2), backend_, mockAmendmentCenterPtr_);
web::SubscriptionContextPtr session_ = std::make_shared<MockSession>();
MockSession* sessionPtr_ = dynamic_cast<MockSession*>(session_.get());
uint32_t const networkID_ = 123;
std::shared_ptr<SubscriptionManager> subscriptionManagerPtr_ =
std::make_shared<SubscriptionManager>(Execution(2), backend_, mockAmendmentCenterPtr_);
};

using SubscriptionManagerTest = SubscriptionManagerBaseTest<util::async::SyncExecutionContext>;
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/util/async/AsyncExecutionContextTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ TYPED_TEST(ExecutionContextTests, repeatingOperation)
{
auto const repeatDelay = std::chrono::milliseconds{1};
auto const timeout = std::chrono::milliseconds{15};
auto callCount = 0uz;
std::atomic_size_t callCount = 0uz;

auto res = this->ctx.executeRepeatedly(repeatDelay, [&] { ++callCount; });
auto timeSpent = util::timed([timeout] { std::this_thread::sleep_for(timeout); }); // calculate actual time spent
Expand Down
Loading