Skip to content

Commit

Permalink
fix regressions in automated tests for bulk upload
Browse files Browse the repository at this point in the history
Signed-off-by: Matthieu Gallien <[email protected]>
  • Loading branch information
mgallien committed Nov 28, 2024
1 parent d0b2cc5 commit 0709d00
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 11 deletions.
1 change: 1 addition & 0 deletions src/libsync/bulkpropagatorjob.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,7 @@ void BulkPropagatorJob::finalize(const QJsonObject &fullReply)
}
if (!singleFile._item->hasErrorStatus()) {
finalizeOneFile(singleFile);
singleFile._item->_status = OCC::SyncFileItem::Success;
}

done(singleFile._item, singleFile._item->_status, {}, ErrorCategory::GenericError);
Expand Down
5 changes: 4 additions & 1 deletion src/libsync/propagateupload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,10 @@ qint64 UploadDevice::readData(char *data, qint64 maxlen)
}

auto c = _file.read(data, maxlen);
if (c < 0) {
if (c == 0) {
setErrorString({});
return c;
} else if (c < 0) {
setErrorString(_file.errorString());
return -1;
}
Expand Down
57 changes: 50 additions & 7 deletions test/syncenginetestutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -552,12 +552,12 @@ QVector<FileInfo *> FakePutMultiFileReply::performMultiPart(FileInfo &remoteRoot
auto onePartBody = onePart.mid(headerEndPosition + 4, onePart.size() - headerEndPosition - 6);
auto onePartHeaders = onePartHeaderPart.split(QStringLiteral("\r\n"));
QMap<QString, QString> allHeaders;
for(auto oneHeader : onePartHeaders) {
for(const auto &oneHeader : onePartHeaders) {
auto headerParts = oneHeader.split(QStringLiteral(": "));
allHeaders[headerParts.at(0)] = headerParts.at(1);
allHeaders[headerParts.at(0).toLower()] = headerParts.at(1);
}
const auto fileName = allHeaders[QStringLiteral("X-File-Path")];
const auto modtime = allHeaders[QByteArrayLiteral("X-File-Mtime")].toLongLong();
const auto fileName = allHeaders[QStringLiteral("x-file-path")];
const auto modtime = allHeaders[QByteArrayLiteral("x-file-mtime")].toLongLong();
Q_ASSERT(!fileName.isEmpty());
Q_ASSERT(modtime > 0);
FileInfo *fileInfo = remoteRootFileInfo.find(fileName);
Expand All @@ -568,7 +568,7 @@ QVector<FileInfo *> FakePutMultiFileReply::performMultiPart(FileInfo &remoteRoot
// Assume that the file is filled with the same character
fileInfo = remoteRootFileInfo.create(fileName, onePartBody.size(), onePartBody.at(0).toLatin1());
}
fileInfo->lastModified = OCC::Utility::qDateTimeFromTime_t(request.rawHeader("X-OC-Mtime").toLongLong());
fileInfo->lastModified = OCC::Utility::qDateTimeFromTime_t(request.rawHeader("x-oc-mtime").toLongLong());
remoteRootFileInfo.find(fileName, /*invalidateEtags=*/true);
result.push_back(fileInfo);
}
Expand Down Expand Up @@ -1052,13 +1052,13 @@ QJsonObject FakeQNAM::forEachReplyPart(QIODevice *outgoingData,
QMap<QString, QByteArray> allHeaders;
for(const auto &oneHeader : qAsConst(onePartHeaders)) {
auto headerParts = oneHeader.split(QStringLiteral(": "));
allHeaders[headerParts.at(0)] = headerParts.at(1).toLatin1();
allHeaders[headerParts.at(0).toLower()] = headerParts.at(1).toLatin1();
}

auto reply = replyFunction(allHeaders);
if (reply.contains(QStringLiteral("error")) &&
reply.contains(QStringLiteral("etag"))) {
fullReply.insert(allHeaders[QStringLiteral("X-File-Path")], reply);
fullReply.insert(allHeaders[QStringLiteral("x-file-path")], reply);
}
}

Expand Down Expand Up @@ -1413,3 +1413,46 @@ FakeFileLockReply::FakeFileLockReply(FileInfo &remoteRootFileInfo,
xml.writeEndElement(); // prop
xml.writeEndDocument();
}

FakeJsonReply::FakeJsonReply(QNetworkAccessManager::Operation op,
const QNetworkRequest &request,
QObject *parent,
int httpReturnCode,
const QJsonDocument &reply)
: FakeReply{parent}
, _body{reply.toJson()}
{
setRequest(request);
setUrl(request.url());
setOperation(op);
open(QIODevice::ReadOnly);
setAttribute(QNetworkRequest::HttpStatusCodeAttribute, httpReturnCode);
QMetaObject::invokeMethod(this, &FakeJsonReply::respond, Qt::QueuedConnection);
}

void FakeJsonReply::respond()
{
emit metaDataChanged();
emit readyRead();
// finishing can come strictly after readyRead was called
QTimer::singleShot(5, this, &FakeJsonReply::slotSetFinished);
}

void FakeJsonReply::slotSetFinished()
{
setFinished(true);
emit finished();
}

qint64 FakeJsonReply::readData(char *buf, qint64 max)
{
max = qMin<qint64>(max, _body.size());
memcpy(buf, _body.constData(), max);
_body = _body.mid(max);
return max;
}

qint64 FakeJsonReply::bytesAvailable() const
{
return _body.size();
}
23 changes: 23 additions & 0 deletions test/syncenginetestutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,29 @@ class FakeReply : public QNetworkReply
using QNetworkReply::setRawHeader;
};

class FakeJsonReply : public FakeReply
{
Q_OBJECT
public:
FakeJsonReply(QNetworkAccessManager::Operation op,
const QNetworkRequest &request,
QObject *parent,
int httpReturnCode,
const QJsonDocument &reply = QJsonDocument());

Q_INVOKABLE virtual void respond();

public slots:
void slotSetFinished();

public:
void abort() override { }
qint64 readData(char *buf, qint64 max) override;
[[nodiscard]] qint64 bytesAvailable() const override;

QByteArray _body;
};

class FakePropfindReply : public FakeReply
{
Q_OBJECT
Expand Down
12 changes: 9 additions & 3 deletions test/testsyncengine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -984,15 +984,17 @@ private slots:
if (op == QNetworkAccessManager::PostOperation) {
++nPOST;
if (contentType.startsWith(QStringLiteral("multipart/related; boundary="))) {
auto jsonReplyObject = fakeFolder.forEachReplyPart(outgoingData, contentType, [] (const QMap<QString, QByteArray> &allHeaders) -> QJsonObject {
auto hasAnError = false;
auto jsonReplyObject = fakeFolder.forEachReplyPart(outgoingData, contentType, [&hasAnError] (const QMap<QString, QByteArray> &allHeaders) -> QJsonObject {
auto reply = QJsonObject{};
const auto fileName = allHeaders[QStringLiteral("X-File-Path")];
const auto fileName = allHeaders[QStringLiteral("x-file-path")];
if (fileName.endsWith("A/big2") ||
fileName.endsWith("A/big3") ||
fileName.endsWith("A/big4") ||
fileName.endsWith("A/big5") ||
fileName.endsWith("A/big7") ||
fileName.endsWith("B/big8")) {
hasAnError = true;
reply.insert(QStringLiteral("error"), true);
reply.insert(QStringLiteral("etag"), {});
return reply;
Expand All @@ -1005,7 +1007,11 @@ private slots:
if (jsonReplyObject.size()) {
auto jsonReply = QJsonDocument{};
jsonReply.setObject(jsonReplyObject);
return new FakeJsonErrorReply{op, request, this, 200, jsonReply};
if (hasAnError) {
return new FakeJsonErrorReply{op, request, this, 200, jsonReply};
} else {
return new FakeJsonReply{op, request, this, 200, jsonReply};
}
}
return nullptr;
}
Expand Down

0 comments on commit 0709d00

Please sign in to comment.