diff options
-rw-r--r-- | tests/arthur/baselineserver/src/baselineserver.cpp | 73 | ||||
-rw-r--r-- | tests/arthur/baselineserver/src/baselineserver.h | 3 | ||||
-rw-r--r-- | tests/arthur/baselineserver/src/report.cpp | 11 | ||||
-rw-r--r-- | tests/arthur/baselineserver/src/report.h | 2 |
4 files changed, 67 insertions, 22 deletions
diff --git a/tests/arthur/baselineserver/src/baselineserver.cpp b/tests/arthur/baselineserver/src/baselineserver.cpp index f59600f..64b50fd 100644 --- a/tests/arthur/baselineserver/src/baselineserver.cpp +++ b/tests/arthur/baselineserver/src/baselineserver.cpp @@ -55,6 +55,11 @@ QString BaselineServer::storage; +// extra fields, for use in image metadata storage +const QString PI_ImageChecksum(QLS("ImageChecksum")); +const QString PI_RunId(QLS("RunId")); +const QString PI_CreationDate(QLS("CreationDate")); + BaselineServer::BaselineServer(QObject *parent) : QTcpServer(parent) @@ -220,16 +225,17 @@ void BaselineHandler::provideBaselineChecksums(const QByteArray &itemListBlock) for (ImageItemList::iterator i = itemList.begin(); i != itemList.end(); ++i) { i->imageChecksums.clear(); + i->status = ImageItem::BaselineNotFound; QString prefix = pathForItem(*i, true); - QFile file(prefix + QLS("metadata")); - if (file.open(QIODevice::ReadOnly)) { - QDataStream checkSums(&file); - checkSums >> i->imageChecksums; - file.close(); - i->status = ImageItem::Ok; + PlatformInfo itemData = fetchItemMetadata(prefix); + if (itemData.contains(PI_ImageChecksum)) { + bool ok = false; + quint64 checksum = itemData.value(PI_ImageChecksum).toULongLong(&ok, 16); + if (ok) { + i->imageChecksums.prepend(checksum); + i->status = ImageItem::Ok; + } } - if (!i->imageChecksums.count()) - i->status = ImageItem::BaselineNotFound; } // Find and mark blacklisted items @@ -280,18 +286,51 @@ void BaselineHandler::storeImage(const QByteArray &itemBlock, bool isBaseline) cwd.mkpath(dir); item.image.save(prefix + QLS(FileFormat), FileFormat); - //# Could use QSettings or XML or even DB, could use common file for whole dir or even whole storage - but for now, keep it simple - QFile file(prefix + QLS("metadata")); - file.open(QIODevice::WriteOnly | QIODevice::Truncate); - QDataStream checkSums(&file); - checkSums << item.imageChecksums; - file.close(); + PlatformInfo itemData = plat; + itemData.insert(PI_ImageChecksum, QString::number(item.imageChecksums.at(0), 16)); //# Only the first is stored. TBD: get rid of list + itemData.insert(PI_RunId, runId); + itemData.insert(PI_CreationDate, QDateTime::currentDateTime().toString()); + storeItemMetadata(itemData, prefix); if (!isBaseline) report.addMismatch(item); } +void BaselineHandler::storeItemMetadata(const PlatformInfo &metadata, const QString &path) +{ + QFile file(path + QLS(MetadataFileExt)); + if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) { + qWarning() << runId << logtime() << "ERROR: could not write to file" << file.fileName(); + return; + } + QTextStream out(&file); + PlatformInfo::const_iterator it = metadata.constBegin(); + while (it != metadata.constEnd()) { + out << it.key() << ": " << it.value() << endl; + ++it; + } + file.close(); +} + + +PlatformInfo BaselineHandler::fetchItemMetadata(const QString &path) +{ + PlatformInfo res; + QFile file(path + QLS(MetadataFileExt)); + if (!file.open(QIODevice::ReadOnly)) + return res; + QTextStream in(&file); + do { + QString line = in.readLine(); + int idx = line.indexOf(QLS(": ")); + if (idx > 0) + res.insert(line.left(idx), line.mid(idx+2)); + } while (!in.atEnd()); + return res; +} + + void BaselineHandler::receiveDisconnect() { qDebug() << runId << logtime() << "Client disconnected."; @@ -371,7 +410,7 @@ QString BaselineHandler::clearAllBaselines(const QString &context) int tot = 0; int failed = 0; QDirIterator it(BaselineServer::storagePath() + QLC('/') + context, - QStringList() << QLS("*.png") << QLS("*.metadata")); + QStringList() << QLS("*.") + QLS(FileFormat) << QLS("*.") + QLS(MetadataFileExt)); while (it.hasNext()) { tot++; if (!QFile::remove(it.next())) @@ -389,10 +428,10 @@ QString BaselineHandler::updateSingleBaseline(const QString &oldBaseline, const QProcess proc; proc.setProcessChannelMode(QProcess::MergedChannels); - proc.start(QLS("cp"), QStringList() << QLS("-f") << srcBase + QLS("png") << srcBase + QLS("metadata") << dstDir); + proc.start(QLS("cp"), QStringList() << QLS("-f") << srcBase + QLS(FileFormat) << srcBase + QLS(MetadataFileExt) << dstDir); proc.waitForFinished(); if (proc.exitCode() == 0) - res = QString("Successfully updated '%1'").arg(oldBaseline + QLS("/metadata")); + res = QString("Successfully updated '%1'").arg(oldBaseline); else res = QString("Error updating baseline: %1<br>" "Command output: <pre>%2</pre>").arg(proc.errorString(), proc.readAll().constData()); diff --git a/tests/arthur/baselineserver/src/baselineserver.h b/tests/arthur/baselineserver/src/baselineserver.h index e09a9d0..1409afc 100644 --- a/tests/arthur/baselineserver/src/baselineserver.h +++ b/tests/arthur/baselineserver/src/baselineserver.h @@ -54,6 +54,7 @@ // #seconds between update checks #define HEARTBEAT 10 +#define MetadataFileExt "metadata" class BaselineServer : public QTcpServer { @@ -115,6 +116,8 @@ private: bool establishConnection(); void provideBaselineChecksums(const QByteArray &itemListBlock); void storeImage(const QByteArray &itemBlock, bool isBaseline); + void storeItemMetadata(const PlatformInfo &metadata, const QString &path); + PlatformInfo fetchItemMetadata(const QString &path); void mapPlatformInfo() const; const char *logtime(); QString computeMismatchScore(const QImage& baseline, const QImage& rendered); diff --git a/tests/arthur/baselineserver/src/report.cpp b/tests/arthur/baselineserver/src/report.cpp index f5bb418..505fd62 100644 --- a/tests/arthur/baselineserver/src/report.cpp +++ b/tests/arthur/baselineserver/src/report.cpp @@ -170,13 +170,15 @@ void Report::writeFunctionResults(const ImageItemList &list) foreach (const ImageItem &item, list) { out << "<tr>\n"; out << "<td>" << item.itemName << "</td>\n"; - QString baseline = handler->pathForItem(item, true, false) + QLS(FileFormat); + QString prefix = handler->pathForItem(item, true, false); + QString baseline = prefix + QLS(FileFormat); + QString metadata = prefix + QLS(MetadataFileExt); if (item.status == ImageItem::Mismatch) { QString rendered = handler->pathForItem(item, false, false) + QLS(FileFormat); - writeItem(baseline, rendered, item, ctx); + writeItem(baseline, rendered, item, ctx, metadata); } else { - out << "<td align=center><a href=\"/" << baseline << "\">view</a></td>\n" + out << "<td align=center><a href=\"/" << baseline << "\">image</a> <a href=\"/" << metadata << "\">info</a></td>\n" << "<td align=center colspan=2><small>n/a</small></td>\n" << "<td align=center>"; switch (item.status) { @@ -204,7 +206,7 @@ void Report::writeFunctionResults(const ImageItemList &list) out << "</table>\n"; } -void Report::writeItem(const QString &baseline, const QString &rendered, const ImageItem &item, const QString &ctx) +void Report::writeItem(const QString &baseline, const QString &rendered, const ImageItem &item, const QString &ctx, const QString &metadata) { QString compared = generateCompared(baseline, rendered); QString pageUrl = BaselineServer::baseUrl() + path; @@ -215,6 +217,7 @@ void Report::writeItem(const QString &baseline, const QString &rendered, const I out << "<td align=center>\n" << "<p><span style=\"color:red\">Mismatch reported</span></p>\n" + << "<p><a href=\"/" << metadata << "\">Baseline Info</a>\n" << "<p><a href=\"/cgi-bin/server.cgi?cmd=updateSingleBaseline&oldBaseline=" << baseline << "&newBaseline=" << rendered << "&url=" << pageUrl << "\">Replace baseline with rendered</a></p>\n" << "<p><a href=\"/cgi-bin/server.cgi?cmd=blacklist&context=" << ctx diff --git a/tests/arthur/baselineserver/src/report.h b/tests/arthur/baselineserver/src/report.h index 0df613a..a56aafb 100644 --- a/tests/arthur/baselineserver/src/report.h +++ b/tests/arthur/baselineserver/src/report.h @@ -67,7 +67,7 @@ public: private: void write(); void writeFunctionResults(const ImageItemList &list); - void writeItem(const QString &baseline, const QString &rendered, const ImageItem &item, const QString &ctx); + void writeItem(const QString &baseline, const QString &rendered, const ImageItem &item, const QString &ctx, const QString &metadata); void writeHeader(); void writeFooter(); QString generateCompared(const QString &baseline, const QString &rendered, bool fuzzy = false); |