summaryrefslogtreecommitdiffstats
path: root/tests/arthur/datagenerator
diff options
context:
space:
mode:
Diffstat (limited to 'tests/arthur/datagenerator')
-rw-r--r--tests/arthur/datagenerator/datagenerator.cpp481
-rw-r--r--tests/arthur/datagenerator/datagenerator.h103
-rw-r--r--tests/arthur/datagenerator/datagenerator.pri2
-rw-r--r--tests/arthur/datagenerator/datagenerator.pro22
-rw-r--r--tests/arthur/datagenerator/main.cpp54
-rw-r--r--tests/arthur/datagenerator/xmlgenerator.cpp262
-rw-r--r--tests/arthur/datagenerator/xmlgenerator.h73
7 files changed, 997 insertions, 0 deletions
diff --git a/tests/arthur/datagenerator/datagenerator.cpp b/tests/arthur/datagenerator/datagenerator.cpp
new file mode 100644
index 0000000000..2ffcc76270
--- /dev/null
+++ b/tests/arthur/datagenerator/datagenerator.cpp
@@ -0,0 +1,481 @@
+/****************************************************************************
+**
+** 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$
+** 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 "datagenerator.h"
+
+#include "qengines.h"
+#include "xmlgenerator.h"
+
+#include <QDateTime>
+#include <QDir>
+#include <QFile>
+#include <QFileInfo>
+#include <QSvgRenderer>
+#include <QImage>
+#include <QPainter>
+#include <QProcess>
+#include <QSettings>
+#include <QtDebug>
+
+#include <iostream>
+
+#define W3C_SVG_BASE "http://www.w3.org/Graphics/SVG/Test/20030813/png/"
+
+static QString createW3CReference(const QString &refUrl, const QString &filename)
+{
+ QString base(refUrl);
+
+ QString pngFile = filename;
+ pngFile.replace(".svg", ".png");
+
+ base += "full-";
+
+ base += pngFile;
+ return base;
+}
+
+
+static QString createOutFilename(const QString &baseDir, const QString &filename,
+ QEngine *engine)
+{
+ QString outFile = filename;
+ if (outFile.endsWith(".svgz"))
+ outFile.replace(".svgz", ".png");
+ else
+ outFile.replace(".svg", ".png");
+
+ outFile.replace(".qps", ".qps.png");
+
+ if (!baseDir.isEmpty())
+ outFile = QString("%1/%2/%3").arg(baseDir)
+ .arg(engine->name()).arg(outFile);
+ else
+ outFile = QString("%1/%2").arg(engine->name())
+ .arg(outFile);
+
+ return outFile;
+}
+
+static void usage(const char *progname)
+{
+ std::cerr << "Couldn't find 'framework.ini' "
+ << "file and no suite has been specified."<<std::endl;
+ std::cerr << "Usage: "<<progname << "\n"
+ << "\t-framework <framework.ini>\n"
+ << "\t-engine <engine name>|onscreen|printing\n"
+ << "\t-suite <suite name>\n"
+ << "\t-testcase <file.svg>\n"
+ << "\t-file </path/to/file.svg>\n"
+ << "\t-size <width,height>\n"
+ << "\t-fill <color>\n"
+ << "\t-output <dirname>\n"
+ << std::endl;
+}
+
+DataGenerator::DataGenerator()
+ : iterations(1)
+ , size(480, 360)
+ , fillColor(Qt::white)
+{
+ settings.load(QString("framework.ini"));
+ renderer = new QSvgRenderer();
+}
+
+DataGenerator::~DataGenerator()
+{
+}
+
+void DataGenerator::run(int argc, char **argv)
+{
+ if (!processArguments(argc, argv))
+ return;
+
+ if (!fileName.isEmpty()) {
+ testGivenFile();
+ return;
+ }
+ if (!settings.isValid() && suiteName.isEmpty()) {
+ usage(argv[0]);
+ return;
+ }
+
+ prepareDirs();
+ if (!settings.isValid()) { //only suite specified
+ XMLGenerator generator(outputDirName);
+ testSuite(generator, suiteName,
+ QString(), QString());
+ return;
+ }
+
+ XMLGenerator generator(outputDirName);
+ QStringList tests = settings.suites();
+ qDebug()<<"tests = "<<tests;
+ foreach(QString test, tests) {
+ if (!suiteName.isEmpty() && test != suiteName)
+ continue;
+
+ qDebug()<<"testing "<<test;
+ settings.settings()->beginGroup(test);
+
+ QString dirName = settings.settings()->value("dir").toString();
+ QString refUrl = settings.settings()->value("reference").toString();
+
+ QDir dir(dirName);
+ if (!dir.isAbsolute() && !dir.exists())
+ dir = QDir(QString("%1/%2").arg(baseDataDir).arg(dirName));
+
+ testSuite(generator, test, dir.absolutePath(), refUrl);
+ settings.settings()->endGroup();
+ }
+ generator.generateOutput(outputDirName);
+}
+
+void DataGenerator::testEngines(XMLGenerator &generator, const QString &file,
+ const QString &refUrl)
+{
+ QFileInfo fileInfo(file);
+
+ generator.startTestcase(file);
+
+ if (!refUrl.isEmpty()) {
+ QString ref = createW3CReference(refUrl, fileInfo.fileName());
+ generator.addImage("Reference", ref, XMLData(), Reference);
+ }
+
+ //bool isQpsScript = file.endsWith(".qps");
+ bool isSvgFile = file.endsWith(".svg") || file.endsWith(".svgz");
+
+ if (isSvgFile) {
+ QDir oldDir = QDir::current();
+ if (!baseDataDir.isEmpty()) {
+ QDir::setCurrent(baseDataDir);
+ }
+ renderer->load(fileInfo.absoluteFilePath());
+ if (!baseDataDir.isEmpty()) {
+ QDir::setCurrent(oldDir.absolutePath());
+ }
+ if (!renderer->isValid()) {
+ qWarning()<<"Error while processing " <<file;
+ return;
+ }
+ }
+
+ QList<QEngine*> engines = QtEngines::self()->engines();
+ testGivenEngines(engines, fileInfo, file, generator, Normal);
+
+ engines = QtEngines::self()->foreignEngines();
+ testGivenEngines(engines, fileInfo, file, generator, Foreign);
+
+ generator.endTestcase();
+}
+
+void DataGenerator::prepareDirs()
+{
+ QList<QEngine*> engines = QtEngines::self()->engines();
+ QDir outDirs;
+ foreach(QEngine *engine, engines) {
+ if (!wantedEngine(engine->name()))
+ continue;
+
+ QString dirName = engine->name();
+ if (!outputDirName.isEmpty())
+ dirName = QString("%1/%2").arg(outputDirName).arg(dirName);
+ outDirs.mkpath(dirName);
+ }
+
+ engines = QtEngines::self()->foreignEngines();
+ foreach(QEngine *engine, engines) {
+ if (!wantedEngine(engine->name()))
+ continue;
+
+ QString dirName = engine->name();
+ if (!outputDirName.isEmpty())
+ dirName = QString("%1/%2").arg(outputDirName).arg(dirName);
+ outDirs.mkpath(dirName);
+ }
+}
+
+bool DataGenerator::processArguments(int argc, char **argv)
+{
+ QString frameworkFile;
+ for (int i=1; i < argc; ++i) {
+ QString opt(argv[i]);
+ if (opt == "-framework") {
+ frameworkFile = QString(argv[i+1]);
+ } else if (opt == "-engine") {
+ engineName = QString(argv[i+1]);
+ } else if (opt == "-suite") {
+ suiteName = QString(argv[i+1]);
+ } else if (opt == "-testcase") {
+ testcase = QString(argv[i+1]);
+ } else if (opt == "-file") {
+ fileName = QString(argv[i+1]);
+ } else if (opt == "-output") {
+ outputDirName = QString(argv[i+1]);
+ } else if (opt == "-iterations") {
+ iterations = QString(argv[i+1]).toInt();
+ } else if (opt == "-size") {
+ QStringList args = QString(argv[i+1]).split(",", QString::SkipEmptyParts);
+ size = QSize(args[0].toInt(), args.size() > 1 ? args[1].toInt() : args[0].toInt());
+ } else if (opt == "-fill") {
+ fillColor = QColor(QString(argv[i+1]));
+ } else if (opt.startsWith('-')) {
+ qDebug()<<"Unknown option "<<opt;
+ }
+ }
+ if (!frameworkFile.isEmpty() && QFile::exists(frameworkFile)) {
+ baseDataDir = QFileInfo(frameworkFile).absoluteDir().absolutePath();
+ settings.load(frameworkFile);
+ }
+
+ if (outputDirName.isEmpty() && settings.isValid()) {
+ outputDirName = settings.outputDir();
+ }
+
+ if (!outputDirName.isEmpty()) {
+ QDir dir;
+ dir.mkpath(outputDirName);
+ }
+
+
+ if (!engineName.isEmpty()) {
+ QList<QEngine *> engines = QtEngines::self()->engines();
+ bool found = false;
+ if (engineName == QLatin1String("onscreen")||
+ engineName == QLatin1String("printing"))
+ found = true;
+ else {
+ for (int i=0; i<engines.size(); ++i)
+ found |= (engines.at(i)->name() == engineName);
+ }
+ if (!found) {
+ qDebug("No such engine: '%s'\nAvailable engines are:", qPrintable(engineName));
+ for (int i=0; i<engines.size(); ++i)
+ qDebug(" %s", qPrintable(engines.at(i)->name()));
+ return false;
+ }
+ }
+
+ if (!fileName.isEmpty()) {
+ baseDataDir = QFileInfo(fileName).absoluteDir().absolutePath();
+ }
+
+ return true;
+}
+
+void DataGenerator::testGivenFile()
+{
+ prepareDirs();
+
+ XMLGenerator generator(baseDataDir);
+ generator.startSuite("Single");
+
+ QFileInfo fileInfo(fileName);
+
+ bool qpsScript = fileName.endsWith("qps");
+ if (!qpsScript) {
+ QDir oldDir = QDir::current();
+ if (!baseDataDir.isEmpty()) {
+ QDir::setCurrent(baseDataDir);
+ }
+ renderer->load(fileInfo.absoluteFilePath());
+
+ if (!baseDataDir.isEmpty()) {
+ QDir::setCurrent(oldDir.absolutePath());
+ }
+
+ if (!renderer->isValid()) {
+ qWarning()<<"Error while processing " <<fileInfo.absolutePath();
+ return;
+ }
+ }
+
+ QList<QEngine*> engines = QtEngines::self()->engines();
+ testGivenEngines(engines, fileInfo, fileInfo.fileName(), generator,
+ Normal);
+ generator.endSuite();
+
+ std::cout<< qPrintable(generator.generateData());
+}
+
+void DataGenerator::testSuite(XMLGenerator &generator, const QString &test,
+ const QString &dirName, const QString &refUrl)
+{
+ generator.startSuite(test);
+
+ QDir dir(dirName);
+ dir.setFilter(QDir::Files | QDir::NoSymLinks);
+ //dir.setNameFilter()
+
+ foreach (QFileInfo fileInfo, dir.entryInfoList()) {
+ if (!testcase.isEmpty() && fileInfo.fileName() != testcase)
+ continue;
+ QString suffix = fileInfo.suffix().toLower();
+ if (suffix != "qps" && suffix != "svg" && suffix != "svgz")
+ continue;
+ qDebug()<<"Testing: "<<fileInfo.absoluteFilePath();
+ testEngines(generator, fileInfo.absoluteFilePath(), refUrl);
+ }
+
+ generator.endSuite();
+}
+
+static QString loadFile(const QString &name)
+{
+ QFile file(name);
+ if (!file.open(QFile::ReadOnly)) {
+ qDebug("Can't open file '%s'", qPrintable(name));
+ return QString();
+ }
+ QTextStream str(&file);
+ return str.readAll();
+}
+
+void DataGenerator::testGivenEngines(const QList<QEngine*> engines,
+ const QFileInfo &fileInfo,
+ const QString &file,
+ XMLGenerator &generator,
+ GeneratorFlags eflags)
+{
+ QString fileName = fileInfo.absoluteFilePath();
+ bool qpsScript = fileName.endsWith(".qps");
+ QStringList qpsContents;
+ if (qpsScript) {
+ QString script = loadFile(fileName);
+ qpsContents = script.split("\n", QString::SkipEmptyParts);
+ }
+
+ //foreign one don't generate qpsScripts
+ if ((eflags & Foreign) && qpsScript)
+ return;
+
+ foreach (QEngine *engine, engines) {
+ if (!wantedEngine(engine->name()))
+ continue;
+ if (settings.isTestBlacklisted(engine->name(), fileInfo.fileName())) {
+ XMLData data;
+ data.details = QString("Test blacklisted");
+ data.iterations = 1;
+ generator.addImage(engine->name(), QString(""), data, eflags);
+ continue;
+ }
+
+ QString outFilename = createOutFilename(outputDirName,
+ fileInfo.fileName(), engine);
+ engine->prepare(qpsScript ? QSize(800, 800) : size, fillColor);
+ int elapsed = -1;
+ int maxElapsed = 0;
+ int minElapsed = 0;
+ if ((eflags & Foreign)) {
+ engine->render(renderer, file);
+ engine->save(outFilename);
+ } else {
+ bool saved = false;
+ //only measure Qt engines
+ QTime time;
+ int currentElapsed = 0;
+ for (int i = 0; i < iterations; ++i) {
+ if (qpsScript) {
+ QDir oldDir = QDir::current();
+ if (!baseDataDir.isEmpty()) {
+ QDir::setCurrent(baseDataDir+"/images");
+ }
+ time.start();
+ engine->render(qpsContents, fileName);
+ currentElapsed = time.elapsed();
+ if (!baseDataDir.isEmpty()) {
+ QDir::setCurrent(oldDir.absolutePath());
+ }
+ } else {
+ time.start();
+ engine->render(renderer, file);
+ currentElapsed = time.elapsed();
+ }
+ if (currentElapsed > maxElapsed)
+ maxElapsed = currentElapsed;
+ if (!minElapsed ||
+ currentElapsed < minElapsed)
+ minElapsed = currentElapsed;
+ elapsed += currentElapsed;
+ if (!saved) {
+ //qDebug()<<"saving "<<i<<engine->name();
+ engine->save(outFilename);
+ engine->cleanup();
+ engine->prepare(size, fillColor);
+ saved = true;
+ }
+ }
+ engine->cleanup();
+ }
+ GeneratorFlags flags = Normal;
+ if (QtEngines::self()->defaultEngine() == engine)
+ flags |= Default;
+ flags |= eflags;
+ if ((eflags & Foreign))
+ flags ^= Normal;
+ XMLData data;
+ data.date = QDateTime::currentDateTime();
+ data.timeToRender = elapsed;
+ data.iterations = iterations;
+ data.maxElapsed = maxElapsed;
+ data.minElapsed = minElapsed;
+ generator.addImage(engine->name(), outFilename,
+ data, flags);
+ }
+}
+
+bool DataGenerator::wantedEngine(const QString &engine) const
+{
+ if (!engineName.isEmpty() &&
+ engine != engineName) {
+ if (engineName == "onscreen") {
+ if (engine.startsWith("Native") ||
+ engine == QLatin1String("Raster") ||
+ engine == QLatin1String("OpenGL"))
+ return true;
+ } else if (engineName == QLatin1String("printing")) {
+ if (engine == QLatin1String("PS") ||
+ engine == QLatin1String("PDF"))
+ return true;
+ }
+ return false;
+ }
+ return true;
+}
diff --git a/tests/arthur/datagenerator/datagenerator.h b/tests/arthur/datagenerator/datagenerator.h
new file mode 100644
index 0000000000..cef49e11b1
--- /dev/null
+++ b/tests/arthur/datagenerator/datagenerator.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** 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$
+** 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 DATAGENERATOR_H
+#define DATAGENERATOR_H
+
+#include "xmlgenerator.h"
+#include "framework.h"
+
+#include <QTextStream>
+#include <QSettings>
+#include <QSize>
+#include <QColor>
+
+QT_FORWARD_DECLARE_CLASS(QSvgRenderer)
+QT_FORWARD_DECLARE_CLASS(QEngine)
+QT_FORWARD_DECLARE_CLASS(QFileInfo)
+
+class DataGenerator
+{
+public:
+ DataGenerator();
+ ~DataGenerator();
+
+ void run(int argc, char **argv);
+private:
+ bool processArguments(int argc, char **argv);
+ void testEngines(XMLGenerator &generator, const QString &file,
+ const QString &refUrl);
+ void testDirectory(const QString &dirname, const QString &refUrl);
+ void testFile(const QString &file, const QString &refUrl,
+ QTextStream &out, QTextStream &hout);
+ void testGivenFile();
+ void testSuite(XMLGenerator &generator, const QString &suite,
+ const QString &dirName, const QString &refUrl);
+ void prepareDirs();
+
+ void testGivenEngines(const QList<QEngine*> engines,
+ const QFileInfo &fileInfo,
+ const QString &file,
+ XMLGenerator &generator,
+ GeneratorFlags flags);
+ void testGivenEngines(const QList<QEngine*> engines,
+ const QFileInfo &fileInfo,
+ const QString &file,
+ XMLGenerator &generator,
+ int iterations,
+ GeneratorFlags flags);
+
+ bool wantedEngine(const QString &engine) const;
+private:
+ QSvgRenderer *renderer;
+ Framework settings;
+
+ QString engineName;
+ QString suiteName;
+ QString testcase;
+ QString fileName;
+ QString outputDirName;
+ QString baseDataDir;
+ int iterations;
+ QSize size;
+ QColor fillColor;
+};
+
+#endif
diff --git a/tests/arthur/datagenerator/datagenerator.pri b/tests/arthur/datagenerator/datagenerator.pri
new file mode 100644
index 0000000000..987573f956
--- /dev/null
+++ b/tests/arthur/datagenerator/datagenerator.pri
@@ -0,0 +1,2 @@
+VPATH += $$PWD
+SOURCES += datagenerator.cpp xmlgenerator.cpp
diff --git a/tests/arthur/datagenerator/datagenerator.pro b/tests/arthur/datagenerator/datagenerator.pro
new file mode 100644
index 0000000000..9da6fcd5c5
--- /dev/null
+++ b/tests/arthur/datagenerator/datagenerator.pro
@@ -0,0 +1,22 @@
+# -*- Mode: makefile -*-
+COMMON_FOLDER = $$PWD/../common
+include(../arthurtester.pri)
+CONFIG += debug console
+TEMPLATE = app
+TARGET = datagenerator
+DEPENDPATH += .
+INCLUDEPATH += .
+DESTDIR = ../bin
+
+QT += svg xml
+contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles1)|contains(QT_CONFIG, opengles2):QT += opengl
+contains(QT_CONFIG, qt3support):QT += qt3support
+
+# Input
+HEADERS += datagenerator.h \
+ xmlgenerator.h
+SOURCES += main.cpp datagenerator.cpp \
+ xmlgenerator.cpp
+
+DEFINES += QT_USE_USING_NAMESPACE
+
diff --git a/tests/arthur/datagenerator/main.cpp b/tests/arthur/datagenerator/main.cpp
new file mode 100644
index 0000000000..e85733634e
--- /dev/null
+++ b/tests/arthur/datagenerator/main.cpp
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** 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$
+** 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 <QApplication>
+
+#include "datagenerator.h"
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+
+ DataGenerator tester;
+
+ tester.run(argc, argv);
+
+ return 0;
+}
diff --git a/tests/arthur/datagenerator/xmlgenerator.cpp b/tests/arthur/datagenerator/xmlgenerator.cpp
new file mode 100644
index 0000000000..919870b74d
--- /dev/null
+++ b/tests/arthur/datagenerator/xmlgenerator.cpp
@@ -0,0 +1,262 @@
+/****************************************************************************
+**
+** 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$
+** 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 "xmlgenerator.h"
+
+#include "qengines.h"
+
+#include <QtXml>
+#include <QDir>
+
+XMLGenerator::XMLGenerator(const QString &baseDir)
+{
+ QList<QEngine*> qengines = QtEngines::self()->engines();
+ foreach(QEngine *engine, qengines) {
+ QString engineDir = engine->name();
+ QString fileName = engineDir + "/" + "data.xml";
+
+ if (!baseDir.isEmpty()) {
+ engineDir = QString("%1/%2").arg(baseDir).arg(engineDir);
+ fileName = QString("%1/%2").arg(baseDir).arg(fileName);
+ }
+
+ if (!QFile::exists(fileName))
+ continue;
+
+
+ XMLReader handler;
+ QXmlSimpleReader reader;
+ reader.setContentHandler(&handler);
+ reader.setErrorHandler(&handler);
+
+ QFile file(fileName);
+ if (!file.open(QFile::ReadOnly | QFile::Text)) {
+ qWarning("Cannot open file '%s', because: %s",
+ qPrintable(fileName), qPrintable(file.errorString()));
+ continue;
+ }
+
+ QXmlInputSource xmlInputSource(&file);
+ if (reader.parse(xmlInputSource)) {
+ XMLEngine *engine = handler.xmlEngine();
+ checkDirs(engine->generationDate, engineDir);
+ engines.insert(engine->name, engine);
+ }
+ }
+}
+
+
+void XMLGenerator::startSuite(const QString &name)
+{
+ currentSuite = name;
+}
+
+
+void XMLGenerator::startTestcase(const QString &testcase)
+{
+ currentTestcase = testcase;
+}
+
+
+void XMLGenerator::addImage(const QString &engineName, const QString &image,
+ const XMLData &data, GeneratorFlags flags)
+{
+ XMLEngine *engine;
+ if (engines.contains(engineName))
+ engine = engines[engineName];
+ else {
+ engine = new XMLEngine(engineName, flags & Default);
+ engine->defaultEngine = (flags & Default);
+ engine->foreignEngine = (flags & Foreign);
+ engine->referenceEngine = (flags & Reference);
+ engine->generationDate = QDateTime::currentDateTime();
+ engines.insert(engineName, engine);
+ }
+
+ XMLSuite *suite;
+ if (engine->suites.contains(currentSuite))
+ suite = engine->suites[currentSuite];
+ else {
+ suite = new XMLSuite(currentSuite);
+ engine->suites.insert(currentSuite, suite);
+ }
+
+ XMLFile *file;
+ if (suite->files.contains(currentTestcase))
+ file = suite->files[currentTestcase];
+ else {
+ file = new XMLFile(currentTestcase);
+ suite->files.insert(currentTestcase, file);
+ }
+
+ file->output = image;
+ file->data += data;
+}
+
+
+void XMLGenerator::endTestcase()
+{
+
+}
+
+
+void XMLGenerator::endSuite()
+{
+
+}
+
+static void generateDataFile(QTextStream &out, XMLEngine *engine)
+{
+ QString indent;
+ out << "<arthur engine=\""<<engine->name<<"\" default=\"";
+ if (engine->defaultEngine) {
+ out<<"true\"";
+ } else
+ out<<"false\"";
+
+ out << " foreign=\"" << (engine->foreignEngine?"true":"false")
+ << "\" reference=\"" << (engine->referenceEngine?"true":"false")
+ << "\" generationDate=\"" << (engine->generationDate.toString())
+ << "\">\n";
+
+ indent += " ";
+ foreach(XMLSuite *suite, engine->suites) {
+ out << indent << "<suite dir=\"" << suite->name << "\">\n";
+ indent += " ";
+
+ foreach(XMLFile *file, suite->files) {
+ out << indent << "<file name=\""<<file->name<<"\" output=\""<<file->output<<"\">\n";
+ indent += " ";
+ foreach(XMLData data, file->data) {
+ out << indent
+ << "<data date=\""<<data.date.toString()
+ << "\" time_to_render=\""<<data.timeToRender
+ << "\" iterations=\""<<data.iterations
+ << "\" details=\""<<data.details
+ << "\" maxElapsed=\""<<data.maxElapsed
+ << "\" minElapsed=\""<<data.minElapsed
+ << "\" />\n";
+ }
+ indent.chop(2);
+ out << indent << "</file>\n";
+ }
+
+ indent.chop(2);
+ out << indent << "</suite>\n";
+ }
+
+ out << "</arthur>";
+}
+
+void XMLGenerator::generateOutput(const QString &baseDir)
+{
+ QDir dir;
+ if (!baseDir.isEmpty()) {
+ dir = QDir(baseDir);
+ }
+ foreach(XMLEngine *engine, engines) {
+ QFile file(QString("%1/%2/data.xml").arg(dir.absolutePath())
+ .arg(engine->name));
+
+ dir.mkpath(QFileInfo(file).absolutePath());
+
+ if (!file.open(QFile::WriteOnly | QFile::Truncate)) {
+ fprintf(stderr, "Failed to open output file '%s' for writing\n",
+ qPrintable(QFileInfo(file).absoluteFilePath()));
+ return;
+ }
+ QTextStream out(&file);
+ generateDataFile(out, engine);
+ }
+}
+
+QString XMLGenerator::generateData() const
+{
+ QString str;
+ foreach(XMLEngine *engine, engines) {
+ QTextStream out(&str);
+ generateDataFile(out, engine);
+ }
+ return str;
+}
+
+void XMLGenerator::checkDirs(const QDateTime &currentDate, const QString &engineDir)
+{
+ QDateTime yesterday = QDateTime::currentDateTime();
+ QDateTime lastWeek = QDateTime::currentDateTime();
+ yesterday = yesterday.addDays(-1);
+ lastWeek = lastWeek.addDays(-7);
+
+ if (currentDate <= yesterday) {
+ QString newDir = engineDir + ".yesterday";
+ if (QFile::exists(engineDir)) {
+ //### handle last week
+ QString oldFileName = QString("%1/data.xml").arg(newDir);
+ XMLReader handler;
+ QXmlSimpleReader reader;
+ reader.setContentHandler(&handler);
+ reader.setErrorHandler(&handler);
+ QFile file(oldFileName);
+ if (file.open(QFile::ReadOnly | QFile::Text)) {
+ QXmlInputSource xmlInputSource(&file);
+ if (reader.parse(xmlInputSource)) {
+ XMLEngine *engine = handler.xmlEngine();
+ if (engine->generationDate <= lastWeek) {
+ QString newDir = engineDir + ".lastweek";
+ qDebug()<<"Backing last weeks's "<< qPrintable(engine->name);
+ QStringList args;
+ args << "-rf";
+ args << engineDir;
+ args << newDir;
+ QProcess::execute("cp", args);
+ }
+ }
+ }
+ }
+ qDebug()<<"Backing yesterday's "<< engineDir;
+ QStringList args;
+ args << "-rf";
+ args << engineDir;
+ args << newDir;
+ QProcess::execute("cp", args);
+ }
+}
+
+
diff --git a/tests/arthur/datagenerator/xmlgenerator.h b/tests/arthur/datagenerator/xmlgenerator.h
new file mode 100644
index 0000000000..0dbdaebc7e
--- /dev/null
+++ b/tests/arthur/datagenerator/xmlgenerator.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** 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$
+** 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 XMLGENERATOR_H
+#define XMLGENERATOR_H
+
+#include "xmldata.h"
+
+#include <QDateTime>
+#include <QMap>
+#include <QList>
+#include <QString>
+
+
+class XMLGenerator
+{
+public:
+ XMLGenerator(const QString &baseDir);
+
+ void startSuite(const QString &name);
+ void startTestcase(const QString &testcase);
+ void addImage(const QString &engine, const QString &image,
+ const XMLData &data, GeneratorFlags flags);
+ void endTestcase();
+ void endSuite();
+
+ void checkDirs(const QDateTime &dt, const QString &baseDir);
+ void generateOutput(const QString &baseDir);
+ QString generateData() const;
+private:
+ QMap<QString, XMLEngine*> engines;
+ QString currentSuite;
+ QString currentTestcase;
+};
+
+#endif