1
0
mirror of https://github.com/chylex/Nextcloud-Desktop.git synced 2024-10-24 00:42:48 +02:00
Nextcloud-Desktop/test/testuploadreset.cpp
Olivier Goffart 64014dd374 Upload: Store the size in the UploadInfo, and compare it when resolving potential conflict
This is about the conflicts that happens when the file has been uploaded
correctly to the server, but the etag was not recieved because the connection
was closed before we got the reply.

We used to compare only the mtime when comparing the uploaded file and the
existing file.  However, to be perfectly correct, we also should check the
size.

This was found because TestChunkingNG::connectionDroppedBeforeEtagRecieved is
flaky. Example of faillure found in https://drone.owncloud.com/owncloud/client/481/5
while testing PR #6626

(very trimmed log:)

06-29 07:58:02:015 [ info sync.csync.csync ]:	## Starting local discovery ##
06-29 07:58:02:016 [ info sync.csync.updater ]:	Database entry found, compare: 1530259082 <-> 1530259051, etag:  <-> 1644a8c8750, inode: 1935629 <-> 1935629, size: 301 <-> 300, perms: 0 <-> ff, type: 0 <-> 0, checksum:  <-> SHA1:cc9adedebe27a6259efb8d6ed09f4f2eff559ad1, ignore: 0
06-29 07:58:02:016 [ info sync.csync.updater ]:	file: A/a0, instruction: INSTRUCTION_EVAL <<=
06-29 07:58:02:972 [ warning sync.networkjob ]:	QNetworkReply::NetworkError(OperationCanceledError) "Connection timed out" QVariant(Invalid)
.. next sync...
06-29 07:58:02:980 [ info sync.engine ]:	#### Discovery start ####################################################
06-29 07:58:02:981 [ info sync.csync.csync ]:	## Starting local discovery ##
06-29 07:58:02:983 [ info sync.csync.updater ]:	Database entry found, compare: 1530259082 <-> 1530259051, etag:  <-> 1644a8c8750, inode: 1935629 <-> 1935629, size: 302 <-> 300, perms: 0 <-> ff, type: 0 <-> 0, checksum:  <-> SHA1:cc9adedebe27a6259efb8d6ed09f4f2eff559ad1, ignore: 0
06-29 07:58:02:983 [ info sync.csync.updater ]:	file: A/a0, instruction: INSTRUCTION_EVAL <<=
06-29 07:58:02:985 [ info sync.csync.csync ]:	## Starting remote discovery ##
06-29 07:58:02:985 [ info sync.networkjob ]:	OCC::LsColJob created for "http://localhost/owncloud" + "" "OCC::DiscoverySingleDirectoryJob"
06-29 07:58:02:987 [ info sync.csync.updater ]:	Database entry found, compare: 1530259082 <-> 1530259051, etag: 1644a8c8b26 <-> 1644a8c8750, inode: 0 <-> 1935629, size: 301 <-> 300, perms: ff <-> ff, type: 0 <-> 0, checksum: SHA1:5adcdac9608ae0811247f07f4cf1ab0a2ef99154 <-> SHA1:cc9adedebe27a6259efb8d6ed09f4f2eff559ad1, ignore: 0
06-29 07:58:02:987 [ info sync.csync.updater ]:	file: A/a0, instruction: INSTRUCTION_EVAL <<=
06-29 07:58:02:989 [ info sync.csync.csync ]:	Update detection for remote replica took 0.004 seconds walking 13 files
06-29 07:58:02:990 [ info sync.engine ]:	#### Discovery end ####################################################  9 ms
06-29 07:58:02:990 [ info sync.database ]:	Updating file record for path: "A/a0" inode: 1935629 modtime: 1530259082 type: 0 etag: "1644a8c8b26" fileId: "16383ea4" remotePerm: "WDNVCKR" fileSize: 301 checksum: "SHA1:cc9adedebe27a6259efb8d6ed09f4f2eff559ad1"
06-29 07:58:02:990 [ info sync.csync.reconciler ]:	INSTRUCTION_UPDATE_METADATA    client file: A/a0
06-29 07:58:02:990 [ info sync.csync.csync ]:	Reconciliation for local replica took  0 seconds visiting  13  files.
06-29 07:58:02:990 [ info sync.csync.reconciler ]:	INSTRUCTION_UPDATE_METADATA    server dir:  A
06-29 07:58:02:990 [ info sync.csync.csync ]:	Reconciliation for remote replica took  0 seconds visiting  13  files.
06-29 07:58:02:990 [ info sync.engine ]:	#### Reconcile end ####################################################  9 ms
06-29 07:58:02:990 [ info sync.database ]:	Updating local metadata for: "A/a0" 1530259082 302 1935629
FAIL!  : TestChunkingNG::connectionDroppedBeforeEtagRecieved(small file) '!fakeFolder.syncOnce()' returned FALSE. ()
2018-07-04 17:26:56 +02:00

