Files
sonus/tests/render_snapshot.cpp
T
khodowany 59b96ddf95
publish / publish (push) Successful in 14m33s
Formatting
2026-09-14 23:56:16 -05:00

93 lines
2.4 KiB
C++

#include <boost/test/unit_test.hpp>
#include <array>
#include <atomic>
#include <barrier>
#include <memory>
#include <thread>
#include "detail/render_snapshot.hpp"
namespace {
struct snapshot {
std::atomic<int> &live;
std::array<int, 64> samples{};
explicit snapshot(std::atomic<int> &count, int value = 0)
: live(count) {
++live;
samples.fill(value);
}
~snapshot() {
--live;
}
};
}
BOOST_AUTO_TEST_CASE(sonus_snapshots_are_reclaimed_without_rendering) {
auto live = std::atomic<int>{0};
auto state = sonus::detail::render_snapshot<snapshot>{};
for (auto index = 0; index < 1000; ++index) {
state.publish(std::make_unique<snapshot>(live, index));
BOOST_TEST(live.load() == 1);
}
state.publish(nullptr);
BOOST_TEST(live.load() == 0);
}
BOOST_AUTO_TEST_CASE(sonus_snapshots_outlive_readers_and_are_collected_on_control_thread) {
auto live = std::atomic<int>{0};
auto state = sonus::detail::render_snapshot<snapshot>{};
state.publish(std::make_unique<snapshot>(live, 42));
{
auto first = state.read();
state.publish(std::make_unique<snapshot>(live, 43));
{
auto second = state.read();
state.publish(std::make_unique<snapshot>(live, 44));
state.collect();
BOOST_TEST(live.load() == 3);
BOOST_TEST(second.get()->samples.front() == 43);
}
state.collect();
BOOST_TEST(live.load() == 3);
BOOST_TEST(first.get()->samples.back() == 42);
}
BOOST_TEST(live.load() == 3);
state.collect();
BOOST_TEST(live.load() == 1);
}
BOOST_AUTO_TEST_CASE(sonus_snapshot_publication_overlaps_readers) {
auto live = std::atomic<int>{0};
auto state = sonus::detail::render_snapshot<snapshot>{};
state.publish(std::make_unique<snapshot>(live));
auto start = std::barrier{3};
auto failed = std::atomic<bool>{false};
auto reader = [&] {
start.arrive_and_wait();
for (auto index = 0; index < 20000; ++index) {
auto guard = state.read();
auto const *value = guard.get();
for (auto sample : value->samples) {
if (sample != value->samples.front()) {
failed.store(true);
}
}
}
};
auto first = std::thread{reader};
auto second = std::thread{reader};
start.arrive_and_wait();
for (auto index = 0; index < 20000; ++index) {
state.publish(std::make_unique<snapshot>(live, index));
}
first.join();
second.join();
state.collect();
BOOST_TEST(!failed.load());
BOOST_TEST(live.load() == 1);
}