diff options
author | Trond Kjernåsen <trond.kjernasen@nokia.com> | 2010-09-30 15:11:09 (GMT) |
---|---|---|
committer | Trond Kjernåsen <trond.kjernasen@nokia.com> | 2010-09-30 15:11:09 (GMT) |
commit | 72b1a614748add429f301ea156760fafc01a5128 (patch) | |
tree | 65f167d610d73c7670e25ce957631dcaee64f249 /tests/arthur | |
parent | e1bdeb521fa1c53a8039fec77fad80994b394413 (diff) | |
download | Qt-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.cpp | 70 | ||||
-rw-r--r-- | tests/arthur/baselineserver/src/baselineserver.h | 5 | ||||
-rw-r--r-- | tests/arthur/baselineserver/src/htmlpage.cpp | 36 | ||||
-rw-r--r-- | tests/arthur/baselineserver/src/htmlpage.h | 3 | ||||
-rw-r--r-- | tests/arthur/baselineserver/src/main.cpp | 8 |
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(); |