feat: simulate consumer crash in race condition tests to verify producer behavior

This commit is contained in:
unai_71 2026-03-10 20:19:09 +00:00
parent 3d2c193db9
commit 79f5ad10b6

View File

@ -3,6 +3,9 @@
// Author: Unai Blazquez <unaibg2000@gmail.com>
#include <gtest/gtest.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <QCoreApplication>
#include <QSignalSpy>
@ -137,8 +140,28 @@ TEST(RaceConditionTest, ProducerSurvivesConsumerCrash)
}
ASSERT_GE(spy.count(), 2) << "Phase 1: producer should have delivered values";
// "Crash" the consumer: stop + destroy.
consumer.stop();
// Simulate a hard crash: force-close the consumer's server fd from
// outside its thread, causing accept() to fail with EBADF. This is
// what happens when the kernel reclaims fds on SIGKILL / abort().
//
// We find the server fd by calling getsockname() on open fds and
// matching against our socket path.
for (int fd = 3; fd < 1024; ++fd)
{
struct sockaddr_un addr = {};
socklen_t len = sizeof(addr);
if (getsockname(fd, reinterpret_cast<sockaddr*>(&addr), &len) == 0 &&
addr.sun_family == AF_UNIX &&
std::string(addr.sun_path) == sock)
{
::close(fd); // Yank the fd — consumer thread crashes out of accept()
break;
}
}
// Destructor calls stop(), which joins the (now-exited) thread and
// cleans up. In a real crash no cleanup runs, but we can't leak
// threads in a test process.
}
// Phase 2: producer is still running with no consumer (sends will fail).