/**************************************************************************** ** ** 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 "datagenerator.h" #include "qengines.h" #include "xmlgenerator.h" #include #include #include #include #include #include #include #include #include #include #include #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."<\n" << "\t-engine |onscreen|printing\n" << "\t-suite \n" << "\t-testcase \n" << "\t-file \n" << "\t-size \n" << "\t-fill \n" << "\t-output \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 = "<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 " < 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 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 "< engines = QtEngines::self()->engines(); bool found = false; if (engineName == QLatin1String("onscreen")|| engineName == QLatin1String("printing")) found = true; else { for (int i=0; iname() == engineName); } if (!found) { qDebug("No such engine: '%s'\nAvailable engines are:", qPrintable(engineName)); for (int i=0; iname())); 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 " < 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: "< 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 "<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; }