feat: implemented consumer thread, all tests pass
This commit is contained in:
120
tests/test_consumer.cxx
Normal file
120
tests/test_consumer.cxx
Normal file
@@ -0,0 +1,120 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QSignalSpy>
|
||||
|
||||
#include "Consumer.hpp"
|
||||
#include "UnixIpcBridge.hpp"
|
||||
|
||||
// QSignalSpy needs a QCoreApplication to dispatch queued signals
|
||||
static int argc_ = 0;
|
||||
static QCoreApplication app_(argc_, nullptr);
|
||||
|
||||
TEST(ConsumerThreadTest, ReceivesSingleValue)
|
||||
{
|
||||
const std::string sock = "/tmp/test_ct_single.sock";
|
||||
|
||||
ConsumerThread consumer(sock);
|
||||
|
||||
// QSignalSpy records every emission of the given signal
|
||||
QSignalSpy spy(&consumer, &ConsumerThread::valueReceived);
|
||||
consumer.start();
|
||||
|
||||
UnixIpcBridge bridge(sock);
|
||||
bridge.send(42);
|
||||
|
||||
// spy.wait() pumps the event loop for up to 1s until a signal arrives
|
||||
spy.wait(1000);
|
||||
consumer.stop();
|
||||
|
||||
ASSERT_EQ(spy.count(), 1);
|
||||
EXPECT_EQ(spy.at(0).at(0).toInt(), 42);
|
||||
}
|
||||
|
||||
TEST(ConsumerThreadTest, ReceivesMultipleValues)
|
||||
{
|
||||
const std::string sock = "/tmp/test_ct_multi.sock";
|
||||
|
||||
ConsumerThread consumer(sock);
|
||||
QSignalSpy spy(&consumer, &ConsumerThread::valueReceived);
|
||||
consumer.start();
|
||||
|
||||
constexpr int kMessages = 5;
|
||||
for (int i = 0; i < kMessages; ++i)
|
||||
{
|
||||
UnixIpcBridge bridge(sock);
|
||||
bridge.send(i * 10);
|
||||
// Small delay so the consumer can re-enter accept() between sends
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
}
|
||||
|
||||
// Wait until all signals arrive (or timeout after 5s)
|
||||
for (int attempt = 0; spy.count() < kMessages && attempt < 50; ++attempt)
|
||||
{
|
||||
spy.wait(100);
|
||||
}
|
||||
|
||||
consumer.stop();
|
||||
|
||||
ASSERT_EQ(spy.count(), kMessages);
|
||||
for (int i = 0; i < kMessages; ++i)
|
||||
{
|
||||
EXPECT_EQ(spy.at(i).at(0).toInt(), i * 10);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(ConsumerThreadTest, ReceivesNegativeAndZero)
|
||||
{
|
||||
// Zero
|
||||
{
|
||||
const std::string sock = "/tmp/test_ct_zero.sock";
|
||||
ConsumerThread consumer(sock);
|
||||
QSignalSpy spy(&consumer, &ConsumerThread::valueReceived);
|
||||
consumer.start();
|
||||
|
||||
UnixIpcBridge bridge(sock);
|
||||
bridge.send(0);
|
||||
|
||||
spy.wait(1000);
|
||||
consumer.stop();
|
||||
|
||||
ASSERT_EQ(spy.count(), 1);
|
||||
EXPECT_EQ(spy.at(0).at(0).toInt(), 0);
|
||||
}
|
||||
|
||||
// Negative
|
||||
{
|
||||
const std::string sock = "/tmp/test_ct_neg.sock";
|
||||
ConsumerThread consumer(sock);
|
||||
QSignalSpy spy(&consumer, &ConsumerThread::valueReceived);
|
||||
consumer.start();
|
||||
|
||||
UnixIpcBridge bridge(sock);
|
||||
bridge.send(-999);
|
||||
|
||||
spy.wait(1000);
|
||||
consumer.stop();
|
||||
|
||||
ASSERT_EQ(spy.count(), 1);
|
||||
EXPECT_EQ(spy.at(0).at(0).toInt(), -999);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(ConsumerThreadTest, StopsCleanlyWithoutDeadlock)
|
||||
{
|
||||
const std::string sock = "/tmp/test_ct_stop.sock";
|
||||
|
||||
ConsumerThread consumer(sock);
|
||||
consumer.start();
|
||||
// stop() must return without hanging, even with no connections
|
||||
consumer.stop();
|
||||
}
|
||||
|
||||
TEST(ConsumerThreadTest, StopsCleanlyWhenNeverStarted)
|
||||
{
|
||||
const std::string sock = "/tmp/test_ct_nostart.sock";
|
||||
|
||||
ConsumerThread consumer(sock);
|
||||
// stop() on a consumer that was never started must not crash
|
||||
consumer.stop();
|
||||
}
|
||||
Reference in New Issue
Block a user