77 lines
2.6 KiB
C++

/*
* This software is in the public domain, furnished "as is", without technical
* support, and with no warranty, express or implied, as to its usefulness for
* any purpose.
*
*/
#include <QtTest>
#include "syncenginetestutils.h"
#include <syncengine.h>
#include <common/syncjournaldb.h>
using namespace OCC;
class TestUploadReset : public QObject
{
Q_OBJECT
private slots:
// Verify that the chunked transfer eventually gets reset with the new chunking
void testFileUploadNg() {
FakeFolder fakeFolder{FileInfo::A12_B12_C12_S12()};
fakeFolder.syncEngine().account()->setCapabilities({ { "dav", QVariantMap{
{"chunking", "1.0"},
{"httpErrorCodesThatResetFailingChunkedUploads", QVariantList{500} } } } });
const int size = 100 * 1000 * 1000; // 100 MB
fakeFolder.localModifier().insert("A/a0", size);
QDateTime modTime = QDateTime::currentDateTime();
fakeFolder.localModifier().setModTime("A/a0", modTime);
// Create a transfer id, so we can make the final MOVE fail
SyncJournalDb::UploadInfo uploadInfo;
uploadInfo._transferid = 1;
uploadInfo._valid = true;
uploadInfo._modtime = Utility::qDateTimeToTime_t(modTime);
uploadInfo._size = size;
fakeFolder.syncEngine().journal()->setUploadInfo("A/a0", uploadInfo);
fakeFolder.uploadState().mkdir("1");
fakeFolder.serverErrorPaths().append("1/.file");
QVERIFY(!fakeFolder.syncOnce());
uploadInfo = fakeFolder.syncEngine().journal()->getUploadInfo("A/a0");
QCOMPARE(uploadInfo._errorCount, 1);
QCOMPARE(uploadInfo._transferid, 1);
fakeFolder.syncEngine().journal()->wipeErrorBlacklist();
QVERIFY(!fakeFolder.syncOnce());
uploadInfo = fakeFolder.syncEngine().journal()->getUploadInfo("A/a0");
QCOMPARE(uploadInfo._errorCount, 2);
QCOMPARE(uploadInfo._transferid, 1);
fakeFolder.syncEngine().journal()->wipeErrorBlacklist();
QVERIFY(!fakeFolder.syncOnce());
uploadInfo = fakeFolder.syncEngine().journal()->getUploadInfo("A/a0");
QCOMPARE(uploadInfo._errorCount, 3);
QCOMPARE(uploadInfo._transferid, 1);
fakeFolder.syncEngine().journal()->wipeErrorBlacklist();
QVERIFY(!fakeFolder.syncOnce());
uploadInfo = fakeFolder.syncEngine().journal()->getUploadInfo("A/a0");
QCOMPARE(uploadInfo._errorCount, 0);
QCOMPARE(uploadInfo._transferid, 0);
QVERIFY(!uploadInfo._valid);
}
};
QTEST_GUILESS_MAIN(TestUploadReset)
#include "testuploadreset.moc"