summaryrefslogtreecommitdiffstats
path: root/tests/arthur
diff options
context:
space:
mode:
authoraavit <qt-info@nokia.com>2010-09-16 13:33:57 (GMT)
committeraavit <qt-info@nokia.com>2010-09-16 13:33:57 (GMT)
commit43a3763e392f05e758085c6b06a5001d9b51aafb (patch)
tree8fa2a8f489fefd3c5ac6393aff20dd9610aaa4ed /tests/arthur
parent1ac37675969d31fb508d9f46f2e39b0e2b68dc20 (diff)
downloadQt-43a3763e392f05e758085c6b06a5001d9b51aafb.zip
Qt-43a3763e392f05e758085c6b06a5001d9b51aafb.tar.gz
Qt-43a3763e392f05e758085c6b06a5001d9b51aafb.tar.bz2
Server generation of HTML mismatch reports added
Diffstat (limited to 'tests/arthur')
-rw-r--r--tests/arthur/baselineserver/src/baselineserver.cpp33
-rw-r--r--tests/arthur/baselineserver/src/baselineserver.h7
-rw-r--r--tests/arthur/baselineserver/src/baselineserver.pro6
-rw-r--r--tests/arthur/baselineserver/src/htmlpage.cpp110
-rw-r--r--tests/arthur/baselineserver/src/htmlpage.h34
-rw-r--r--tests/arthur/common/baselineprotocol.h3
6 files changed, 178 insertions, 15 deletions
diff --git a/tests/arthur/baselineserver/src/baselineserver.cpp b/tests/arthur/baselineserver/src/baselineserver.cpp
index d58313f..c25bfc4 100644
--- a/tests/arthur/baselineserver/src/baselineserver.cpp
+++ b/tests/arthur/baselineserver/src/baselineserver.cpp
@@ -7,9 +7,6 @@
#include <QHostInfo>
#include <QTextStream>
-#define QLS QLatin1String
-#define QLC QLatin1Char
-
QString BaselineServer::storage;
BaselineServer::BaselineServer(QObject *parent)
@@ -160,6 +157,7 @@ void BaselineHandler::provideBaselineChecksums(const QByteArray &itemListBlock)
QDataStream ods(&block, QIODevice::WriteOnly);
ods << itemList;
proto.sendBlock(BaselineProtocol::Ack, block);
+ report.start(BaselineServer::storagePath(), runId, plat);
}
@@ -172,7 +170,7 @@ void BaselineHandler::storeImage(const QByteArray &itemBlock, bool isBaseline)
QString prefix = pathForItem(item, isBaseline);
qDebug() << runId << logtime() << "Received" << (isBaseline ? "baseline" : "mismatched") << "image for:" << item.scriptName << "Storing in" << prefix;
- QString dir = prefix.section(QDir::separator(), 0, -2);
+ QString dir = prefix.section(QLC('/'), 0, -2);
QDir cwd;
if (!cwd.exists(dir))
cwd.mkpath(dir);
@@ -185,11 +183,21 @@ void BaselineHandler::storeImage(const QByteArray &itemBlock, bool isBaseline)
checkSums << item.imageChecksums;
file.close();
- QByteArray msg(isBaseline ? "Baseline" : "Mismatching" );
- msg += " image stored in "
- + QHostInfo::localHostName().toLatin1() + '.'
- + QHostInfo::localDomainName().toLatin1() + ':'
- + prefix.toLatin1() + FileFormat;
+ if (!isBaseline)
+ report.addItem(pathForItem(item, true, false) + QLS(FileFormat),
+ pathForItem(item, false, false) + QLS(FileFormat),
+ item);
+
+ QByteArray msg(isBaseline ? "New baseline image stored: " :
+ "Mismatch report: " );
+ msg += "http://"
+ + QHostInfo::localHostName().toLatin1() + '.'
+ + QHostInfo::localDomainName().toLatin1() + '/';
+ if (isBaseline)
+ msg += pathForItem(item, true, false).toLatin1() + FileFormat;
+ else
+ msg += report.filePath();
+
proto.sendBlock(BaselineProtocol::Ack, msg);
}
@@ -197,11 +205,12 @@ void BaselineHandler::storeImage(const QByteArray &itemBlock, bool isBaseline)
void BaselineHandler::receiveDisconnect()
{
qDebug() << runId << logtime() << "Client disconnected.";
+ report.end();
QThread::currentThread()->exit(0);
}
-QString BaselineHandler::pathForItem(const ImageItem &item, bool isBaseline)
+QString BaselineHandler::pathForItem(const ImageItem &item, bool isBaseline, bool absolute)
{
if (pathForRun.isNull()) {
QString host = plat.hostname.section(QLC('.'), 0, 0); // Filter away domain, if any
@@ -213,7 +222,7 @@ QString BaselineHandler::pathForItem(const ImageItem &item, bool isBaseline)
host.replace(QRegExp(QLS("^(bq|oslo?)-(.*)$")), QLS("\\2"));
host.replace(QRegExp(QLS("^(.*)-\\d+$")), QLS("vm-\\1"));
}
- pathForRun = BaselineServer::storagePath() + host + QLC('/');
+ pathForRun = host + QLC('/');
}
QString storePath = pathForRun;
@@ -228,6 +237,8 @@ QString BaselineHandler::pathForItem(const ImageItem &item, bool isBaseline)
itemName.append(QLC('_'));
itemName.append(QString::number(item.scriptChecksum, 16).rightJustified(4, QLC('0')));
+ if (absolute)
+ storePath.prepend(BaselineServer::storagePath());
return storePath + itemName + QLC('.');
}
diff --git a/tests/arthur/baselineserver/src/baselineserver.h b/tests/arthur/baselineserver/src/baselineserver.h
index a4b46f6..8d791e0 100644
--- a/tests/arthur/baselineserver/src/baselineserver.h
+++ b/tests/arthur/baselineserver/src/baselineserver.h
@@ -5,11 +5,13 @@
#include <QTcpServer>
#include <QThread>
#include <QTcpSocket>
-#include "baselineprotocol.h"
#include <QScopedPointer>
#include <QTimer>
#include <QDateTime>
+#include "baselineprotocol.h"
+#include "htmlpage.h"
+
// #seconds between update checks
#define HEARTBEAT 5
@@ -64,7 +66,7 @@ private slots:
private:
void provideBaselineChecksums(const QByteArray &itemListBlock);
void storeImage(const QByteArray &itemBlock, bool isBaseline);
- QString pathForItem(const ImageItem &item, bool isBaseline = true);
+ QString pathForItem(const ImageItem &item, bool isBaseline = true, bool absolute = true);
QString logtime();
QString computeMismatchScore(const QImage& baseline, const QImage& rendered);
QString engineForItem(const ImageItem &item);
@@ -74,6 +76,7 @@ private:
bool connectionEstablished;
QString runId;
QString pathForRun;
+ HTMLPage report;
};
#endif // BASELINESERVER_H
diff --git a/tests/arthur/baselineserver/src/baselineserver.pro b/tests/arthur/baselineserver/src/baselineserver.pro
index 2065d4a..a7be03d 100644
--- a/tests/arthur/baselineserver/src/baselineserver.pro
+++ b/tests/arthur/baselineserver/src/baselineserver.pro
@@ -19,7 +19,9 @@ TEMPLATE = app
include(../../common/baselineprotocol.pri)
SOURCES += main.cpp \
- baselineserver.cpp
+ baselineserver.cpp \
+ htmlpage.cpp
HEADERS += \
- baselineserver.h
+ baselineserver.h \
+ htmlpage.h
diff --git a/tests/arthur/baselineserver/src/htmlpage.cpp b/tests/arthur/baselineserver/src/htmlpage.cpp
new file mode 100644
index 0000000..3ff138f
--- /dev/null
+++ b/tests/arthur/baselineserver/src/htmlpage.cpp
@@ -0,0 +1,110 @@
+#include "htmlpage.h"
+#include "baselineprotocol.h"
+#include <QDir>
+#include <QProcess>
+
+HTMLPage::HTMLPage()
+ : headerWritten(false)
+{
+}
+
+HTMLPage::~HTMLPage()
+{
+ end();
+}
+
+QString HTMLPage::filePath()
+{
+ return path;
+}
+
+void HTMLPage::start(const QString &storagepath, const QString &runId, const PlatformInfo pinfo)
+{
+ end();
+
+ id = runId;
+ plat = pinfo;
+ root = storagepath;
+ QString dir = root + QLS("reports/");
+ QDir cwd;
+ if (!cwd.exists(dir))
+ cwd.mkpath(dir);
+}
+
+
+void HTMLPage::writeHeader(const ImageItem &item)
+{
+ path = QLS("reports/") + id + QLC('_') + item.engineAsString()
+ + QLC('_') + item.formatAsString() + QLS(".html");
+ file.setFileName(root + path);
+ if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
+ qWarning() << "Failed to open report file" << file.fileName();
+ out.setDevice(&file);
+
+ out << "<html><body><h1>Lancelot results from run " << id << "</h1>\n\n";
+ out << "<h3>Host: " << plat.hostname << "</h3>\n";
+ out << "<h3>Qt version: " << plat.qtVersion << "</h3>\n";
+ out << "<h3>Build key: " << plat.buildKey << "</h3>\n";
+ out << "<h3>Engine: " << item.engineAsString() << "</h3>\n";
+ out << "<h3>Format: " << item.formatAsString() << "</h3>\n\n";
+ out << "<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>Fuzzy Comparison</b></td>\n"
+ "<td><b>Score</b></td>\n"
+ "</b></tr>\n\n";
+}
+
+
+void HTMLPage::writeFooter()
+{
+ out << "</table>\n</body></html>\n";
+}
+
+
+void HTMLPage::addItem(const QString &baseline, const QString &rendered, const ImageItem &item)
+{
+ if (!headerWritten) {
+ writeHeader(item);
+ headerWritten = true;
+ }
+ QString compared = generateCompared(baseline, rendered);
+ QString fuzzy = generateCompared(baseline, rendered, true);
+
+ out << "<tr>\n";
+ out << "<td>" << item.scriptName << "</td>\n";
+ QStringList images = QStringList() << baseline << rendered << compared << fuzzy;
+ foreach(const QString& img, images)
+ out << "<td><a href=\"/" << img << "\"><img src=\"/" << img << "\" width=240 height=240></a></td>\n";
+ out << "<tr>\n\n";
+}
+
+
+void HTMLPage::end()
+{
+ if (file.isOpen()) {
+ writeFooter();
+ out.flush();
+ file.close();
+ path.clear();
+ headerWritten = false;
+ }
+}
+
+
+QString HTMLPage::generateCompared(const QString &baseline, const QString &rendered, bool fuzzy)
+{
+ QString res = rendered;
+ QFileInfo fi(res);
+ res.chop(fi.suffix().length() + 1);
+ res += QLS(fuzzy ? "_fuzzycompared.png" : "_compared.png");
+ QStringList args;
+ if (fuzzy)
+ args << QLS("-fuzz") << QLS("5%");
+ args << root+baseline << root+rendered << root+res;
+ QProcess::execute(QLS("compare"), args);
+ return res;
+}
diff --git a/tests/arthur/baselineserver/src/htmlpage.h b/tests/arthur/baselineserver/src/htmlpage.h
new file mode 100644
index 0000000..af0e364
--- /dev/null
+++ b/tests/arthur/baselineserver/src/htmlpage.h
@@ -0,0 +1,34 @@
+#ifndef HTMLPAGE_H
+#define HTMLPAGE_H
+
+#include "baselineprotocol.h"
+#include <QFile>
+#include <QTextStream>
+
+class HTMLPage
+{
+public:
+ HTMLPage();
+ ~HTMLPage();
+
+ void start(const QString &storagePath, const QString &runId, const PlatformInfo pinfo);
+ void addItem(const QString &baseline, const QString &rendered, const ImageItem &item);
+ void end();
+
+ QString filePath();
+
+private:
+ void writeHeader(const ImageItem &item);
+ void writeFooter();
+ QString generateCompared(const QString &baseline, const QString &rendered, bool fuzzy = false);
+
+ QString root;
+ QString path;
+ QFile file;
+ QTextStream out;
+ QString id;
+ PlatformInfo plat;
+ bool headerWritten;
+};
+
+#endif // HTMLPAGE_H
diff --git a/tests/arthur/common/baselineprotocol.h b/tests/arthur/common/baselineprotocol.h
index 062a99c..6af4f22 100644
--- a/tests/arthur/common/baselineprotocol.h
+++ b/tests/arthur/common/baselineprotocol.h
@@ -6,6 +6,9 @@
#include <QImage>
#include <QVector>
+#define QLS QLatin1String
+#define QLC QLatin1Char
+
#define FileFormat "png"
struct PlatformInfo