summaryrefslogtreecommitdiffstats
path: root/tests/arthur/baselineserver
diff options
context:
space:
mode:
Diffstat (limited to 'tests/arthur/baselineserver')
-rw-r--r--tests/arthur/baselineserver/.gitignore2
-rwxr-xr-xtests/arthur/baselineserver/bin/runserver13
-rw-r--r--tests/arthur/baselineserver/src/baselineserver.cpp576
-rw-r--r--tests/arthur/baselineserver/src/baselineserver.h141
-rw-r--r--tests/arthur/baselineserver/src/baselineserver.pro30
-rw-r--r--tests/arthur/baselineserver/src/baselineserver.qrc5
-rw-r--r--tests/arthur/baselineserver/src/main.cpp70
-rw-r--r--tests/arthur/baselineserver/src/report.cpp311
-rw-r--r--tests/arthur/baselineserver/src/report.h91
-rw-r--r--tests/arthur/baselineserver/src/templates/view.html79
10 files changed, 0 insertions, 1318 deletions
diff --git a/tests/arthur/baselineserver/.gitignore b/tests/arthur/baselineserver/.gitignore
deleted file mode 100644
index cc513e0df2..0000000000
--- a/tests/arthur/baselineserver/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-storage
-bin/baselineserver
diff --git a/tests/arthur/baselineserver/bin/runserver b/tests/arthur/baselineserver/bin/runserver
deleted file mode 100755
index 48c5c1d086..0000000000
--- a/tests/arthur/baselineserver/bin/runserver
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/bin/bash
-
-logfile=baselineserver.log
-
-while true; do
- echo >> $logfile
- echo -n "***RESTARTING*** " >> $logfile
- date >> $logfile
-
- ./baselineserver 2>&1 | tee -a $logfile
-
- sleep 2
-done
diff --git a/tests/arthur/baselineserver/src/baselineserver.cpp b/tests/arthur/baselineserver/src/baselineserver.cpp
deleted file mode 100644
index 6ff0a0c72d..0000000000
--- a/tests/arthur/baselineserver/src/baselineserver.cpp
+++ /dev/null
@@ -1,576 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#define QT_USE_FAST_CONCATENATION
-#define QT_USE_FAST_OPERATOR_PLUS
-
-#include "baselineserver.h"
-#include <QBuffer>
-#include <QFile>
-#include <QDir>
-#include <QCoreApplication>
-#include <QFileInfo>
-#include <QHostInfo>
-#include <QTextStream>
-#include <QProcess>
-#include <QDirIterator>
-
-// 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;
-QString BaselineServer::settingsFile;
-
-BaselineServer::BaselineServer(QObject *parent)
- : QTcpServer(parent), lastRunIdIdx(0)
-{
- QFileInfo me(QCoreApplication::applicationFilePath());
- meLastMod = me.lastModified();
- heartbeatTimer = new QTimer(this);
- connect(heartbeatTimer, SIGNAL(timeout()), this, SLOT(heartbeat()));
- heartbeatTimer->start(HEARTBEAT*1000);
-}
-
-QString BaselineServer::storagePath()
-{
- if (storage.isEmpty()) {
- storage = QLS(qgetenv("QT_LANCELOT_DIR"));
- if (storage.isEmpty())
- storage = QLS("/var/www");
- }
- return storage;
-}
-
-QString BaselineServer::baseUrl()
-{
- if (url.isEmpty()) {
- url = QLS("http://")
- + QHostInfo::localHostName().toLatin1() + '.'
- + QHostInfo::localDomainName().toLatin1() + '/';
- }
- return url;
-}
-
-QString BaselineServer::settingsFilePath()
-{
- if (settingsFile.isEmpty()) {
- QString exeName = QCoreApplication::applicationFilePath().section(QLC('/'), -1);
- settingsFile = storagePath() + QLC('/') + exeName + QLS(".ini");
- }
- return settingsFile;
-}
-
-void BaselineServer::incomingConnection(int socketDescriptor)
-{
- 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();
-}
-
-void BaselineServer::heartbeat()
-{
- // The idea is to exit to be restarted when modified, as soon as not actually serving
- 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
- bool isServing = false;
- foreach(BaselineThread *thread, findChildren<BaselineThread *>()) {
- if (thread->isRunning()) {
- isServing = true;
- break;
- }
- }
-
- if (!isServing)
- QCoreApplication::exit();
-}
-
-BaselineThread::BaselineThread(const QString &runId, int socketDescriptor, QObject *parent)
- : QThread(parent), runId(runId), socketDescriptor(socketDescriptor)
-{
-}
-
-void BaselineThread::run()
-{
- BaselineHandler handler(runId, socketDescriptor);
- exec();
-}
-
-
-BaselineHandler::BaselineHandler(const QString &runId, int socketDescriptor)
- : QObject(), runId(runId), connectionEstablished(false)
-{
- settings = new QSettings(BaselineServer::settingsFilePath(), QSettings::IniFormat, this);
-
- if (socketDescriptor == -1)
- return;
-
- connect(&proto.socket, SIGNAL(readyRead()), this, SLOT(receiveRequest()));
- connect(&proto.socket, SIGNAL(disconnected()), this, SLOT(receiveDisconnect()));
- proto.socket.setSocketDescriptor(socketDescriptor);
-}
-
-const char *BaselineHandler::logtime()
-{
- return 0;
- //return QTime::currentTime().toString(QLS("mm:ss.zzz"));
-}
-
-bool BaselineHandler::establishConnection()
-{
- if (!proto.acceptConnection(&plat)) {
- qWarning() << runId << logtime() << "Accepting new connection from" << proto.socket.peerAddress().toString() << "failed." << proto.errorMessage();
- proto.sendBlock(BaselineProtocol::Abort, proto.errorMessage().toLatin1()); // In case the client can hear us, tell it what's wrong.
- 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;
-
- settings->beginGroup("ClientFilters");
- if (!settings->childKeys().isEmpty() && !plat.value(PI_PulseGitBranch).isEmpty()) { // i.e. not adhoc client
- // Abort if client does not match the filters
- foreach (QString filterKey, settings->childKeys()) {
- QString filter = settings->value(filterKey).toString();
- QString platVal = plat.value(filterKey);
- if (filter.isEmpty() || platVal.isEmpty())
- continue; // tbd: add a syntax for specifying a "value-must-be-present" filter
- if (!platVal.contains(filter)) {
- qDebug() << runId << logtime() << "Did not pass client filter on" << filterKey << "; disconnecting.";
- proto.sendBlock(BaselineProtocol::Abort, QByteArray("Configured to not do testing for this client or repo, ref. ") + BaselineServer::settingsFilePath().toLatin1());
- proto.socket.disconnectFromHost();
- return false;
- }
- }
- }
- settings->endGroup();
-
- proto.sendBlock(BaselineProtocol::Ack, QByteArray());
-
- report.init(this, runId, plat);
- return true;
-}
-
-void BaselineHandler::receiveRequest()
-{
- if (!connectionEstablished) {
- connectionEstablished = establishConnection();
- return;
- }
-
- QByteArray block;
- BaselineProtocol::Command cmd;
- if (!proto.receiveBlock(&cmd, &block)) {
- qWarning() << runId << logtime() << "Command reception failed. "<< proto.errorMessage();
- QThread::currentThread()->exit(1);
- return;
- }
-
- switch(cmd) {
- case BaselineProtocol::RequestBaselineChecksums:
- provideBaselineChecksums(block);
- break;
- case BaselineProtocol::AcceptNewBaseline:
- storeImage(block, true);
- break;
- case BaselineProtocol::AcceptMismatch:
- storeImage(block, false);
- break;
- default:
- qWarning() << runId << logtime() << "Unknown command received. " << proto.errorMessage();
- proto.sendBlock(BaselineProtocol::UnknownError, QByteArray());
- }
-}
-
-
-void BaselineHandler::provideBaselineChecksums(const QByteArray &itemListBlock)
-{
- ImageItemList itemList;
- QDataStream ds(itemListBlock);
- ds >> itemList;
- 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);
- 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;
- }
- }
- }
-
- // Find and mark blacklisted items
- QString context = pathForItem(itemList.at(0), true, false).section(QLC('/'), 0, -2);
- if (itemList.count() > 0) {
- QFile file(BaselineServer::storagePath() + QLC('/') + context + QLS("/BLACKLIST"));
- if (file.open(QIODevice::ReadOnly)) {
- QTextStream in(&file);
- do {
- QString itemName = in.readLine();
- if (!itemName.isNull()) {
- for (ImageItemList::iterator i = itemList.begin(); i != itemList.end(); ++i) {
- if (i->itemName == itemName)
- i->status = ImageItem::IgnoreItem;
- }
- }
- } while (!in.atEnd());
- }
- }
-
- QByteArray block;
- QDataStream ods(&block, QIODevice::WriteOnly);
- ods << itemList;
- proto.sendBlock(BaselineProtocol::Ack, block);
- report.addItems(itemList);
-}
-
-
-void BaselineHandler::storeImage(const QByteArray &itemBlock, bool isBaseline)
-{
- QDataStream ds(itemBlock);
- ImageItem item;
- ds >> item;
-
- QString prefix = pathForItem(item, isBaseline);
- 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;
- if (!cwd.exists(dir))
- cwd.mkpath(dir);
- item.image.save(prefix + QLS(FileFormat), FileFormat);
-
- 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.addMismatch(item);
-}
-
-
-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;
-}
-
-
-void BaselineHandler::receiveDisconnect()
-{
- qDebug() << runId << logtime() << "Client disconnected.";
- report.end();
- QThread::currentThread()->exit(0);
-}
-
-
-void BaselineHandler::mapPlatformInfo() const
-{
- mapped = plat;
-
- // Map hostname
- QString host = plat.value(PI_HostName).section(QLC('.'), 0, 0); // Filter away domain, if any
- if (host.isEmpty() || host == QLS("localhost")) {
- host = plat.value(PI_HostAddress);
- } else {
- 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);
- }
- }
- if (host.isEmpty())
- host = QLS("unknownhost");
- mapped.insert(PI_HostName, host);
-
- // Map qmakespec
- QString mkspec = plat.value(PI_QMakeSpec);
- mapped.insert(PI_QMakeSpec, mkspec.replace(QLC('/'), QLC('_')));
-
- // Map Qt version
- QString ver = plat.value(PI_QtVersion);
- mapped.insert(PI_QtVersion, ver.prepend(QLS("Qt-")));
-}
-
-QString BaselineHandler::pathForItem(const ImageItem &item, bool isBaseline, bool absolute) const
-{
- if (mapped.isEmpty())
- mapPlatformInfo();
-
- QString itemName = item.itemName.simplified();
- itemName.replace(QLC(' '), QLC('_'));
- itemName.replace(QLC('.'), QLC('_'));
- itemName.append(QLC('_'));
- 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.testFunction;
- path += mapped.value(PI_QtVersion);
- path += mapped.value(PI_QMakeSpec);
- path += mapped.value(PI_HostName);
- if (!isBaseline)
- path += runId;
- path += itemName + QLC('.');
-
- return path.join(QLS("/"));
-}
-
-
-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("*.") + QLS(FileFormat) << QLS("*.") + QLS(MetadataFileExt));
- while (it.hasNext()) {
- tot++;
- if (!QFile::remove(it.next()))
- failed++;
- }
- return QString(QLS("%1 of %2 baselines cleared from context ")).arg((tot-failed)/2).arg(tot/2) + context;
-}
-
-QString BaselineHandler::updateBaselines(const QString &context, const QString &mismatchContext, const QString &itemFile)
-{
- int tot = 0;
- int failed = 0;
- QString storagePrefix = BaselineServer::storagePath() + QLC('/');
- // If itemId is set, update just that one, otherwise, update all:
- QString filter = itemFile.isEmpty() ? QLS("*_????.") : itemFile;
- QDirIterator it(storagePrefix + mismatchContext, QStringList() << filter + QLS(FileFormat) << filter + QLS(MetadataFileExt));
- while (it.hasNext()) {
- tot++;
- it.next();
- QString oldFile = storagePrefix + context + QLC('/') + it.fileName();
- QFile::remove(oldFile); // Remove existing baseline file
- if (!QFile::copy(it.filePath(), oldFile)) // and replace it with the mismatch
- failed++;
- }
- return QString(QLS("%1 of %2 baselines updated in context %3 from context %4")).arg((tot-failed)/2).arg(tot/2).arg(context, mismatchContext);
-}
-
-QString BaselineHandler::blacklistTest(const QString &context, const QString &itemId, bool removeFromBlacklist)
-{
- QFile file(BaselineServer::storagePath() + QLC('/') + context + QLS("/BLACKLIST"));
- QStringList blackList;
- if (file.open(QIODevice::ReadWrite)) {
- while (!file.atEnd())
- blackList.append(file.readLine().trimmed());
-
- if (removeFromBlacklist)
- blackList.removeAll(itemId);
- else if (!blackList.contains(itemId))
- blackList.append(itemId);
-
- file.resize(0);
- foreach (QString id, blackList)
- file.write(id.toLatin1() + '\n');
- file.close();
- return QLS(removeFromBlacklist ? "Whitelisted " : "Blacklisted ") + itemId + QLS(" in context ") + context;
- } else {
- return QLS("Unable to update blacklisted tests, failed to open ") + file.fileName();
- }
-}
-
-
-void BaselineHandler::testPathMapping()
-{
- qDebug() << "Storage prefix:" << BaselineServer::storagePath();
-
- QStringList hosts;
- hosts << QLS("bq-ubuntu910-x86-01")
- << QLS("bq-ubuntu910-x86-15")
- << QLS("osl-mac-master-5.test.qt.nokia.com")
- << QLS("osl-mac-master-6.test.qt.nokia.com")
- << QLS("sv-xp-vs-010")
- << QLS("sv-xp-vs-011")
- << QLS("sv-solaris-sparc-008")
- << QLS("macbuilder-02.test.troll.no")
- << QLS("bqvm1164")
- << QLS("chimera")
- << QLS("localhost")
- << QLS("");
-
- ImageItem item;
- item.testFunction = QLS("testPathMapping");
- item.itemName = QLS("arcs.qps");
- item.imageChecksums << 0x0123456789abcdefULL;
- item.itemChecksum = 0x0123;
-
- plat.insert(PI_QtVersion, QLS("5.0.0"));
- plat.insert(PI_BuildKey, QLS("(nobuildkey)"));
- 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);
- qDebug() << "Baseline from" << host << "->" << pathForItem(item, true);
- qDebug() << "Mismatch from" << host << "->" << pathForItem(item, false);
- }
-}
-
-
-QString BaselineHandler::computeMismatchScore(const QImage &baseline, const QImage &rendered)
-{
- if (baseline.size() != rendered.size() || baseline.format() != rendered.format())
- return QLS("[No score, incomparable images.]");
- if (baseline.depth() != 32)
- return QLS("[Score computation not implemented for format.]");
-
- int w = baseline.width();
- int h = baseline.height();
-
- uint ncd = 0; // number of differing color pixels
- uint nad = 0; // number of differing alpha pixels
- uint scd = 0; // sum of color pixel difference
- uint sad = 0; // sum of alpha pixel difference
-
- for (int y=0; y<h; ++y) {
- const QRgb *bl = (const QRgb *) baseline.constScanLine(y);
- const QRgb *rl = (const QRgb *) rendered.constScanLine(y);
- for (int x=0; x<w; ++x) {
- QRgb b = bl[x];
- QRgb r = rl[x];
- if (r != b) {
- int dr = qAbs(qRed(b) - qRed(r));
- int dg = qAbs(qGreen(b) - qGreen(r));
- int db = qAbs(qBlue(b) - qBlue(r));
- int ds = dr + dg + db;
- int da = qAbs(qAlpha(b) - qAlpha(r));
- if (ds) {
- ncd++;
- scd += ds;
- }
- if (da) {
- nad++;
- sad += da;
- }
- }
- }
- }
-
- double pcd = 100.0 * ncd / (w*h); // percent of pixels that differ
- double acd = ncd ? double(scd) / (3*ncd) : 0; // avg. difference
- QString res = QString(QLS("Diffscore: %1% (Num:%2 Avg:%3)")).arg(pcd, 0, 'g', 2).arg(ncd).arg(acd, 0, 'g', 2);
- if (baseline.hasAlphaChannel()) {
- double pad = 100.0 * nad / (w*h); // percent of pixels that differ
- double aad = nad ? double(sad) / (3*nad) : 0; // avg. difference
- res += QString(QLS(" Alpha-diffscore: %1% (Num:%2 Avg:%3)")).arg(pad, 0, 'g', 2).arg(nad).arg(aad, 0, 'g', 2);
- }
- return res;
-}
diff --git a/tests/arthur/baselineserver/src/baselineserver.h b/tests/arthur/baselineserver/src/baselineserver.h
deleted file mode 100644
index d73bb974f9..0000000000
--- a/tests/arthur/baselineserver/src/baselineserver.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#ifndef BASELINESERVER_H
-#define BASELINESERVER_H
-
-#include <QStringList>
-#include <QTcpServer>
-#include <QThread>
-#include <QTcpSocket>
-#include <QScopedPointer>
-#include <QTimer>
-#include <QDateTime>
-#include <QSettings>
-
-#include "baselineprotocol.h"
-#include "report.h"
-
-// #seconds between update checks
-#define HEARTBEAT 10
-#define MetadataFileExt "metadata"
-
-class BaselineServer : public QTcpServer
-{
- Q_OBJECT
-
-public:
- BaselineServer(QObject *parent = 0);
-
- static QString storagePath();
- static QString baseUrl();
- static QString settingsFilePath();
-
-protected:
- void incomingConnection(int socketDescriptor);
-
-private slots:
- void heartbeat();
-
-private:
- QTimer *heartbeatTimer;
- QDateTime meLastMod;
- QString lastRunId;
- int lastRunIdIdx;
- static QString storage;
- static QString url;
- static QString settingsFile;
-};
-
-
-
-class BaselineThread : public QThread
-{
- Q_OBJECT
-
-public:
- BaselineThread(const QString &runId, int socketDescriptor, QObject *parent);
- void run();
-
-private:
- QString runId;
- int socketDescriptor;
-};
-
-
-class BaselineHandler : public QObject
-{
- Q_OBJECT
-
-public:
- 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 updateBaselines(const QString &context, const QString &mismatchContext, const QString &itemFile);
- static QString blacklistTest(const QString &context, const QString &itemId, bool removeFromBlacklist = false);
-
-private slots:
- void receiveRequest();
- void receiveDisconnect();
-
-private:
- bool establishConnection();
- void provideBaselineChecksums(const QByteArray &itemListBlock);
- void storeImage(const QByteArray &itemBlock, bool isBaseline);
- 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;
- mutable PlatformInfo mapped;
- QString runId;
- bool connectionEstablished;
- Report report;
- QSettings *settings;
-};
-
-#endif // BASELINESERVER_H
diff --git a/tests/arthur/baselineserver/src/baselineserver.pro b/tests/arthur/baselineserver/src/baselineserver.pro
deleted file mode 100644
index 770662b5fd..0000000000
--- a/tests/arthur/baselineserver/src/baselineserver.pro
+++ /dev/null
@@ -1,30 +0,0 @@
-#-------------------------------------------------
-#
-# Project created by QtCreator 2010-08-11T11:51:09
-#
-#-------------------------------------------------
-
-QT += core network
-
-# gui needed for QImage
-# QT -= gui
-
-TARGET = baselineserver
-DESTDIR = ../bin
-CONFIG += console
-CONFIG -= app_bundle
-
-TEMPLATE = app
-
-include(../../common/baselineprotocol.pri)
-
-SOURCES += main.cpp \
- baselineserver.cpp \
- report.cpp
-
-HEADERS += \
- baselineserver.h \
- report.h
-
-RESOURCES += \
- baselineserver.qrc
diff --git a/tests/arthur/baselineserver/src/baselineserver.qrc b/tests/arthur/baselineserver/src/baselineserver.qrc
deleted file mode 100644
index b5cd6afadb..0000000000
--- a/tests/arthur/baselineserver/src/baselineserver.qrc
+++ /dev/null
@@ -1,5 +0,0 @@
-<RCC>
- <qresource prefix="/">
- <file>templates/view.html</file>
- </qresource>
-</RCC>
diff --git a/tests/arthur/baselineserver/src/main.cpp b/tests/arthur/baselineserver/src/main.cpp
deleted file mode 100644
index 8e5fa4e669..0000000000
--- a/tests/arthur/baselineserver/src/main.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#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
- Report::handleCGIQuery(queryString);
- return 0;
- }
-
- if (a.arguments().contains(QLatin1String("-testmapping"))) {
- BaselineHandler h(QLS("SomeRunId"));
- h.testPathMapping();
- return 0;
- }
-
- BaselineServer server;
- if (!server.listen(QHostAddress::Any, BaselineProtocol::ServerPort)) {
- qWarning("Failed to listen!");
- return 1;
- }
-
- qDebug() << "\n*****" << argv[0] << "started, ready to serve on port" << BaselineProtocol::ServerPort
- << "with baseline protocol version" << BaselineProtocol::ProtocolVersion << "*****\n";
- return a.exec();
-}
diff --git a/tests/arthur/baselineserver/src/report.cpp b/tests/arthur/baselineserver/src/report.cpp
deleted file mode 100644
index 7c2d6ac6df..0000000000
--- a/tests/arthur/baselineserver/src/report.cpp
+++ /dev/null
@@ -1,311 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $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);
- QString misCtx = handler->pathForItem(list.at(0), false, 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>Clear all baselines</b></a> for this testfunction (They will be recreated by the next run)</p>\n";
- out << "<p><a href=\"/cgi-bin/server.cgi?cmd=updateAllBaselines&context=" << ctx << "&mismatchContext=" << misCtx << "&url=" << pageUrl
- << "\"><b>Let these mismatching images be the new baselines</b></a> for this testfunction</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);
- QString itemFile = prefix.section(QLC('/'), -1);
- writeItem(baseline, rendered, item, itemFile, ctx, misCtx, 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 &itemFile, const QString &ctx, const QString &misCtx, 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&context=" << ctx << "&mismatchContext=" << misCtx
- << "&itemFile=" << itemFile << "&url=" << pageUrl << "\">Let this be the new baseline</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::updateBaselines(cgiUrl.queryItemValue(QLS("context")),
- cgiUrl.queryItemValue(QLS("mismatchContext")),
- cgiUrl.queryItemValue(QLS("itemFile")));
- } else if (command == QLS("updateAllBaselines")) {
- s << BaselineHandler::updateBaselines(cgiUrl.queryItemValue(QLS("context")),
- cgiUrl.queryItemValue(QLS("mismatchContext")),
- QString());
- } 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/report.h b/tests/arthur/baselineserver/src/report.h
deleted file mode 100644
index d21102d32f..0000000000
--- a/tests/arthur/baselineserver/src/report.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#ifndef REPORT_H
-#define REPORT_H
-
-#include "baselineprotocol.h"
-#include <QFile>
-#include <QTextStream>
-#include <QMap>
-#include <QStringList>
-
-class BaselineHandler;
-
-class Report
-{
-public:
- Report();
- ~Report();
-
- 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 write();
- void writeFunctionResults(const ImageItemList &list);
- void writeItem(const QString &baseline, const QString &rendered, const ImageItem &item,
- const QString &itemFile, const QString &ctx, const QString &misCtx, const QString &metadata);
- void writeHeader();
- void writeFooter();
- QString generateCompared(const QString &baseline, const QString &rendered, bool fuzzy = false);
- QString generateThumbnail(const QString &image);
-
- const BaselineHandler *handler;
- QString runId;
- PlatformInfo plat;
- QString rootDir;
- QString reportDir;
- QString path;
- QStringList testFunctions;
- QMap<QString, ImageItemList> itemLists;
- bool written;
- int numItems;
- int numMismatches;
- QTextStream out;
-};
-
-#endif // REPORT_H
diff --git a/tests/arthur/baselineserver/src/templates/view.html b/tests/arthur/baselineserver/src/templates/view.html
deleted file mode 100644
index c048f4781c..0000000000
--- a/tests/arthur/baselineserver/src/templates/view.html
+++ /dev/null
@@ -1,79 +0,0 @@
-<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>