You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

104 lines
3.8 KiB

/* Формат канального события: live/history сохраняются при передаче в GUI, битые события отбрасываются. */
#include "../transport/gui_bridge.h"
#include "../../../lib/debug_config.h"
#include "../../../src/chat/chat_event.h"
#include <QtTest>
#include <cstring>
#include <thread>
struct ReceivedMessage {
QString channel;
quint64 author;
bool initialSync;
bool guiThread;
};
static QList<ReceivedMessage> received;
static QList<int> cpuLoads;
static bool cpuOnGuiThread = true;
static void cpu_received(int percent) {
cpuLoads.append(percent);
cpuOnGuiThread &= QThread::currentThread() == qApp->thread();
}
static void message_received(const char* channel, int length, uint64_t author, int initial_sync) {
received.append({QString::fromUtf8(channel, length), author, initial_sync != 0, QThread::currentThread() == qApp->thread()});
}
static QByteArray message_event(quint64 author, bool initialSync) {
const QByteArray channel("12345");
QByteArray event(1 + channel.size() + 9, '\0');
event[0] = char(channel.size());
memcpy(event.data() + 1, channel.constData(), channel.size());
memcpy(event.data() + 1 + channel.size(), &author, 8);
event[event.size() - 1] = initialSync;
return event;
}
static void post_message(const QByteArray& event) {
gui_bridge_post(GUI_EVT_MSG_RECEIVED, reinterpret_cast<const uint8_t*>(event.constData()), event.size());
}
class MessageEventTest : public QObject {
Q_OBJECT
private slots:
void initTestCase() {
debug_config_init();
debug_set_level(DEBUG_LEVEL_DEBUG);
gui_bridge_init();
gui_bridge_set_msg_received_cb(message_received);
}
void cleanupTestCase() { gui_bridge_set_msg_received_cb(nullptr); gui_bridge_set_cpu_load_cb(nullptr); }
void init() { received.clear(); }
void liveAndHistory() {
post_message(message_event(42, false));
post_message(message_event(43, true));
QTRY_COMPARE(received.size(), 2);
QCOMPARE(received[0].channel, QString("12345"));
QCOMPARE(received[0].author, quint64(42));
QVERIFY(!received[0].initialSync);
QVERIFY(received[0].guiThread);
QCOMPARE(received[1].author, quint64(43));
QVERIFY(received[1].initialSync);
QVERIFY(received[1].guiThread);
}
void rejectsMalformedEvents() {
QByteArray event = message_event(42, false);
event.chop(1);
post_message(event);
event = message_event(42, false);
event[event.size() - 1] = 2;
post_message(event);
event = message_event(42, false);
event[0] = char(255);
post_message(event);
post_message({});
QTest::qWait(100);
QVERIFY(received.isEmpty());
}
void cpuLoadDeliveredToGuiThread() {
cpuLoads.clear(); cpuOnGuiThread = true;
gui_bridge_set_cpu_load_cb(cpu_received);
std::thread worker([] {
const uint8_t samples[][2] = {{1, 0}, {1, 50}, {1, 100}, {0, 90}, {1, 101}};
for (const auto& sample : samples) gui_bridge_post(CHAT_EVT_CPU_LOAD, sample, sizeof(sample));
gui_bridge_post(CHAT_EVT_CPU_LOAD, nullptr, 0);
});
worker.join();
QVERIFY(cpuLoads.isEmpty()); // Worker не вызывает UI напрямую.
QTRY_COMPARE(cpuLoads.size(), 6);
QCOMPARE(cpuLoads, QList<int>({0, 50, 100, 0, 0, 0}));
QVERIFY(cpuOnGuiThread);
gui_bridge_set_cpu_load_cb(nullptr);
const uint8_t sample[] = {1, 75};
gui_bridge_post(CHAT_EVT_CPU_LOAD, sample, sizeof(sample));
QCoreApplication::processEvents();
QCOMPARE(cpuLoads.size(), 6);
}
};
QTEST_MAIN(MessageEventTest)
#include "test_message_events.moc"