Commit 3c89460d authored by Martin Flöser's avatar Martin Flöser
Browse files

Import client autotests

parents 0cd3cbcf faa80cef
include_directories(${CMAKE_BINARY_DIR}/wayland_protocols/)
set_source_files_properties(${CMAKE_BINARY_DIR}/wayland_protocols/wayland-client-fullscreen-shell.c GENERATED)
########################################################
# Test WaylandConnectionThread
########################################################
set( testWaylandConnectionThread_SRCS
test_wayland_connection_thread.cpp
${KWIN_SOURCE_DIR}/wayland_server/buffer_interface.cpp
${KWIN_SOURCE_DIR}/wayland_client/connection_thread.cpp
${KWIN_SOURCE_DIR}/wayland_server/compositor_interface.cpp
${KWIN_SOURCE_DIR}/wayland_server/display.cpp
${KWIN_SOURCE_DIR}/wayland_server/output_interface.cpp
${KWIN_SOURCE_DIR}/wayland_server/seat_interface.cpp
${KWIN_SOURCE_DIR}/wayland_server/shell_interface.cpp
${KWIN_SOURCE_DIR}/wayland_server/surface_interface.cpp
)
add_executable(testWaylandConnectionThread ${testWaylandConnectionThread_SRCS})
target_link_libraries( testWaylandConnectionThread Qt5::Test Qt5::Gui Wayland::Client Wayland::Server)
add_test(kwin-testWaylandConnectionThread testWaylandConnectionThread)
ecm_mark_as_test(testWaylandConnectionThread)
########################################################
# Test WaylandRegistry
########################################################
set( testWaylandRegistry_SRCS
test_wayland_registry.cpp
${KWIN_SOURCE_DIR}/wayland_client/connection_thread.cpp
${KWIN_SOURCE_DIR}/wayland_client/registry.cpp
${CMAKE_BINARY_DIR}/wayland_protocols/wayland-client-fullscreen-shell.c
${KWIN_SOURCE_DIR}/wayland_server/buffer_interface.cpp
${KWIN_SOURCE_DIR}/wayland_server/compositor_interface.cpp
${KWIN_SOURCE_DIR}/wayland_server/display.cpp
${KWIN_SOURCE_DIR}/wayland_server/output_interface.cpp
${KWIN_SOURCE_DIR}/wayland_server/seat_interface.cpp
${KWIN_SOURCE_DIR}/wayland_server/shell_interface.cpp
${KWIN_SOURCE_DIR}/wayland_server/surface_interface.cpp
)
add_executable(testWaylandRegistry ${testWaylandRegistry_SRCS})
add_dependencies(testWaylandRegistry wayland-client-fullscreen-shell)
target_link_libraries( testWaylandRegistry Qt5::Test Qt5::Gui Wayland::Client Wayland::Server)
add_test(kwin-testWaylandRegistry testWaylandRegistry)
ecm_mark_as_test(testWaylandRegistry)
########################################################
# Test WaylandFullscreenShell
########################################################
if(Wayland_VERSION VERSION_GREATER "1.4.0")
set( testWaylandFullscreenShell_SRCS
test_wayland_fullscreen_shell.cpp
${KWIN_SOURCE_DIR}/wayland_client/connection_thread.cpp
${KWIN_SOURCE_DIR}/wayland_client/registry.cpp
${KWIN_SOURCE_DIR}/wayland_client/fullscreen_shell.cpp
${CMAKE_BINARY_DIR}/wayland_protocols/wayland-client-fullscreen-shell.c
)
add_executable(testWaylandFullscreenShell ${testWaylandFullscreenShell_SRCS})
add_dependencies(testWaylandFullscreenShell wayland-client-fullscreen-shell)
target_link_libraries( testWaylandFullscreenShell Qt5::Test Wayland::Client)
add_test(kwin-testWaylandFullscreenShell testWaylandFullscreenShell)
ecm_mark_as_test(testWaylandFullscreenShell)
endif()
########################################################
# Test WaylandOutput
########################################################
set( testWaylandOutput_SRCS
test_wayland_output.cpp
${KWIN_SOURCE_DIR}/wayland_client/connection_thread.cpp
${KWIN_SOURCE_DIR}/wayland_client/registry.cpp
${KWIN_SOURCE_DIR}/wayland_client/fullscreen_shell.cpp
${KWIN_SOURCE_DIR}/wayland_client/output.cpp
${CMAKE_BINARY_DIR}/wayland_protocols/wayland-client-fullscreen-shell.c
${KWIN_SOURCE_DIR}/wayland_server/buffer_interface.cpp
${KWIN_SOURCE_DIR}/wayland_server/compositor_interface.cpp
${KWIN_SOURCE_DIR}/wayland_server/display.cpp
${KWIN_SOURCE_DIR}/wayland_server/output_interface.cpp
${KWIN_SOURCE_DIR}/wayland_server/seat_interface.cpp
${KWIN_SOURCE_DIR}/wayland_server/shell_interface.cpp
${KWIN_SOURCE_DIR}/wayland_server/surface_interface.cpp
)
add_executable(testWaylandOutput ${testWaylandOutput_SRCS})
add_dependencies(testWaylandOutput wayland-client-fullscreen-shell)
target_link_libraries( testWaylandOutput Qt5::Test Qt5::Gui Wayland::Client Wayland::Server)
add_test(kwin-testWaylandOutput testWaylandOutput)
ecm_mark_as_test(testWaylandOutput)
########################################################
# Test WaylandShell
########################################################
set( testWaylandShell_SRCS
test_wayland_shell.cpp
${KWIN_SOURCE_DIR}/wayland_client/compositor.cpp
${KWIN_SOURCE_DIR}/wayland_client/connection_thread.cpp
${KWIN_SOURCE_DIR}/wayland_client/registry.cpp
${KWIN_SOURCE_DIR}/wayland_client/fullscreen_shell.cpp
${KWIN_SOURCE_DIR}/wayland_client/shell.cpp
${KWIN_SOURCE_DIR}/wayland_client/surface.cpp
${CMAKE_BINARY_DIR}/wayland_protocols/wayland-client-fullscreen-shell.c
${KWIN_SOURCE_DIR}/wayland_server/buffer_interface.cpp
${KWIN_SOURCE_DIR}/wayland_server/compositor_interface.cpp
${KWIN_SOURCE_DIR}/wayland_server/display.cpp
${KWIN_SOURCE_DIR}/wayland_server/output_interface.cpp
${KWIN_SOURCE_DIR}/wayland_server/seat_interface.cpp
${KWIN_SOURCE_DIR}/wayland_server/shell_interface.cpp
${KWIN_SOURCE_DIR}/wayland_server/surface_interface.cpp
)
add_executable(testWaylandShell ${testWaylandShell_SRCS})
add_dependencies(testWaylandShell wayland-client-fullscreen-shell)
target_link_libraries( testWaylandShell Qt5::Test Qt5::Gui Wayland::Client Wayland::Server)
add_test(kwin-testWaylandShell testWaylandShell)
ecm_mark_as_test(testWaylandShell)
########################################################
# Test WaylandSurface
########################################################
set( testWaylandSurface_SRCS
test_wayland_surface.cpp
${KWIN_SOURCE_DIR}/wayland_client/buffer.cpp
${KWIN_SOURCE_DIR}/wayland_client/compositor.cpp
${KWIN_SOURCE_DIR}/wayland_client/connection_thread.cpp
${KWIN_SOURCE_DIR}/wayland_client/registry.cpp
${KWIN_SOURCE_DIR}/wayland_client/fullscreen_shell.cpp
${KWIN_SOURCE_DIR}/wayland_client/shm_pool.cpp
${KWIN_SOURCE_DIR}/wayland_client/surface.cpp
${CMAKE_BINARY_DIR}/wayland_protocols/wayland-client-fullscreen-shell.c
${KWIN_SOURCE_DIR}/wayland_server/buffer_interface.cpp
${KWIN_SOURCE_DIR}/wayland_server/compositor_interface.cpp
${KWIN_SOURCE_DIR}/wayland_server/display.cpp
${KWIN_SOURCE_DIR}/wayland_server/output_interface.cpp
${KWIN_SOURCE_DIR}/wayland_server/seat_interface.cpp
${KWIN_SOURCE_DIR}/wayland_server/shell_interface.cpp
${KWIN_SOURCE_DIR}/wayland_server/surface_interface.cpp
)
add_executable(testWaylandSurface ${testWaylandSurface_SRCS})
add_dependencies(testWaylandSurface wayland-client-fullscreen-shell)
target_link_libraries( testWaylandSurface Qt5::Test Qt5::Gui Wayland::Client Wayland::Server)
add_test(kwin-testWaylandSurface testWaylandSurface)
ecm_mark_as_test(testWaylandSurface)
########################################################
# Test WaylandSeat
########################################################
set( testWaylandSeat_SRCS
test_wayland_seat.cpp
${KWIN_SOURCE_DIR}/wayland_client/buffer.cpp
${KWIN_SOURCE_DIR}/wayland_client/compositor.cpp
${KWIN_SOURCE_DIR}/wayland_client/connection_thread.cpp
${KWIN_SOURCE_DIR}/wayland_client/registry.cpp
${KWIN_SOURCE_DIR}/wayland_client/fullscreen_shell.cpp
${KWIN_SOURCE_DIR}/wayland_client/keyboard.cpp
${KWIN_SOURCE_DIR}/wayland_client/pointer.cpp
${KWIN_SOURCE_DIR}/wayland_client/seat.cpp
${KWIN_SOURCE_DIR}/wayland_client/shm_pool.cpp
${KWIN_SOURCE_DIR}/wayland_client/surface.cpp
${CMAKE_BINARY_DIR}/wayland_protocols/wayland-client-fullscreen-shell.c
${KWIN_SOURCE_DIR}/wayland_server/buffer_interface.cpp
${KWIN_SOURCE_DIR}/wayland_server/compositor_interface.cpp
${KWIN_SOURCE_DIR}/wayland_server/display.cpp
${KWIN_SOURCE_DIR}/wayland_server/output_interface.cpp
${KWIN_SOURCE_DIR}/wayland_server/seat_interface.cpp
${KWIN_SOURCE_DIR}/wayland_server/shell_interface.cpp
${KWIN_SOURCE_DIR}/wayland_server/surface_interface.cpp
)
add_executable(testWaylandSeat ${testWaylandSeat_SRCS})
add_dependencies(testWaylandSeat wayland-client-fullscreen-shell)
target_link_libraries( testWaylandSeat Qt5::Test Qt5::Gui Wayland::Client Wayland::Server)
add_test(kwin-testWaylandSeat testWaylandSeat)
ecm_mark_as_test(testWaylandSeat)
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2014 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/>.
*********************************************************************/
// Qt
#include <QtTest/QtTest>
// KWin
#include "../../wayland_client/connection_thread.h"
#include "../../wayland_server/display.h"
// Wayland
#include <wayland-client-protocol.h>
class TestWaylandConnectionThread : public QObject
{
Q_OBJECT
public:
explicit TestWaylandConnectionThread(QObject *parent = nullptr);
private Q_SLOTS:
void init();
void cleanup();
void testInitConnectionNoThread();
void testConnectionFailure();
void testConnectionDieing();
void testConnectionThread();
private:
KWin::WaylandServer::Display *m_display;
};
static const QString s_socketName = QStringLiteral("kwin-test-wayland-connection-0");
TestWaylandConnectionThread::TestWaylandConnectionThread(QObject *parent)
: QObject(parent)
, m_display(nullptr)
{
}
void TestWaylandConnectionThread::init()
{
using namespace KWin::WaylandServer;
delete m_display;
m_display = new Display(this);
QSignalSpy displayRunning(m_display, SIGNAL(runningChanged(bool)));
m_display->setSocketName(s_socketName);
m_display->start();
QVERIFY(m_display->isRunning());
}
void TestWaylandConnectionThread::cleanup()
{
delete m_display;
m_display = nullptr;
}
void TestWaylandConnectionThread::testInitConnectionNoThread()
{
QScopedPointer<KWin::Wayland::ConnectionThread> connection(new KWin::Wayland::ConnectionThread);
QCOMPARE(connection->socketName(), QStringLiteral("wayland-0"));
connection->setSocketName(s_socketName);
QCOMPARE(connection->socketName(), s_socketName);
QSignalSpy connectedSpy(connection.data(), SIGNAL(connected()));
QSignalSpy failedSpy(connection.data(), SIGNAL(failed()));
connection->initConnection();
QVERIFY(connectedSpy.wait());
QCOMPARE(connectedSpy.count(), 1);
QCOMPARE(failedSpy.count(), 0);
QVERIFY(connection->display());
}
void TestWaylandConnectionThread::testConnectionFailure()
{
QScopedPointer<KWin::Wayland::ConnectionThread> connection(new KWin::Wayland::ConnectionThread);
connection->setSocketName(QStringLiteral("kwin-test-socket-does-not-exist"));
QSignalSpy connectedSpy(connection.data(), SIGNAL(connected()));
QSignalSpy failedSpy(connection.data(), SIGNAL(failed()));
connection->initConnection();
QVERIFY(failedSpy.wait());
QCOMPARE(connectedSpy.count(), 0);
QCOMPARE(failedSpy.count(), 1);
QVERIFY(!connection->display());
}
static void registryHandleGlobal(void *data, struct wl_registry *registry,
uint32_t name, const char *interface, uint32_t version)
{
Q_UNUSED(data)
Q_UNUSED(registry)
Q_UNUSED(name)
Q_UNUSED(interface)
Q_UNUSED(version)
}
static void registryHandleGlobalRemove(void *data, struct wl_registry *registry, uint32_t name)
{
Q_UNUSED(data)
Q_UNUSED(registry)
Q_UNUSED(name)
}
static const struct wl_registry_listener s_registryListener = {
registryHandleGlobal,
registryHandleGlobalRemove
};
void TestWaylandConnectionThread::testConnectionThread()
{
QScopedPointer<KWin::Wayland::ConnectionThread> connection(new KWin::Wayland::ConnectionThread);
connection->setSocketName(s_socketName);
QThread *connectionThread = new QThread(this);
connection->moveToThread(connectionThread);
connectionThread->start();
QSignalSpy connectedSpy(connection.data(), SIGNAL(connected()));
QSignalSpy failedSpy(connection.data(), SIGNAL(failed()));
connection->initConnection();
QVERIFY(connectedSpy.wait());
QCOMPARE(connectedSpy.count(), 1);
QCOMPARE(failedSpy.count(), 0);
QVERIFY(connection->display());
// now we have the connection ready, let's get some events
QSignalSpy eventsSpy(connection.data(), SIGNAL(eventsRead()));
wl_display *display = connection->display();
wl_event_queue *queue = wl_display_create_queue(display);
wl_registry *registry = wl_display_get_registry(display);
wl_proxy_set_queue((wl_proxy*)registry, queue);
wl_registry_add_listener(registry, &s_registryListener, this);
wl_display_flush(display);
if (eventsSpy.isEmpty()) {
QVERIFY(eventsSpy.wait());
}
QVERIFY(!eventsSpy.isEmpty());
wl_registry_destroy(registry);
wl_event_queue_destroy(queue);
connectionThread->quit();
connectionThread->wait();
delete connectionThread;
}
void TestWaylandConnectionThread::testConnectionDieing()
{
QScopedPointer<KWin::Wayland::ConnectionThread> connection(new KWin::Wayland::ConnectionThread);
QSignalSpy connectedSpy(connection.data(), SIGNAL(connected()));
connection->setSocketName(s_socketName);
connection->initConnection();
QVERIFY(connectedSpy.wait());
QVERIFY(connection->display());
QSignalSpy diedSpy(connection.data(), SIGNAL(connectionDied()));
m_display->terminate();
QVERIFY(!m_display->isRunning());
QVERIFY(diedSpy.wait());
QCOMPARE(diedSpy.count(), 1);
QVERIFY(!connection->display());
connectedSpy.clear();
QVERIFY(connectedSpy.isEmpty());
// restarts the server
m_display->start();
QVERIFY(m_display->isRunning());
if (connectedSpy.count() == 0) {
QVERIFY(connectedSpy.wait());
}
QCOMPARE(connectedSpy.count(), 1);
}
QTEST_MAIN(TestWaylandConnectionThread)
#include "test_wayland_connection_thread.moc"
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2014 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/>.
*********************************************************************/
// Qt
#include <QtTest/QtTest>
// KWin
#include "../../wayland_client/connection_thread.h"
#include "../../wayland_client/registry.h"
#include "../../wayland_client/fullscreen_shell.h"
// Wayland
#include <wayland-client-protocol.h>
class TestWaylandFullscreenShell : public QObject
{
Q_OBJECT
public:
explicit TestWaylandFullscreenShell(QObject *parent = nullptr);
private Q_SLOTS:
void init();
void cleanup();
void testRegistry();
// TODO: add tests for removal - requires more control over the compositor
private:
QProcess *m_westonProcess;
};
static const QString s_socketName = QStringLiteral("kwin-test-wayland-fullscreen-shell-0");
TestWaylandFullscreenShell::TestWaylandFullscreenShell(QObject *parent)
: QObject(parent)
, m_westonProcess(nullptr)
{
}
void TestWaylandFullscreenShell::init()
{
QVERIFY(!m_westonProcess);
// starts weston
m_westonProcess = new QProcess(this);
m_westonProcess->setProgram(QStringLiteral("weston"));
m_westonProcess->setArguments(QStringList({QStringLiteral("--socket=%1").arg(s_socketName),
QStringLiteral("--use-pixman"),
QStringLiteral("--shell=fullscreen-shell.so")}));
m_westonProcess->start();
QVERIFY(m_westonProcess->waitForStarted());
// wait for the socket to appear
QDir runtimeDir(qgetenv("XDG_RUNTIME_DIR"));
if (runtimeDir.exists(s_socketName)) {
return;
}
QFileSystemWatcher *socketWatcher = new QFileSystemWatcher(QStringList({runtimeDir.absolutePath()}), this);
QSignalSpy socketSpy(socketWatcher, SIGNAL(directoryChanged(QString)));
// limit to maximum of 10 waits
for (int i = 0; i < 10; ++i) {
QVERIFY(socketSpy.wait());
if (runtimeDir.exists(s_socketName)) {
delete socketWatcher;
return;
}
}
}
void TestWaylandFullscreenShell::cleanup()
{
// terminates weston
m_westonProcess->terminate();
QVERIFY(m_westonProcess->waitForFinished());
delete m_westonProcess;
m_westonProcess = nullptr;
}
void TestWaylandFullscreenShell::testRegistry()
{
if (m_westonProcess->state() != QProcess::Running) {
QSKIP("This test requires a running wayland server");
}
KWin::Wayland::ConnectionThread connection;
QSignalSpy connectedSpy(&connection, SIGNAL(connected()));
connection.setSocketName(s_socketName);
connection.initConnection();
QVERIFY(connectedSpy.wait());
KWin::Wayland::Registry registry;
QSignalSpy announced(&registry, SIGNAL(fullscreenShellAnnounced(quint32,quint32)));
registry.create(connection.display());
QVERIFY(registry.isValid());
registry.setup();
wl_display_flush(connection.display());
QVERIFY(announced.wait());
KWin::Wayland::FullscreenShell fullscreenShell;
QVERIFY(!fullscreenShell.isValid());
QVERIFY(!fullscreenShell.hasCapabilityArbitraryModes());
QVERIFY(!fullscreenShell.hasCapabilityCursorPlane());
fullscreenShell.setup(registry.bindFullscreenShell(announced.first().first().value<quint32>(), 1));
QVERIFY(fullscreenShell.isValid());
}
QTEST_MAIN(TestWaylandFullscreenShell)
#include "test_wayland_fullscreen_shell.moc"
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2014 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/>.
*********************************************************************/
// Qt
#include <QtTest/QtTest>
// KWin
#include "../../wayland_client/connection_thread.h"
#include "../../wayland_client/output.h"
#include "../../wayland_client/registry.h"
#include "../../wayland_server/display.h"
#include "../../wayland_server/output_interface.h"
// Wayland
#include <wayland-client-protocol.h>
class TestWaylandOutput : public QObject
{
Q_OBJECT
public:
explicit TestWaylandOutput(QObject *parent = nullptr);
private Q_SLOTS:
void init();
void cleanup();
void testRegistry();
void testModeChanges();
void testScaleChange();
void testSubPixel_data();
void testSubPixel();
void testTransform_data();
void testTransform();
private:
KWin::WaylandServer::Display *m_display;
KWin::WaylandServer::OutputInterface *m_serverOutput;
KWin::Wayland::ConnectionThread *m_connection;
QThread *m_thread;
};
static const QString s_socketName = QStringLiteral("kwin-test-wayland-output-0");
TestWaylandOutput::TestWaylandOutput(QObject *parent)
: QObject(parent)
, m_display(nullptr)
, m_serverOutput(nullptr)
, m_connection(nullptr)
, m_thread(nullptr)
{
}
void TestWaylandOutput::init()
{
using namespace KWin::WaylandServer;
delete m_display;
m_display = new Display(this);
m_display->setSocketName(s_socketName);
m_display->start();
QVERIFY(m_display->isRunning());
m_serverOutput = m_display->createOutput(this);
m_serverOutput->addMode(QSize(800, 600));
m_serverOutput->addMode(QSize(1024, 768));
m_serverOutput->addMode(QSize(1280, 1024));
m_serverOutput->setCurrentMode(QSize(1024, 768));
m_serverOutput->create();
// setup connection
m_connection = new KWin::Wayland::ConnectionThread;
QSignalSpy connectedSpy(m_connection, SIGNAL(connected()));
m_connection->setSocketName(s_socketName);
m_thread = new QThread(this);
m_connection->moveToThread(m_thread);
m_thread->start();
m_connection->initConnection();
QVERIFY(connectedSpy.wait());
}
void TestWaylandOutput::cleanup()
{
if (m_thread) {
m_thread->quit();
m_thread->wait();
delete m_thread;
m_thread = nullptr;
}
delete m_connection;
m_connection = nullptr;
delete m_serverOutput;
m_serverOutput = nullptr;
delete m_display;