summaryrefslogtreecommitdiffstats
path: root/tests/arthur
diff options
context:
space:
mode:
Diffstat (limited to 'tests/arthur')
-rw-r--r--tests/arthur/baselineserver/src/baselineserver.cpp59
-rw-r--r--tests/arthur/baselineserver/src/baselineserver.h3
-rw-r--r--tests/arthur/baselineserver/src/htmlpage.cpp51
-rw-r--r--tests/arthur/baselineserver/src/htmlpage.h2
-rw-r--r--tests/arthur/common/baselineprotocol.cpp47
-rw-r--r--tests/arthur/common/baselineprotocol.h7
6 files changed, 103 insertions, 66 deletions
diff --git a/tests/arthur/baselineserver/src/baselineserver.cpp b/tests/arthur/baselineserver/src/baselineserver.cpp
index 7679f13..0399224 100644
--- a/tests/arthur/baselineserver/src/baselineserver.cpp
+++ b/tests/arthur/baselineserver/src/baselineserver.cpp
@@ -51,6 +51,7 @@
#include <QHostInfo>
#include <QTextStream>
#include <QProcess>
+#include <QDirIterator>
QString BaselineServer::storage;
@@ -97,8 +98,8 @@ void BaselineServer::heartbeat()
if (me.lastModified() == meLastMod)
return;
- // (could close() here to avoid accepting new connections, to avoid livelock)
- // also, could check for a timeout to force exit, to avoid hung threads blocking
+ //# (could close() here to avoid accepting new connections, to avoid livelock)
+ //# also, could check for a timeout to force exit, to avoid hung threads blocking
bool isServing = false;
foreach(BaselineThread *thread, findChildren<BaselineThread *>()) {
if (thread->isRunning()) {
@@ -304,10 +305,13 @@ void BaselineHandler::mapPlatformInfo()
if (host.isEmpty() || host == QLS("localhost")) {
host = plat.value(PI_HostAddress);
} else {
- // remove index postfix typical of vm hostnames
- host.remove(QRegExp(QLS("\\d+$")));
- if (host.endsWith(QLC('-')))
- host.chop(1);
+ //# Site specific, should be in a config file
+ if (!host.startsWith(QLS("oldhcp"))) {
+ // remove index postfix typical of vm hostnames
+ host.remove(QRegExp(QLS("\\d+$")));
+ if (host.endsWith(QLC('-')))
+ host.chop(1);
+ }
}
if (host.isEmpty())
host = QLS("unknownhost");
@@ -349,43 +353,18 @@ QString BaselineHandler::pathForItem(const ImageItem &item, bool isBaseline, boo
}
-QString BaselineHandler::updateAllBaselines(const QString &host, const QString &id,
- const QString &engine, const QString &format)
+QString BaselineHandler::clearAllBaselines(const QString &context)
{
-#if 0
- QString basePath(BaselineServer::storagePath());
- QString srcDir(basePath + host + QLC('/') + itemSubPath(engine, format, false) + id);
- QString dstDir(basePath + host + QLC('/') + itemSubPath(engine, format));
-
- QDir dir(srcDir);
- QStringList nameFilter;
- nameFilter << "*.metadata" << "*.png";
- QStringList fileList = dir.entryList(nameFilter, QDir::Files | QDir::NoDotAndDotDot);
-
- // remove the generated _fuzzycompared.png and _compared.png files from the list
- QMutableStringListIterator it(fileList);
+ int tot = 0;
+ int failed = 0;
+ QDirIterator it(BaselineServer::storagePath() + QLC('/') + context,
+ QStringList() << QLS("*.png") << QLS("*.metadata"));
while (it.hasNext()) {
- it.next();
- if (it.value().endsWith(QLS("compared.png")))
- it.remove();
+ tot++;
+ if (!QFile::remove(it.next()))
+ failed++;
}
-
- QString res;
- QProcess proc;
- proc.setWorkingDirectory(srcDir);
- proc.setProcessChannelMode(QProcess::MergedChannels);
- proc.start(QLS("cp"), QStringList() << QLS("-f") << fileList << dstDir);
- proc.waitForFinished();
- if (proc.exitCode() == 0)
- res = QLS("Successfully updated baseline for all failed tests.");
- else
- res = QString("Error updating baseline: %1<br>"
- "Command output: <pre>%2</pre>").arg(proc.errorString(), proc.readAll().constData());
-
- return res;
-#else
- return QString();
-#endif
+ return QString(QLS("%1 of %2 baselines cleared from context ")).arg((tot-failed)/2).arg(tot/2) + context;
}
QString BaselineHandler::updateSingleBaseline(const QString &oldBaseline, const QString &newBaseline)
diff --git a/tests/arthur/baselineserver/src/baselineserver.h b/tests/arthur/baselineserver/src/baselineserver.h
index d49aedb..c5cb45e 100644
--- a/tests/arthur/baselineserver/src/baselineserver.h
+++ b/tests/arthur/baselineserver/src/baselineserver.h
@@ -100,8 +100,7 @@ public:
BaselineHandler(int socketDescriptor = -1);
void testPathMapping();
- static QString updateAllBaselines(const QString &host, const QString &id,
- const QString &engine, const QString &format);
+ static QString clearAllBaselines(const QString &context);
static QString updateSingleBaseline(const QString &oldBaseline, const QString &newBaseline);
static QString blacklistTest(const QString &context, const QString &itemId, bool removeFromBlacklist = false);
diff --git a/tests/arthur/baselineserver/src/htmlpage.cpp b/tests/arthur/baselineserver/src/htmlpage.cpp
index f75da88..9659505 100644
--- a/tests/arthur/baselineserver/src/htmlpage.cpp
+++ b/tests/arthur/baselineserver/src/htmlpage.cpp
@@ -69,7 +69,8 @@ void HTMLPage::start(const QString &storagepath, const QString &runId, const Pla
ctx = context;
root = storagepath + QLC('/');
imageItems = itemList;
- QString dir = root + QLS("reports/");
+ reportDir = pinfo.value(PI_PulseGitBranch).isEmpty() ? QLS("reports/adhoc/") : QLS("reports/pulse/");
+ QString dir = root + reportDir;
QDir cwd;
if (!cwd.exists(dir))
cwd.mkpath(dir);
@@ -78,7 +79,7 @@ void HTMLPage::start(const QString &storagepath, const QString &runId, const Pla
void HTMLPage::writeHeader(const ImageItem &item)
{
- path = QLS("reports/") + id + QLC('_') + item.engineAsString()
+ path = reportDir + id + QLC('_') + item.engineAsString()
+ QLC('_') + item.formatAsString() + QLS(".html");
QString pageUrl = BaselineServer::baseUrl() + path;
@@ -89,24 +90,21 @@ void HTMLPage::writeHeader(const ImageItem &item)
out.setDevice(&file);
out << "<html><body><h1>Lancelot results from run " << id << "</h1>\n\n";
- out << "<h3>Platform Info:</h3>\n";
+ out << "<p><h3>Platform Info:</h3>\n";
out << "<table>\n";
foreach (QString key, plat.keys())
out << "<tr><td>" << key << "</td><td>" << plat.value(key) << "</td></tr>\n";
- out << "</table>\n";
-
-#if 0
- out << "<h3><a href=\"/cgi-bin/server.cgi?cmd=updateAllBaselines&id="<< id << "&host=" << plat.hostName
- << "&engine=" << item.engineAsString() << "&format=" << item.formatAsString()
- << "&url=" << pageUrl
- << "\">Update all baselines</a><br>";
-#endif
- out << "<table border=\"2\">\n"
+ out << "</table></p>\n\n";
+
+ out << "<p><a href=\"/cgi-bin/server.cgi?cmd=clearAllBaselines&context=" << ctx << "&url=" << pageUrl
+ << "\"><b><big>Clear all baselines</big></b></a></h3> (They will be recreated by the next run)</p>\n\n";
+
+ out << "<p><table border=\"2\">\n"
"<tr>\n"
"<td><b>Script</b></td>\n"
"<td><b>Baseline</b></td>\n"
"<td><b>Rendered</b></td>\n"
- "<td><b>Comparison</b></td>\n"
+ "<td><b>Comparison</b> (diffs are <span style=\"color:red\">RED</span>)</td>\n"
"<td><b>Info/Action</b></td>\n"
"</b></tr><br>";
}
@@ -114,7 +112,7 @@ void HTMLPage::writeHeader(const ImageItem &item)
void HTMLPage::writeFooter()
{
- out << "</table>\n</body></html>\n";
+ out << "</table></p>\n</body></html>\n";
}
@@ -131,7 +129,7 @@ void HTMLPage::addItem(const QString &baseline, const QString &rendered, const I
out << "<td>" << item.scriptName << "</td>\n";
QStringList images = QStringList() << baseline << rendered << compared;
foreach(const QString& img, images)
- out << "<td><a href=\"/" << img << "\"><img src=\"/" << img << "\" width=240 height=240></a></td>\n";
+ out << "<td><a href=\"/" << img << "\"><img src=\"/" << generateThumbnail(img) << "\" width=240 height=240></a></td>\n";
out << "<td><p><a href=\"/cgi-bin/server.cgi?cmd=updateSingleBaseline&oldBaseline=" << baseline
<< "&newBaseline=" << rendered << "&url=" << pageUrl << "\">Replace baseline with rendered</a></p>"
@@ -193,6 +191,22 @@ QString HTMLPage::generateCompared(const QString &baseline, const QString &rende
}
+QString HTMLPage::generateThumbnail(const QString &image)
+{
+ QString res = image;
+ QFileInfo imgFI(root+image);
+ res.chop(imgFI.suffix().length() + 1);
+ res += QLS("_thumbnail.jpg");
+ QFileInfo resFI(root+res);
+ if (resFI.exists() && resFI.lastModified() > imgFI.lastModified())
+ return res;
+ QStringList args;
+ args << root+image << QLS("-resize") << QLS("240x240") << QLS("-quality") << QLS("50") << root+res;
+ QProcess::execute(QLS("convert"), args);
+ return res;
+}
+
+
void HTMLPage::handleCGIQuery(const QString &query)
{
QUrl cgiUrl(QLS("http://dummy/cgi-bin/dummy.cgi?") + query);
@@ -207,11 +221,8 @@ void HTMLPage::handleCGIQuery(const QString &query)
if (command == QLS("updateSingleBaseline")) {
s << BaselineHandler::updateSingleBaseline(cgiUrl.queryItemValue(QLS("oldBaseline")),
cgiUrl.queryItemValue(QLS("newBaseline")));
- } else if (command == QLS("updateAllBaselines")) {
- s << BaselineHandler::updateAllBaselines(cgiUrl.queryItemValue(QLS("host")),
- cgiUrl.queryItemValue(QLS("id")),
- cgiUrl.queryItemValue(QLS("engine")),
- cgiUrl.queryItemValue(QLS("format")));
+ } else if (command == QLS("clearAllBaselines")) {
+ s << BaselineHandler::clearAllBaselines(cgiUrl.queryItemValue(QLS("context")));
} else if (command == QLS("blacklist")) {
// blacklist a test
s << BaselineHandler::blacklistTest(cgiUrl.queryItemValue(QLS("context")),
diff --git a/tests/arthur/baselineserver/src/htmlpage.h b/tests/arthur/baselineserver/src/htmlpage.h
index fa4d1ed..5f1e051 100644
--- a/tests/arthur/baselineserver/src/htmlpage.h
+++ b/tests/arthur/baselineserver/src/htmlpage.h
@@ -62,9 +62,11 @@ private:
void writeHeader(const ImageItem &item);
void writeFooter();
QString generateCompared(const QString &baseline, const QString &rendered, bool fuzzy = false);
+ QString generateThumbnail(const QString &image);
QString root;
QString path;
+ QString reportDir;
QFile file;
QTextStream out;
QString id;
diff --git a/tests/arthur/common/baselineprotocol.cpp b/tests/arthur/common/baselineprotocol.cpp
index 6d26e9a..5ed58b4 100644
--- a/tests/arthur/common/baselineprotocol.cpp
+++ b/tests/arthur/common/baselineprotocol.cpp
@@ -206,10 +206,52 @@ QString ImageItem::formatAsString() const
return QLS(formatNames[renderFormat]);
}
+void ImageItem::writeImageToStream(QDataStream &out) const
+{
+ if (image.isNull() || image.format() == QImage::Format_Invalid) {
+ out << quint8(0);
+ return;
+ }
+ out << quint8('Q') << quint8(image.format());
+ out << quint8(QSysInfo::ByteOrder) << quint8(0); // pad to multiple of 4 bytes
+ out << quint32(image.width()) << quint32(image.height()) << quint32(image.bytesPerLine());
+ out << qCompress((const uchar *)image.constBits(), image.byteCount());
+ //# can be followed by colormap for formats that use it
+}
+
+void ImageItem::readImageFromStream(QDataStream &in)
+{
+ quint8 hdr, fmt, endian, pad;
+ quint32 width, height, bpl;
+ QByteArray data;
+
+ in >> hdr;
+ if (hdr != 'Q') {
+ image = QImage();
+ return;
+ }
+ in >> fmt >> endian >> pad;
+ if (!fmt || fmt >= QImage::NImageFormats) {
+ image = QImage();
+ return;
+ }
+ if (endian != QSysInfo::ByteOrder) {
+ qWarning("ImageItem cannot read streamed image with different endianness");
+ image = QImage();
+ return;
+ }
+ in >> width >> height >> bpl;
+ in >> data;
+ data = qUncompress(data);
+ QImage res((const uchar *)data.constData(), width, height, bpl, QImage::Format(fmt));
+ image = res.copy(); //# yuck, seems there is currently no way to avoid data copy
+}
+
QDataStream & operator<< (QDataStream &stream, const ImageItem &ii)
{
stream << ii.scriptName << ii.scriptChecksum << quint8(ii.status) << quint8(ii.renderFormat)
- << quint8(ii.engine) << ii.image << ii.imageChecksums;
+ << quint8(ii.engine) << ii.imageChecksums;
+ ii.writeImageToStream(stream);
return stream;
}
@@ -217,10 +259,11 @@ QDataStream & operator>> (QDataStream &stream, ImageItem &ii)
{
quint8 encFormat, encStatus, encEngine;
stream >> ii.scriptName >> ii.scriptChecksum >> encStatus >> encFormat
- >> encEngine >> ii.image >> ii.imageChecksums;
+ >> encEngine >> ii.imageChecksums;
ii.renderFormat = QImage::Format(encFormat);
ii.status = ImageItem::ItemStatus(encStatus);
ii.engine = ImageItem::GraphicsEngine(encEngine);
+ ii.readImageFromStream(stream);
return stream;
}
diff --git a/tests/arthur/common/baselineprotocol.h b/tests/arthur/common/baselineprotocol.h
index 9f59454..baffb4a 100644
--- a/tests/arthur/common/baselineprotocol.h
+++ b/tests/arthur/common/baselineprotocol.h
@@ -84,6 +84,9 @@ public:
QString engineAsString() const;
QString formatAsString() const;
+ void writeImageToStream(QDataStream &stream) const;
+ void readImageFromStream(QDataStream &stream);
+
enum ItemStatus {
Ok = 0,
BaselineNotFound = 1,
@@ -105,7 +108,7 @@ public:
quint16 scriptChecksum;
};
QDataStream & operator<< (QDataStream &stream, const ImageItem &ii);
-QDataStream & operator>> (QDataStream& stream, ImageItem& ii);
+QDataStream & operator>> (QDataStream &stream, ImageItem& ii);
Q_DECLARE_METATYPE(ImageItem);
@@ -121,7 +124,7 @@ public:
// Important constants here
// ****************************************************
enum Constant {
- ProtocolVersion = 2,
+ ProtocolVersion = 3,
ServerPort = 54129,
Timeout = 5000
};