From b7643ecbadf3674772ee13c3f4cc6764a2a8d5b3 Mon Sep 17 00:00:00 2001 From: Simon Redman Date: Sat, 21 Mar 2020 15:04:30 -0700 Subject: [PATCH] Delete flakey tests --- tests/CMakeLists.txt | 7 +- tests/devicetest.cpp | 127 -------- tests/kdeconnectconfigtest.cpp | 85 ------ tests/lanlinkprovidertest.cpp | 454 ---------------------------- tests/networkpackettests.cpp | 143 --------- tests/testnotificationlistener.cpp | 456 ----------------------------- tests/testsslsocketlinereader.cpp | 361 ----------------------- 7 files changed, 1 insertion(+), 1632 deletions(-) delete mode 100644 tests/devicetest.cpp delete mode 100644 tests/kdeconnectconfigtest.cpp delete mode 100644 tests/lanlinkprovidertest.cpp delete mode 100644 tests/networkpackettests.cpp delete mode 100644 tests/testnotificationlistener.cpp delete mode 100644 tests/testsslsocketlinereader.cpp diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 6bfce2a2f..a25b401ab 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -28,12 +28,7 @@ set(kdeconnect_sms_libraries ecm_add_test(pluginloadtest.cpp LINK_LIBRARIES ${kdeconnect_libraries}) ecm_add_test(sendfiletest.cpp LINK_LIBRARIES ${kdeconnect_libraries}) -ecm_add_test(networkpackettests.cpp LINK_LIBRARIES ${kdeconnect_libraries}) -ecm_add_test(testsocketlinereader.cpp TEST_NAME testsocketlinereader LINK_LIBRARIES ${kdeconnect_libraries}) -ecm_add_test(testsslsocketlinereader.cpp TEST_NAME testsslsocketlinereader LINK_LIBRARIES ${kdeconnect_libraries}) -ecm_add_test(kdeconnectconfigtest.cpp TEST_NAME kdeconnectconfigtest LINK_LIBRARIES ${kdeconnect_libraries}) -ecm_add_test(lanlinkprovidertest.cpp TEST_NAME lanlinkprovidertest LINK_LIBRARIES ${kdeconnect_libraries}) -ecm_add_test(devicetest.cpp TEST_NAME devicetest LINK_LIBRARIES ${kdeconnect_libraries}) +ecm_add_test(testsocketlinereader.cpp TEST_NAME testsocketlinereader LINK_LIBRARIES ${kdeconnect_libraries})\ if (NOT SAILFISHOS) ecm_add_test(testnotificationlistener.cpp diff --git a/tests/devicetest.cpp b/tests/devicetest.cpp deleted file mode 100644 index 6f5193b43..000000000 --- a/tests/devicetest.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/** - * Copyright 2015 Vineet Garg - * - * 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) version 3 or any later version - * accepted by the membership of KDE e.V. (or its successor approved - * by the membership of KDE e.V.), which shall act as a proxy - * defined in Section 14 of version 3 of the license. - * - * 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 . - */ - -#include "../core/device.h" -#include "../core/backends/lan/lanlinkprovider.h" -#include "../core/kdeconnectconfig.h" - -#include - -/** - * This class tests the working of device class - */ -class DeviceTest : public QObject -{ - Q_OBJECT - -private Q_SLOTS: - - void initTestCase(); - void testUnpairedDevice(); - void testPairedDevice(); - void cleanupTestCase(); - -private: - QString deviceId; - QString deviceName; - QString deviceType; - NetworkPacket* identityPacket; - -}; - -void DeviceTest::initTestCase() -{ - deviceId = QStringLiteral("testdevice"); - deviceName = QStringLiteral("Test Device"); - deviceType = QStringLiteral("smartphone"); - QString stringPacket = QStringLiteral("{\"id\":1439365924847,\"type\":\"kdeconnect.identity\",\"body\":{\"deviceId\":\"testdevice\",\"deviceName\":\"Test Device\",\"protocolVersion\":6,\"deviceType\":\"phone\"}}"); - identityPacket = new NetworkPacket(QStringLiteral("kdeconnect.identity")); - NetworkPacket::unserialize(stringPacket.toLatin1(), identityPacket); -} - -void DeviceTest::testPairedDevice() -{ - KdeConnectConfig::instance().addTrustedDevice(deviceId, deviceName, deviceType); - KdeConnectConfig::instance().setDeviceProperty(deviceId, QStringLiteral("certificate"), QString::fromLatin1(KdeConnectConfig::instance().certificate().toPem())); // Using same certificate from kcc, instead of generating one - - Device device(this, deviceId); - - QCOMPARE(device.id(), deviceId); - QCOMPARE(device.name(), deviceName); - QCOMPARE(device.type(), deviceType); - - QCOMPARE(device.isTrusted(), true); - - QCOMPARE(device.isReachable(), false); - - // Add link - LanLinkProvider linkProvider; - QSslSocket socket; - LanDeviceLink* link = new LanDeviceLink(deviceId, &linkProvider, &socket, LanDeviceLink::Locally); - device.addLink(*identityPacket, link); - - QCOMPARE(device.isReachable(), true); - QCOMPARE(device.availableLinks().contains(linkProvider.name()), true); - - // Remove link - device.removeLink(link); - - QCOMPARE(device.isReachable(), false); - QCOMPARE(device.availableLinks().contains(linkProvider.name()), false); - - device.unpair(); - QCOMPARE(device.isTrusted(), false); - -} - -void DeviceTest::testUnpairedDevice() -{ - KdeConnectConfig::instance().removeTrustedDevice(deviceId); - - LanLinkProvider linkProvider; - QSslSocket socket; - LanDeviceLink* link = new LanDeviceLink(deviceId, &linkProvider, &socket, LanDeviceLink::Locally); - - Device device(this, *identityPacket, link); - - QCOMPARE(device.id(), deviceId); - QCOMPARE(device.name(), deviceName); - QCOMPARE(device.type(), deviceType); - - QCOMPARE(device.isTrusted(), false); - - QCOMPARE(device.isReachable(), true); - QCOMPARE(device.availableLinks().contains(linkProvider.name()), true); - - // Remove link - device.removeLink(link); - - QCOMPARE(device.isReachable(), false); - QCOMPARE(device.availableLinks().contains(linkProvider.name()), false); -} - -void DeviceTest::cleanupTestCase() -{ - delete identityPacket; -} - -QTEST_GUILESS_MAIN(DeviceTest) - -#include "devicetest.moc" diff --git a/tests/kdeconnectconfigtest.cpp b/tests/kdeconnectconfigtest.cpp deleted file mode 100644 index 781d94834..000000000 --- a/tests/kdeconnectconfigtest.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/** - * Copyright 2015 Vineet Garg - * - * 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) version 3 or any later version - * accepted by the membership of KDE e.V. (or its successor approved - * by the membership of KDE e.V.), which shall act as a proxy - * defined in Section 14 of version 3 of the license. - * - * 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 . - */ - - - -#include "../core/kdeconnectconfig.h" - -#include - -/* - * This class tests the working of kdeconnect config that certificate and key is generated and saved properly - */ -class KdeConnectConfigTest : public QObject -{ -Q_OBJECT - -private Q_SLOTS: - void addTrustedDevice(); -/* - void remoteCertificateTest(); -*/ - void removeTrustedDevice(); -}; - -void KdeConnectConfigTest::addTrustedDevice() -{ - KdeConnectConfig::instance().addTrustedDevice(QStringLiteral("testdevice"), QStringLiteral("Test Device"), QStringLiteral("phone")); - KdeConnectConfig::DeviceInfo devInfo = KdeConnectConfig::instance().getTrustedDevice(QStringLiteral("testdevice")); - QCOMPARE(devInfo.deviceName, QStringLiteral("Test Device")); - QCOMPARE(devInfo.deviceType, QStringLiteral("phone")); -} - -/* -// This checks whether certificate is generated correctly and stored correctly or not -void KdeConnectConfigTest::remoteCertificateTest() -{ - QSslCertificate certificate = kcc->certificate(); // Using same certificate as of device - - QCOMPARE(certificate.serialNumber().toInt(0,16), 10); - QCOMPARE(certificate.subjectInfo(QSslCertificate::SubjectInfo::CommonName).first(), kcc->deviceId()); - QCOMPARE(certificate.subjectInfo(QSslCertificate::SubjectInfo::Organization).first(), QString("KDE")); - QCOMPARE(certificate.subjectInfo(QSslCertificate::OrganizationalUnitName).first(), QString("Kde connect")); - - kcc->setDeviceProperty("testdevice","certificate", QString::fromLatin1(certificate.toPem())); - - KdeConnectConfig::DeviceInfo devInfo = kcc->getTrustedDevice("testdevice"); - QSslCertificate devCertificate = QSslCertificate::fromData(devInfo.certificate.toLatin1()).first(); - - QCOMPARE(devCertificate.serialNumber().toInt(0,16), 10); - QCOMPARE(devCertificate.subjectInfo(QSslCertificate::SubjectInfo::CommonName).first(), kcc->deviceId()); - QCOMPARE(devCertificate.subjectInfo(QSslCertificate::SubjectInfo::Organization).first(), QString("KDE")); - QCOMPARE(devCertificate.subjectInfo(QSslCertificate::OrganizationalUnitName).first(), QString("Kde connect")); - -} -*/ - - -void KdeConnectConfigTest::removeTrustedDevice() -{ - KdeConnectConfig::instance().removeTrustedDevice(QStringLiteral("testdevice")); - KdeConnectConfig::DeviceInfo devInfo = KdeConnectConfig::instance().getTrustedDevice(QStringLiteral("testdevice")); - QCOMPARE(devInfo.deviceName, QStringLiteral("unnamed")); - QCOMPARE(devInfo.deviceType, QStringLiteral("unknown")); -} - -QTEST_GUILESS_MAIN(KdeConnectConfigTest) - -#include "kdeconnectconfigtest.moc" diff --git a/tests/lanlinkprovidertest.cpp b/tests/lanlinkprovidertest.cpp deleted file mode 100644 index 953e6c511..000000000 --- a/tests/lanlinkprovidertest.cpp +++ /dev/null @@ -1,454 +0,0 @@ -/** - * Copyright 2015 Vineet Garg - * - * 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) version 3 or any later version - * accepted by the membership of KDE e.V. (or its successor approved - * by the membership of KDE e.V.), which shall act as a proxy - * defined in Section 14 of version 3 of the license. - * - * 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 . - */ - -// This class tests the behaviour of the class LanLinkProvider, be sure to kill process kdeconnectd to avoid any port binding issues - - -#include "../core/backends/lan/lanlinkprovider.h" -#include "../core/backends/lan/server.h" -#include "../core/backends/lan/socketlinereader.h" -#include "../core/kdeconnectconfig.h" - -#include -#include -#include -#include -#include -#include -#include - -/* - * This class tests the working of LanLinkProvider under different conditions that when identity packet is received over TCP, over UDP and same when the device is paired. - * It depends on KdeConnectConfig since LanLinkProvider internally uses it. - */ -class LanLinkProviderTest : public QObject -{ - Q_OBJECT -public: - explicit LanLinkProviderTest() - : m_lanLinkProvider(true) - , m_server(nullptr) - , m_reader(nullptr) - , m_udpSocket(nullptr) - { - QStandardPaths::setTestModeEnabled(true); - } - -public Q_SLOTS: - void initTestCase(); - void init(); - void cleanup(); - -private Q_SLOTS: - /** - * Test that the LanLinkProvider will send an identity packet to a non-default port - */ - void testChangedUDPBroadcastPort(); - /** - * Test that the LanLinkProvider will receive an identity packet on a non-default port - */ - void testChangedUDPListenPort(); - - void pairedDeviceTcpPacketReceived(); - void pairedDeviceUdpPacketReceived(); - - void unpairedDeviceTcpPacketReceived(); - void unpairedDeviceUdpPacketReceived(); - - -private: - const int TEST_PORT = 8520; - // Add some private fields here - LanLinkProvider m_lanLinkProvider; - Server* m_server; - SocketLineReader* m_reader; - QUdpSocket* m_udpSocket; - QString m_identityPacket; - - // Attributes for test device - QString m_deviceId; - QString m_name; - QCA::PrivateKey m_privateKey; - QSslCertificate m_certificate; - - QSslCertificate generateCertificate(QString&, QCA::PrivateKey&); - void addTrustedDevice(); - void removeTrustedDevice(); - void setSocketAttributes(QSslSocket* socket); - void testIdentityPacket(QByteArray& identityPacket); - void socketBindErrorFail(const QUdpSocket& socket); -}; - -void LanLinkProviderTest::initTestCase() -{ - removeTrustedDevice(); // Remove trusted device if left by chance by any test - - m_deviceId = QStringLiteral("testdevice"); - m_name = QStringLiteral("Test Device"); - m_privateKey = QCA::KeyGenerator().createRSA(2048); - m_certificate = generateCertificate(m_deviceId, m_privateKey); - - m_identityPacket = QStringLiteral("{\"id\":1439365924847,\"type\":\"kdeconnect.identity\",\"body\":{\"deviceId\":\"testdevice\",\"deviceName\":\"Test Device\",\"protocolVersion\":6,\"deviceType\":\"phone\",\"tcpPort\":") + QString::number(TEST_PORT) + QStringLiteral("}}"); -} - -void LanLinkProviderTest::init() -{ - m_lanLinkProvider.onStart(); -} - -void LanLinkProviderTest::cleanup() -{ - m_lanLinkProvider.onStop(); -} - -void LanLinkProviderTest::testChangedUDPBroadcastPort() -{ - quint16 udpListenPort = LanLinkProvider::UDP_PORT; - quint16 udpBroadcastPort = LanLinkProvider::UDP_PORT + 1; - - m_lanLinkProvider.onStop(); - LanLinkProvider testlanLinkProvider(true, udpBroadcastPort, udpListenPort); - testlanLinkProvider.onStart(); - - QUdpSocket mUdpServer; - bool bindSuccessful = mUdpServer.bind(QHostAddress::LocalHost, udpBroadcastPort, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint); - if (!bindSuccessful) { - socketBindErrorFail(mUdpServer); - } - - QSignalSpy spy(&mUdpServer, SIGNAL(readyRead())); - testlanLinkProvider.onNetworkChange(); - QVERIFY2(!spy.isEmpty() || spy.wait(), "Did not receive UDP packet"); -} - -void LanLinkProviderTest::testChangedUDPListenPort() -{ - quint16 udpListenPort = LanLinkProvider::UDP_PORT + 1; - quint16 udpBroadcastPort = LanLinkProvider::UDP_PORT; - - m_lanLinkProvider.onStop(); - LanLinkProvider testlanLinkProvider(true, udpBroadcastPort, udpListenPort); - testlanLinkProvider.onStart(); - - m_server = new Server(this); - QUdpSocket testUdpSocket; - - m_server->listen(QHostAddress::LocalHost, TEST_PORT); - - QSignalSpy spy(m_server, SIGNAL(newConnection())); - - // Write an identity packet to udp socket here. We do not broadcast it here. - qint64 bytesWritten = testUdpSocket.writeDatagram(m_identityPacket.toLatin1(), QHostAddress::LocalHost, udpListenPort); - QCOMPARE(bytesWritten, m_identityPacket.size()); - - // In response to receiving an identity packet, the LanLinkProvider should try to open a TCP connection to us - QVERIFY(!spy.isEmpty() || spy.wait()); - - QSslSocket* serverSocket = m_server->nextPendingConnection(); - - QVERIFY2(serverSocket != 0, "Server socket is null"); - QVERIFY2(serverSocket->isOpen(), "Server socket already closed"); - - delete m_server; -} - -void LanLinkProviderTest::pairedDeviceTcpPacketReceived() -{ - quint16 udpListenPort = LanLinkProvider::UDP_PORT; - quint16 udpBroadcastPort = LanLinkProvider::UDP_PORT + 1; - - m_lanLinkProvider.onStop(); - LanLinkProvider testlanLinkProvider(true, udpBroadcastPort, udpListenPort); - testlanLinkProvider.onStart(); - - addTrustedDevice(); - - QUdpSocket* mUdpServer = new QUdpSocket; - bool bindSuccessful = mUdpServer->bind(QHostAddress::LocalHost, udpBroadcastPort, QUdpSocket::ShareAddress); - if (!bindSuccessful) { - socketBindErrorFail(*mUdpServer); - } - - QSignalSpy spy(mUdpServer, SIGNAL(readyRead())); - testlanLinkProvider.onNetworkChange(); - QVERIFY(!spy.isEmpty() || spy.wait()); - - QByteArray datagram; - datagram.resize(mUdpServer->pendingDatagramSize()); - QHostAddress sender; - - mUdpServer->readDatagram(datagram.data(), datagram.size(), &sender); - - testIdentityPacket(datagram); - - QJsonDocument jsonDocument = QJsonDocument::fromJson(datagram); - QJsonObject body = jsonDocument.object().value(QStringLiteral("body")).toObject(); - int tcpPort = body.value(QStringLiteral("tcpPort")).toInt(); - - QSslSocket socket; - QSignalSpy spy2(&socket, SIGNAL(connected())); - - socket.connectToHost(sender, tcpPort); - QVERIFY(spy2.wait()); - - QVERIFY2(socket.isOpen(), "Socket disconnected immediately"); - - socket.write(m_identityPacket.toLatin1()); - socket.waitForBytesWritten(2000); - - QSignalSpy spy3(&socket, SIGNAL(encrypted())); - - setSocketAttributes(&socket); - socket.addCaCertificate(KdeConnectConfig::instance().certificate()); - socket.setPeerVerifyMode(QSslSocket::VerifyPeer); - socket.setPeerVerifyName(KdeConnectConfig::instance().name()); - - socket.startServerEncryption(); - QVERIFY(spy3.wait()); - - QCOMPARE(socket.sslErrors().size(), 0); - QVERIFY2(socket.isValid(), "Server socket disconnected"); - QVERIFY2(socket.isEncrypted(), "Server socket not yet encrypted"); - QVERIFY2(!socket.peerCertificate().isNull(), "Peer certificate is null"); - - removeTrustedDevice(); - delete mUdpServer; -} - -void LanLinkProviderTest::pairedDeviceUdpPacketReceived() -{ - addTrustedDevice(); - - m_server = new Server(this); - m_udpSocket = new QUdpSocket(this); - - m_server->listen(QHostAddress::LocalHost, TEST_PORT); - - QSignalSpy spy(m_server, SIGNAL(newConnection())); - - qint64 bytesWritten = m_udpSocket->writeDatagram(m_identityPacket.toLatin1(), QHostAddress::LocalHost, LanLinkProvider::UDP_PORT); // write an identity packet to udp socket here, we do not broadcast it here - QCOMPARE(bytesWritten, m_identityPacket.size()); - - // We should have an incoming connection now, wait for incoming connection - QVERIFY(!spy.isEmpty() || spy.wait()); - - QSslSocket* serverSocket = m_server->nextPendingConnection(); - - QVERIFY2(serverSocket != 0, "Server socket is null"); - QVERIFY2(serverSocket->isOpen(), "Server socket already closed"); - - m_reader = new SocketLineReader(serverSocket, this); - QSignalSpy spy2(m_reader, SIGNAL(readyRead())); - QVERIFY(spy2.wait()); - - QByteArray receivedPacket = m_reader->readLine(); - testIdentityPacket(receivedPacket); - // Received identity packet from LanLinkProvider now start ssl - - QSignalSpy spy3(serverSocket, SIGNAL(encrypted())); - QVERIFY(connect(serverSocket, static_cast(&QSslSocket::error), - this, [](QAbstractSocket::SocketError error){ qDebug() << "error:" << error; })); - - setSocketAttributes(serverSocket); - serverSocket->addCaCertificate(KdeConnectConfig::instance().certificate()); - serverSocket->setPeerVerifyMode(QSslSocket::VerifyPeer); - serverSocket->setPeerVerifyName(KdeConnectConfig::instance().deviceId()); - - serverSocket->startClientEncryption(); // Its TCP server. but SSL client - QVERIFY(!serverSocket->isEncrypted()); - spy3.wait(2000); - qDebug() << "xxxxxxxxx" << serverSocket->sslErrors(); - - QCOMPARE(serverSocket->sslErrors().size(), 0); - QVERIFY2(serverSocket->isValid(), "Server socket disconnected"); - QVERIFY2(serverSocket->isEncrypted(), "Server socket not yet encrypted"); - QVERIFY2(!serverSocket->peerCertificate().isNull(), "Peer certificate is null"); - - removeTrustedDevice(); - - delete m_server; - delete m_udpSocket; -} - -void LanLinkProviderTest::unpairedDeviceTcpPacketReceived() -{ - quint16 udpListenPort = LanLinkProvider::UDP_PORT; - quint16 udpBroadcastPort = LanLinkProvider::UDP_PORT + 1; - - m_lanLinkProvider.onStop(); - LanLinkProvider testlanLinkProvider(true, udpBroadcastPort, udpListenPort); - testlanLinkProvider.onStart(); - - QUdpSocket* mUdpServer = new QUdpSocket; - bool bindSuccessful = mUdpServer->bind(QHostAddress::LocalHost, udpBroadcastPort, QUdpSocket::ShareAddress); - if (!bindSuccessful) { - socketBindErrorFail(*mUdpServer); - } - - QSignalSpy spy(mUdpServer, SIGNAL(readyRead())); - testlanLinkProvider.onNetworkChange(); - QVERIFY(!spy.isEmpty() || spy.wait()); - - QByteArray datagram; - datagram.resize(mUdpServer->pendingDatagramSize()); - QHostAddress sender; - - mUdpServer->readDatagram(datagram.data(), datagram.size(), &sender); - - testIdentityPacket(datagram); - - QJsonDocument jsonDocument = QJsonDocument::fromJson(datagram); - QJsonObject body = jsonDocument.object().value(QStringLiteral("body")).toObject(); - int tcpPort = body.value(QStringLiteral("tcpPort")).toInt(); - - QSslSocket socket; - QSignalSpy spy2(&socket, SIGNAL(connected())); - - socket.connectToHost(sender, tcpPort); - QVERIFY(spy2.wait()); - - QVERIFY2(socket.isOpen(), "Socket disconnected immediately"); - - socket.write(m_identityPacket.toLatin1()); - socket.waitForBytesWritten(2000); - - QSignalSpy spy3(&socket, SIGNAL(encrypted())); - // We don't take care for sslErrors signal here, but signal will emit still we will get successful connection - - setSocketAttributes(&socket); - socket.setPeerVerifyMode(QSslSocket::QueryPeer); - - socket.startServerEncryption(); - - QVERIFY(spy3.wait()); - - QVERIFY2(socket.isValid(), "Server socket disconnected"); - QVERIFY2(socket.isEncrypted(), "Server socket not yet encrypted"); - QVERIFY2(!socket.peerCertificate().isNull(), "Peer certificate is null"); - - delete mUdpServer; -} - -void LanLinkProviderTest::unpairedDeviceUdpPacketReceived() -{ - m_server = new Server(this); - m_udpSocket = new QUdpSocket(this); - - m_server->listen(QHostAddress::LocalHost, TEST_PORT); - - QSignalSpy spy(m_server, &Server::newConnection); - qint64 bytesWritten = m_udpSocket->writeDatagram(m_identityPacket.toLatin1(), QHostAddress::LocalHost, LanLinkProvider::UDP_PORT); // write an identity packet to udp socket here, we do not broadcast it here - QCOMPARE(bytesWritten, m_identityPacket.size()); - - QVERIFY(!spy.isEmpty() || spy.wait()); - - QSslSocket* serverSocket = m_server->nextPendingConnection(); - - QVERIFY2(serverSocket != 0, "Server socket is null"); - QVERIFY2(serverSocket->isOpen(), "Server socket already closed"); - - m_reader = new SocketLineReader(serverSocket, this); - QSignalSpy spy2(m_reader, &SocketLineReader::readyRead); - QVERIFY(spy2.wait()); - - QByteArray receivedPacket = m_reader->readLine(); - QVERIFY2(!receivedPacket.isEmpty(), "Empty packet received"); - - testIdentityPacket(receivedPacket); - - // Received identity packet from LanLinkProvider now start ssl - - QSignalSpy spy3(serverSocket, SIGNAL(encrypted())); - - setSocketAttributes(serverSocket); - serverSocket->setPeerVerifyMode(QSslSocket::QueryPeer); - serverSocket->startClientEncryption(); // Its TCP server. but SSL client - QVERIFY(spy3.wait()); - - QVERIFY2(serverSocket->isValid(), "Server socket disconnected"); - QVERIFY2(serverSocket->isEncrypted(), "Server socket not yet encrypted"); - QVERIFY2(!serverSocket->peerCertificate().isNull(), "Peer certificate is null"); - - delete m_server; - delete m_udpSocket; -} - -void LanLinkProviderTest::testIdentityPacket(QByteArray& identityPacket) -{ - QJsonDocument jsonDocument = QJsonDocument::fromJson(identityPacket); - QJsonObject jsonObject = jsonDocument.object(); - QJsonObject body = jsonObject.value(QStringLiteral("body")).toObject(); - - QCOMPARE(jsonObject.value(QStringLiteral("type")).toString(), QStringLiteral("kdeconnect.identity")); - QVERIFY2(body.contains(QStringLiteral("deviceName")), "Device name not found in identity packet"); - QVERIFY2(body.contains(QStringLiteral("deviceId")), "Device id not found in identity packet"); - QVERIFY2(body.contains(QStringLiteral("protocolVersion")), "Protocol version not found in identity packet"); - QVERIFY2(body.contains(QStringLiteral("deviceType")), "Device type not found in identity packet"); -} - -QSslCertificate LanLinkProviderTest::generateCertificate(QString& commonName, QCA::PrivateKey& privateKey) -{ - QDateTime startTime = QDateTime::currentDateTime(); - QDateTime endTime = startTime.addYears(10); - QCA::CertificateInfo certificateInfo; - certificateInfo.insert(QCA::CommonName,commonName); - certificateInfo.insert(QCA::Organization,QStringLiteral("KDE")); - certificateInfo.insert(QCA::OrganizationalUnit,QStringLiteral("Kde connect")); - - QCA::CertificateOptions certificateOptions(QCA::PKCS10); - certificateOptions.setSerialNumber(10); - certificateOptions.setInfo(certificateInfo); - certificateOptions.setValidityPeriod(startTime, endTime); - certificateOptions.setFormat(QCA::PKCS10); - - QSslCertificate certificate = QSslCertificate(QCA::Certificate(certificateOptions, privateKey).toPEM().toLatin1()); - return certificate; -} - -void LanLinkProviderTest::setSocketAttributes(QSslSocket* socket) -{ - socket->setPrivateKey(QSslKey(m_privateKey.toPEM().toLatin1(), QSsl::Rsa)); - socket->setLocalCertificate(m_certificate); -} - -void LanLinkProviderTest::addTrustedDevice() -{ - KdeConnectConfig::instance().addTrustedDevice(m_deviceId, m_name, QStringLiteral("phone")); - KdeConnectConfig::instance().setDeviceProperty(m_deviceId, QStringLiteral("certificate"), QString::fromLatin1(m_certificate.toPem())); -} - -void LanLinkProviderTest::removeTrustedDevice() -{ - KdeConnectConfig::instance().removeTrustedDevice(m_deviceId); -} - -void LanLinkProviderTest::socketBindErrorFail(const QUdpSocket& socket) -{ - QAbstractSocket::SocketError sockErr = socket.error(); - // Refer to https://doc.qt.io/qt-5/qabstractsocket.html#SocketError-enum to decode socket error number - QString errorMessage = QLatin1String("Failed to bind UDP socket with error "); - errorMessage = errorMessage + QString::fromLatin1(QMetaEnum::fromType().valueToKey(sockErr)); - QFAIL(errorMessage.toLocal8Bit().data()); -} - - -QTEST_GUILESS_MAIN(LanLinkProviderTest) - -#include "lanlinkprovidertest.moc" diff --git a/tests/networkpackettests.cpp b/tests/networkpackettests.cpp deleted file mode 100644 index e4e8082ab..000000000 --- a/tests/networkpackettests.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/** - * Copyright 2013 Albert Vaca - * - * 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) version 3 or any later version - * accepted by the membership of KDE e.V. (or its successor approved - * by the membership of KDE e.V.), which shall act as a proxy - * defined in Section 14 of version 3 of the license. - * - * 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 . - */ - -#include "networkpackettests.h" - -#include "core/networkpacket.h" - -#include -#include - -QTEST_GUILESS_MAIN(NetworkPacketTests); - -void NetworkPacketTests::initTestCase() -{ - // Called before the first testfunction is executed -} - -void NetworkPacketTests::networkPacketTest() -{ - NetworkPacket np(QStringLiteral("com.test")); - - np.set(QStringLiteral("hello"), QStringLiteral("hola")); - QCOMPARE( (np.get(QStringLiteral("hello"), QStringLiteral("bye"))) , QStringLiteral("hola") ); - - np.set(QStringLiteral("hello"), QString()); - QCOMPARE((np.get(QStringLiteral("hello"), QStringLiteral("bye"))) , QString()); - - np.body().remove(QStringLiteral("hello")); - QCOMPARE((np.get(QStringLiteral("hello"), QStringLiteral("bye"))) , QStringLiteral("bye")); - - np.set(QStringLiteral("foo"), QStringLiteral("bar")); - QByteArray ba = np.serialize(); - //qDebug() << "Serialized packet:" << ba; - NetworkPacket np2(QLatin1String("")); - NetworkPacket::unserialize(ba,&np2); - - QCOMPARE( np.id(), np2.id() ); - QCOMPARE( np.type(), np2.type() ); - QCOMPARE( np.body(), np2.body() ); - - QByteArray json("{\"id\":\"123\",\"type\":\"test\",\"body\":{\"testing\":true}}"); - //qDebug() << json; - NetworkPacket::unserialize(json,&np2); - QCOMPARE( np2.id(), QStringLiteral("123") ); - QCOMPARE( (np2.get(QStringLiteral("testing"))), true ); - QCOMPARE( (np2.get(QStringLiteral("not_testing"))), false ); - QCOMPARE( (np2.get(QStringLiteral("not_testing"),true)), true ); - - //NetworkPacket::unserialize("this is not json",&np2); - //QtTest::ignoreMessage(QtSystemMsg, "json_parser - syntax error found, forcing abort, Line 1 Column 0"); - //QtTest::ignoreMessage(QtDebugMsg, "Unserialization error: 1 \"syntax error, unexpected string\""); - -} - -void NetworkPacketTests::networkPacketIdentityTest() -{ - NetworkPacket np(QLatin1String("")); - NetworkPacket::createIdentityPacket(&np); - - QCOMPARE( np.get(QStringLiteral("protocolVersion"), -1) , NetworkPacket::s_protocolVersion ); - QCOMPARE( np.type() , PACKET_TYPE_IDENTITY ); - -} - -void NetworkPacketTests::networkPacketPayloadTest() -{ - QByteArray json; - NetworkPacket np; - - // empty package - np = NetworkPacket(QStringLiteral("com.test")); - json = np.serialize(); - qDebug() << json; - QVERIFY(!json.contains("\"payloadSize\"")); - QVERIFY(!json.contains("\"payloadTransferInfo\"")); - - // package with payload - QByteArray buffer("test data"); - auto payload = QSharedPointer(new QBuffer(&buffer, this)); - np = NetworkPacket(QStringLiteral("com.test")); - np.setPayload(payload, buffer.size()); - - json = np.serialize(); - qDebug() << json; - QVERIFY(json.contains("\"payloadSize\":9")); - QVERIFY(json.contains("\"payloadTransferInfo\"")); - - // package with empty payload - QByteArray emptyBuffer("test data"); - auto emptyPayload = QSharedPointer(new QBuffer(&emptyBuffer, this)); - np = NetworkPacket(QStringLiteral("com.test")); - np.setPayload(emptyPayload, 0); - - json = np.serialize(); - qDebug() << json; - QVERIFY(!json.contains("\"payloadSize\"")); - QVERIFY(!json.contains("\"payloadTransferInfo\"")); - - // incoming package without payload - np = NetworkPacket(); - QVERIFY(NetworkPacket::unserialize( - "{\"body\":{},\"id\":\"1578136807254\",\"type\":\"com.test\"}\n", &np)); - QVERIFY(!np.hasPayload()); - - // incoming package without payload (but with payload keys) - np = NetworkPacket(); - QVERIFY(NetworkPacket::unserialize( - "{\"body\":{},\"id\":\"1578136807254\",\"payloadSize\":0,\"payloadTransferInfo\":{},\"type\":\"com.test\"}\n", &np)); - QVERIFY(!np.hasPayload()); -} - -void NetworkPacketTests::cleanupTestCase() -{ - // Called after the last testfunction was executed -} - -void NetworkPacketTests::init() -{ - // Called before each testfunction is executed -} - -void NetworkPacketTests::cleanup() -{ - // Called after every testfunction -} - diff --git a/tests/testnotificationlistener.cpp b/tests/testnotificationlistener.cpp deleted file mode 100644 index 16ca6269f..000000000 --- a/tests/testnotificationlistener.cpp +++ /dev/null @@ -1,456 +0,0 @@ -/** - * Copyright 2015 Holger Kaelberer - * - * 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) version 3 or any later version - * accepted by the membership of KDE e.V. (or its successor approved - * by the membership of KDE e.V.), which shall act as a proxy - * defined in Section 14 of version 3 of the license. - * - * 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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "core/daemon.h" -#include "core/device.h" -#include "testdevice.h" -#include "core/kdeconnectplugin.h" -#include "kdeconnect-version.h" -#include "plugins/sendnotifications/sendnotificationsplugin.h" -#include "plugins/sendnotifications/notificationslistener.h" -#include "plugins/sendnotifications/notifyingapplication.h" - -// Tweaked NotificationsPlugin for testing -class TestNotificationsPlugin : public SendNotificationsPlugin -{ - Q_OBJECT -public: - explicit TestNotificationsPlugin(QObject* parent, const QVariantList& args) - : SendNotificationsPlugin(parent, args) - { - } - - ~TestNotificationsPlugin() override = default; - - // allow to access notificationsListener for testing: - NotificationsListener* getNotificationsListener() const - { - return notificationsListener; - } - - void setNotificationsListener(NotificationsListener* value) - { - notificationsListener = value; - } - -}; - -// Tweaked NotificationsListener for testing: -class TestedNotificationsListener: public NotificationsListener -{ - Q_OBJECT -public: - explicit TestedNotificationsListener(KdeConnectPlugin* aPlugin) - : NotificationsListener(aPlugin) - {} - - ~TestedNotificationsListener() override - {} - - QHash& getApplications() - { - return m_applications; - } - - void setApplications(const QHash& value) - { - m_applications = value; - } - - QSharedPointer iconForIconName(const QString& iconName) const { - return NotificationsListener::iconForIconName(iconName); - } - -protected: - bool parseImageDataArgument(const QVariant& argument, int& width, - int& height, int& rowStride, int& bitsPerSample, - int& channels, bool& hasAlpha, - QByteArray& imageData) const override - { - width = argument.toMap().value(QStringLiteral("width")).toInt(); - height = argument.toMap().value(QStringLiteral("height")).toInt(); - rowStride = argument.toMap().value(QStringLiteral("rowStride")).toInt(); - bitsPerSample = argument.toMap().value(QStringLiteral("bitsPerSample")).toInt(); - channels = argument.toMap().value(QStringLiteral("channels")).toInt(); - hasAlpha = argument.toMap().value(QStringLiteral("hasAlpha")).toBool(); - imageData = argument.toMap().value(QStringLiteral("imageData")).toByteArray(); - return true; - } - -}; - -class TestNotificationListener : public QObject -{ - Q_OBJECT - public: - TestNotificationListener() - : plugin(nullptr) - { - QStandardPaths::setTestModeEnabled(true); - } - - private Q_SLOTS: - void testNotify(); - - private: - TestNotificationsPlugin* plugin; -}; - -void TestNotificationListener::testNotify() -{ - // - // set things up: - // - - QString dId(QStringLiteral("testid")); - TestDevice* d = new TestDevice(nullptr, dId); - - int proxiedNotifications = 0; - QCOMPARE(proxiedNotifications, d->getSentPackets()); - plugin = new TestNotificationsPlugin(this, - QVariantList({ QVariant::fromValue(d), - QStringLiteral("notifications_plugin"), - {QStringLiteral("kdeconnect.notification")}, - QStringLiteral("preferences-desktop-notification")})); - QVERIFY(plugin->getNotificationsListener()); - delete plugin->getNotificationsListener(); - - // inject our tweaked NotificationsListener: - TestedNotificationsListener* listener = new TestedNotificationsListener(plugin); - QVERIFY(listener); - plugin->setNotificationsListener(listener); - QCOMPARE(listener, plugin->getNotificationsListener()); - - // make sure config is default: - plugin->config()->set(QStringLiteral("generalPersistent"), false); - plugin->config()->set(QStringLiteral("generalIncludeBody"), true); - plugin->config()->set(QStringLiteral("generalUrgency"), 0); - QCOMPARE(plugin->config()->get(QStringLiteral("generalPersistent")), false); - QCOMPARE(plugin->config()->get(QStringLiteral("generalIncludeBody")), true); - QCOMPARE(plugin->config()->get(QStringLiteral("generalUrgency")), false); - - // applications are modified directly: - listener->getApplications().clear(); - QCOMPARE(listener->getApplications().count(), 0); - - // - // Go !!! - // - - uint replacesId = 99; - uint retId; - QString appName(QStringLiteral("some-appName")); - QString body(QStringLiteral("some-body")); - QString icon(QStringLiteral("some-icon")); - QString summary(QStringLiteral("some-summary")); - - // regular Notify call that is synchronized ... - retId = listener->Notify(appName, replacesId, icon, summary, body, {}, {{}}, 0); - // ... should return replacesId, - QCOMPARE(retId, replacesId); - // ... have triggered sending a packet - QCOMPARE(++proxiedNotifications, d->getSentPackets()); - // ... with our properties, - QCOMPARE(d->getLastPacket()->get(QStringLiteral("id")), replacesId); - QCOMPARE(d->getLastPacket()->get(QStringLiteral("appName")), appName); - QCOMPARE(d->getLastPacket()->get(QStringLiteral("ticker")), summary + QStringLiteral(": ") + body); - QCOMPARE(d->getLastPacket()->get(QStringLiteral("isClearable")), true); - QCOMPARE(d->getLastPacket()->hasPayload(), false); - - // ... and create a new application internally that is initialized correctly: - QCOMPARE(listener->getApplications().count(), 1); - QVERIFY(listener->getApplications().contains(appName)); - QVERIFY(listener->getApplications()[appName].active); - QCOMPARE(listener->getApplications()[appName].name, appName); - QVERIFY(listener->getApplications()[appName].blacklistExpression.pattern().isEmpty()); - QCOMPARE(listener->getApplications()[appName].name, appName); - QCOMPARE(listener->getApplications()[appName].icon, icon); - - // another one, with other timeout and urgency values: - QString appName2(QStringLiteral("some-appName2")); - QString body2(QStringLiteral("some-body2")); - QString icon2(QStringLiteral("some-icon2")); - QString summary2(QStringLiteral("some-summary2")); - - retId = listener->Notify(appName2, replacesId+1, icon2, summary2, body2, {}, {{QStringLiteral("urgency"), 2}}, 10); - QCOMPARE(retId, replacesId+1); - QCOMPARE(++proxiedNotifications, d->getSentPackets()); - QCOMPARE(d->getLastPacket()->get(QStringLiteral("id")), replacesId+1); - QCOMPARE(d->getLastPacket()->get(QStringLiteral("appName")), appName2); - QCOMPARE(d->getLastPacket()->get(QStringLiteral("ticker")), summary2 + QStringLiteral(": ") + body2); - QCOMPARE(d->getLastPacket()->get(QStringLiteral("isClearable")), false); // timeout != 0 - QCOMPARE(d->getLastPacket()->hasPayload(), false); - QCOMPARE(listener->getApplications().count(), 2); - QVERIFY(listener->getApplications().contains(appName2)); - QVERIFY(listener->getApplications().contains(appName)); - - // if persistent-only is set, timeouts > 0 are not synced: - plugin->config()->set(QStringLiteral("generalPersistent"), true); - retId = listener->Notify(appName, replacesId, icon, summary, body, {}, {{}}, 1); - QCOMPARE(retId, 0U); - QCOMPARE(proxiedNotifications, d->getSentPackets()); - retId = listener->Notify(appName2, replacesId, icon2, summary2, body2, {}, {{}}, 3); - QCOMPARE(retId, 0U); - QCOMPARE(proxiedNotifications, d->getSentPackets()); - // but timeout == 0 is - retId = listener->Notify(appName, replacesId, icon, summary, body, {}, {{}}, 0); - QCOMPARE(retId, replacesId); - QCOMPARE(++proxiedNotifications, d->getSentPackets()); - plugin->config()->set(QStringLiteral("generalPersistent"), false); - - // if min-urgency is set, lower urgency levels are not synced: - plugin->config()->set(QStringLiteral("generalUrgency"), 1); - retId = listener->Notify(appName, replacesId, icon, summary, body, {}, {{QStringLiteral("urgency"), 0}}, 0); - QCOMPARE(retId, 0U); - QCOMPARE(proxiedNotifications, d->getSentPackets()); - // equal urgency is - retId = listener->Notify(appName, replacesId, icon, summary, body, {}, {{QStringLiteral("urgency"), 1}}, 0); - QCOMPARE(retId, replacesId); - QCOMPARE(++proxiedNotifications, d->getSentPackets()); - // higher urgency as well - retId = listener->Notify(appName, replacesId, icon, summary, body, {}, {{QStringLiteral("urgency"), 2}}, 0); - QCOMPARE(retId, replacesId); - QCOMPARE(++proxiedNotifications, d->getSentPackets()); - plugin->config()->set(QStringLiteral("generalUrgency"), 0); - - // notifications for a deactivated application are not synced: - QVERIFY(listener->getApplications().contains(appName)); - listener->getApplications()[appName].active = false; - QVERIFY(!listener->getApplications()[appName].active); - retId = listener->Notify(appName, replacesId, icon, summary, body, {}, {{QStringLiteral("urgency"), 0}}, 0); - QCOMPARE(retId, 0U); - QCOMPARE(proxiedNotifications, d->getSentPackets()); - // others are still: - retId = listener->Notify(appName2, replacesId+1, icon2, summary2, body2, {}, {{}}, 0); - QCOMPARE(retId, replacesId+1); - QCOMPARE(++proxiedNotifications, d->getSentPackets()); - // back to normal: - listener->getApplications()[appName].active = true; - QVERIFY(listener->getApplications()[appName].active); - retId = listener->Notify(appName, replacesId, icon, summary, body, {}, {{}}, 0); - QCOMPARE(retId, replacesId); - QCOMPARE(++proxiedNotifications, d->getSentPackets()); - - // notifications with blacklisted subjects are not synced: - QVERIFY(listener->getApplications().contains(appName)); - listener->getApplications()[appName].blacklistExpression.setPattern(QStringLiteral("black[12]|foo(bar|baz)")); - retId = listener->Notify(appName, replacesId, icon, QStringLiteral("summary black1"), body, {}, {{}}, 0); - QCOMPARE(retId, 0U); - QCOMPARE(proxiedNotifications, d->getSentPackets()); - retId = listener->Notify(appName, replacesId, icon, QStringLiteral("summary foobar"), body, {}, {{}}, 0); - QCOMPARE(retId, 0U); - QCOMPARE(proxiedNotifications, d->getSentPackets()); - // other subjects are synced: - retId = listener->Notify(appName, replacesId, icon, QStringLiteral("summary foo"), body, {}, {{}}, 0); - QCOMPARE(retId, replacesId); - QCOMPARE(++proxiedNotifications, d->getSentPackets()); - retId = listener->Notify(appName, replacesId, icon, QStringLiteral("summary black3"), body, {}, {{}}, 0); - QCOMPARE(retId, replacesId); - QCOMPARE(++proxiedNotifications, d->getSentPackets()); - // also body is checked by blacklist if requested: - plugin->config()->set(QStringLiteral("generalIncludeBody"), true); - retId = listener->Notify(appName, replacesId, icon, summary, QStringLiteral("body black1"), {}, {{}}, 0); - QCOMPARE(retId, 0U); - QCOMPARE(proxiedNotifications, d->getSentPackets()); - retId = listener->Notify(appName, replacesId, icon, summary, QStringLiteral("body foobaz"), {}, {{}}, 0); - QCOMPARE(retId, 0U); - QCOMPARE(proxiedNotifications, d->getSentPackets()); - // body does not matter if inclusion was not requested: - plugin->config()->set(QStringLiteral("generalIncludeBody"), false); - retId = listener->Notify(appName, replacesId, icon, summary, QStringLiteral("body black1"), {}, {{}}, 0); - QCOMPARE(retId, replacesId); - QCOMPARE(++proxiedNotifications, d->getSentPackets()); - // without body, also ticker value is different: - QCOMPARE(d->getLastPacket()->get(QStringLiteral("ticker")), summary); - retId = listener->Notify(appName, replacesId, icon, summary, QStringLiteral("body foobaz"), {}, {{}}, 0); - QCOMPARE(retId, replacesId); - QCOMPARE(++proxiedNotifications, d->getSentPackets()); - - // back to normal: - listener->getApplications()[appName].blacklistExpression.setPattern(QLatin1String("")); - plugin->config()->set(QStringLiteral("generalIncludeBody"), true); - retId = listener->Notify(appName, replacesId, icon, summary, body, {}, {{}}, 0); - QCOMPARE(retId, replacesId); - QCOMPARE(++proxiedNotifications, d->getSentPackets()); - retId = listener->Notify(appName2, replacesId, icon2, summary2, body2, {}, {{}}, 0); - QCOMPARE(retId, replacesId); - QCOMPARE(++proxiedNotifications, d->getSentPackets()); - - // icon synchronization: - QStringList iconPaths; - // appIcon - int count = 0; - const QStringList icons = KIconLoader::global()->queryIcons(-KIconLoader::SizeEnormous, KIconLoader::Application); - for (const auto& iconName : icons) { - if (!iconName.endsWith(QLatin1String(".png"))) - continue; - if (count++ > 3) // max 3 iterations - break; - iconPaths.append(iconName); // memorize some paths for later - - // existing icons are sync-ed if requested - plugin->config()->set(QStringLiteral("generalSynchronizeIcons"), true); - QFileInfo fi(iconName); - retId = listener->Notify(appName, replacesId, fi.baseName(), summary, body, {}, {{}}, 0); - QCOMPARE(retId, replacesId); - QCOMPARE(++proxiedNotifications, d->getSentPackets()); - QVERIFY(d->getLastPacket()->hasPayload()); - QCOMPARE(d->getLastPacket()->payloadSize(), listener->iconForIconName(fi.baseName())->size()); - // works also with absolute paths - retId = listener->Notify(appName, replacesId, iconName, summary, body, {}, {{}}, 0); - QCOMPARE(retId, replacesId); - QCOMPARE(++proxiedNotifications, d->getSentPackets()); - QVERIFY(d->getLastPacket()->hasPayload()); - QCOMPARE(d->getLastPacket()->payloadSize(), fi.size()); - // extensions other than png are not accepted: - retId = listener->Notify(appName, replacesId, iconName + QStringLiteral(".svg"), summary, body, {}, {{}}, 0); - QCOMPARE(retId, replacesId); - QCOMPARE(++proxiedNotifications, d->getSentPackets()); - QVERIFY(!d->getLastPacket()->hasPayload()); - - // if sync not requested no payload: - plugin->config()->set(QStringLiteral("generalSynchronizeIcons"), false); - retId = listener->Notify(appName, replacesId, fi.baseName(), summary, body, {}, {{}}, 0); - QCOMPARE(retId, replacesId); - QCOMPARE(++proxiedNotifications, d->getSentPackets()); - QVERIFY(!d->getLastPacket()->hasPayload()); - QCOMPARE(d->getLastPacket()->payloadSize(), 0); - } - plugin->config()->set(QStringLiteral("generalSynchronizeIcons"), true); - - // image-path in hints - if (iconPaths.size() > 0) { - retId = listener->Notify(appName, replacesId, iconPaths.size() > 1 ? iconPaths[1] : icon, summary, body, {}, {{QStringLiteral("image-path"), iconPaths[0]}}, 0); - QCOMPARE(retId, replacesId); - QCOMPARE(++proxiedNotifications, d->getSentPackets()); - QVERIFY(d->getLastPacket()->hasPayload()); - QFileInfo hintsFi(iconPaths[0]); - // image-path has priority over appIcon parameter: - QCOMPARE(d->getLastPacket()->payloadSize(), hintsFi.size()); - } - - // image_path in hints - if (iconPaths.size() > 0) { - retId = listener->Notify(appName, replacesId, iconPaths.size() > 1 ? iconPaths[1] : icon, summary, body, {}, {{QStringLiteral("image_path"), iconPaths[0]}}, 0); - QCOMPARE(retId, replacesId); - QCOMPARE(++proxiedNotifications, d->getSentPackets()); - QVERIFY(d->getLastPacket()->hasPayload()); - QFileInfo hintsFi(iconPaths[0]); - // image_path has priority over appIcon parameter: - QCOMPARE(d->getLastPacket()->payloadSize(), hintsFi.size()); - } - - // image-data in hints - // set up: - QBuffer* buffer; - QImage image; - int width = 2, height = 2, rowStride = 4*width, bitsPerSample = 8, - channels = 4; - bool hasAlpha = 1; - char rawData[] = { 0x01, 0x02, 0x03, 0x04, // raw rgba data - 0x11, 0x12, 0x13, 0x14, - 0x21, 0x22, 0x23, 0x24, - 0x31, 0x32, 0x33, 0x34 }; - QVariantMap imageData = {{QStringLiteral("width"), width}, {QStringLiteral("height"), height}, {QStringLiteral("rowStride"), rowStride}, - {QStringLiteral("bitsPerSample"), bitsPerSample}, {QStringLiteral("channels"), channels}, - {QStringLiteral("hasAlpha"), hasAlpha}, {QStringLiteral("imageData"), QByteArray(rawData, sizeof(rawData))}}; - QVariantMap hints; -#define COMPARE_PIXEL(x, y) \ - QCOMPARE(qRed(image.pixel(x,y)), (int)rawData[x*4 + y*rowStride + 0]); \ - QCOMPARE(qGreen(image.pixel(x,y)), (int)rawData[x*4 + y*rowStride + 1]); \ - QCOMPARE(qBlue(image.pixel(x,y)), (int)rawData[x*4 + y*rowStride + 2]); \ - QCOMPARE(qAlpha(image.pixel(x,y)), (int)rawData[x*4 + y*rowStride + 3]); - - hints.insert(QStringLiteral("image-data"), imageData); - if (iconPaths.size() > 0) - hints.insert(QStringLiteral("image-path"), iconPaths[0]); - retId = listener->Notify(appName, replacesId, icon, summary, body, {}, hints, 0); - QCOMPARE(retId, replacesId); - QCOMPARE(++proxiedNotifications, d->getSentPackets()); - QVERIFY(d->getLastPacket()->hasPayload()); - buffer = dynamic_cast(d->getLastPacket()->payload().data()); - QCOMPARE(d->getLastPacket()->payloadSize(), buffer->size()); - // image-data is attached as png data - QVERIFY(image.loadFromData(reinterpret_cast(buffer->data().constData()), buffer->size(), "PNG")); - // image-data has priority over image-path: - QCOMPARE(image.sizeInBytes(), rowStride*height); - // rgba -> argb conversion was done correctly: - COMPARE_PIXEL(0,0); - COMPARE_PIXEL(1,0); - COMPARE_PIXEL(0,1); - COMPARE_PIXEL(1,1); - - // same for image_data in hints - hints.clear(); - hints.insert(QStringLiteral("image-data"), imageData); - if (iconPaths.size() > 0) - hints.insert(QStringLiteral("image_path"), iconPaths[0]); - retId = listener->Notify(appName, replacesId, icon, summary, body, {}, hints, 0); - QCOMPARE(retId, replacesId); - QCOMPARE(++proxiedNotifications, d->getSentPackets()); - QVERIFY(d->getLastPacket()->hasPayload()); - buffer = dynamic_cast(d->getLastPacket()->payload().data()); - QCOMPARE(d->getLastPacket()->payloadSize(), buffer->size()); - // image-data is attached as png data - QVERIFY(image.loadFromData(reinterpret_cast(buffer->data().constData()), buffer->size(), "PNG")); - // image_data has priority over image_path/image-path: - QCOMPARE(image.sizeInBytes(), rowStride*height); - // rgba -> argb conversion was done correctly: - COMPARE_PIXEL(0,0); - COMPARE_PIXEL(1,0); - COMPARE_PIXEL(0,1); - COMPARE_PIXEL(1,1); - - // same for icon_data, which has lowest priority - hints.clear(); - hints.insert(QStringLiteral("icon_data"), imageData); - retId = listener->Notify(appName, replacesId, QLatin1String(""), summary, body, {}, hints, 0); - QCOMPARE(retId, replacesId); - QCOMPARE(++proxiedNotifications, d->getSentPackets()); - QVERIFY(d->getLastPacket()); - QVERIFY(d->getLastPacket()->hasPayload()); - buffer = dynamic_cast(d->getLastPacket()->payload().data()); - // image-data is attached as png data - QVERIFY(image.loadFromData(reinterpret_cast(buffer->data().constData()), buffer->size(), "PNG")); - QCOMPARE(image.sizeInBytes(), rowStride*height); - // rgba -> argb conversion was done correctly: - COMPARE_PIXEL(0,0); - COMPARE_PIXEL(1,0); - COMPARE_PIXEL(0,1); - COMPARE_PIXEL(1,1); - -#undef COMPARE_PIXEL -} - - -QTEST_GUILESS_MAIN(TestNotificationListener); - -#include "testnotificationlistener.moc" diff --git a/tests/testsslsocketlinereader.cpp b/tests/testsslsocketlinereader.cpp deleted file mode 100644 index a9d4e9a5d..000000000 --- a/tests/testsslsocketlinereader.cpp +++ /dev/null @@ -1,361 +0,0 @@ -/** - * Copyright 2015 Vineet Garg - * - * 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) version 3 or any later version - * accepted by the membership of KDE e.V. (or its successor approved - * by the membership of KDE e.V.), which shall act as a proxy - * defined in Section 14 of version 3 of the license. - * - * 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 . - */ - -#include "../core/backends/lan/server.h" -#include "../core/backends/lan/socketlinereader.h" -#include "../core/qtcompat_p.h" - -#include -#include -#include -#include -#include - -/* - * This class tests the behaviour of socket line reader when the connection if over ssl. Since SSL takes part below application layer, - * working of SocketLineReader should be same. - */ -class TestSslSocketLineReader : public QObject -{ - Q_OBJECT -public Q_SLOTS: - void newPacket(); - void testTimeout(); - -private Q_SLOTS: - - void initTestCase(); - void init(); - void cleanup(); - void cleanupTestCase(); - - void testTrustedDevice(); - void testUntrustedDevice(); - void testTrustedDeviceWithWrongCertificate(); - - -private: - const int PORT = 7894; - const int TIMEOUT = 4 * 1000; - QTimer m_timer; - QCA::Initializer m_qcaInitializer; - QEventLoop m_loop; - QList m_packets; - Server* m_server; - QSslSocket* m_clientSocket; - SocketLineReader* m_reader; - -private: - void setSocketAttributes(QSslSocket* socket, QString deviceName); -}; - -void TestSslSocketLineReader::initTestCase() -{ - m_server = new Server(this); - - QVERIFY2(m_server->listen(QHostAddress::LocalHost, PORT), "Failed to create local tcp server"); - - m_timer.setSingleShot(true); - connect(&m_timer, &QTimer::timeout, this, &TestSslSocketLineReader::testTimeout); -} - -void TestSslSocketLineReader::init() -{ - m_timer.setInterval(TIMEOUT); - m_timer.start(); - - m_clientSocket = new QSslSocket(this); - m_clientSocket->connectToHost(QHostAddress::LocalHost, PORT); - connect(m_clientSocket, &QAbstractSocket::connected, &m_loop, &QEventLoop::quit); - - m_loop.processEvents(QEventLoop::AllEvents, TIMEOUT); - - QVERIFY2(m_clientSocket->isOpen(), "Could not connect to local tcp server"); -} - -void TestSslSocketLineReader::cleanup() -{ - m_clientSocket->disconnectFromHost(); - m_timer.stop(); - delete m_clientSocket; -} - -void TestSslSocketLineReader::cleanupTestCase() -{ - delete m_server; -} - -void TestSslSocketLineReader::testTrustedDevice() -{ - - int maxAttemps = 5; - while(!m_server->hasPendingConnections() && maxAttemps > 0) { - --maxAttemps; - QTest::qSleep(1000); - } - QCOMPARE(true, m_server->hasPendingConnections()); - - QSslSocket* serverSocket = m_server->nextPendingConnection(); - - QSignalSpy serverEncryptedSpy(serverSocket, SIGNAL(encrypted())); - - QVERIFY2(serverSocket != 0, "Null socket returned by server"); - QVERIFY2(serverSocket->isOpen(), "Server socket already closed"); - - setSocketAttributes(serverSocket, QStringLiteral("Test Server")); - setSocketAttributes(m_clientSocket, QStringLiteral("Test Client")); - - serverSocket->setPeerVerifyName(QStringLiteral("Test Client")); - serverSocket->setPeerVerifyMode(QSslSocket::VerifyPeer); - serverSocket->addCaCertificate(m_clientSocket->localCertificate()); - - m_clientSocket->setPeerVerifyName(QStringLiteral("Test Server")); - m_clientSocket->setPeerVerifyMode(QSslSocket::VerifyPeer); - m_clientSocket->addCaCertificate(serverSocket->localCertificate()); - - int connected_sockets = 0; - auto connected_lambda = [&](){ - connected_sockets++; - if (connected_sockets >= 2) { - m_loop.quit(); - } - }; - connect(serverSocket, &QSslSocket::encrypted, connected_lambda); - connect(m_clientSocket, &QSslSocket::encrypted, connected_lambda); - - serverSocket->startServerEncryption(); - m_clientSocket->startClientEncryption(); - m_loop.exec(); //Block until QEventLoop::quit gets called by the lambda - - if (serverEncryptedSpy.count() < 1) { - for(int x = 0;x < 50; ++x) { - QVERIFY(serverEncryptedSpy.wait(100)); - if (serverEncryptedSpy.count() > 0) { - break; - } - } - } - - // Both client and server socket should be encrypted here and should have remote certificate because VerifyPeer is used - QVERIFY2(m_clientSocket->isOpen(), "Client socket already closed"); - QVERIFY2(serverSocket->isOpen(), "Server socket already closed"); - QVERIFY2(m_clientSocket->isEncrypted(), "Client is not encrypted"); - QVERIFY2(serverSocket->isEncrypted(), "Server is not encrypted"); - QVERIFY2(!m_clientSocket->peerCertificate().isNull(), "Server certificate not received"); - QVERIFY2(!serverSocket->peerCertificate().isNull(), "Client certificate not received"); - - QList dataToSend; - dataToSend << "foobar\n" << "barfoo\n" << "foobar?\n" << "\n" << "barfoo!\n" << "panda\n"; - for (const QByteArray& line : qAsConst(dataToSend)) { - m_clientSocket->write(line); - } - m_clientSocket->flush(); - - m_packets.clear(); - - m_reader = new SocketLineReader(serverSocket, this); - connect(m_reader, &SocketLineReader::readyRead, this,&TestSslSocketLineReader::newPacket); - m_loop.exec(); - - /* remove the empty line before compare */ - dataToSend.removeOne("\n"); - - QCOMPARE(m_packets.count(), 5);//We expect 5 Packets - for(int x = 0;x < 5; ++x) { - QCOMPARE(m_packets[x], dataToSend[x]); - } - - delete m_reader; -} - -void TestSslSocketLineReader::testUntrustedDevice() -{ - int maxAttemps = 5; - while(!m_server->hasPendingConnections() && maxAttemps > 0) { - --maxAttemps; - QTest::qSleep(1000); - } - QCOMPARE(true, m_server->hasPendingConnections()); - - QSslSocket* serverSocket = m_server->nextPendingConnection(); - - QSignalSpy serverEncryptedSpy(serverSocket, SIGNAL(encrypted())); - - QVERIFY2(serverSocket != 0, "Null socket returned by server"); - QVERIFY2(serverSocket->isOpen(), "Server socket already closed"); - - setSocketAttributes(serverSocket, QStringLiteral("Test Server")); - setSocketAttributes(m_clientSocket, QStringLiteral("Test Client")); - - serverSocket->setPeerVerifyName(QStringLiteral("Test Client")); - serverSocket->setPeerVerifyMode(QSslSocket::QueryPeer); - - m_clientSocket->setPeerVerifyName(QStringLiteral("Test Server")); - m_clientSocket->setPeerVerifyMode(QSslSocket::QueryPeer); - - int connected_sockets = 0; - auto connected_lambda = [&](){ - connected_sockets++; - if (connected_sockets >= 2) { - m_loop.quit(); - } - }; - connect(serverSocket, &QSslSocket::encrypted, connected_lambda); - connect(m_clientSocket, &QSslSocket::encrypted, connected_lambda); - serverSocket->startServerEncryption(); - m_clientSocket->startClientEncryption(); - m_loop.exec(); //Block until QEventLoop::quit gets called by the lambda - - if (serverEncryptedSpy.count() < 1) { - for(int x = 0;x < 50; ++x) { - QVERIFY(serverEncryptedSpy.wait(100)); - if (serverEncryptedSpy.count() > 0) { - break; - } - } - } - - QVERIFY2(m_clientSocket->isOpen(), "Client socket already closed"); - QVERIFY2(serverSocket->isOpen(), "Server socket already closed"); - QVERIFY2(m_clientSocket->isEncrypted(), "Client is not encrypted"); - QVERIFY2(serverSocket->isEncrypted(), "Server is not encrypted"); - QVERIFY2(!m_clientSocket->peerCertificate().isNull(), "Server certificate not received"); - QVERIFY2(!serverSocket->peerCertificate().isNull(), "Client certificate not received"); - - QList dataToSend; - dataToSend << "foobar\n" << "barfoo\n" << "foobar?\n" << "\n" << "barfoo!\n" << "panda\n"; - for (const QByteArray& line : qAsConst(dataToSend)) { - m_clientSocket->write(line); - } - m_clientSocket->flush(); - - m_packets.clear(); - - m_reader = new SocketLineReader(serverSocket, this); - connect(m_reader, &SocketLineReader::readyRead, this, &TestSslSocketLineReader::newPacket); - m_loop.exec(); - - /* remove the empty line before compare */ - dataToSend.removeOne("\n"); - - QCOMPARE(m_packets.count(), 5);//We expect 5 Packets - for(int x = 0;x < 5; ++x) { - QCOMPARE(m_packets[x], dataToSend[x]); - } - - delete m_reader; -} - -void TestSslSocketLineReader::testTrustedDeviceWithWrongCertificate() -{ - int maxAttemps = 5; - while(!m_server->hasPendingConnections() && maxAttemps > 0) { - --maxAttemps; - QTest::qSleep(1000); - } - QCOMPARE(true, m_server->hasPendingConnections()); - - QSslSocket* serverSocket = m_server->nextPendingConnection(); - - QVERIFY2(serverSocket != 0, "Could not open a connection to the client"); - - setSocketAttributes(serverSocket, QStringLiteral("Test Server")); - setSocketAttributes(m_clientSocket, QStringLiteral("Test Client")); - - // Not adding other device certificate to list of CA certificate, and using VerifyPeer. This should lead to handshake failure - serverSocket->setPeerVerifyName(QStringLiteral("Test Client")); - serverSocket->setPeerVerifyMode(QSslSocket::VerifyPeer); - - m_clientSocket->setPeerVerifyName(QStringLiteral("Test Server")); - m_clientSocket->setPeerVerifyMode(QSslSocket::VerifyPeer); - - connect(serverSocket, &QSslSocket::encrypted, &m_loop, &QEventLoop::quit); // Encrypted signal should never be emitted - connect(m_clientSocket, &QSslSocket::encrypted, &m_loop, &QEventLoop::quit); // Encrypted signal should never be emitted - connect(serverSocket, &QAbstractSocket::disconnected, &m_loop, &QEventLoop::quit); - connect(m_clientSocket, &QAbstractSocket::disconnected, &m_loop, &QEventLoop::quit); - - serverSocket->startServerEncryption(); - m_clientSocket->startClientEncryption(); - m_loop.exec(); - - QVERIFY2(!serverSocket->isEncrypted(), "Server is encrypted, it should not"); - QVERIFY2(!m_clientSocket->isEncrypted(), "lient is encrypted, it should now"); - - if (serverSocket->state() != QAbstractSocket::UnconnectedState) m_loop.exec(); // Wait until serverSocket is disconnected, It should be in disconnected state - if (m_clientSocket->state() != QAbstractSocket::UnconnectedState) m_loop.exec(); // Wait until mClientSocket is disconnected, It should be in disconnected state - - QCOMPARE((int)m_clientSocket->state(), 0); - QCOMPARE((int)serverSocket->state(), 0); - -} - -void TestSslSocketLineReader::newPacket() -{ - if (!m_reader->bytesAvailable()) { - return; - } - - int maxLoops = 5; - while(m_reader->bytesAvailable() > 0 && maxLoops > 0) { - --maxLoops; - const QByteArray packet = m_reader->readLine(); - if (!packet.isEmpty()) { - m_packets.append(packet); - } - - if (m_packets.count() == 5) { - m_loop.exit(); - } - } -} - -void TestSslSocketLineReader::testTimeout() -{ - m_loop.exit(-1); - QFAIL("Test Timed Out"); -} - -void TestSslSocketLineReader::setSocketAttributes(QSslSocket* socket, QString deviceName) { - - QDateTime startTime = QDateTime::currentDateTime(); - QDateTime endTime = startTime.addYears(10); - QCA::CertificateInfo certificateInfo; - certificateInfo.insert(QCA::CommonName,deviceName); - certificateInfo.insert(QCA::Organization,QStringLiteral("KDE")); - certificateInfo.insert(QCA::OrganizationalUnit,QStringLiteral("Kde connect")); - - QCA::CertificateOptions certificateOptions(QCA::PKCS10); - certificateOptions.setSerialNumber(10); - certificateOptions.setInfo(certificateInfo); - certificateOptions.setValidityPeriod(startTime, endTime); - certificateOptions.setFormat(QCA::PKCS10); - - QCA::PrivateKey privKey = QCA::KeyGenerator().createRSA(2048); - QSslCertificate certificate = QSslCertificate(QCA::Certificate(certificateOptions, privKey).toPEM().toLatin1()); - - socket->setPrivateKey(QSslKey(privKey.toPEM().toLatin1(), QSsl::Rsa)); - socket->setLocalCertificate(certificate); - -} - -QTEST_GUILESS_MAIN(TestSslSocketLineReader) - -#include "testsslsocketlinereader.moc" -