Stabilize flakiness in tst_QOpenGLWidget
qWaitForWindowActive was called in two test functions without activating the relevant widget. This patch adds widget activation before calling qWaitForWindowActive. Helper function verifyColor: A loop made six comparison attempts of widget size, pixel color and image with a 200ms waiting time after each unsuccessful attempt. The widget size was tested at the beginning of the loop. The test was failed on the first size mismatch, which occurred when verifyColor was called before the widget was rendered. That has lead to flakiness (e.g. on openSuSE). This patch encapsules each check in a lambda and calls qWaitFor to ensure event processing until each condition has become true. Change-Id: Ic98f93c8acf41459bc728f2969fe8b01768048dd Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
parent
fe67c69643
commit
ca254a0937
@ -423,6 +423,7 @@ void tst_QOpenGLWidget::asViewport()
|
|||||||
// repainted when going from Inactive to Active. So wait for the window to be
|
// repainted when going from Inactive to Active. So wait for the window to be
|
||||||
// active before we continue, so the activation doesn't happen at a random
|
// active before we continue, so the activation doesn't happen at a random
|
||||||
// time below. And call processEvents to have the paint events delivered right away.
|
// time below. And call processEvents to have the paint events delivered right away.
|
||||||
|
widget.activateWindow();
|
||||||
QVERIFY(QTest::qWaitForWindowActive(&widget));
|
QVERIFY(QTest::qWaitForWindowActive(&widget));
|
||||||
qApp->processEvents();
|
qApp->processEvents();
|
||||||
}
|
}
|
||||||
@ -599,50 +600,59 @@ static QPixmap grabWidgetWithoutRepaint(const QWidget *widget, QRect clipArea)
|
|||||||
|
|
||||||
bool verifyColor(const QWidget *widget, const QRect &clipArea, const QColor &color, int callerLine)
|
bool verifyColor(const QWidget *widget, const QRect &clipArea, const QColor &color, int callerLine)
|
||||||
{
|
{
|
||||||
for (int t = 0; t < 6; t++) {
|
// Create a comparison target image
|
||||||
const QPixmap pixmap = grabWidgetWithoutRepaint(widget, clipArea);
|
QPixmap expectedPixmap(grabWidgetWithoutRepaint(widget, clipArea)); /* ensure equal formats */
|
||||||
if (!QTest::qCompare(pixmap.size(),
|
expectedPixmap.detach();
|
||||||
clipArea.size(),
|
expectedPixmap.fill(color);
|
||||||
"pixmap.size()",
|
const QImage expectedImage = expectedPixmap.toImage();
|
||||||
"rect.size()",
|
|
||||||
__FILE__,
|
|
||||||
callerLine))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
|
// test image size
|
||||||
|
QPixmap pixmap;
|
||||||
|
auto testSize = [&](){
|
||||||
|
pixmap = grabWidgetWithoutRepaint(widget, clipArea);
|
||||||
|
return pixmap.size() == clipArea.size();
|
||||||
|
};
|
||||||
|
|
||||||
const QImage image = pixmap.toImage();
|
// test the first pixel's color
|
||||||
QPixmap expectedPixmap(pixmap); /* ensure equal formats */
|
uint firstPixel;
|
||||||
expectedPixmap.detach();
|
auto testPixel = [&](){
|
||||||
expectedPixmap.fill(color);
|
const QImage image = grabWidgetWithoutRepaint(widget, clipArea).toImage();
|
||||||
|
|
||||||
uint alphaCorrection = image.format() == QImage::Format_RGB32 ? 0xff000000 : 0;
|
uint alphaCorrection = image.format() == QImage::Format_RGB32 ? 0xff000000 : 0;
|
||||||
uint firstPixel = image.pixel(0,0) | alphaCorrection;
|
firstPixel = image.pixel(0,0) | alphaCorrection;
|
||||||
|
return firstPixel == QColor(color).rgb();
|
||||||
|
};
|
||||||
|
|
||||||
// Retry a couple of times. Some window managers have transparency animation, or are
|
// test the rendered image
|
||||||
// just slow to render.
|
QImage image;
|
||||||
if (t < 5) {
|
auto testImage = [&](){
|
||||||
if (firstPixel == QColor(color).rgb()
|
image = grabWidgetWithoutRepaint(widget, clipArea).toImage();
|
||||||
&& image == expectedPixmap.toImage())
|
return image == expectedImage;
|
||||||
return true;
|
};
|
||||||
else
|
|
||||||
QTest::qWait(200);
|
// Perform checks and make test case fail if unsuccessful
|
||||||
} else {
|
if (!QTest::qWaitFor(testSize))
|
||||||
if (!QTest::qVerify(firstPixel == QColor(color).rgb(),
|
return QTest::qCompare(pixmap.size(),
|
||||||
"firstPixel == QColor(color).rgb()",
|
clipArea.size(),
|
||||||
qPrintable(msgRgbMismatch(firstPixel, QColor(color).rgb())),
|
"pixmap.size()",
|
||||||
__FILE__, callerLine)) {
|
"rect.size()",
|
||||||
return false;
|
__FILE__,
|
||||||
}
|
callerLine);
|
||||||
if (!QTest::qVerify(image == expectedPixmap.toImage(),
|
|
||||||
"image == expectedPixmap.toImage()",
|
if (!QTest::qWaitFor(testPixel)) {
|
||||||
"grabbed pixmap differs from expected pixmap",
|
return QTest::qVerify(firstPixel == QColor(color).rgb(),
|
||||||
__FILE__, callerLine)) {
|
"firstPixel == QColor(color).rgb()",
|
||||||
return false;
|
qPrintable(msgRgbMismatch(firstPixel, QColor(color).rgb())),
|
||||||
}
|
__FILE__, callerLine);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
if (!QTest::qWaitFor(testImage)) {
|
||||||
|
return QTest::qVerify(image == expectedImage,
|
||||||
|
"image == expectedPixmap.toImage()",
|
||||||
|
"grabbed pixmap differs from expected pixmap",
|
||||||
|
__FILE__, callerLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QOpenGLWidget::stackWidgetOpaqueChildIsVisible()
|
void tst_QOpenGLWidget::stackWidgetOpaqueChildIsVisible()
|
||||||
@ -675,6 +685,7 @@ void tst_QOpenGLWidget::stackWidgetOpaqueChildIsVisible()
|
|||||||
stack.resize(dimensionSize, dimensionSize);
|
stack.resize(dimensionSize, dimensionSize);
|
||||||
stack.show();
|
stack.show();
|
||||||
QVERIFY(QTest::qWaitForWindowExposed(&stack));
|
QVERIFY(QTest::qWaitForWindowExposed(&stack));
|
||||||
|
stack.activateWindow();
|
||||||
QVERIFY(QTest::qWaitForWindowActive(&stack));
|
QVERIFY(QTest::qWaitForWindowActive(&stack));
|
||||||
|
|
||||||
// Switch to the QOpenGLWidget.
|
// Switch to the QOpenGLWidget.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user