summaryrefslogtreecommitdiffstats
path: root/tests/arthur
diff options
context:
space:
mode:
authorShane Kearns <shane.kearns@accenture.com>2011-02-07 17:20:33 (GMT)
committerShane Kearns <shane.kearns@accenture.com>2011-02-07 17:20:33 (GMT)
commit59a9938f91070ad3699fc6544848f0955ecf0bdd (patch)
tree99ad7312ddddf7233290115c7ea5daa3af0b83ec /tests/arthur
parentb9307547c717606e08661cf474eeaf81cc0789e6 (diff)
parent44298c848ac254fe1942eb32eed7651dec5bf0e3 (diff)
downloadQt-59a9938f91070ad3699fc6544848f0955ecf0bdd.zip
Qt-59a9938f91070ad3699fc6544848f0955ecf0bdd.tar.gz
Qt-59a9938f91070ad3699fc6544848f0955ecf0bdd.tar.bz2
Merge remote branch 'qt/master' into symbian-socket-engine
Conflicts: src/network/access/qnetworkaccessmanager.cpp src/network/bearer/qnetworksession.cpp src/network/kernel/qnetworkproxy_symbian.cpp src/network/socket/qnativesocketengine_unix.cpp tests/auto/platformsocketengine/tst_platformsocketengine.cpp
Diffstat (limited to 'tests/arthur')
-rw-r--r--tests/arthur/baselineserver/src/baselineserver.cpp249
-rw-r--r--tests/arthur/baselineserver/src/baselineserver.h26
-rw-r--r--tests/arthur/baselineserver/src/baselineserver.pro7
-rw-r--r--tests/arthur/baselineserver/src/baselineserver.qrc5
-rw-r--r--tests/arthur/baselineserver/src/htmlpage.cpp239
-rw-r--r--tests/arthur/baselineserver/src/main.cpp4
-rw-r--r--tests/arthur/baselineserver/src/report.cpp300
-rw-r--r--tests/arthur/baselineserver/src/report.h (renamed from tests/arthur/baselineserver/src/htmlpage.h)45
-rw-r--r--tests/arthur/baselineserver/src/templates/view.html79
-rw-r--r--tests/arthur/common/baselineprotocol.cpp33
-rw-r--r--tests/arthur/common/baselineprotocol.h43
-rw-r--r--tests/arthur/common/baselineprotocol.pri1
-rw-r--r--tests/arthur/common/framework.cpp2
-rw-r--r--tests/arthur/common/framework.h2
-rw-r--r--tests/arthur/common/paintcommands.cpp2
-rw-r--r--tests/arthur/common/paintcommands.h2
-rw-r--r--tests/arthur/common/qbaselinetest.cpp193
-rw-r--r--tests/arthur/common/qbaselinetest.h77
-rw-r--r--tests/arthur/common/qbaselinetest.pri13
-rw-r--r--tests/arthur/common/qengines.cpp2
-rw-r--r--tests/arthur/common/qengines.h2
-rw-r--r--tests/arthur/common/xmldata.cpp2
-rw-r--r--tests/arthur/common/xmldata.h2
-rw-r--r--tests/arthur/datagenerator/datagenerator.cpp2
-rw-r--r--tests/arthur/datagenerator/datagenerator.h2
-rw-r--r--tests/arthur/datagenerator/main.cpp2
-rw-r--r--tests/arthur/datagenerator/xmlgenerator.cpp2
-rw-r--r--tests/arthur/datagenerator/xmlgenerator.h2
-rw-r--r--tests/arthur/htmlgenerator/htmlgenerator.cpp2
-rw-r--r--tests/arthur/htmlgenerator/htmlgenerator.h2
-rw-r--r--tests/arthur/htmlgenerator/main.cpp2
-rw-r--r--tests/arthur/lance/interactivewidget.cpp2
-rw-r--r--tests/arthur/lance/interactivewidget.h2
-rw-r--r--tests/arthur/lance/main.cpp2
-rw-r--r--tests/arthur/lance/widgets.h2
-rw-r--r--tests/arthur/performancediff/main.cpp2
-rw-r--r--tests/arthur/performancediff/performancediff.cpp2
-rw-r--r--tests/arthur/performancediff/performancediff.h2
-rw-r--r--tests/arthur/shower/main.cpp2
-rw-r--r--tests/arthur/shower/shower.cpp2
-rw-r--r--tests/arthur/shower/shower.h2
41 files changed, 944 insertions, 422 deletions
diff --git a/tests/arthur/baselineserver/src/baselineserver.cpp b/tests/arthur/baselineserver/src/baselineserver.cpp
index 0399224..8aaa8ff 100644
--- a/tests/arthur/baselineserver/src/baselineserver.cpp
+++ b/tests/arthur/baselineserver/src/baselineserver.cpp
@@ -53,11 +53,16 @@
#include <QProcess>
#include <QDirIterator>
-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"));
+QString BaselineServer::storage;
+QString BaselineServer::url;
BaselineServer::BaselineServer(QObject *parent)
- : QTcpServer(parent)
+ : QTcpServer(parent), lastRunIdIdx(0)
{
QFileInfo me(QCoreApplication::applicationFilePath());
meLastMod = me.lastModified();
@@ -71,22 +76,32 @@ QString BaselineServer::storagePath()
if (storage.isEmpty()) {
storage = QLS(qgetenv("QT_LANCELOT_DIR"));
if (storage.isEmpty())
- storage = QLS("/var/www");
+ storage = QLS("/var/www");
}
return storage;
}
QString BaselineServer::baseUrl()
{
- return QLS("http://")
- + QHostInfo::localHostName().toLatin1() + '.'
- + QHostInfo::localDomainName().toLatin1() + '/';
+ if (url.isEmpty()) {
+ url = QLS("http://")
+ + QHostInfo::localHostName().toLatin1() + '.'
+ + QHostInfo::localDomainName().toLatin1() + '/';
+ }
+ return url;
}
void BaselineServer::incomingConnection(int socketDescriptor)
{
- qDebug() << "Server: New connection!";
- BaselineThread *thread = new BaselineThread(socketDescriptor, this);
+ QString runId = QDateTime::currentDateTime().toString(QLS("MMMdd-hhmmss"));
+ if (runId == lastRunId) {
+ runId += QLC('-') + QString::number(++lastRunIdIdx);
+ } else {
+ lastRunId = runId;
+ lastRunIdIdx = 0;
+ }
+ qDebug() << "Server: New connection! RunId:" << runId;
+ BaselineThread *thread = new BaselineThread(runId, socketDescriptor, this);
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();
}
@@ -97,6 +112,8 @@ void BaselineServer::heartbeat()
QFileInfo me(QCoreApplication::applicationFilePath());
if (me.lastModified() == meLastMod)
return;
+ if (!me.exists() || !me.isExecutable())
+ 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
@@ -112,23 +129,21 @@ void BaselineServer::heartbeat()
QCoreApplication::exit();
}
-BaselineThread::BaselineThread(int socketDescriptor, QObject *parent)
- : QThread(parent), socketDescriptor(socketDescriptor)
+BaselineThread::BaselineThread(const QString &runId, int socketDescriptor, QObject *parent)
+ : QThread(parent), runId(runId), socketDescriptor(socketDescriptor)
{
}
void BaselineThread::run()
{
- BaselineHandler handler(socketDescriptor);
+ BaselineHandler handler(runId, socketDescriptor);
exec();
}
-BaselineHandler::BaselineHandler(int socketDescriptor)
- : QObject(), connectionEstablished(false)
+BaselineHandler::BaselineHandler(const QString &runId, int socketDescriptor)
+ : QObject(), runId(runId), connectionEstablished(false)
{
- runId = QDateTime::currentDateTime().toString(QLS("MMMdd-hhmmss"));
-
if (socketDescriptor == -1)
return;
@@ -143,36 +158,43 @@ const char *BaselineHandler::logtime()
//return QTime::currentTime().toString(QLS("mm:ss.zzz"));
}
-void BaselineHandler::receiveRequest()
+bool BaselineHandler::establishConnection()
{
- if (!connectionEstablished) {
- if (!proto.acceptConnection(&plat)) {
- qWarning() << runId << logtime() << "Accepting new connection from" << proto.socket.peerAddress().toString() << "failed." << proto.errorMessage();
- proto.socket.disconnectFromHost();
- return;
- }
- QString logMsg;
- foreach (QString key, plat.keys()) {
- if (key != PI_HostName && key != PI_HostAddress)
- logMsg += key + QLS(": '") + plat.value(key) + QLS("', ");
- }
- qDebug() << runId << logtime() << "Connection established with" << plat.value(PI_HostName)
- << "[" << qPrintable(plat.value(PI_HostAddress)) << "]" << logMsg;
+ if (!proto.acceptConnection(&plat)) {
+ qWarning() << runId << logtime() << "Accepting new connection from" << proto.socket.peerAddress().toString() << "failed." << proto.errorMessage();
+ proto.socket.disconnectFromHost();
+ return false;
+ }
+ QString logMsg;
+ foreach (QString key, plat.keys()) {
+ if (key != PI_HostName && key != PI_HostAddress)
+ logMsg += key + QLS(": '") + plat.value(key) + QLS("', ");
+ }
+ qDebug() << runId << logtime() << "Connection established with" << plat.value(PI_HostName)
+ << "[" << qPrintable(plat.value(PI_HostAddress)) << "]" << logMsg;
- // Filter on branch
- QString branch = plat.value(PI_PulseGitBranch);
- if (branch.isEmpty()) {
- // Not run by Pulse, i.e. ad hoc run: Ok.
- }
- else if (branch != QLS("master-integration") || !plat.value(PI_GitCommit).contains(QLS("Merge branch 'master' of scm.dev.nokia.troll.no:qt/oslo-staging-2 into master-integration"))) {
- qDebug() << runId << logtime() << "Did not pass branch/staging repo filter, disconnecting.";
- proto.sendBlock(BaselineProtocol::Abort, QByteArray("This branch/staging repo is not assigned to be tested."));
- proto.socket.disconnectFromHost();
- return;
- }
+ // Filter on branch
+ QString branch = plat.value(PI_PulseGitBranch);
+ if (branch.isEmpty()) {
+ // Not run by Pulse, i.e. ad hoc run: Ok.
+ }
+ else if (branch != QLS("master-integration") || !plat.value(PI_GitCommit).contains(QLS("Merge branch 'master' of scm.dev.nokia.troll.no:qt/oslo-staging-2 into master-integration"))) {
+ qDebug() << runId << logtime() << "Did not pass branch/staging repo filter, disconnecting.";
+ proto.sendBlock(BaselineProtocol::Abort, QByteArray("This branch/staging repo is not assigned to be tested."));
+ proto.socket.disconnectFromHost();
+ return false;
+ }
+
+ proto.sendBlock(BaselineProtocol::Ack, QByteArray());
- proto.sendBlock(BaselineProtocol::Ack, QByteArray());
- connectionEstablished = true;
+ report.init(this, runId, plat);
+ return true;
+}
+
+void BaselineHandler::receiveRequest()
+{
+ if (!connectionEstablished) {
+ connectionEstablished = establishConnection();
return;
}
@@ -206,21 +228,22 @@ void BaselineHandler::provideBaselineChecksums(const QByteArray &itemListBlock)
ImageItemList itemList;
QDataStream ds(itemListBlock);
ds >> itemList;
- qDebug() << runId << logtime() << "Received request for checksums for" << itemList.count() << "items, engine"
- << itemList.at(0).engineAsString() << "pixel format" << itemList.at(0).formatAsString();
+ qDebug() << runId << logtime() << "Received request for checksums for" << itemList.count()
+ << "items in test function" << itemList.at(0).testFunction;
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
@@ -230,10 +253,10 @@ void BaselineHandler::provideBaselineChecksums(const QByteArray &itemListBlock)
if (file.open(QIODevice::ReadOnly)) {
QTextStream in(&file);
do {
- QString scriptName = in.readLine();
- if (!scriptName.isNull()) {
+ QString itemName = in.readLine();
+ if (!itemName.isNull()) {
for (ImageItemList::iterator i = itemList.begin(); i != itemList.end(); ++i) {
- if (i->scriptName == scriptName)
+ if (i->itemName == itemName)
i->status = ImageItem::IgnoreItem;
}
}
@@ -245,7 +268,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, context, itemList);
+ report.addItems(itemList);
}
@@ -256,7 +279,14 @@ void BaselineHandler::storeImage(const QByteArray &itemBlock, bool isBaseline)
ds >> item;
QString prefix = pathForItem(item, isBaseline);
- qDebug() << runId << logtime() << "Received" << (isBaseline ? "baseline" : "mismatched") << "image for:" << item.scriptName << "Storing in" << prefix;
+ qDebug() << runId << logtime() << "Received" << (isBaseline ? "baseline" : "mismatched") << "image for:" << item.itemName << "Storing in" << prefix;
+
+ QString msg;
+ if (isBaseline)
+ msg = QLS("New baseline image stored: ") + pathForItem(item, true, true) + QLS(FileFormat);
+ else
+ msg = BaselineServer::baseUrl() + report.filePath();
+ proto.sendBlock(BaselineProtocol::Ack, msg.toLatin1());
QString dir = prefix.section(QLC('/'), 0, -2);
QDir cwd;
@@ -264,27 +294,48 @@ 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.addItem(pathForItem(item, true, false) + QLS(FileFormat),
- pathForItem(item, false, false) + QLS(FileFormat),
- item);
+ report.addMismatch(item);
+}
- QByteArray msg(isBaseline ? "New baseline image stored: " :
- "Mismatch report: " );
- msg += BaselineServer::baseUrl();
- if (isBaseline)
- msg += pathForItem(item, true, false).toLatin1() + FileFormat;
- else
- msg += report.filePath();
- proto.sendBlock(BaselineProtocol::Ack, msg);
+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;
}
@@ -296,7 +347,7 @@ void BaselineHandler::receiveDisconnect()
}
-void BaselineHandler::mapPlatformInfo()
+void BaselineHandler::mapPlatformInfo() const
{
mapped = plat;
@@ -305,9 +356,8 @@ void BaselineHandler::mapPlatformInfo()
if (host.isEmpty() || host == QLS("localhost")) {
host = plat.value(PI_HostAddress);
} else {
- //# Site specific, should be in a config file
- if (!host.startsWith(QLS("oldhcp"))) {
- // remove index postfix typical of vm hostnames
+ if (!plat.value(PI_PulseGitBranch).isEmpty()) {
+ // i.e. pulse run, so remove index postfix typical of vm hostnames
host.remove(QRegExp(QLS("\\d+$")));
if (host.endsWith(QLC('-')))
host.chop(1);
@@ -323,25 +373,26 @@ void BaselineHandler::mapPlatformInfo()
// Map Qt version
QString ver = plat.value(PI_QtVersion);
- mapped.insert(PI_QtVersion, ver.prepend(QLS("Qt-"))); //### TBD: remove patch version
+ mapped.insert(PI_QtVersion, ver.prepend(QLS("Qt-")));
}
-QString BaselineHandler::pathForItem(const ImageItem &item, bool isBaseline, bool absolute)
+QString BaselineHandler::pathForItem(const ImageItem &item, bool isBaseline, bool absolute) const
{
if (mapped.isEmpty())
mapPlatformInfo();
- QString itemName = item.scriptName;
- if (itemName.contains(QLC('.')))
- itemName.replace(itemName.lastIndexOf(QLC('.')), 1, QLC('_'));
+ QString itemName = item.itemName.simplified();
+ itemName.replace(QLC(' '), QLC('_'));
+ itemName.replace(QLC('.'), QLC('_'));
itemName.append(QLC('_'));
- itemName.append(QString::number(item.scriptChecksum, 16).rightJustified(4, QLC('0')));
+ itemName.append(QString::number(item.itemChecksum, 16).rightJustified(4, QLC('0')));
QStringList path;
if (absolute)
path += BaselineServer::storagePath();
+ path += mapped.value(PI_TestCase);
path += QLS(isBaseline ? "baselines" : "mismatches");
- path += item.engineAsString() + QLC('_') + item.formatAsString();
+ path += item.testFunction;
path += mapped.value(PI_QtVersion);
path += mapped.value(PI_QMakeSpec);
path += mapped.value(PI_HostName);
@@ -353,12 +404,20 @@ QString BaselineHandler::pathForItem(const ImageItem &item, bool isBaseline, boo
}
+QString BaselineHandler::view(const QString &baseline, const QString &rendered, const QString &compared)
+{
+ QFile f(":/templates/view.html");
+ f.open(QIODevice::ReadOnly);
+ return QString::fromLatin1(f.readAll()).arg('/'+baseline, '/'+rendered, '/'+compared);
+}
+
+
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()))
@@ -376,10 +435,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());
@@ -387,6 +446,7 @@ QString BaselineHandler::updateSingleBaseline(const QString &oldBaseline, const
return res;
}
+
QString BaselineHandler::blacklistTest(const QString &context, const QString &itemId, bool removeFromBlacklist)
{
QFile file(BaselineServer::storagePath() + QLC('/') + context + QLS("/BLACKLIST"));
@@ -426,18 +486,19 @@ void BaselineHandler::testPathMapping()
<< QLS("macbuilder-02.test.troll.no")
<< QLS("bqvm1164")
<< QLS("chimera")
- << QLS("localhost");
+ << QLS("localhost")
+ << QLS("");
ImageItem item;
- item.scriptName = QLS("arcs.qps");
- item.engine = ImageItem::Raster;
- item.renderFormat = QImage::Format_ARGB32_Premultiplied;
+ item.testFunction = QLS("testPathMapping");
+ item.itemName = QLS("arcs.qps");
item.imageChecksums << 0x0123456789abcdefULL;
- item.scriptChecksum = 0x0123;
+ item.itemChecksum = 0x0123;
plat.insert(PI_QtVersion, QLS("4.8.0"));
plat.insert(PI_BuildKey, QLS("(nobuildkey)"));
- plat.insert(PI_QMakeSpec, "linux-g++");
+ plat.insert(PI_QMakeSpec, QLS("linux-g++"));
+ plat.insert(PI_PulseGitBranch, QLS("somebranch"));
foreach(const QString& host, hosts) {
mapped.clear();
plat.insert(PI_HostName, host);
diff --git a/tests/arthur/baselineserver/src/baselineserver.h b/tests/arthur/baselineserver/src/baselineserver.h
index c5cb45e..a5683b2 100644
--- a/tests/arthur/baselineserver/src/baselineserver.h
+++ b/tests/arthur/baselineserver/src/baselineserver.h
@@ -50,10 +50,11 @@
#include <QDateTime>
#include "baselineprotocol.h"
-#include "htmlpage.h"
+#include "report.h"
// #seconds between update checks
#define HEARTBEAT 10
+#define MetadataFileExt "metadata"
class BaselineServer : public QTcpServer
{
@@ -74,7 +75,10 @@ private slots:
private:
QTimer *heartbeatTimer;
QDateTime meLastMod;
+ QString lastRunId;
+ int lastRunIdIdx;
static QString storage;
+ static QString url;
};
@@ -84,10 +88,11 @@ class BaselineThread : public QThread
Q_OBJECT
public:
- BaselineThread(int socketDescriptor, QObject *parent);
+ BaselineThread(const QString &runId, int socketDescriptor, QObject *parent);
void run();
private:
+ QString runId;
int socketDescriptor;
};
@@ -97,9 +102,12 @@ class BaselineHandler : public QObject
Q_OBJECT
public:
- BaselineHandler(int socketDescriptor = -1);
+ BaselineHandler(const QString &runId, int socketDescriptor = -1);
void testPathMapping();
+ QString pathForItem(const ImageItem &item, bool isBaseline = true, bool absolute = true) const;
+ // CGI callbacks:
+ static QString view(const QString &baseline, const QString &rendered, const QString &compared);
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);
@@ -109,19 +117,21 @@ private slots:
void receiveDisconnect();
private:
+ bool establishConnection();
void provideBaselineChecksums(const QByteArray &itemListBlock);
void storeImage(const QByteArray &itemBlock, bool isBaseline);
- void mapPlatformInfo();
- QString pathForItem(const ImageItem &item, bool isBaseline = true, bool absolute = true);
+ 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);
BaselineProtocol proto;
PlatformInfo plat;
- PlatformInfo mapped;
- bool connectionEstablished;
+ mutable PlatformInfo mapped;
QString runId;
- HTMLPage report;
+ bool connectionEstablished;
+ Report report;
};
#endif // BASELINESERVER_H
diff --git a/tests/arthur/baselineserver/src/baselineserver.pro b/tests/arthur/baselineserver/src/baselineserver.pro
index a7be03d..770662b 100644
--- a/tests/arthur/baselineserver/src/baselineserver.pro
+++ b/tests/arthur/baselineserver/src/baselineserver.pro
@@ -20,8 +20,11 @@ include(../../common/baselineprotocol.pri)
SOURCES += main.cpp \
baselineserver.cpp \
- htmlpage.cpp
+ report.cpp
HEADERS += \
baselineserver.h \
- htmlpage.h
+ report.h
+
+RESOURCES += \
+ baselineserver.qrc
diff --git a/tests/arthur/baselineserver/src/baselineserver.qrc b/tests/arthur/baselineserver/src/baselineserver.qrc
new file mode 100644
index 0000000..b5cd6af
--- /dev/null
+++ b/tests/arthur/baselineserver/src/baselineserver.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/">
+ <file>templates/view.html</file>
+ </qresource>
+</RCC>
diff --git a/tests/arthur/baselineserver/src/htmlpage.cpp b/tests/arthur/baselineserver/src/htmlpage.cpp
deleted file mode 100644
index 9659505..0000000
--- a/tests/arthur/baselineserver/src/htmlpage.cpp
+++ /dev/null
@@ -1,239 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#include "htmlpage.h"
-#include "baselineprotocol.h"
-#include "baselineserver.h"
-#include <QDir>
-#include <QProcess>
-#include <QUrl>
-
-HTMLPage::HTMLPage()
- : headerWritten(false)
-{
-}
-
-HTMLPage::~HTMLPage()
-{
- end();
-}
-
-QString HTMLPage::filePath()
-{
- return path;
-}
-
-void HTMLPage::start(const QString &storagepath, const QString &runId, const PlatformInfo pinfo, const QString &context, const ImageItemList &itemList)
-{
- end();
-
- id = runId;
- plat = pinfo;
- ctx = context;
- root = storagepath + QLC('/');
- imageItems = itemList;
- 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);
-}
-
-
-void HTMLPage::writeHeader(const ImageItem &item)
-{
- path = reportDir + 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();
- out.setDevice(&file);
-
- out << "<html><body><h1>Lancelot results from run " << id << "</h1>\n\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></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> (diffs are <span style=\"color:red\">RED</span>)</td>\n"
- "<td><b>Info/Action</b></td>\n"
- "</b></tr><br>";
-}
-
-
-void HTMLPage::writeFooter()
-{
- out << "</table></p>\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 pageUrl = BaselineServer::baseUrl() + path;
-
- out << "<tr>\n";
- out << "<td>" << item.scriptName << "</td>\n";
- QStringList images = QStringList() << baseline << rendered << compared;
- foreach(const QString& img, images)
- 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>"
- << "<p><a href=\"/cgi-bin/server.cgi?cmd=blacklist&context=" << ctx
- << "&itemId=" << item.scriptName << "&url=" << pageUrl << "\">Blacklist this item</a></p>"
- << "</td>\n";
- out << "</tr>\n\n";
-
- QMutableVectorIterator<ImageItem> it(imageItems);
- while (it.hasNext()) {
- it.next();
- if (it.value().scriptName == item.scriptName) {
- it.remove();
- break;
- }
- }
-}
-
-
-void HTMLPage::end()
-{
- if (file.isOpen()) {
- // Add the names of the scripts that passed the test, or were blacklisted
- QString pageUrl = BaselineServer::baseUrl() + path;
- for (int i=0; i<imageItems.count(); ++i) {
- out << "<tr><td>" << imageItems.at(i).scriptName << "</td><td>N/A</td><td>N/A</td><td>N/A</td><td>";
- if (imageItems.at(i).status == ImageItem::IgnoreItem) {
- out << "<span style=\"background-color:yellow\">Blacklisted</span> "
- << "<a href=\"/cgi-bin/server.cgi?cmd=whitelist&context=" << ctx
- << "&itemId=" << imageItems.at(i).scriptName << "&url=" << pageUrl
- << "\">Whitelist item</a>";
- } else {
- out << "<span style=\"color:green\">Test passed</span>";
- }
- out << "</td></tr>\n";
- }
-
- 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;
-}
-
-
-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);
- QTextStream s(stdout);
- s << "Content-Type: text/html\r\n\r\n"
- << "<HTML>";
-// << "Contents of QUERY_STRING:<br>"
-// << "Full string = " << query << "<br>";
-
- QString command(cgiUrl.queryItemValue("cmd"));
-
- if (command == QLS("updateSingleBaseline")) {
- s << BaselineHandler::updateSingleBaseline(cgiUrl.queryItemValue(QLS("oldBaseline")),
- cgiUrl.queryItemValue(QLS("newBaseline")));
- } 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")),
- cgiUrl.queryItemValue(QLS("itemId")));
- } else if (command == QLS("whitelist")) {
- // whitelist a test
- s << BaselineHandler::blacklistTest(cgiUrl.queryItemValue(QLS("context")),
- cgiUrl.queryItemValue(QLS("itemId")), true);
- } else {
- s << "Unknown query:<br>" << query << "<br>";
- }
- s << "<p><a href=\"" << cgiUrl.queryItemValue(QLS("url")) << "\">Back to report</a>";
- s << "</HTML>";
-}
diff --git a/tests/arthur/baselineserver/src/main.cpp b/tests/arthur/baselineserver/src/main.cpp
index a5ec4db..02fc2fa 100644
--- a/tests/arthur/baselineserver/src/main.cpp
+++ b/tests/arthur/baselineserver/src/main.cpp
@@ -48,12 +48,12 @@ int main(int argc, char *argv[])
QString queryString(qgetenv("QUERY_STRING"));
if (!queryString.isEmpty()) {
// run as CGI script
- HTMLPage::handleCGIQuery(queryString);
+ Report::handleCGIQuery(queryString);
return 0;
}
if (a.arguments().contains(QLatin1String("-testmapping"))) {
- BaselineHandler h;
+ BaselineHandler h(QLS("SomeRunId"));
h.testPathMapping();
return 0;
}
diff --git a/tests/arthur/baselineserver/src/report.cpp b/tests/arthur/baselineserver/src/report.cpp
new file mode 100644
index 0000000..c85f144
--- /dev/null
+++ b/tests/arthur/baselineserver/src/report.cpp
@@ -0,0 +1,300 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "report.h"
+#include "baselineprotocol.h"
+#include "baselineserver.h"
+#include <QDir>
+#include <QProcess>
+#include <QUrl>
+
+Report::Report()
+ : written(false), numItems(0), numMismatches(0)
+{
+}
+
+Report::~Report()
+{
+ end();
+}
+
+QString Report::filePath()
+{
+ return path;
+}
+
+void Report::init(const BaselineHandler *h, const QString &r, const PlatformInfo &p)
+{
+ handler = h;
+ runId = r;
+ plat = p;
+ rootDir = BaselineServer::storagePath() + QLC('/');
+ reportDir = plat.value(PI_TestCase) + QLC('/') + (plat.value(PI_PulseGitBranch).isEmpty() ? QLS("reports/adhoc/") : QLS("reports/pulse/"));
+ QString dir = rootDir + reportDir;
+ QDir cwd;
+ if (!cwd.exists(dir))
+ cwd.mkpath(dir);
+ path = reportDir + QLS("Report_") + runId + QLS(".html");
+}
+
+void Report::addItems(const ImageItemList &items)
+{
+ if (items.isEmpty())
+ return;
+ numItems += items.size();
+ QString func = items.at(0).testFunction;
+ if (!testFunctions.contains(func))
+ testFunctions.append(func);
+ itemLists[func] += items;
+}
+
+void Report::addMismatch(const ImageItem &item)
+{
+ if (!testFunctions.contains(item.testFunction)) {
+ qWarning() << "Report::addMismatch: unknown testfunction" << item.testFunction;
+ return;
+ }
+ bool found = false;
+ ImageItemList &list = itemLists[item.testFunction];
+ for (ImageItemList::iterator it = list.begin(); it != list.end(); ++it) {
+ if (it->itemName == item.itemName && it->itemChecksum == item.itemChecksum) {
+ it->status = ImageItem::Mismatch;
+ found = true;
+ break;
+ }
+ }
+ if (found)
+ numMismatches++;
+ else
+ qWarning() << "Report::addMismatch: unknown item" << item.itemName << "in testfunction" << item.testFunction;
+}
+
+void Report::end()
+{
+ if (written || !numMismatches)
+ return;
+ write();
+ written = true;
+}
+
+
+void Report::write()
+{
+ QFile file(rootDir + path);
+ if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
+ qWarning() << "Failed to open report file" << file.fileName();
+ return;
+ }
+ out.setDevice(&file);
+
+ writeHeader();
+ foreach(const QString &func, testFunctions) {
+ writeFunctionResults(itemLists.value(func));
+ }
+ writeFooter();
+ file.close();
+}
+
+
+void Report::writeHeader()
+{
+ QString title = plat.value(PI_TestCase) + QLS(" Qt Baseline Test Report");
+ out << "<head><title>" << title << "</title></head>\n"
+ << "<html><body><h1>" << title << "</h1>\n"
+ << "<p>Note: This is a <i>static</i> page, generated at " << QDateTime::currentDateTime().toString()
+ << " for the test run with id " << runId << "</p>\n"
+ << "<p>Summary: <b><span style=\"color:red\">" << numMismatches << " of " << numItems << "</b></span> items reported mismatching</p>\n\n";
+ out << "<h3>Platform Info:</h3>\n"
+ << "<table>\n";
+ foreach (QString key, plat.keys())
+ out << "<tr><td>" << key << "</td><td>" << plat.value(key) << "</td></tr>\n";
+ out << "</table>\n\n";
+}
+
+
+void Report::writeFunctionResults(const ImageItemList &list)
+{
+ QString testFunction = list.at(0).testFunction;
+ QString pageUrl = BaselineServer::baseUrl() + path;
+ QString ctx = handler->pathForItem(list.at(0), true, false).section(QLC('/'), 0, -2);
+
+ out << "\n<p>&nbsp;</p><h3>Test function: " << testFunction << "</h3>\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 << "<table border=\"2\">\n"
+ "<tr>\n"
+ "<th width=123>Item</th>\n"
+ "<th width=246>Baseline</th>\n"
+ "<th width=246>Rendered</th>\n"
+ "<th width=246>Comparison (diffs are <span style=\"color:red\">RED</span>)</th>\n"
+ "<th width=246>Info/Action</th>\n"
+ "</tr>\n\n";
+
+ foreach (const ImageItem &item, list) {
+ out << "<tr>\n";
+ out << "<td>" << item.itemName << "</td>\n";
+ 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, metadata);
+ }
+ else {
+ 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) {
+ case ImageItem::BaselineNotFound:
+ out << "Baseline not found/regenerated";
+ break;
+ case ImageItem::IgnoreItem:
+ out << "<span style=\"background-color:yellow\">Blacklisted</span> "
+ << "<a href=\"/cgi-bin/server.cgi?cmd=whitelist&context=" << ctx
+ << "&itemId=" << item.itemName << "&url=" << pageUrl
+ << "\">Whitelist this item</a>";
+ break;
+ case ImageItem::Ok:
+ out << "<span style=\"color:green\"><small>No mismatch reported</small></span>";
+ break;
+ default:
+ out << "?";
+ break;
+ }
+ out << "</td>\n";
+ }
+ out << "</tr>\n\n";
+ }
+
+ out << "</table>\n";
+}
+
+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;
+
+ QStringList images = QStringList() << baseline << rendered << compared;
+ foreach (const QString& img, images)
+ out << "<td height=246 align=center><a href=\"/" << img << "\"><img src=\"/" << generateThumbnail(img) << "\"></a></td>\n";
+
+ 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
+ << "&itemId=" << item.itemName << "&url=" << pageUrl << "\">Blacklist this item</a></p>\n"
+ << "<p><a href=\"/cgi-bin/server.cgi?cmd=view&baseline=" << baseline << "&rendered=" << rendered
+ << "&compared=" << compared << "&url=" << pageUrl << "\">Inspect</a></p>\n"
+ << "</td>\n";
+}
+
+void Report::writeFooter()
+{
+ out << "\n</body></html>\n";
+}
+
+
+QString Report::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 << rootDir+baseline << rootDir+rendered << rootDir+res;
+ QProcess::execute(QLS("compare"), args);
+ return res;
+}
+
+
+QString Report::generateThumbnail(const QString &image)
+{
+ QString res = image;
+ QFileInfo imgFI(rootDir+image);
+ res.chop(imgFI.suffix().length() + 1);
+ res += QLS("_thumbnail.jpg");
+ QFileInfo resFI(rootDir+res);
+ if (resFI.exists() && resFI.lastModified() > imgFI.lastModified())
+ return res;
+ QStringList args;
+ args << rootDir+image << QLS("-resize") << QLS("240x240>") << QLS("-quality") << QLS("50") << rootDir+res;
+ QProcess::execute(QLS("convert"), args);
+ return res;
+}
+
+
+void Report::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>";
+
+ QString command(cgiUrl.queryItemValue("cmd"));
+
+ if (command == QLS("view")) {
+ s << BaselineHandler::view(cgiUrl.queryItemValue(QLS("baseline")),
+ cgiUrl.queryItemValue(QLS("rendered")),
+ cgiUrl.queryItemValue(QLS("compared")));
+ }
+ else if (command == QLS("updateSingleBaseline")) {
+ s << BaselineHandler::updateSingleBaseline(cgiUrl.queryItemValue(QLS("oldBaseline")),
+ cgiUrl.queryItemValue(QLS("newBaseline")));
+ } 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")),
+ cgiUrl.queryItemValue(QLS("itemId")));
+ } else if (command == QLS("whitelist")) {
+ // whitelist a test
+ s << BaselineHandler::blacklistTest(cgiUrl.queryItemValue(QLS("context")),
+ cgiUrl.queryItemValue(QLS("itemId")), true);
+ } else {
+ s << "Unknown query:<br>" << query << "<br>";
+ }
+ 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/report.h
index 5f1e051..a56aafb 100644
--- a/tests/arthur/baselineserver/src/htmlpage.h
+++ b/tests/arthur/baselineserver/src/report.h
@@ -38,42 +38,53 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-#ifndef HTMLPAGE_H
-#define HTMLPAGE_H
+#ifndef REPORT_H
+#define REPORT_H
#include "baselineprotocol.h"
#include <QFile>
#include <QTextStream>
+#include <QMap>
+#include <QStringList>
-class HTMLPage
+class BaselineHandler;
+
+class Report
{
public:
- HTMLPage();
- ~HTMLPage();
+ Report();
+ ~Report();
- void start(const QString &storagePath, const QString &runId, const PlatformInfo pinfo, const QString &context, const ImageItemList &itemList);
- void addItem(const QString &baseline, const QString &rendered, const ImageItem &item);
+ void init(const BaselineHandler *h, const QString &r, const PlatformInfo &p);
+ void addItems(const ImageItemList& items);
+ void addMismatch(const ImageItem& item);
void end();
+
QString filePath();
static void handleCGIQuery(const QString &query);
private:
- void writeHeader(const ImageItem &item);
+ void write();
+ void writeFunctionResults(const ImageItemList &list);
+ 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);
QString generateThumbnail(const QString &image);
- QString root;
- QString path;
+ const BaselineHandler *handler;
+ QString runId;
+ PlatformInfo plat;
+ QString rootDir;
QString reportDir;
- QFile file;
+ QString path;
+ QStringList testFunctions;
+ QMap<QString, ImageItemList> itemLists;
+ bool written;
+ int numItems;
+ int numMismatches;
QTextStream out;
- QString id;
- PlatformInfo plat;
- QString ctx;
- ImageItemList imageItems;
- bool headerWritten;
};
-#endif // HTMLPAGE_H
+#endif // REPORT_H
diff --git a/tests/arthur/baselineserver/src/templates/view.html b/tests/arthur/baselineserver/src/templates/view.html
new file mode 100644
index 0000000..c048f47
--- /dev/null
+++ b/tests/arthur/baselineserver/src/templates/view.html
@@ -0,0 +1,79 @@
+<h3>Lancelot Viewer</h3>
+
+<p>
+Zoom:
+<input name="zoom" id="z1" type="radio" checked="Checked">1x</input>
+<input name="zoom" id="z2" type="radio">2x</input>
+<input name="zoom" id="z4" type="radio">4x</input>
+</p>
+
+<p><table>
+<tr>
+<td><input name="imgselect" id="baseline" type="radio" checked="Checked">Baseline</input></td>
+<td>%1</td>
+</tr>
+<tr>
+<td><input name="imgselect" id="rendered" type="radio">Rendered</input></td>
+<td>%2</td>
+</tr>
+<tr>
+<td><input name="imgselect" id="compared" type="radio">Differences</input></td>
+<td></td>
+</tr>
+</table></p>
+
+
+<p>
+<canvas id="c" width="800" height="800"></canvas>
+</p>
+
+<script>
+ var canvas = document.getElementById("c");
+ var context = canvas.getContext("2d");
+ var cat = new Image();
+ cat.src = "%1";
+ var z = 1;
+ cat.onload = function() {
+ context.mozImageSmoothingEnabled = false;
+ context.drawImage(cat, 0, 0, z*cat.width, z*cat.height);
+ };
+
+ var bbut = document.getElementById("baseline");
+ bbut.onclick = function() {
+ cat.src = "%1";
+ };
+
+ var rbut = document.getElementById("rendered");
+ rbut.onclick = function() {
+ cat.src = "%2";
+ };
+
+ var cbut = document.getElementById("compared");
+ cbut.onclick = function() {
+ cat.src = "%3";
+ };
+
+ function setZoom(zoom)
+ {
+ z = zoom;
+ canvas.width = z*800;
+ canvas.height = z*800;
+ context.mozImageSmoothingEnabled = false;
+ context.drawImage(cat, 0, 0, z*cat.width, z*cat.height);
+ }
+
+ var z1but = document.getElementById("z1");
+ z1but.onclick = function() {
+ setZoom(1);
+ };
+
+ var z2but = document.getElementById("z2");
+ z2but.onclick = function() {
+ setZoom(2);
+ };
+
+ var z4but = document.getElementById("z4");
+ z4but.onclick = function() {
+ setZoom(4);
+ };
+</script>
diff --git a/tests/arthur/common/baselineprotocol.cpp b/tests/arthur/common/baselineprotocol.cpp
index 5ed58b4..e4445bd 100644
--- a/tests/arthur/common/baselineprotocol.cpp
+++ b/tests/arthur/common/baselineprotocol.cpp
@@ -48,6 +48,7 @@
#include <QFileInfo>
#include <QDir>
#include <QTime>
+#include <QPointer>
#ifndef QMAKESPEC
#define QMAKESPEC "Unknown"
@@ -128,11 +129,10 @@ PlatformInfo::PlatformInfo(bool useLocal)
ImageItem &ImageItem::operator=(const ImageItem &other)
{
- scriptName = other.scriptName;
- scriptChecksum = other.scriptChecksum;
+ testFunction = other.testFunction;
+ itemName = other.itemName;
+ itemChecksum = other.itemChecksum;
status = other.status;
- renderFormat = other.renderFormat;
- engine = other.engine;
image = other.image;
imageChecksums = other.imageChecksums;
return *this;
@@ -165,6 +165,7 @@ quint64 ImageItem::computeChecksum(const QImage &image)
return (quint64(h1) << 32) | h2;
}
+#if 0
QString ImageItem::engineAsString() const
{
switch (engine) {
@@ -205,6 +206,7 @@ QString ImageItem::formatAsString() const
return QLS("UnknownFormat");
return QLS(formatNames[renderFormat]);
}
+#endif
void ImageItem::writeImageToStream(QDataStream &out) const
{
@@ -249,24 +251,24 @@ void ImageItem::readImageFromStream(QDataStream &in)
QDataStream & operator<< (QDataStream &stream, const ImageItem &ii)
{
- stream << ii.scriptName << ii.scriptChecksum << quint8(ii.status) << quint8(ii.renderFormat)
- << quint8(ii.engine) << ii.imageChecksums;
+ stream << ii.testFunction << ii.itemName << ii.itemChecksum << quint8(ii.status) << ii.imageChecksums;
ii.writeImageToStream(stream);
return stream;
}
QDataStream & operator>> (QDataStream &stream, ImageItem &ii)
{
- quint8 encFormat, encStatus, encEngine;
- stream >> ii.scriptName >> ii.scriptChecksum >> encStatus >> encFormat
- >> encEngine >> ii.imageChecksums;
- ii.renderFormat = QImage::Format(encFormat);
+ quint8 encStatus;
+ stream >> ii.testFunction >> ii.itemName >> ii.itemChecksum >> encStatus >> ii.imageChecksums;
ii.status = ImageItem::ItemStatus(encStatus);
- ii.engine = ImageItem::GraphicsEngine(encEngine);
ii.readImageFromStream(stream);
return stream;
}
+BaselineProtocol::BaselineProtocol()
+{
+}
+
BaselineProtocol::~BaselineProtocol()
{
socket.close();
@@ -275,7 +277,7 @@ BaselineProtocol::~BaselineProtocol()
}
-bool BaselineProtocol::connect(bool *dryrun)
+bool BaselineProtocol::connect(const QString &testCase, bool *dryrun)
{
errMsg.clear();
QByteArray serverName(qgetenv("QT_LANCELOT_SERVER"));
@@ -292,6 +294,7 @@ bool BaselineProtocol::connect(bool *dryrun)
}
PlatformInfo pi(true);
+ pi.insert(PI_TestCase, testCase);
QByteArray block;
QDataStream ds(&block, QIODevice::ReadWrite);
ds << pi;
@@ -342,11 +345,15 @@ bool BaselineProtocol::acceptConnection(PlatformInfo *pi)
}
-bool BaselineProtocol::requestBaselineChecksums(ImageItemList *itemList)
+bool BaselineProtocol::requestBaselineChecksums(const QString &testFunction, ImageItemList *itemList)
{
errMsg.clear();
if (!itemList)
return false;
+
+ for(ImageItemList::iterator it = itemList->begin(); it != itemList->end(); it++)
+ it->testFunction = testFunction;
+
QByteArray block;
QDataStream ds(&block, QIODevice::ReadWrite);
ds << *itemList;
diff --git a/tests/arthur/common/baselineprotocol.h b/tests/arthur/common/baselineprotocol.h
index baffb4a..2315bc3 100644
--- a/tests/arthur/common/baselineprotocol.h
+++ b/tests/arthur/common/baselineprotocol.h
@@ -38,6 +38,7 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+
#ifndef BASELINEPROTOCOL_H
#define BASELINEPROTOCOL_H
@@ -46,12 +47,14 @@
#include <QImage>
#include <QVector>
#include <QMap>
+#include <QPointer>
#define QLS QLatin1String
#define QLC QLatin1Char
#define FileFormat "png"
+const QString PI_TestCase(QLS("TestCase"));
const QString PI_HostName(QLS("HostName"));
const QString PI_HostAddress(QLS("HostAddress"));
const QString PI_OSName(QLS("OSName"));
@@ -73,39 +76,32 @@ struct ImageItem
{
public:
ImageItem()
- : status(Ok), renderFormat(QImage::Format_Invalid), engine(Raster), scriptChecksum(0)
+ : status(Ok), itemChecksum(0)
{}
ImageItem(const ImageItem &other)
{ *this = other; }
~ImageItem()
{}
ImageItem &operator=(const ImageItem &other);
- static quint64 computeChecksum(const QImage& image);
- QString engineAsString() const;
- QString formatAsString() const;
- void writeImageToStream(QDataStream &stream) const;
- void readImageFromStream(QDataStream &stream);
+ static quint64 computeChecksum(const QImage& image);
enum ItemStatus {
Ok = 0,
BaselineNotFound = 1,
- IgnoreItem = 2
- };
-
- enum GraphicsEngine {
- Raster = 0,
- OpenGL = 1
+ IgnoreItem = 2,
+ Mismatch = 3
};
- QString scriptName;
+ QString testFunction;
+ QString itemName;
ItemStatus status;
- QImage::Format renderFormat;
- GraphicsEngine engine;
QImage image;
QList<quint64> imageChecksums;
- // tbd: add diffscore
- quint16 scriptChecksum;
+ quint16 itemChecksum;
+
+ void writeImageToStream(QDataStream &stream) const;
+ void readImageFromStream(QDataStream &stream);
};
QDataStream & operator<< (QDataStream &stream, const ImageItem &ii);
QDataStream & operator>> (QDataStream &stream, ImageItem& ii);
@@ -114,17 +110,20 @@ Q_DECLARE_METATYPE(ImageItem);
typedef QVector<ImageItem> ImageItemList;
+
class BaselineProtocol
{
public:
- BaselineProtocol() {}
+ BaselineProtocol();
~BaselineProtocol();
+ static BaselineProtocol *instance(QObject *parent = 0);
+
// ****************************************************
// Important constants here
// ****************************************************
enum Constant {
- ProtocolVersion = 3,
+ ProtocolVersion = 4,
ServerPort = 54129,
Timeout = 5000
};
@@ -143,8 +142,10 @@ public:
};
// For client:
- bool connect(bool *dryrun = 0);
- bool requestBaselineChecksums(ImageItemList *itemList);
+
+ // For advanced client:
+ bool connect(const QString &testCase, bool *dryrun = 0);
+ bool requestBaselineChecksums(const QString &testFunction, ImageItemList *itemList);
bool submitNewBaseline(const ImageItem &item, QByteArray *serverMsg);
bool submitMismatch(const ImageItem &item, QByteArray *serverMsg);
diff --git a/tests/arthur/common/baselineprotocol.pri b/tests/arthur/common/baselineprotocol.pri
index 996f9d5..62e38a6 100644
--- a/tests/arthur/common/baselineprotocol.pri
+++ b/tests/arthur/common/baselineprotocol.pri
@@ -1,4 +1,5 @@
INCLUDEPATH += $$PWD
+DEPENDPATH += $$PWD
QT *= network
diff --git a/tests/arthur/common/framework.cpp b/tests/arthur/common/framework.cpp
index 19d33ec..1271e59 100644
--- a/tests/arthur/common/framework.cpp
+++ b/tests/arthur/common/framework.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/tests/arthur/common/framework.h b/tests/arthur/common/framework.h
index 8a4d837..e25c9a1 100644
--- a/tests/arthur/common/framework.h
+++ b/tests/arthur/common/framework.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/tests/arthur/common/paintcommands.cpp b/tests/arthur/common/paintcommands.cpp
index dc1b008..b00ce81 100644
--- a/tests/arthur/common/paintcommands.cpp
+++ b/tests/arthur/common/paintcommands.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/tests/arthur/common/paintcommands.h b/tests/arthur/common/paintcommands.h
index ebd882b..b2516e1 100644
--- a/tests/arthur/common/paintcommands.h
+++ b/tests/arthur/common/paintcommands.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/tests/arthur/common/qbaselinetest.cpp b/tests/arthur/common/qbaselinetest.cpp
new file mode 100644
index 0000000..79241d5
--- /dev/null
+++ b/tests/arthur/common/qbaselinetest.cpp
@@ -0,0 +1,193 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbaselinetest.h"
+#include "baselineprotocol.h"
+
+namespace QBaselineTest {
+
+BaselineProtocol proto;
+bool connected = false;
+bool triedConnecting = false;
+
+QByteArray curFunction;
+ImageItemList itemList;
+bool gotBaselines;
+
+
+bool connect(QByteArray *msg, bool *error)
+{
+ if (!triedConnecting) {
+ triedConnecting = true;
+ if (!proto.connect(QTest::testObject()->metaObject()->className())) {
+ *msg += "Failed to connect to baseline server: " + proto.errorMessage().toLatin1();
+ *error = true;
+ return false;
+ }
+ connected = true;
+ }
+ if (!connected) {
+ *msg = "Not connected to baseline server.";
+ *error = true;
+ return false;
+ }
+ return true;
+}
+
+
+bool compareItem(const ImageItem &baseline, const QImage &img, QByteArray *msg, bool *error)
+{
+ ImageItem item = baseline;
+ item.image = img;
+ item.imageChecksums.clear();
+ item.imageChecksums.prepend(ImageItem::computeChecksum(img));
+ QByteArray srvMsg;
+ switch (baseline.status) {
+ case ImageItem::Ok:
+ break;
+ case ImageItem::IgnoreItem :
+ qDebug() << msg->constData() << "Ignored, blacklisted on server.";
+ return true;
+ break;
+ case ImageItem::BaselineNotFound:
+ if (proto.submitNewBaseline(item, &srvMsg))
+ qDebug() << msg->constData() << "Baseline not found on server. New baseline uploaded.";
+ else
+ qDebug() << msg->constData() << "Baseline not found on server. Uploading of new baseline failed:" << srvMsg;
+ return true;
+ break;
+ default:
+ qWarning() << "Unexpected reply from baseline server.";
+ return true;
+ break;
+ }
+ *error = false;
+ // The actual comparison of the given image with the baseline:
+ if (baseline.imageChecksums.contains(item.imageChecksums.at(0)))
+ return true;
+ proto.submitMismatch(item, &srvMsg);
+ *msg += "Mismatch. See report:\n " + srvMsg;
+ return false;
+}
+
+bool checkImage(const QImage &img, const char *name, quint16 checksum, QByteArray *msg, bool *error)
+{
+ if (!connected && !connect(msg, error))
+ return true;
+
+ QByteArray itemName;
+ bool hasName = qstrlen(name);
+ const char *tag = QTest::currentDataTag();
+ if (qstrlen(tag)) {
+ itemName = tag;
+ if (hasName)
+ itemName.append('_').append(name);
+ } else {
+ itemName = hasName ? name : "default_name";
+ }
+
+ *msg = "Baseline check of image '" + itemName + "': ";
+
+
+ ImageItem item;
+ item.itemName = QString::fromLatin1(itemName);
+ item.itemChecksum = checksum;
+ item.testFunction = QString::fromLatin1(QTest::currentTestFunction());
+ ImageItemList list;
+ list.append(item);
+ if (!proto.requestBaselineChecksums(QLatin1String(QTest::currentTestFunction()), &list) || list.isEmpty()) {
+ *msg = "Communication with baseline server failed: " + proto.errorMessage().toLatin1();
+ *error = true;
+ return true;
+ }
+
+ return compareItem(list.at(0), img, msg, error);
+}
+
+
+QTestData &newRow(const char *dataTag, quint16 checksum)
+{
+ if (QTest::currentTestFunction() != curFunction) {
+ curFunction = QTest::currentTestFunction();
+ itemList.clear();
+ gotBaselines = false;
+ }
+ ImageItem item;
+ item.itemName = QString::fromLatin1(dataTag);
+ item.itemChecksum = checksum;
+ item.testFunction = QString::fromLatin1(QTest::currentTestFunction());
+ itemList.append(item);
+
+ return QTest::newRow(dataTag);
+}
+
+
+bool testImage(const QImage& img, QByteArray *msg, bool *error)
+{
+ if (!connected && !connect(msg, error))
+ return true;
+
+ if (QTest::currentTestFunction() != curFunction || itemList.isEmpty()) {
+ qWarning() << "Usage error: QBASELINE_TEST used without corresponding QBaselineTest::newRow()";
+ return true;
+ }
+
+ if (!gotBaselines) {
+ if (!proto.requestBaselineChecksums(QString::fromLatin1(QTest::currentTestFunction()), &itemList) || itemList.isEmpty()) {
+ *msg = "Communication with baseline server failed: " + proto.errorMessage().toLatin1();
+ *error = true;
+ return true;
+ }
+ gotBaselines = true;
+ }
+
+ QString curTag = QString::fromLatin1(QTest::currentDataTag());
+ ImageItemList::const_iterator it = itemList.constBegin();
+ while (it != itemList.constEnd() && it->itemName != curTag)
+ ++it;
+ if (it == itemList.constEnd()) {
+ qWarning() << "Usage error: QBASELINE_TEST used without corresponding QBaselineTest::newRow() for row" << curTag;
+ return true;
+ }
+ return compareItem(*it, img, msg, error);
+}
+
+}
diff --git a/tests/arthur/common/qbaselinetest.h b/tests/arthur/common/qbaselinetest.h
new file mode 100644
index 0000000..e27cda2
--- /dev/null
+++ b/tests/arthur/common/qbaselinetest.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef BASELINETEST_H
+#define BASELINETEST_H
+
+#include <QTest>
+
+namespace QBaselineTest {
+bool checkImage(const QImage& img, const char *name, quint16 checksum, QByteArray *msg, bool *error);
+bool testImage(const QImage& img, QByteArray *msg, bool *error);
+QTestData &newRow(const char *dataTag, quint16 checksum = 0);
+}
+
+#define QBASELINE_CHECK_SUM(image, name, checksum)\
+do {\
+ QByteArray _msg;\
+ bool _err = false;\
+ if (!QBaselineTest::checkImage((image), (name), (checksum), &_msg, &_err)) {\
+ QFAIL(_msg.constData());\
+ } else if (_err) {\
+ QSKIP(_msg.constData(), SkipSingle);\
+ }\
+} while (0)
+
+#define QBASELINE_CHECK(image, name) QBASELINE_CHECK_SUM(image, name, 0)
+
+#define QBASELINE_TEST(image)\
+do {\
+ QByteArray _msg;\
+ bool _err = false;\
+ if (!QBaselineTest::testImage((image), &_msg, &_err)) {\
+ QFAIL(_msg.constData());\
+ } else if (_err) {\
+ QSKIP(_msg.constData(), SkipSingle);\
+ }\
+} while (0)
+
+#endif // BASELINETEST_H
diff --git a/tests/arthur/common/qbaselinetest.pri b/tests/arthur/common/qbaselinetest.pri
new file mode 100644
index 0000000..5420c6e
--- /dev/null
+++ b/tests/arthur/common/qbaselinetest.pri
@@ -0,0 +1,13 @@
+QT *= testlib
+
+SOURCES += \
+ $$PWD/qbaselinetest.cpp
+
+HEADERS += \
+ $$PWD/qbaselinetest.h
+
+win32|symbian*:MKSPEC=$$replace(QMAKESPEC, \\\\, /)
+else:MKSPEC=$$QMAKESPEC
+DEFINES += QMAKESPEC=\\\"$$MKSPEC\\\"
+
+include($$PWD/baselineprotocol.pri)
diff --git a/tests/arthur/common/qengines.cpp b/tests/arthur/common/qengines.cpp
index 12457fd..8eff221 100644
--- a/tests/arthur/common/qengines.cpp
+++ b/tests/arthur/common/qengines.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/tests/arthur/common/qengines.h b/tests/arthur/common/qengines.h
index 48405c7..b731cfe 100644
--- a/tests/arthur/common/qengines.h
+++ b/tests/arthur/common/qengines.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/tests/arthur/common/xmldata.cpp b/tests/arthur/common/xmldata.cpp
index ab237a3..5b6e1fd 100644
--- a/tests/arthur/common/xmldata.cpp
+++ b/tests/arthur/common/xmldata.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/tests/arthur/common/xmldata.h b/tests/arthur/common/xmldata.h
index 99e6e91..17d1405 100644
--- a/tests/arthur/common/xmldata.h
+++ b/tests/arthur/common/xmldata.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/tests/arthur/datagenerator/datagenerator.cpp b/tests/arthur/datagenerator/datagenerator.cpp
index 7692f68..2ffcc76 100644
--- a/tests/arthur/datagenerator/datagenerator.cpp
+++ b/tests/arthur/datagenerator/datagenerator.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/tests/arthur/datagenerator/datagenerator.h b/tests/arthur/datagenerator/datagenerator.h
index c6c6eb0..cef49e1 100644
--- a/tests/arthur/datagenerator/datagenerator.h
+++ b/tests/arthur/datagenerator/datagenerator.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/tests/arthur/datagenerator/main.cpp b/tests/arthur/datagenerator/main.cpp
index c217b25..e857336 100644
--- a/tests/arthur/datagenerator/main.cpp
+++ b/tests/arthur/datagenerator/main.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/tests/arthur/datagenerator/xmlgenerator.cpp b/tests/arthur/datagenerator/xmlgenerator.cpp
index e18d821..919870b 100644
--- a/tests/arthur/datagenerator/xmlgenerator.cpp
+++ b/tests/arthur/datagenerator/xmlgenerator.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/tests/arthur/datagenerator/xmlgenerator.h b/tests/arthur/datagenerator/xmlgenerator.h
index b8c77a8..0dbdaeb 100644
--- a/tests/arthur/datagenerator/xmlgenerator.h
+++ b/tests/arthur/datagenerator/xmlgenerator.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/tests/arthur/htmlgenerator/htmlgenerator.cpp b/tests/arthur/htmlgenerator/htmlgenerator.cpp
index e683017..e86352f 100644
--- a/tests/arthur/htmlgenerator/htmlgenerator.cpp
+++ b/tests/arthur/htmlgenerator/htmlgenerator.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/tests/arthur/htmlgenerator/htmlgenerator.h b/tests/arthur/htmlgenerator/htmlgenerator.h
index 85b56fa..d79dff6 100644
--- a/tests/arthur/htmlgenerator/htmlgenerator.h
+++ b/tests/arthur/htmlgenerator/htmlgenerator.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/tests/arthur/htmlgenerator/main.cpp b/tests/arthur/htmlgenerator/main.cpp
index 7521e0c..8752994 100644
--- a/tests/arthur/htmlgenerator/main.cpp
+++ b/tests/arthur/htmlgenerator/main.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/tests/arthur/lance/interactivewidget.cpp b/tests/arthur/lance/interactivewidget.cpp
index 307c3f7..2fb03ab 100644
--- a/tests/arthur/lance/interactivewidget.cpp
+++ b/tests/arthur/lance/interactivewidget.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/tests/arthur/lance/interactivewidget.h b/tests/arthur/lance/interactivewidget.h
index a49b46c..86cc7fc 100644
--- a/tests/arthur/lance/interactivewidget.h
+++ b/tests/arthur/lance/interactivewidget.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/tests/arthur/lance/main.cpp b/tests/arthur/lance/main.cpp
index 85ee8b5..2bda932 100644
--- a/tests/arthur/lance/main.cpp
+++ b/tests/arthur/lance/main.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/tests/arthur/lance/widgets.h b/tests/arthur/lance/widgets.h
index f7d3268..4643411 100644
--- a/tests/arthur/lance/widgets.h
+++ b/tests/arthur/lance/widgets.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/tests/arthur/performancediff/main.cpp b/tests/arthur/performancediff/main.cpp
index 8cb3ac9..da9af5a 100644
--- a/tests/arthur/performancediff/main.cpp
+++ b/tests/arthur/performancediff/main.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/tests/arthur/performancediff/performancediff.cpp b/tests/arthur/performancediff/performancediff.cpp
index 94f73c3..fa7ebac 100644
--- a/tests/arthur/performancediff/performancediff.cpp
+++ b/tests/arthur/performancediff/performancediff.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/tests/arthur/performancediff/performancediff.h b/tests/arthur/performancediff/performancediff.h
index 48dd4e7..480f377 100644
--- a/tests/arthur/performancediff/performancediff.h
+++ b/tests/arthur/performancediff/performancediff.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/tests/arthur/shower/main.cpp b/tests/arthur/shower/main.cpp
index 3474b4a..a12bdd6 100644
--- a/tests/arthur/shower/main.cpp
+++ b/tests/arthur/shower/main.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/tests/arthur/shower/shower.cpp b/tests/arthur/shower/shower.cpp
index 1de162c..b287444 100644
--- a/tests/arthur/shower/shower.cpp
+++ b/tests/arthur/shower/shower.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/tests/arthur/shower/shower.h b/tests/arthur/shower/shower.h
index 3013c7b..db95be6 100644
--- a/tests/arthur/shower/shower.h
+++ b/tests/arthur/shower/shower.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**