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:
authorErik Verbruggen <erik@verbruggen.consulting>2021-12-09 16:24:22 +0300
committerErik Verbruggen <Erik.Verbruggen@Me.com>2021-12-15 15:23:55 +0300
commit8484e759060f221cbc6f519165572e3559cbc560 (patch)
tree9c097283ddf675031ba88f4f46748f17acedfe32 /test/testutils
parent6300c004300655c2de18da42766a547137217f8a (diff)
Tests: always check the hydration state and the mtime
operator== will now always also check the hydration state and mtime. For the few cases where this will fail (on purpose), the equals method can be called with `IgnoreLastModified` passed to it.
Diffstat (limited to 'test/testutils')
-rw-r--r--test/testutils/syncenginetestutils.cpp86
-rw-r--r--test/testutils/syncenginetestutils.h66
2 files changed, 98 insertions, 54 deletions
diff --git a/test/testutils/syncenginetestutils.cpp b/test/testutils/syncenginetestutils.cpp
index 7edcb6e19..fe72c642f 100644
--- a/test/testutils/syncenginetestutils.cpp
+++ b/test/testutils/syncenginetestutils.cpp
@@ -166,7 +166,10 @@ void FileInfo::appendByte(const QString &relativePath, char contentChar)
Q_UNUSED(contentChar);
FileInfo *file = findInvalidatingEtags(relativePath);
Q_ASSERT(file);
- file->contentSize += 1;
+ if (!file->isDehydratedPlaceholder) {
+ file->contentSize += 1;
+ }
+ file->fileSize += 1;
}
void FileInfo::modifyByte(const QString &relativePath, quint64 offset, char contentChar)
@@ -203,7 +206,7 @@ void FileInfo::setModTime(const QString &relativePath, const QDateTime &modTime)
{
FileInfo *file = findInvalidatingEtags(relativePath);
Q_ASSERT(file);
- file->lastModified = modTime;
+ file->setLastModified(modTime);
}
FileInfo *FileInfo::find(PathComponents pathComponents, const bool invalidateEtags)
@@ -250,44 +253,45 @@ FileInfo *FileInfo::create(const QString &relativePath, qint64 size, char conten
return &child;
}
-bool FileInfo::operator==(const FileInfo &other) const
+bool FileInfo::equals(const FileInfo &other, CompareWhat compareWhat) const
{
- // Consider files to be equal between local<->remote as a user would.
- return name == other.name
- && isDir == other.isDir
- && 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;
- }
+ // Only check the content and contentSize if both files are hydrated:
+ 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;
- }
- }
- }
+ // We need to check this before we use isDir in the next if-statement:
+ if (isDir != other.isDir) {
+ return false;
+ }
+
+ if (compareWhat == CompareLastModified) {
+ // Don't check directory mtime: it might change when (unsynced) files get created.
+ if (!isDir && _lastModifiedInSecondsUTC != other._lastModifiedInSecondsUTC) {
+ return false;
}
+ }
+
+ if (name != other.name || fileSize != other.fileSize) {
+ return false;
+ }
- return true;
+ if (children.size() != other.children.size()) {
+ return false;
}
- Q_UNREACHABLE();
+ for (auto it = children.constBegin(), eit = children.constEnd(); it != eit; ++it) {
+ auto oit = other.children.constFind(it.key());
+ if (oit == other.children.constEnd()) {
+ return false;
+ } else if (!it.value().equals(oit.value(), compareWhat)) {
+ return false;
+ }
+ }
+
+ return true;
}
QString FileInfo::path() const
@@ -360,7 +364,7 @@ FakePropfindReply::FakePropfindReply(FileInfo &remoteRootFileInfo, QNetworkAcces
} else
xml.writeEmptyElement(davUri, QStringLiteral("resourcetype"));
- auto gmtDate = fileInfo.lastModified.toUTC();
+ auto gmtDate = fileInfo.lastModifiedInUtc();
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.contentSize));
@@ -442,12 +446,12 @@ FileInfo *FakePutReply::perform(FileInfo &remoteRootFileInfo, const QNetworkRequ
if (fileInfo) {
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));
}
- fileInfo->lastModified = OCC::Utility::qDateTimeFromTime_t(request.rawHeader("X-OC-Mtime").toLongLong());
+ fileInfo->fileSize = fileInfo->contentSize; // it's hydrated on the server, so these are the same
+ fileInfo->setLastModifiedFromSecondsUTC(request.rawHeader("X-OC-Mtime").toLongLong());
remoteRootFileInfo.find(fileName, /*invalidate_etags=*/true);
return fileInfo;
}
@@ -574,6 +578,7 @@ void FakeGetReply::respond()
setRawHeader("OC-ETag", fileInfo->etag);
setRawHeader("ETag", fileInfo->etag);
setRawHeader("OC-FileId", fileInfo->fileId);
+ setRawHeader("X-OC-Mtime", QByteArray::number(fileInfo->lastModifiedInSecondsUTC()));
emit metaDataChanged();
if (bytesAvailable())
emit readyRead();
@@ -641,6 +646,7 @@ void FakeGetWithDataReply::respond()
setRawHeader("OC-ETag", fileInfo->etag);
setRawHeader("ETag", fileInfo->etag);
setRawHeader("OC-FileId", fileInfo->fileId);
+ setRawHeader("X-OC-Mtime", QByteArray::number(fileInfo->lastModifiedInSecondsUTC()));
emit metaDataChanged();
if (bytesAvailable())
emit readyRead();
@@ -739,7 +745,7 @@ FileInfo *FakeChunkMoveReply::perform(FileInfo &uploadsFileInfo, FileInfo &remot
// Assume that the file is filled with the same character
fileInfo = remoteRootFileInfo.create(fileName, size, payload);
}
- fileInfo->lastModified = OCC::Utility::qDateTimeFromTime_t(request.rawHeader("X-OC-Mtime").toLongLong());
+ fileInfo->setLastModifiedFromSecondsUTC(request.rawHeader("X-OC-Mtime").toLongLong());
remoteRootFileInfo.find(fileName, /*invalidate_etags=*/true);
return fileInfo;
@@ -1052,7 +1058,7 @@ void FakeFolder::toDisk(QDir &dir, const FileInfo &templateFi)
file.open(QFile::WriteOnly);
file.write(QByteArray {}.fill(child.contentChar, child.contentSize));
file.close();
- OCC::FileSystem::setModTime(file.fileName(), OCC::Utility::qDateTimeToTime_t(child.lastModified));
+ OCC::FileSystem::setModTime(file.fileName(), child.lastModifiedInSecondsUTC());
}
}
}
@@ -1065,12 +1071,14 @@ void FakeFolder::fromDisk(QDir &dir, FileInfo &templateFi)
QDir subDir = dir;
subDir.cd(diskChild.fileName());
FileInfo &subFi = templateFi.children[diskChild.fileName()] = FileInfo { diskChild.fileName() };
+ subFi.setLastModified(diskChild.lastModified());
fromDisk(subDir, subFi);
} else {
FileInfo fi(diskChild.fileName());
fi.isDir = false;
fi.fileSize = diskChild.size();
fi.isDehydratedPlaceholder = isDehydratedPlaceholder(diskChild.absoluteFilePath());
+ fi.setLastModified(diskChild.lastModified());
if (fi.isDehydratedPlaceholder) {
fi.contentChar = '\0';
} else {
@@ -1118,7 +1126,7 @@ FileInfo FakeFolder::dbState() const
item.isDir = record._type == ItemTypeDirectory;
item.permissions = record._remotePerm;
item.etag = record._etag;
- item.lastModified = OCC::Utility::qDateTimeFromTime_t(record._modtime);
+ item.setLastModifiedFromSecondsUTC(record._modtime);
item.fileId = record._fileId;
item.checksums = record._checksumHeader;
// item.contentChar can't be set from the db
diff --git a/test/testutils/syncenginetestutils.h b/test/testutils/syncenginetestutils.h
index 22b0fa296..61b258b4a 100644
--- a/test/testutils/syncenginetestutils.h
+++ b/test/testutils/syncenginetestutils.h
@@ -109,6 +109,13 @@ public:
void setModTime(const QString &relativePath, const QDateTime &modTime) override;
};
+static inline qint64 defaultLastModified()
+{
+ auto precise = QDateTime::currentDateTimeUtc().addDays(-7);
+ time_t timeInSeconds = OCC::Utility::qDateTimeToTime_t(precise);
+ return timeInSeconds;
+}
+
/// FIXME: we should make it explicit in the construtor if we're talking about a hydrated or a dehydrated file!
class FileInfo : public FileModifier
{
@@ -167,19 +174,44 @@ public:
return name < other.name;
}
- bool operator==(const FileInfo &other) const;
+ enum CompareWhat {
+ CompareLastModified,
+ IgnoreLastModified,
+ };
+
+ bool operator==(const FileInfo &other) const { return equals(other, CompareLastModified); }
+
+ bool equals(const FileInfo &other, CompareWhat compareWhat) const;
bool operator!=(const FileInfo &other) const
{
return !operator==(other);
}
- enum ComparissonOption {
- IgnoreContentOfDehydratedFiles,
- ContentIsKing,
- };
+ QDateTime lastModified() const
+ {
+ return QDateTime::fromSecsSinceEpoch(_lastModifiedInSecondsUTC, Qt::LocalTime);
+ }
+
+ QDateTime lastModifiedInUtc() const
+ {
+ return QDateTime::fromSecsSinceEpoch(_lastModifiedInSecondsUTC, Qt::UTC);
+ }
+
+ void setLastModified(const QDateTime &t)
+ {
+ _lastModifiedInSecondsUTC = t.toSecsSinceEpoch();
+ }
- bool equals(const FileInfo &other, ComparissonOption opt) const;
+ qint64 lastModifiedInSecondsUTC() const
+ {
+ return _lastModifiedInSecondsUTC;
+ }
+
+ void setLastModifiedFromSecondsUTC(qint64 utcSecs)
+ {
+ _lastModifiedInSecondsUTC = utcSecs;
+ }
QString path() const;
QString absolutePath() const;
@@ -190,7 +222,7 @@ public:
bool isDir = true;
bool isShared = false;
OCC::RemotePermissions permissions; // When uset, defaults to everything
- QDateTime lastModified = QDateTime::currentDateTimeUtc().addDays(-7);
+ qint64 _lastModifiedInSecondsUTC = defaultLastModified();
QByteArray etag = generateEtag();
QByteArray fileId = generateFileId();
QByteArray checksums;
@@ -208,12 +240,16 @@ public:
friend inline QDebug operator<<(QDebug dbg, const FileInfo &fi)
{
- return dbg << "{ " << fi.path() << ": "
- << ", fileSize:" << fi.fileSize
- << ", contentSize:" << fi.contentSize
- << ", contentChar:" << fi.contentChar
- << ", isDehydratedPlaceholder:" << fi.isDehydratedPlaceholder
- << ", children:" << fi.children;
+ return dbg.nospace().noquote()
+ << "{ '" << fi.path() << "': "
+ << ", isDir:" << fi.isDir
+ << QStringLiteral(", lastModified: %1 (%2)").arg(QString::number(fi._lastModifiedInSecondsUTC), fi.lastModifiedInUtc().toString())
+ << ", fileSize:" << fi.fileSize
+ << ", contentSize:" << fi.contentSize
+ << QStringLiteral(", contentChar: 0x%1").arg(QString::number(int(fi.contentChar), 16))
+ << ", isDehydratedPlaceholder:" << fi.isDehydratedPlaceholder
+ << ", children:" << fi.children
+ << " }";
}
};
@@ -614,11 +650,11 @@ inline void addFilesDbData(QStringList &dest, const FileInfo &fi)
{
// could include etag, permissions etc, but would need extra work
if (fi.isDir) {
- dest += QStringLiteral("%1 - %2 %3 %4").arg(fi.name, fi.isDir ? QStringLiteral("dir") : QStringLiteral("file"), QString::number(fi.lastModified.toSecsSinceEpoch()), QString::fromUtf8(fi.fileId));
+ dest += QStringLiteral("%1 - %2 %3 %4").arg(fi.name, fi.isDir ? QStringLiteral("dir") : QStringLiteral("file"), QString::number(fi.lastModifiedInSecondsUTC()), QString::fromUtf8(fi.fileId));
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.contentSize), 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.lastModifiedInSecondsUTC()), QString::fromUtf8(fi.fileId));
}
}