Verify file command success against the real storage service
This commit is contained in:
1 parent
83f8b0cbe2
commit
ba44e243a9
1 file changed
+81
-2
@@ -13,6 +13,7 @@
|
||||
#include <QScopeGuard>
|
||||
extern "C" {
|
||||
#include "utun_instance.h"
|
||||
#include "chat/chat_core.h"
|
||||
#include "member_files/member_files.h"
|
||||
#include "debug_config.h"
|
||||
#include "mem.h"
|
||||
@@ -80,7 +81,8 @@ private slots:
|
||||
gui_bridge_set_member_files_response_cb(nullptr); gui_bridge_set_member_files_transfer_cb(nullptr);
|
||||
}
|
||||
void cleanup() {
|
||||
activeBatch = nullptr; activeBrowser = nullptr; responses.clear(); transfers.clear();
|
||||
activeBatch = nullptr; activeBrowser = nullptr;
|
||||
QCoreApplication::processEvents(); responses.clear(); transfers.clear();
|
||||
#ifdef UTUN_TEST_FILE_ALLOC_FAILURES
|
||||
failAllocation = 0;
|
||||
#endif
|
||||
@@ -320,7 +322,7 @@ private slots:
|
||||
#ifdef UTUN_TEST_FILE_ALLOC_FAILURES
|
||||
QCOMPARE(failAllocation, 0);
|
||||
#endif
|
||||
core.attach(); QVERIFY(download->isEnabled());
|
||||
core.attach(); item->setSelected(false); item->setSelected(true); QVERIFY(download->isEnabled());
|
||||
QTimer::singleShot(0, [&] {
|
||||
auto* dialog = qobject_cast<QFileDialog*>(QApplication::activeModalWidget());
|
||||
if (dialog) { dialog->selectFile(destination); QMetaObject::invokeMethod(dialog, "accept"); }
|
||||
@@ -331,6 +333,83 @@ private slots:
|
||||
}
|
||||
QCOMPARE(u_get_allocated_count(), before);
|
||||
}
|
||||
|
||||
void realStorageRoundTrip() {
|
||||
const size_t before = u_get_allocated_count();
|
||||
{
|
||||
QTemporaryDir root; QVERIFY(root.isValid());
|
||||
UASYNC* ua = uasync_create(); QVERIFY(ua); UTUN_INSTANCE* instance = nullptr; QTimer poll;
|
||||
const auto cleanup = qScopeGuard([&] {
|
||||
activeBatch = nullptr; poll.stop(); gui_bridge_set_inst(nullptr); gui_bridge_set_uasync(nullptr);
|
||||
uasync_mark_stopped(ua);
|
||||
if (instance) utun_instance_destroy(instance);
|
||||
uasync_destroy(ua, 0); QCoreApplication::processEvents();
|
||||
});
|
||||
const QByteArray config = "[global]\nauto_sockets=no\ntun_enabled=no\n"
|
||||
"my_private_key=704f2e012c8fa8768130cb0f988a997dccb628372bc5ceccacc78dcbfec5916f\n"
|
||||
"my_public_key=b3193173def895bd0fcea6f86af077c7d77216f10395275f627ac18242ec0f01\n"
|
||||
"[chatserver]\ngroup_autoconnect=0\nstorage_autoload=0\nmember_files_enabled=1\n"
|
||||
"local_invites_enabled=0\nlocal_broadcasts_enabled=0\nmember_files_path=" + root.path().toUtf8() +
|
||||
"/storage\n[ntp]\nenabled=no\n";
|
||||
instance = utun_instance_create_from_str(ua, config.constData()); QVERIFY(instance);
|
||||
QCOMPARE(utun_core_start(instance), 0); QCOMPARE(chat_service_start(instance), 0);
|
||||
const uint64_t group = chat_core_create_channel_auto(instance, "Files"); QVERIFY(group);
|
||||
const QByteArray channel = QByteArray::number(group); const uint64_t node = instance->node_id;
|
||||
auto* tags = chat_member_tags_load(instance, channel.constData(), node); QVERIFY(tags);
|
||||
const int set = chat_member_tags_set(tags, "storage", "yes");
|
||||
const int commit = set ? set : chat_member_tags_commit(instance, tags); chat_member_tags_free(tags); QCOMPARE(commit, 0);
|
||||
chat_event_set_handler(instance, [](UTUN_INSTANCE*, int event, const uint8_t* data, int size) {
|
||||
gui_bridge_post(event, data, size);
|
||||
});
|
||||
uasync_mark_running(ua); gui_bridge_set_uasync(ua); gui_bridge_set_inst(instance);
|
||||
connect(&poll, &QTimer::timeout, this, [ua] { uasync_poll(ua, 0); }); poll.start(1);
|
||||
// Дождаться ответа готового storage, не подменяя асинхронный старт его worker.
|
||||
bool ready = false;
|
||||
for (int attempt = 0; attempt < 20 && !ready; attempt++) {
|
||||
mf_message q{}; q.kind = MF_REQUEST; q.command = MF_QUOTA; q.request_id = 100 + attempt; q.owner = node;
|
||||
const auto count = responses.size(); QCOMPARE(gui_bridge_member_files_request(group, node, &q), 0);
|
||||
QTRY_COMPARE_WITH_TIMEOUT(responses.size(), count + 1, 3000); mf_message r{};
|
||||
const auto& bytes = responses.last();
|
||||
QCOMPARE(mf_decode((const uint8_t*)bytes.constData() + 16, bytes.size() - 16, &r), 0);
|
||||
QVERIFY(r.status == MF_OK || r.status == MF_BUSY); ready = r.status == MF_OK;
|
||||
}
|
||||
QVERIFY(ready);
|
||||
const QByteArray payload(20000, 'f'); const QString source = root.filePath("source.txt");
|
||||
{ QFile file(source); QVERIFY(file.open(QIODevice::WriteOnly)); QCOMPARE(file.write(payload), qint64(payload.size())); }
|
||||
int completed = 0; bool success = false; QString summary;
|
||||
auto finished = [&](bool ok, const QString& text, const QStringList&) { completed++; success = ok; summary = text; };
|
||||
const QString stored = root.filePath("storage/" + QString::number(group) + '/' + QString::number(node) + "/source.txt");
|
||||
{
|
||||
MemberFileBatch batch(group, node, node, MemberFileBatch::Upload, nullptr); activeBatch = &batch;
|
||||
batch.progress = [](const QString&, int) {}; batch.finished = finished;
|
||||
batch.upload({source}, {}); QTRY_COMPARE_WITH_TIMEOUT(completed, 1, 5000); QVERIFY2(success, qPrintable(summary));
|
||||
}
|
||||
{ QFile file(stored); QVERIFY(file.open(QIODevice::ReadOnly)); QCOMPARE(file.readAll(), payload); }
|
||||
mf_message q{}; q.kind = MF_REQUEST; q.command = MF_STAT; q.request_id = 1000; q.owner = node; strcpy(q.path, "source.txt");
|
||||
const auto count = responses.size(); QCOMPARE(gui_bridge_member_files_request(group, node, &q), 0);
|
||||
QTRY_COMPARE_WITH_TIMEOUT(responses.size(), count + 1, 3000); mf_message info{};
|
||||
const auto bytes = responses.last();
|
||||
QCOMPARE(mf_decode((const uint8_t*)bytes.constData() + 16, bytes.size() - 16, &info), 0); QCOMPARE(info.status, uint16_t(MF_OK));
|
||||
const QString destination = root.filePath("download.txt");
|
||||
const QByteArray version((const char*)info.version, 16); completed = 0; success = false;
|
||||
{
|
||||
MemberFileBatch batch(group, node, node, MemberFileBatch::Download, nullptr); activeBatch = &batch;
|
||||
batch.progress = [](const QString&, int) {}; batch.finished = finished;
|
||||
batch.start({{"source.txt", destination, version, false}});
|
||||
QTRY_COMPARE_WITH_TIMEOUT(completed, 1, 5000); QVERIFY2(success, qPrintable(summary));
|
||||
}
|
||||
{ QFile file(destination); QVERIFY(file.open(QIODevice::ReadOnly)); QCOMPARE(file.readAll(), payload); }
|
||||
completed = 0; success = false;
|
||||
{
|
||||
MemberFileBatch batch(group, node, node, MemberFileBatch::Remove, nullptr); activeBatch = &batch;
|
||||
batch.progress = [](const QString&, int) {}; batch.finished = finished;
|
||||
batch.start({{"source.txt", {}, version, false}});
|
||||
QTRY_COMPARE_WITH_TIMEOUT(completed, 1, 5000); QVERIFY2(success, qPrintable(summary));
|
||||
}
|
||||
QVERIFY(!QFile::exists(stored)); QVERIFY(QFile::exists(source)); QVERIFY(QFile::exists(destination));
|
||||
}
|
||||
QCOMPARE(u_get_allocated_count(), before);
|
||||
}
|
||||
};
|
||||
|
||||
QTEST_MAIN(FileLifecycleTest)
|
||||
|
||||
Reference in new issue
Block a user