kwin/autotests/wayland/dont_crash_glxgears.cpp
Martin Gräßlin 58bcf66ecf [autotests] Test case for 10ad9262a1
The problem we had was closing a glxgears through an Aurorae theme
crashed KWin inside QtQuick.

This test case simulates the sequence:
1. starts glxgears
2. wait till we have a Client for it
3. send mouse move to guessed close button position
4. send mouse press/release at that position
5. verify the window is closed
6. verify glxgears exits

With the given commit reverted this crashes, with it in place it passes.

Please note: on CI it might fail as glxgears is not yet installed. [1]
Also we cannot enforce using Aurorae from the test yet, though on
the CI system it should get picked automatically as no other deco
plugin should be installed.

[1] Sysadmin ticket already created
2015-10-22 10:08:49 +02:00

104 lines
3.7 KiB
C++

/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2015 Martin Gräßlin <mgraesslin@kde.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#include "kwin_wayland_test.h"
#include "abstract_backend.h"
#include "abstract_client.h"
#include "client.h"
#include "deleted.h"
#include "screens.h"
#include "wayland_server.h"
#include "workspace.h"
#include <KDecoration2/Decoration>
namespace KWin
{
static const QString s_socketName = QStringLiteral("wayland_test_kwin_dont_crash_glxgears-0");
class DontCrashGlxgearsTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
void initTestCase();
void testGlxgears();
};
void DontCrashGlxgearsTest::initTestCase()
{
qRegisterMetaType<KWin::Deleted*>();
QSignalSpy workspaceCreatedSpy(kwinApp(), &Application::workspaceCreated);
QVERIFY(workspaceCreatedSpy.isValid());
waylandServer()->backend()->setInitialWindowSize(QSize(1280, 1024));
waylandServer()->init(s_socketName.toLocal8Bit());
kwinApp()->start();
QVERIFY(workspaceCreatedSpy.wait());
}
void DontCrashGlxgearsTest::testGlxgears()
{
// closing a glxgears window through Aurorae themes used to crash KWin
// Let's make sure that doesn't happen anymore
QSignalSpy clientAddedSpy(workspace(), &Workspace::clientAdded);
QVERIFY(clientAddedSpy.isValid());
QProcess glxgears;
glxgears.start(QStringLiteral("glxgears"));
QVERIFY(glxgears.waitForStarted());
QVERIFY(clientAddedSpy.wait());
QCOMPARE(clientAddedSpy.count(), 1);
QCOMPARE(workspace()->clientList().count(), 1);
Client *glxgearsClient = workspace()->clientList().first();
QVERIFY(glxgearsClient->isDecorated());
QSignalSpy closedSpy(glxgearsClient, &Client::windowClosed);
QVERIFY(closedSpy.isValid());
KDecoration2::Decoration *decoration = glxgearsClient->decoration();
QVERIFY(decoration);
// send a mouse event to the position of the close button
QPointF pos = decoration->rect().topRight() + QPointF(-decoration->borderRight() * 2, decoration->borderRight() * 2);
QHoverEvent event(QEvent::HoverMove, pos, pos);
QCoreApplication::instance()->sendEvent(decoration, &event);
// mouse press
QMouseEvent mousePressevent(QEvent::MouseButtonPress, pos, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
mousePressevent.setAccepted(false);
QCoreApplication::sendEvent(decoration, &mousePressevent);
QVERIFY(mousePressevent.isAccepted());
// mouse Release
QMouseEvent mouseReleaseEvent(QEvent::MouseButtonRelease, pos, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
mouseReleaseEvent.setAccepted(false);
QCoreApplication::sendEvent(decoration, &mouseReleaseEvent);
QVERIFY(mouseReleaseEvent.isAccepted());
QVERIFY(closedSpy.wait());
QCOMPARE(closedSpy.count(), 1);
xcb_flush(connection());
if (glxgears.state() == QProcess::Running) {
QVERIFY(glxgears.waitForFinished());
}
}
}
WAYLANTEST_MAIN(KWin::DontCrashGlxgearsTest)
#include "dont_crash_glxgears.moc"