Browse Source

Test bounded downloads and late completion after avatar replacement

master
evgeny 6 days ago
parent
commit
dc156c7f2b
  1. 39
      tools/chatgui/tests/test_avatars.cpp

39
tools/chatgui/tests/test_avatars.cpp

@ -21,17 +21,31 @@ extern "C" {
} }
static UTUN_INSTANCE* testInstance; static UTUN_INSTANCE* testInstance;
static unsigned downloads; static unsigned downloads;
static QSet<quint64> downloadIds;
static QHash<quint64, int> finished;
static bool deferDownload;
static QByteArray delayedDownload;
extern "C" int gui_bridge_is_uasync_ready(void) { return testInstance != nullptr; } extern "C" int gui_bridge_is_uasync_ready(void) { return testInstance != nullptr; }
extern "C" UTUN_INSTANCE* gui_bridge_get_inst(void) { return testInstance; } extern "C" UTUN_INSTANCE* gui_bridge_get_inst(void) { return testInstance; }
extern "C" void gui_bridge_post_uasync_fn(void (*fn)(void*), void* arg) { extern "C" void gui_bridge_post_uasync_fn(void (*fn)(void*), void* arg) {
if (fn == member_files_gui_transfer && !((mf_transfer_request*)arg)->upload) downloads++; if (fn == member_files_gui_transfer && !((mf_transfer_request*)arg)->upload) {
downloads++; downloadIds.insert(((mf_transfer_request*)arg)->id);
}
uasync_call_soon(testInstance->ua, arg, fn); uasync_call_soon(testInstance->ua, arg, fn);
} }
static void avatarEvent(UTUN_INSTANCE*, int type, const uint8_t* data, int length) { static void avatarEvent(UTUN_INSTANCE*, int type, const uint8_t* data, int length) {
DEBUG_DEBUG(DEBUG_CATEGORY_MEDIA, "avatar test: event type=%d bytes=%d", type, length); DEBUG_DEBUG(DEBUG_CATEGORY_MEDIA, "avatar test: event type=%d bytes=%d", type, length);
auto* manager = AvatarManager::instance(); if (!manager) return; auto* manager = AvatarManager::instance(); if (!manager) return;
if (type == CHAT_EVT_MEMBER_FILES_RESPONSE) manager->onResponse(data, length); if (type == CHAT_EVT_MEMBER_FILES_RESPONSE) manager->onResponse(data, length);
if (type == CHAT_EVT_MEMBER_FILES_TRANSFER) manager->onTransfer(data, length); if (type == CHAT_EVT_MEMBER_FILES_TRANSFER) {
if (length == 51 && data[50] == 2) {
finished[mf_get64(data)] = data[48] | (int(data[49]) << 8);
if (deferDownload && downloadIds.contains(mf_get64(data)) && !finished[mf_get64(data)]) {
delayedDownload = QByteArray((const char*)data, length); return;
}
}
manager->onTransfer(data, length);
}
if (type == CHAT_EVT_AVATAR_RESULT) manager->onPublished(data, length); if (type == CHAT_EVT_AVATAR_RESULT) manager->onPublished(data, length);
if (type == CHAT_EVT_MEMBER_UPDATED && length >= 2 + data[0] + CHAT_MEMBER_DISPLAY_SIZE) if (type == CHAT_EVT_MEMBER_UPDATED && length >= 2 + data[0] + CHAT_MEMBER_DISPLAY_SIZE)
manager->onMembers(QString::fromLatin1((const char*)data + 1, data[0]), 1, data + 2 + data[0], CHAT_MEMBER_DISPLAY_SIZE, false); manager->onMembers(QString::fromLatin1((const char*)data + 1, data[0]), 1, data + 2 + data[0], CHAT_MEMBER_DISPLAY_SIZE, false);
@ -108,6 +122,15 @@ private slots:
QVERIFY(!manager.image("pm:test", testInstance->node_id).isNull()); QVERIFY(!manager.image("pm:test", testInstance->node_id).isNull());
cached = directory.path() + "/avatar_cache/" + QString::number(testInstance->node_id, 16) + '/' + member.avatar_file; cached = directory.path() + "/avatar_cache/" + QString::number(testInstance->node_id, 16) + '/' + member.avatar_file;
} }
auto* limited = (mf_transfer_request*)u_calloc(1, sizeof(mf_transfer_request)); QVERIFY(limited);
limited->inst = testInstance; limited->id = 41; limited->group = channels[0].channelId.toULongLong();
limited->server = limited->owner = testInstance->node_id; limited->max_bytes = 1;
const QByteArray remote = "avatars/" + QFileInfo(cached).fileName().toLatin1();
const QString rejected = directory.path() + "/rejected.png";
const QByteArray local = rejected.toUtf8(); memcpy(limited->remote, remote.constData(), remote.size());
memcpy(limited->local, local.constData(), local.size()); gui_bridge_post_uasync_fn(member_files_gui_transfer, limited);
QTRY_VERIFY_WITH_TIMEOUT(finished.contains(41), 5000); QCOMPARE(finished.take(41), int(MF_INVALID_RANGE));
QVERIFY(!QFile::exists(rejected));
chat_core_update_my_name(testInstance, "quote\"\\name"); chat_core_sync_my_addresses(testInstance); chat_core_update_my_name(testInstance, "quote\"\\name"); chat_core_sync_my_addresses(testInstance);
for (const auto& channel : channels) { for (const auto& channel : channels) {
char profile[MS_USERINFO_MAX + 1], name[128]; uint8_t signature[64]; uint64_t timestamp; char profile[MS_USERINFO_MAX + 1], name[128]; uint8_t signature[64]; uint64_t timestamp;
@ -132,8 +155,16 @@ private slots:
QVERIFY(QFile::remove(cached)); downloads = 0; QVERIFY(QFile::remove(cached)); downloads = 0;
{ {
AvatarManager manager(&db); manager.initialize(); AvatarManager manager(&db); manager.initialize();
QTRY_VERIFY_WITH_TIMEOUT(!manager.image(channels[0].channelId, testInstance->node_id).isNull(), 10000); deferDownload = true; delayedDownload.clear();
QVERIFY(downloads == 1); QVERIFY(QFile::exists(cached)); QTRY_VERIFY_WITH_TIMEOUT((manager.image(channels[0].channelId, testInstance->node_id), !delayedDownload.isEmpty()), 10000);
QCOMPARE(downloads, 1u);
const QString replacement = directory.path() + "/replacement.png"; image.fill(Qt::red); QVERIFY(image.save(replacement));
manager.uploadDefault(replacement, testInstance->node_id);
for (const auto& channel : channels)
QTRY_VERIFY_WITH_TIMEOUT(manager.image(channel.channelId, testInstance->node_id).pixelColor(128, 128) == QColor(Qt::red), 10000);
deferDownload = false; manager.onTransfer((const uint8_t*)delayedDownload.constData(), delayedDownload.size());
QTRY_VERIFY_WITH_TIMEOUT(QFile::exists(cached), 5000);
for (const auto& channel : channels) QCOMPARE(manager.image(channel.channelId, testInstance->node_id).pixelColor(128, 128), QColor(Qt::red));
manager.clearDefault(); manager.clearDefault();
for (const auto& channel : channels) { for (const auto& channel : channels) {
uint8_t wire[CHAT_MEMBER_DISPLAY_SIZE]; uint8_t wire[CHAT_MEMBER_DISPLAY_SIZE];

Loading…
Cancel
Save