summaryrefslogtreecommitdiffstats
path: root/tests/arthur
diff options
context:
space:
mode:
authorTrond Kjernåsen <trond.kjernasen@nokia.com>2010-09-30 15:11:09 (GMT)
committerTrond Kjernåsen <trond.kjernasen@nokia.com>2010-09-30 15:11:09 (GMT)
commit72b1a614748add429f301ea156760fafc01a5128 (patch)
tree65f167d610d73c7670e25ce957631dcaee64f249 /tests/arthur
parente1bdeb521fa1c53a8039fec77fad80994b394413 (diff)
downloadQt-72b1a614748add429f301ea156760fafc01a5128.zip
Qt-72b1a614748add429f301ea156760fafc01a5128.tar.gz
Qt-72b1a614748add429f301ea156760fafc01a5128.tar.bz2
Added support for updating the baselines via the generated HTML reports.
The baselineserver can now run as a CGI binary if it detects that the QUERY_STRING variable is set. Currently it only handles commands for updating the baselines for failed tests. For this to work properly the baselineserver binary needs to have the setuid bit set, so that when it's run as a CGI binary, it will have the proper rights to move files around. The server currently assumes the CGI binary is a link to the baselineserver executable named 'server.cgi' in the configured 'cgi-bin' directory.
Diffstat (limited to 'tests/arthur')
-rw-r--r--tests/arthur/baselineserver/src/baselineserver.cpp70
-rw-r--r--tests/arthur/baselineserver/src/baselineserver.h5
-rw-r--r--tests/arthur/baselineserver/src/htmlpage.cpp36
-rw-r--r--tests/arthur/baselineserver/src/htmlpage.h3
-rw-r--r--tests/arthur/baselineserver/src/main.cpp8
5 files changed, 117 insertions, 5 deletions
diff --git a/tests/arthur/baselineserver/src/baselineserver.cpp b/tests/arthur/baselineserver/src/baselineserver.cpp
index c25bfc4..41e48eb 100644
--- a/tests/arthur/baselineserver/src/baselineserver.cpp
+++ b/tests/arthur/baselineserver/src/baselineserver.cpp
@@ -6,6 +6,7 @@
#include <QFileInfo>
#include <QHostInfo>
#include <QTextStream>
+#include <QProcess>
QString BaselineServer::storage;
@@ -29,6 +30,13 @@ QString BaselineServer::storagePath()
return storage;
}
+QString BaselineServer::baseUrl()
+{
+ return QLS("http://")
+ + QHostInfo::localHostName().toLatin1() + '.'
+ + QHostInfo::localDomainName().toLatin1() + '/';
+}
+
void BaselineServer::incomingConnection(int socketDescriptor)
{
qDebug() << "Server: New connection!";
@@ -190,9 +198,7 @@ void BaselineHandler::storeImage(const QByteArray &itemBlock, bool isBaseline)
QByteArray msg(isBaseline ? "New baseline image stored: " :
"Mismatch report: " );
- msg += "http://"
- + QHostInfo::localHostName().toLatin1() + '.'
- + QHostInfo::localDomainName().toLatin1() + '/';
+ msg += BaselineServer::baseUrl();
if (isBaseline)
msg += pathForItem(item, true, false).toLatin1() + FileFormat;
else
@@ -243,6 +249,64 @@ 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 basePath(BaselineServer::storagePath());
+ QString srcDir(basePath + host + QLC('/')
+ + QString(QLS("mismatches_%1_%2/")).arg(engine, format)
+ + id);
+ QString dstDir(basePath + host + QLC('/')
+ + QString(QLS("baselines_%1_%2/")).arg(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);
+ while (it.hasNext()) {
+ it.next();
+ if (it.value().endsWith(QLS("compared.png")))
+ it.remove();
+ }
+
+ 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;
+}
+
+QString BaselineHandler::updateSingleBaseline(const QString &oldBaseline, const QString &newBaseline)
+{
+ QString res;
+ QString basePath(BaselineServer::storagePath());
+ QString srcBase(basePath + newBaseline.left(newBaseline.length() - 3));
+ QString dstDir(basePath + oldBaseline.left(oldBaseline.lastIndexOf(QLC('/'))));
+
+ QProcess proc;
+ proc.setProcessChannelMode(QProcess::MergedChannels);
+ proc.start(QLS("cp"), QStringList() << QLS("-f") << srcBase + QLS("png") << srcBase + QLS("metadata") << dstDir);
+ proc.waitForFinished();
+ if (proc.exitCode() == 0)
+ res = QString("Successfully updated '%1'").arg(oldBaseline + QLS("/metadata"));
+ else
+ res = QString("Error updating baseline: %1<br>"
+ "Command output: <pre>%2</pre>").arg(proc.errorString(), proc.readAll().constData());
+
+ return res;
+}
+
void BaselineHandler::testPathMapping()
{
qDebug() << "Storage prefix:" << BaselineServer::storagePath();
diff --git a/tests/arthur/baselineserver/src/baselineserver.h b/tests/arthur/baselineserver/src/baselineserver.h
index 8d791e0..b77bc09 100644
--- a/tests/arthur/baselineserver/src/baselineserver.h
+++ b/tests/arthur/baselineserver/src/baselineserver.h
@@ -23,6 +23,7 @@ public:
BaselineServer(QObject *parent = 0);
static QString storagePath();
+ static QString baseUrl();
protected:
void incomingConnection(int socketDescriptor);
@@ -59,6 +60,10 @@ public:
BaselineHandler(int socketDescriptor = -1);
void testPathMapping();
+ static QString updateAllBaselines(const QString &host, const QString &id,
+ const QString &engine, const QString &format);
+ static QString updateSingleBaseline(const QString &oldBaseline, const QString &newBaseline);
+
private slots:
void receiveRequest();
void receiveDisconnect();
diff --git a/tests/arthur/baselineserver/src/htmlpage.cpp b/tests/arthur/baselineserver/src/htmlpage.cpp
index 3ff138f..4f53c67 100644
--- a/tests/arthur/baselineserver/src/htmlpage.cpp
+++ b/tests/arthur/baselineserver/src/htmlpage.cpp
@@ -1,7 +1,9 @@
#include "htmlpage.h"
#include "baselineprotocol.h"
+#include "baselineserver.h"
#include <QDir>
#include <QProcess>
+#include <QUrl>
HTMLPage::HTMLPage()
: headerWritten(false)
@@ -36,6 +38,9 @@ void HTMLPage::writeHeader(const ImageItem &item)
{
path = QLS("reports/") + id + QLC('_') + item.engineAsString()
+ QLC('_') + item.formatAsString() + QLS(".html");
+
+ QString pageUrl = BaselineServer::baseUrl() + path;
+
file.setFileName(root + path);
if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
qWarning() << "Failed to open report file" << file.fileName();
@@ -47,6 +52,10 @@ void HTMLPage::writeHeader(const ImageItem &item)
out << "<h3>Build key: " << plat.buildKey << "</h3>\n";
out << "<h3>Engine: " << item.engineAsString() << "</h3>\n";
out << "<h3>Format: " << item.formatAsString() << "</h3>\n\n";
+ out << "<h3><a href=\"/cgi-bin/server.cgi?update=all&id="<< id << "&host=" << plat.hostname
+ << "&engine=" << item.engineAsString() << "&format=" << item.formatAsString()
+ << "&url=" << pageUrl
+ << "\">Update all baselines</a></h3>\n\n";
out << "<table border=\"2\">\n"
"<tr>\n"
"<td><b>Script</b></td>\n"
@@ -55,6 +64,7 @@ void HTMLPage::writeHeader(const ImageItem &item)
"<td><b>Comparison</b></td>\n"
"<td><b>Fuzzy Comparison</b></td>\n"
"<td><b>Score</b></td>\n"
+ "<td><b>Update</b></td>\n"
"</b></tr>\n\n";
}
@@ -73,12 +83,15 @@ void HTMLPage::addItem(const QString &baseline, const QString &rendered, const I
}
QString compared = generateCompared(baseline, rendered);
QString fuzzy = generateCompared(baseline, rendered, true);
+ QString pageUrl = BaselineServer::baseUrl() + path;
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 << "<td></td><td><a href=\"/cgi-bin/server.cgi?update=single&oldBaseline=" << baseline
+ << "&newBaseline=" << rendered << "&url=" << pageUrl << "\">Update baseline</a></td>\n";
out << "<tr>\n\n";
}
@@ -108,3 +121,26 @@ QString HTMLPage::generateCompared(const QString &baseline, const QString &rende
QProcess::execute(QLS("compare"), args);
return res;
}
+
+
+void HTMLPage::handleCGIQuery(const QString &query)
+{
+ QUrl cgiUrl(QLS("http://dummy/cgi-bin/dummy.cgi?") + query);
+ QTextStream s(stdout);
+ s << "Content-Type: text/html\r\n\r\n"
+ << "<HTML>";
+// << "Contents of QUERY_STRING:<br>"
+// << "Full string = " << query << "<br>";
+
+ if (cgiUrl.queryItemValue(QLS("update")) == QLS("single")) {
+ s << BaselineHandler::updateSingleBaseline(cgiUrl.queryItemValue(QLS("oldBaseline")),
+ cgiUrl.queryItemValue(QLS("newBaseline")));
+ } else {
+ s << BaselineHandler::updateAllBaselines(cgiUrl.queryItemValue(QLS("host")),
+ cgiUrl.queryItemValue(QLS("id")),
+ cgiUrl.queryItemValue(QLS("engine")),
+ cgiUrl.queryItemValue(QLS("format")));
+ }
+ s << "<p><a href=\"" << cgiUrl.queryItemValue(QLS("url")) << "\">Back to report</a>";
+ s << "</HTML>";
+}
diff --git a/tests/arthur/baselineserver/src/htmlpage.h b/tests/arthur/baselineserver/src/htmlpage.h
index af0e364..29b4ff5 100644
--- a/tests/arthur/baselineserver/src/htmlpage.h
+++ b/tests/arthur/baselineserver/src/htmlpage.h
@@ -14,9 +14,10 @@ public:
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();
+ static void handleCGIQuery(const QString &query);
+
private:
void writeHeader(const ImageItem &item);
void writeFooter();
diff --git a/tests/arthur/baselineserver/src/main.cpp b/tests/arthur/baselineserver/src/main.cpp
index a69a5a2..0e15a60 100644
--- a/tests/arthur/baselineserver/src/main.cpp
+++ b/tests/arthur/baselineserver/src/main.cpp
@@ -1,11 +1,17 @@
#include <QtCore/QCoreApplication>
#include "baselineserver.h"
-
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
+ QString queryString(qgetenv("QUERY_STRING"));
+ if (!queryString.isEmpty()) {
+ // run as CGI script
+ HTMLPage::handleCGIQuery(queryString);
+ return 0;
+ }
+
if (a.arguments().contains(QLatin1String("-testmapping"))) {
BaselineHandler h;
h.testPathMapping();