kwin/autotests/test_utils.cpp
Kai Uwe Broulik 3646620430 utils: Introduce RamFile class for memfd
This class can be used to create an anonymous file, for instance
to pass data between compositor and clients, through means of a
file descriptor, as is done in various Wayland protocols, notably
the keymap exchange.

It also implements sealing the file, so that it can be shared
between multiple clients without them being able to modify it.

If supported, memfd_create is used, otherwise a `QTemporaryFile`
is used.

Signed-off-by: Victoria Fischer <victoria.fischer@mbition.io>
2022-08-19 15:26:22 +02:00

71 lines
1.8 KiB
C++

/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2022 MBition GmbH
SPDX-FileContributor: Kai Uwe Broulik <kai_uwe.broulik@mbition.io>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <config-kwin.h>
#include <sys/mman.h>
#include <unistd.h>
#include "utils/ramfile.h"
#include <QtTest>
using namespace KWin;
class TestUtils : public QObject
{
Q_OBJECT
private Q_SLOTS:
void testRamFile();
void testSealedRamFile();
};
static const QByteArray s_testByteArray = QByteArrayLiteral("Test Data \0\1\2\3");
static const char s_writeTestArray[] = "test";
void TestUtils::testRamFile()
{
KWin::RamFile file("test", s_testByteArray.constData(), s_testByteArray.size());
QVERIFY(file.isValid());
QCOMPARE(file.size(), s_testByteArray.size());
QVERIFY(file.fd() != -1);
char buf[20];
int num = read(file.fd(), buf, sizeof buf);
QCOMPARE(num, file.size());
QCOMPARE(qstrcmp(s_testByteArray.constData(), buf), 0);
}
void TestUtils::testSealedRamFile()
{
#if HAVE_MEMFD
KWin::RamFile file("test", s_testByteArray.constData(), s_testByteArray.size(), KWin::RamFile::Flag::SealWrite);
QVERIFY(file.isValid());
QVERIFY(file.effectiveFlags().testFlag(KWin::RamFile::Flag::SealWrite));
// Writing should not work.
auto written = write(file.fd(), s_writeTestArray, strlen(s_writeTestArray));
QCOMPARE(written, -1);
// Cannot use MAP_SHARED on sealed file descriptor.
void *data = mmap(nullptr, file.size(), PROT_READ, MAP_SHARED, file.fd(), 0);
QCOMPARE(data, MAP_FAILED);
data = mmap(nullptr, file.size(), PROT_READ, MAP_PRIVATE, file.fd(), 0);
QVERIFY(data != MAP_FAILED);
#else
QSKIP("Sealing requires memfd suport.");
#endif
}
QTEST_MAIN(TestUtils)
#include "test_utils.moc"