kwin/autotests/integration/dont_crash_reinitialize_compositor.cpp
Vlad Zahorodnii 6d3f00e82c autotests: Remove QVERIFY(signalSpy.isValid())
We use the PMF syntax so the isValid() check is unnecessary as the
compiler will notify about wrong signal at compile time. It makes
writing autotests feel less boilerplaty.
2022-09-14 09:21:29 +00:00

149 lines
4.8 KiB
C++

/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2018 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "kwin_wayland_test.h"
#include "composite.h"
#include "core/output.h"
#include "core/platform.h"
#include "core/renderbackend.h"
#include "deleted.h"
#include "effectloader.h"
#include "effects.h"
#include "wayland_server.h"
#include "window.h"
#include "workspace.h"
#include <KWayland/Client/surface.h>
namespace KWin
{
static const QString s_socketName = QStringLiteral("wayland_test_kwin_dont_crash_reinitialize_compositor-0");
class DontCrashReinitializeCompositorTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
void initTestCase();
void init();
void cleanup();
void testReinitializeCompositor_data();
void testReinitializeCompositor();
};
void DontCrashReinitializeCompositorTest::initTestCase()
{
qputenv("XDG_DATA_DIRS", QCoreApplication::applicationDirPath().toUtf8());
qRegisterMetaType<KWin::Window *>();
qRegisterMetaType<KWin::Deleted *>();
QSignalSpy applicationStartedSpy(kwinApp(), &Application::started);
kwinApp()->platform()->setInitialWindowSize(QSize(1280, 1024));
QVERIFY(waylandServer()->init(s_socketName));
QMetaObject::invokeMethod(kwinApp()->platform(), "setVirtualOutputs", Qt::DirectConnection, Q_ARG(int, 2));
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
KConfigGroup plugins(config, QStringLiteral("Plugins"));
const auto builtinNames = EffectLoader().listOfKnownEffects();
for (const QString &name : builtinNames) {
plugins.writeEntry(name + QStringLiteral("Enabled"), false);
}
config->sync();
kwinApp()->setConfig(config);
qputenv("KWIN_COMPOSE", QByteArrayLiteral("O2"));
qputenv("KWIN_EFFECTS_FORCE_ANIMATIONS", QByteArrayLiteral("1"));
kwinApp()->start();
QVERIFY(applicationStartedSpy.wait());
const auto outputs = workspace()->outputs();
QCOMPARE(outputs.count(), 2);
QCOMPARE(outputs[0]->geometry(), QRect(0, 0, 1280, 1024));
QCOMPARE(outputs[1]->geometry(), QRect(1280, 0, 1280, 1024));
QCOMPARE(Compositor::self()->backend()->compositingType(), KWin::OpenGLCompositing);
}
void DontCrashReinitializeCompositorTest::init()
{
QVERIFY(Test::setupWaylandConnection());
}
void DontCrashReinitializeCompositorTest::cleanup()
{
// Unload all effects.
auto effectsImpl = qobject_cast<EffectsHandlerImpl *>(effects);
QVERIFY(effectsImpl);
effectsImpl->unloadAllEffects();
QVERIFY(effectsImpl->loadedEffects().isEmpty());
Test::destroyWaylandConnection();
}
void DontCrashReinitializeCompositorTest::testReinitializeCompositor_data()
{
QTest::addColumn<QString>("effectName");
QTest::newRow("Fade") << QStringLiteral("kwin4_effect_fade");
QTest::newRow("Glide") << QStringLiteral("glide");
QTest::newRow("Scale") << QStringLiteral("kwin4_effect_scale");
}
void DontCrashReinitializeCompositorTest::testReinitializeCompositor()
{
// This test verifies that KWin doesn't crash when the compositor settings
// have been changed while a scripted effect animates the disappearing of
// a window.
// Make sure that we have the right effects ptr.
auto effectsImpl = qobject_cast<EffectsHandlerImpl *>(effects);
QVERIFY(effectsImpl);
// Create the test window.
using namespace KWayland::Client;
std::unique_ptr<KWayland::Client::Surface> surface(Test::createSurface());
QVERIFY(surface != nullptr);
std::unique_ptr<Test::XdgToplevel> shellSurface(Test::createXdgToplevelSurface(surface.get()));
QVERIFY(shellSurface != nullptr);
Window *window = Test::renderAndWaitForShown(surface.get(), QSize(100, 50), Qt::blue);
QVERIFY(window);
// Make sure that only the test effect is loaded.
QFETCH(QString, effectName);
QVERIFY(effectsImpl->loadEffect(effectName));
QCOMPARE(effectsImpl->loadedEffects().count(), 1);
QCOMPARE(effectsImpl->loadedEffects().first(), effectName);
Effect *effect = effectsImpl->findEffect(effectName);
QVERIFY(effect);
QVERIFY(!effect->isActive());
// Close the test window.
QSignalSpy windowClosedSpy(window, &Window::windowClosed);
shellSurface.reset();
surface.reset();
QVERIFY(windowClosedSpy.wait());
// The test effect should start animating the test window. Is there a better
// way to verify that the test effect actually animates the test window?
QVERIFY(effect->isActive());
// Re-initialize the compositor, effects will be destroyed and created again.
Compositor::self()->reinitialize();
// By this time, KWin should still be alive.
}
} // namespace KWin
WAYLANDTEST_MAIN(KWin::DontCrashReinitializeCompositorTest)
#include "dont_crash_reinitialize_compositor.moc"