From 0d18809a78021709f024e85c5251815a5864a7e3 Mon Sep 17 00:00:00 2001 From: aavit Date: Fri, 3 Sep 2010 10:29:10 +0200 Subject: Protocol rewrite done; design cleaned up. Client no longer fetches baseline images, not even on mismatch. Bitwise comparison, mismatch score etc. will be done on server, if wanted. --- tests/arthur/baselineserver/src/baselineserver.cpp | 74 +++++--- tests/arthur/baselineserver/src/baselineserver.h | 4 +- tests/arthur/common/baselineprotocol.cpp | 58 +------ tests/arthur/common/baselineprotocol.h | 11 +- tests/auto/lancelot/tst_lancelot.cpp | 190 ++++----------------- 5 files changed, 95 insertions(+), 242 deletions(-) diff --git a/tests/arthur/baselineserver/src/baselineserver.cpp b/tests/arthur/baselineserver/src/baselineserver.cpp index 3087357..0f95474 100644 --- a/tests/arthur/baselineserver/src/baselineserver.cpp +++ b/tests/arthur/baselineserver/src/baselineserver.cpp @@ -110,9 +110,6 @@ void BaselineHandler::receiveRequest() case BaselineProtocol::RequestBaselineChecksums: provideBaselineChecksums(block); break; - case BaselineProtocol::RequestBaseline: - provideBaseline(block); - break; case BaselineProtocol::AcceptNewBaseline: storeImage(block, true); break; @@ -154,24 +151,6 @@ void BaselineHandler::provideBaselineChecksums(const QByteArray &itemListBlock) } -void BaselineHandler::provideBaseline(const QByteArray &caseId) -{ - qDebug() << runId << logtime() << "Received request for baseline" << caseId; - - //### rewrite to use ImageItem - /* - QFile file(pathForCaseId(caseId)); - if (!file.open(QIODevice::ReadOnly)) { - qDebug() << runId << logtime() << "baseline not found."; - proto.sendBlock(BaselineProtocol::BaselineNotPresent, caseId); - return; - } - - proto.sendBlock(BaselineProtocol::AcceptBaseline, file.readAll()); - */ -} - - void BaselineHandler::storeImage(const QByteArray &itemBlock, bool isBaseline) { QDataStream ds(itemBlock); @@ -200,7 +179,6 @@ void BaselineHandler::storeImage(const QByteArray &itemBlock, bool isBaseline) + QHostInfo::localDomainName().toLatin1() + ':' + QFileInfo(file).absoluteFilePath().toLatin1(); proto.sendBlock(BaselineProtocol::Ack, msg); - qDebug() << runId << logtime() << "Storing done."; } @@ -225,6 +203,52 @@ QString BaselineHandler::pathForItem(const ImageItem &item, bool isBaseline) } -// - transferring and comparing checksums instead of images -// - then we could now if multiple error/imgs are really the same (and just store it once) -// - e.g. using db +QString BaselineHandler::computeMismatchScore(const QImage &baseline, const QImage &rendered) +{ + if (baseline.size() != rendered.size() || baseline.format() != rendered.format()) + return QLatin1String("[No score, incomparable images.]"); + if (baseline.depth() != 32) + return QLatin1String("[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; yisNull()) { - errMsg.prepend(QLatin1String("Invalid baseline image data received. ")); - return false; - } - } - return true; - } - errMsg.prepend(QLatin1String("Unexpected reply from server on baseline request. ")); - return false; + return (sendItem(AcceptNewBaseline, item) && receiveBlock(&cmd, serverMsg) && cmd == Ack); } -bool BaselineProtocol::submitNewBaseline(const ImageItem &item) +bool BaselineProtocol::submitMismatch(const ImageItem &item, QByteArray *serverMsg) { - return sendItem(AcceptNewBaseline, item); + Command cmd; + return (sendItem(AcceptMismatch, item) && receiveBlock(&cmd, serverMsg) && cmd == Ack); } @@ -188,32 +166,6 @@ bool BaselineProtocol::sendItem(Command cmd, const ImageItem &item) errMsg.prepend(QLatin1String("Failed to submit image to server. ")); return false; } - receiveBlock(&cmd, 0); // For now, Just wait for the pong; ignore reply contents - return true; -} - - -bool BaselineProtocol::submitMismatch(const QString &caseId, const QImage &mismatch, QByteArray *failMsg) -{ - //### TBD: rewrite to use ImageItem - errMsg.clear(); - QBuffer buf; - buf.open(QIODevice::WriteOnly); - QDataStream ds(&buf); - ds << caseId.toLatin1(); - if (!mismatch.save(&buf, FileFormat)) { - errMsg = QLatin1String("Failed to convert mismatched image to ") + QLatin1String(FileFormat); - return false; - } - if (!sendBlock(AcceptMismatch, buf.data())) { - errMsg.prepend(QLatin1String("Failed to submit mismatched image to server. ")); - return false; - } - Command cmd; - if (!receiveBlock(&cmd, failMsg)) { - errMsg.prepend(QLatin1String("Failed to receive response on mismatched image from server. ")); - return false; - } return true; } diff --git a/tests/arthur/common/baselineprotocol.h b/tests/arthur/common/baselineprotocol.h index b16a55b..749b623 100644 --- a/tests/arthur/common/baselineprotocol.h +++ b/tests/arthur/common/baselineprotocol.h @@ -80,24 +80,17 @@ public: // Queries AcceptPlatformInfo = 1, RequestBaselineChecksums = 2, - RequestBaseline = 3, AcceptNewBaseline = 4, AcceptMismatch = 5, // Responses Ack = 128, - - //#### remove these: - AcceptBaseline = 129, - BaselineNotPresent = 130, - IgnoreCase = 131 }; // For client: bool connect(); bool requestBaselineChecksums(ImageItemList *itemList); - bool requestBaseline(const QString &caseId, Command *response, QImage *baseline); - bool submitNewBaseline(const ImageItem &item); - bool submitMismatch(const QString &caseId, const QImage &mismatch, QByteArray *failMsg); + bool submitNewBaseline(const ImageItem &item, QByteArray *serverMsg); + bool submitMismatch(const ImageItem &item, QByteArray *serverMsg); // For server: bool acceptConnection(PlatformInfo *pi); diff --git a/tests/auto/lancelot/tst_lancelot.cpp b/tests/auto/lancelot/tst_lancelot.cpp index a6bb68f..4485880 100644 --- a/tests/auto/lancelot/tst_lancelot.cpp +++ b/tests/auto/lancelot/tst_lancelot.cpp @@ -64,13 +64,10 @@ public: tst_Lancelot(); private: - QImage getBaseline(const QString &fileName, bool *created); - QImage render(const QString &fileName, QImage::Format format); + ImageItem render(const ImageItem &item); QStringList loadScriptFile(const QString &filePath); - QString computeMismatchScore(const QImage& baseline, const QImage& rendered); void runTestSuite(); - QString errorMsg; BaselineProtocol proto; ImageItemList baseList; @@ -108,24 +105,24 @@ void tst_Lancelot::initTestCase() } baseList.resize(files.count()); - int i = 0; + ImageItemList::iterator it = baseList.begin(); foreach(const QString& file, files) { - baseList[i].scriptName = file; + it->scriptName = file; // tbd: also load, split and generate checksums for scripts - i++; + it++; } } void tst_Lancelot::testRasterARGB32PM_data() { - QTest::addColumn("item"); + QTest::addColumn("baseline"); ImageItemList itemList(baseList); - for(int i = 0; i < itemList.size(); i++) { - itemList[i].engine = ImageItem::Raster; - itemList[i].renderFormat = QImage::Format_ARGB32_Premultiplied; + for(ImageItemList::iterator it = itemList.begin(); it != itemList.end(); it++) { + it->engine = ImageItem::Raster; + it->renderFormat = QImage::Format_ARGB32_Premultiplied; } if (!proto.requestBaselineChecksums(&itemList)) { @@ -133,9 +130,8 @@ void tst_Lancelot::testRasterARGB32PM_data() QSKIP("Communication with baseline image server failed.", SkipAll); } - qDebug() << "items:" << itemList.count(); foreach(const ImageItem& item, itemList) { - if (item.scriptName != QLatin1String("sizes.qps")) // Hardcoded blacklisting for this enigine/format + if (item.scriptName != QLatin1String("sizes.qps")) // Example of hardcoded blacklisting for this enigine/format QTest::newRow(item.scriptName.toLatin1()) << item; } } @@ -149,170 +145,58 @@ void tst_Lancelot::testRasterARGB32PM() void tst_Lancelot::runTestSuite() { - errorMsg.clear(); - QFETCH(ImageItem, item); + QFETCH(ImageItem, baseline); - if (item.status == ImageItem::IgnoreItem) + if (baseline.status == ImageItem::IgnoreItem) QSKIP("Blacklisted by baseline server.", SkipSingle); - QImage rendered = render(item.scriptName, item.renderFormat); - if (!errorMsg.isNull() || rendered.isNull()) { // Assume an error in the test environment, not Qt - QWARN("Error: Failed to render image. " + errorMsg.toLatin1()); + ImageItem rendered = render(baseline); + if (rendered.image.isNull()) { // Assume an error in the test environment, not Qt + QWARN("Error: Failed to render image."); QSKIP("Aborted due to errors.", SkipSingle); } - quint64 checksum = ImageItem::computeChecksum(rendered); - - if (item.status == ImageItem::BaselineNotFound) { - item.image = rendered; - item.imageChecksum = checksum; - proto.submitNewBaseline(item); + if (baseline.status == ImageItem::BaselineNotFound) { + proto.submitNewBaseline(rendered, 0); QSKIP("Baseline not found; new baseline created.", SkipSingle); } - qDebug() << "rendered" << QString::number(checksum, 16).prepend("0x") << "baseline" << QString::number(item.imageChecksum, 16).prepend("0x"); - if (checksum != item.imageChecksum) { - /* TBD - - Get baseline image - - compute diffscore - - submit mismatching - - getBaseline(...) - if (!errorMsg.isNull() || baseline.isNull()) { - QWARN("Error: Failed to get baseline image. " + errorMsg.toLatin1()); - QSKIP("Aborted due to errors.", SkipSingle); - } - - - if (rendered.format() != baseline.format()) - rendered = rendered.convertToFormat(baseline.format()); //### depending on format - - QString scoreMsg = computeMismatchScore(baseline, rendered); + if (rendered.imageChecksum != baseline.imageChecksum) { QByteArray serverMsg; - proto.submitMismatch(fileName, rendered, &serverMsg); - */ - QByteArray failMsg = QByteArray("Rendered image differs from baseline. "); - //+ scoreMsg.toLatin1() + '\n' + serverMsg; - QFAIL(failMsg.constData()); + if (!proto.submitMismatch(rendered, &serverMsg)) + serverMsg = "Failed to submit mismatching image to server."; + QFAIL("Rendered image differs from baseline.\n" + serverMsg); } } -QString tst_Lancelot::computeMismatchScore(const QImage &baseline, const QImage &rendered) +ImageItem tst_Lancelot::render(const ImageItem &item) { - if (baseline.size() != rendered.size() || baseline.format() != rendered.format()) - return QLatin1String("[No score, incomparable images.]"); - if (baseline.depth() != 32) - return QLatin1String("[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