Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/owncloud/client.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHannah von Reth <hannah.vonreth@owncloud.com>2021-12-10 14:16:09 +0300
committerHannah von Reth <hannah.vonreth@owncloud.com>2021-12-10 14:16:09 +0300
commit69a8f2dd833b4f99f514e9571f47fde7728d7436 (patch)
treec6c3489b2e57c2eb6c37e1a55ad877f39f197cac /test/testutils
parentafc1adfd4555e98dc0feb4ef8caaeeca53005ca8 (diff)
parent3412bb22bc3723ea9d05ee149ab83f00d4aa2267 (diff)
Merge remote-tracking branch 'origin/2.10'
Diffstat (limited to 'test/testutils')
-rw-r--r--test/testutils/syncenginetestutils.cpp95
-rw-r--r--test/testutils/syncenginetestutils.h39
2 files changed, 102 insertions, 32 deletions
diff --git a/test/testutils/syncenginetestutils.cpp b/test/testutils/syncenginetestutils.cpp
index cc7604e6a..d6ff3f077 100644
--- a/test/testutils/syncenginetestutils.cpp
+++ b/test/testutils/syncenginetestutils.cpp
@@ -134,11 +134,12 @@ FileInfo::FileInfo(const QString &name, const std::initializer_list<FileInfo> &c
addChild(source);
}
-void FileInfo::addChild(const FileInfo &info)
+FileInfo &FileInfo::addChild(const FileInfo &info)
{
- auto &dest = this->children[info.name] = info;
+ FileInfo &dest = this->children[info.name] = info;
dest.parentPath = path();
dest.fixupParentPathRecursively();
+ return dest;
}
void FileInfo::remove(const QString &relativePath)
@@ -167,7 +168,7 @@ void FileInfo::appendByte(const QString &relativePath, char contentChar)
Q_UNUSED(contentChar);
FileInfo *file = findInvalidatingEtags(relativePath);
Q_ASSERT(file);
- file->size += 1;
+ file->contentSize += 1;
}
void FileInfo::modifyByte(const QString &relativePath, quint64 offset, char contentChar)
@@ -256,11 +257,41 @@ bool FileInfo::operator==(const FileInfo &other) const
// Consider files to be equal between local<->remote as a user would.
return name == other.name
&& isDir == other.isDir
- && size == other.size
+ && contentSize == other.contentSize
&& contentChar == other.contentChar
&& children == other.children;
}
+bool FileInfo::equals(const FileInfo &other, ComparissonOption opt) const
+{
+ switch (opt) {
+ case ContentIsKing:
+ return *this == other;
+ case IgnoreContentOfDehydratedFiles:
+ if (!isDehydratedPlaceholder && !other.isDehydratedPlaceholder) {
+ if (contentSize != other.contentSize || contentChar != other.contentChar) {
+ return false;
+ }
+ }
+
+ if (name == other.name && isDir == other.isDir && fileSize == other.fileSize && lastModified == other.lastModified) {
+ if (children.size() == other.children.size()) {
+ for (auto it = children.constBegin(), eit = children.constEnd(),
+ oit = other.children.constBegin(), oeit = other.children.constEnd();
+ it != eit && oit != oeit; ++it, ++oit) {
+ if (!it->equals(*oit, opt)) {
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+
+ Q_UNREACHABLE();
+}
+
QString FileInfo::path() const
{
return (parentPath.isEmpty() ? QString() : (parentPath + QLatin1Char('/'))) + name;
@@ -334,7 +365,7 @@ FakePropfindReply::FakePropfindReply(FileInfo &remoteRootFileInfo, QNetworkAcces
auto gmtDate = fileInfo.lastModified.toUTC();
auto stringDate = QLocale::c().toString(gmtDate, QStringLiteral("ddd, dd MMM yyyy HH:mm:ss 'GMT'"));
xml.writeTextElement(davUri, QStringLiteral("getlastmodified"), stringDate);
- xml.writeTextElement(davUri, QStringLiteral("getcontentlength"), QString::number(fileInfo.size));
+ xml.writeTextElement(davUri, QStringLiteral("getcontentlength"), QString::number(fileInfo.contentSize));
xml.writeTextElement(davUri, QStringLiteral("getetag"), QStringLiteral("\"%1\"").arg(QString::fromLatin1(fileInfo.etag)));
xml.writeTextElement(ocUri, QStringLiteral("permissions"), !fileInfo.permissions.isNull() ? QString(fileInfo.permissions.toString()) : fileInfo.isShared ? QStringLiteral("SRDNVCKW")
: QStringLiteral("RDNVCKW"));
@@ -411,8 +442,9 @@ FileInfo *FakePutReply::perform(FileInfo &remoteRootFileInfo, const QNetworkRequ
Q_ASSERT(!fileName.isEmpty());
FileInfo *fileInfo = remoteRootFileInfo.find(fileName);
if (fileInfo) {
- fileInfo->size = putPayload.size();
+ fileInfo->contentSize = putPayload.size();
fileInfo->contentChar = putPayload.at(0);
+ fileInfo->fileSize = fileInfo->contentSize; // it's hydrated on the server, so these are the same
} else {
// Assume that the file is filled with the same character
fileInfo = remoteRootFileInfo.create(fileName, putPayload.size(), putPayload.at(0));
@@ -424,7 +456,7 @@ FileInfo *FakePutReply::perform(FileInfo &remoteRootFileInfo, const QNetworkRequ
void FakePutReply::respond()
{
- emit uploadProgress(fileInfo->size, fileInfo->size);
+ emit uploadProgress(fileInfo->contentSize, fileInfo->contentSize);
setRawHeader("OC-ETag", fileInfo->etag);
setRawHeader("ETag", fileInfo->etag);
setRawHeader("OC-FileID", fileInfo->fileId);
@@ -538,7 +570,7 @@ void FakeGetReply::respond()
return;
}
payload = fileInfo->contentChar;
- size = fileInfo->size;
+ size = fileInfo->contentSize;
setHeader(QNetworkRequest::ContentLengthHeader, size);
setAttribute(QNetworkRequest::HttpStatusCodeAttribute, 200);
setRawHeader("OC-ETag", fileInfo->etag);
@@ -679,12 +711,12 @@ FileInfo *FakeChunkMoveReply::perform(FileInfo &uploadsFileInfo, FileInfo &remot
if (chunkNameLongLong != prev)
break;
Q_ASSERT(!x.isDir);
- Q_ASSERT(x.size > 0); // There should not be empty chunks
- size += x.size;
+ Q_ASSERT(x.contentSize > 0); // There should not be empty chunks
+ size += x.contentSize;
Q_ASSERT(!payload || payload == x.contentChar);
payload = x.contentChar;
++count;
- prev = chunkNameLongLong + x.size;
+ prev = chunkNameLongLong + x.contentSize;
}
Q_ASSERT(sourceFolderChildren.count() == count); // There should not be holes or extra files
@@ -701,8 +733,9 @@ FileInfo *FakeChunkMoveReply::perform(FileInfo &uploadsFileInfo, FileInfo &remot
if (request.rawHeader("If") != start + " ([\"" + fileInfo->etag + "\"])") {
return nullptr;
}
- fileInfo->size = size;
+ fileInfo->contentSize = size;
fileInfo->contentChar = payload;
+ fileInfo->fileSize = fileInfo->contentSize; // it's hydrated on the server, so these are the same
} else {
Q_ASSERT(!request.hasRawHeader("If"));
// Assume that the file is filled with the same character
@@ -883,8 +916,9 @@ QNetworkReply *FakeQNAM::createRequest(QNetworkAccessManager::Operation op, cons
return reply;
}
-FakeFolder::FakeFolder(const FileInfo &fileTemplate)
+FakeFolder::FakeFolder(const FileInfo &fileTemplate, OCC::Vfs::Mode vfsMode)
: _localModifier(_tempDir.path())
+ , _vfsMode(vfsMode)
{
// Needs to be done once
OCC::SyncEngine::minimumFileAgeForUpload = std::chrono::milliseconds(0);
@@ -1002,6 +1036,11 @@ void FakeFolder::execUntilItemCompleted(const QString &relativePath)
QVERIFY(false);
}
+bool FakeFolder::isDehydratedPlaceholder(const QString &filePath)
+{
+ return _syncEngine->syncOptions()._vfs->isDehydratedPlaceholder(filePath);
+}
+
void FakeFolder::toDisk(QDir &dir, const FileInfo &templateFi)
{
for (const auto &child : templateFi.children) {
@@ -1013,7 +1052,7 @@ void FakeFolder::toDisk(QDir &dir, const FileInfo &templateFi)
} else {
QFile file { dir.filePath(child.name) };
file.open(QFile::WriteOnly);
- file.write(QByteArray {}.fill(child.contentChar, child.size));
+ file.write(QByteArray {}.fill(child.contentChar, child.contentSize));
file.close();
OCC::FileSystem::setModTime(file.fileName(), OCC::Utility::qDateTimeToTime_t(child.lastModified));
}
@@ -1030,15 +1069,25 @@ void FakeFolder::fromDisk(QDir &dir, FileInfo &templateFi)
FileInfo &subFi = templateFi.children[diskChild.fileName()] = FileInfo { diskChild.fileName() };
fromDisk(subDir, subFi);
} else {
- QFile f { diskChild.filePath() };
- f.open(QFile::ReadOnly);
- auto content = f.read(1);
- if (content.size() == 0) {
- qWarning() << "Empty file at:" << diskChild.filePath();
- continue;
+ FileInfo fi(diskChild.fileName());
+ fi.isDir = false;
+ fi.fileSize = diskChild.size();
+ fi.isDehydratedPlaceholder = isDehydratedPlaceholder(diskChild.absoluteFilePath());
+ if (fi.isDehydratedPlaceholder) {
+ fi.contentChar = '\0';
+ } else {
+ QFile f { diskChild.filePath() };
+ f.open(QFile::ReadOnly);
+ auto content = f.read(1);
+ if (content.size() == 0) {
+ qWarning() << "Empty file at:" << diskChild.filePath();
+ continue;
+ }
+ fi.contentChar = content.at(0);
+ fi.contentSize = fi.fileSize;
}
- char contentChar = content.at(0);
- templateFi.children.insert(diskChild.fileName(), FileInfo { diskChild.fileName(), diskChild.size(), contentChar });
+
+ templateFi.children.insert(fi.name, fi);
}
}
}
@@ -1067,7 +1116,7 @@ FileInfo FakeFolder::dbState() const
auto &item = parentDir.children[name];
item.name = name;
item.parentPath = parentDir.path();
- item.size = record._fileSize;
+ item.contentSize = record._fileSize;
item.isDir = record._type == ItemTypeDirectory;
item.permissions = record._remotePerm;
item.etag = record._etag;
diff --git a/test/testutils/syncenginetestutils.h b/test/testutils/syncenginetestutils.h
index bacc43c63..b38e87809 100644
--- a/test/testutils/syncenginetestutils.h
+++ b/test/testutils/syncenginetestutils.h
@@ -110,6 +110,7 @@ public:
void setModTime(const QString &relativePath, const QDateTime &modTime) override;
};
+/// FIXME: we should make it explicit in the construtor if we're talking about a hydrated or a dehydrated file!
class FileInfo : public FileModifier
{
public:
@@ -123,19 +124,21 @@ public:
FileInfo(const QString &name, qint64 size)
: name { name }
, isDir { false }
- , size { size }
+ , fileSize(size)
+ , contentSize { size }
{
}
FileInfo(const QString &name, qint64 size, char contentChar)
: name { name }
, isDir { false }
- , size { size }
+ , fileSize(size)
+ , contentSize { size }
, contentChar { contentChar }
{
}
FileInfo(const QString &name, const std::initializer_list<FileInfo> &children);
- void addChild(const FileInfo &info);
+ FileInfo &addChild(const FileInfo &info);
void remove(const QString &relativePath) override;
@@ -153,6 +156,7 @@ public:
void setModTime(const QString &relativePath, const QDateTime &modTime) override;
+ /// Return a pointer to the FileInfo, or a nullptr if it doesn't exist
FileInfo *find(PathComponents pathComponents, const bool invalidateEtags = false);
FileInfo *createDir(const QString &relativePath);
@@ -171,6 +175,13 @@ public:
return !operator==(other);
}
+ enum ComparissonOption {
+ IgnoreContentOfDehydratedFiles,
+ ContentIsKing,
+ };
+
+ bool equals(const FileInfo &other, ComparissonOption opt) const;
+
QString path() const;
QString absolutePath() const;
@@ -185,8 +196,10 @@ public:
QByteArray fileId = generateFileId();
QByteArray checksums;
QByteArray extraDavProperties;
- qint64 size = 0;
+ qint64 fileSize = 0;
+ qint64 contentSize = 0;
char contentChar = 'W';
+ bool isDehydratedPlaceholder = false;
// Sorted by name to be able to compare trees
QMap<QString, FileInfo> children;
@@ -196,7 +209,12 @@ public:
friend inline QDebug operator<<(QDebug dbg, const FileInfo &fi)
{
- return dbg << "{ " << fi.path() << ": " << fi.children;
+ return dbg << "{ " << fi.path() << ": "
+ << ", fileSize:" << fi.fileSize
+ << ", contentSize:" << fi.contentSize
+ << ", contentChar:" << fi.contentChar
+ << ", isDehydratedPlaceholder:" << fi.isDehydratedPlaceholder
+ << ", children:" << fi.children;
}
};
@@ -472,9 +490,10 @@ class FakeFolder
OCC::AccountPtr _account;
std::unique_ptr<OCC::SyncJournalDb> _journalDb;
std::unique_ptr<OCC::SyncEngine> _syncEngine;
+ OCC::Vfs::Mode _vfsMode;
public:
- FakeFolder(const FileInfo &fileTemplate);
+ FakeFolder(const FileInfo &fileTemplate, OCC::Vfs::Mode vfsMode = OCC::Vfs::Off);
void switchToVfs(QSharedPointer<OCC::Vfs> vfs);
@@ -524,10 +543,12 @@ public:
return execUntilFinished();
}
+ bool isDehydratedPlaceholder(const QString &filePath);
+
private:
static void toDisk(QDir &dir, const FileInfo &templateFi);
- static void fromDisk(QDir &dir, FileInfo &templateFi);
+ void fromDisk(QDir &dir, FileInfo &templateFi);
};
@@ -572,7 +593,7 @@ inline void addFiles(QStringList &dest, const FileInfo &fi)
for (const auto &fi : fi.children)
addFiles(dest, fi);
} else {
- dest += QStringLiteral("%1 - %2 %3-bytes").arg(fi.path()).arg(fi.size).arg(fi.contentChar);
+ dest += QStringLiteral("%1 - %2 %3-bytes").arg(fi.path()).arg(fi.contentSize).arg(fi.contentChar);
}
}
@@ -598,7 +619,7 @@ inline void addFilesDbData(QStringList &dest, const FileInfo &fi)
for (const auto &fi : fi.children)
addFilesDbData(dest, fi);
} else {
- dest += QStringLiteral("%1 - %2 %3 %4 %5").arg(fi.name, fi.isDir ? QStringLiteral("dir") : QStringLiteral("file"), QString::number(fi.size), QString::number(fi.lastModified.toSecsSinceEpoch()), QString::fromUtf8(fi.fileId));
+ dest += QStringLiteral("%1 - %2 %3 %4 %5").arg(fi.name, fi.isDir ? QStringLiteral("dir") : QStringLiteral("file"), QString::number(fi.contentSize), QString::number(fi.lastModified.toSecsSinceEpoch()), QString::fromUtf8(fi.fileId));
}
}