Advance Wayland and KDE package bring-up
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
include(ECMAddTests)
|
||||
|
||||
find_package(Qt6 ${REQUIRED_QT_VERSION} CONFIG REQUIRED Concurrent Test)
|
||||
|
||||
########### fakehardwaretest ###############
|
||||
|
||||
if (BUILD_DEVICE_BACKEND_fakehw)
|
||||
ecm_add_test(fakehardwaretest.cpp LINK_LIBRARIES KF6Solid_static Qt6::Xml Qt6::Test)
|
||||
# QT5 TODO Port solid to QFINDTESTDATA
|
||||
target_compile_definitions(fakehardwaretest PRIVATE SOLID_STATIC_DEFINE=1 TEST_DATA="${CMAKE_CURRENT_SOURCE_DIR}/../src/solid/devices/backends/fakehw/fakecomputer.xml")
|
||||
endif()
|
||||
|
||||
########### solidhwtest ###############
|
||||
|
||||
if (BUILD_DEVICE_BACKEND_fakehw)
|
||||
ecm_add_test(solidhwtest.cpp LINK_LIBRARIES Qt6::Xml Qt6::Test ${LIBS} KF6Solid_static)
|
||||
target_compile_definitions(solidhwtest PRIVATE SOLID_STATIC_DEFINE=1 FAKE_COMPUTER_XML="${CMAKE_CURRENT_SOURCE_DIR}/../src/solid/devices/backends/fakehw/fakecomputer.xml")
|
||||
target_include_directories(solidhwtest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../src/solid/devices/backends/fakehw)
|
||||
endif()
|
||||
|
||||
########### solidmttest ###############
|
||||
|
||||
ecm_add_test(solidmttest.cpp LINK_LIBRARIES Qt6::Xml Qt6::Test ${LIBS} KF6Solid_static Qt6::Concurrent)
|
||||
target_compile_definitions(solidmttest PRIVATE SOLID_STATIC_DEFINE=1)
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
SPDX-FileCopyrightText: 2014 Alejandro Fiestas Olivares <afiestas@kde.org>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||
*/
|
||||
|
||||
#ifndef SOLID_FAKE_UPOWER_H
|
||||
#define SOLID_FAKE_UPOWER_H
|
||||
|
||||
#include <QDBusObjectPath>
|
||||
#include <QList>
|
||||
#include <QString>
|
||||
|
||||
class FakeUpower : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool IsDocked READ isDocked)
|
||||
Q_PROPERTY(bool OnBattery READ onBattery)
|
||||
Q_CLASSINFO("D-Bus Interface", "org.freedesktop.UPower")
|
||||
public:
|
||||
explicit FakeUpower(QObject *parent);
|
||||
|
||||
QString daemonVersion() const;
|
||||
bool isDocked() const;
|
||||
bool lidIsClosed() const;
|
||||
bool lidIsPresent() const;
|
||||
bool onBattery() const;
|
||||
void setOnBattery(bool onBattery);
|
||||
|
||||
bool m_onBattery;
|
||||
|
||||
void emitPropertiesChanged(const QString &name, const QVariant &value);
|
||||
public Q_SLOTS:
|
||||
QList<QDBusObjectPath> EnumerateDevices();
|
||||
QString GetCriticalAction();
|
||||
QDBusObjectPath GetDisplayDevice();
|
||||
};
|
||||
|
||||
#endif // SOLID_FAKE_UPOWER_H
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
SPDX-FileCopyrightText: 2006 Michaël Larouche <michael.larouche@kdemail.net>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||
*/
|
||||
#include "fakehardwaretest.h"
|
||||
|
||||
// Qt includes
|
||||
#include <QTest>
|
||||
|
||||
// Solid includes
|
||||
#include <solid/devices/ifaces/device.h>
|
||||
#include <solid/devices/ifaces/deviceinterface.h>
|
||||
#include <solid/devices/ifaces/processor.h>
|
||||
|
||||
// Local includes
|
||||
#include "solid/devices/backends/fakehw/fakedevice.h"
|
||||
#include "solid/devices/backends/fakehw/fakemanager.h"
|
||||
|
||||
QTEST_MAIN(FakeHardwareTest)
|
||||
|
||||
void FakeHardwareTest::testFakeBackend()
|
||||
{
|
||||
Solid::Backends::Fake::FakeManager *fakeManager = new Solid::Backends::Fake::FakeManager(nullptr, QStringLiteral(TEST_DATA));
|
||||
|
||||
QVERIFY(!fakeManager->allDevices().isEmpty());
|
||||
QObject *computer = fakeManager->createDevice(QStringLiteral("/org/kde/solid/fakehw/computer"));
|
||||
QVERIFY(computer != nullptr);
|
||||
QVERIFY(fakeManager->createDevice(QStringLiteral("/com/helloworld/troll/compiutor")) == nullptr);
|
||||
|
||||
auto *device = static_cast<Solid::Backends::Fake::FakeDevice *>(fakeManager->createDevice(QStringLiteral("/org/kde/solid/fakehw/acpi_CPU0")));
|
||||
|
||||
QCOMPARE(device->udi(), QStringLiteral("/org/kde/solid/fakehw/acpi_CPU0"));
|
||||
QCOMPARE(device->parentUdi(), QStringLiteral("/org/kde/solid/fakehw/computer"));
|
||||
QCOMPARE(device->vendor(), QStringLiteral("Acme Corporation"));
|
||||
QCOMPARE(device->product(), QStringLiteral("Solid Processor #0"));
|
||||
|
||||
QCOMPARE(device->property(QStringLiteral("number")).toString(), QStringLiteral("0"));
|
||||
QVERIFY(device->propertyExists(QStringLiteral("number")));
|
||||
QVERIFY(!device->propertyExists(QStringLiteral("youstfuqewerrernoob")));
|
||||
|
||||
QVERIFY(device->queryDeviceInterface(Solid::DeviceInterface::Processor));
|
||||
|
||||
QObject *interface = device->createDeviceInterface(Solid::DeviceInterface::Processor);
|
||||
Solid::Ifaces::Processor *processor = qobject_cast<Solid::Ifaces::Processor *>(interface);
|
||||
|
||||
QCOMPARE(processor->number(), 0);
|
||||
QCOMPARE(processor->canChangeFrequency(), true);
|
||||
QCOMPARE((int)processor->maxSpeed(), 3200);
|
||||
|
||||
Solid::Processor::InstructionSets instructionsets;
|
||||
instructionsets |= Solid::Processor::IntelMmx;
|
||||
instructionsets |= Solid::Processor::IntelSse;
|
||||
QCOMPARE(processor->instructionSets(), instructionsets);
|
||||
|
||||
delete processor;
|
||||
delete device;
|
||||
delete computer;
|
||||
delete fakeManager;
|
||||
}
|
||||
|
||||
#include "moc_fakehardwaretest.cpp"
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
SPDX-FileCopyrightText: 2006 Michaël Larouche <michael.larouche@kdemail.net>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||
*/
|
||||
#ifndef FAKEHARDWARETEST_H
|
||||
#define FAKEHARDWARETEST_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class FakeHardwareTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private Q_SLOTS:
|
||||
void testFakeBackend();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
SPDX-FileCopyrightText: 2014 Alejandro Fiestas Olivares <afiestas@kde.org>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||
*/
|
||||
|
||||
#ifndef SOLID_QTEST_DBUS_H
|
||||
#define SOLID_QTEST_DBUS_H
|
||||
|
||||
#include <QDebug>
|
||||
#include <QProcess>
|
||||
#include <QTest>
|
||||
#include <stdlib.h>
|
||||
|
||||
// clang-format off
|
||||
#define QTEST_GUILESS_MAIN_SYSTEM_DBUS(TestObject) \
|
||||
int main(int argc, char *argv[]) \
|
||||
{ \
|
||||
QProcess dbus; \
|
||||
dbus.start("dbus-launch", QStringList()); \
|
||||
dbus.waitForFinished(10000); \
|
||||
QByteArray session = dbus.readLine(); \
|
||||
if (session.isEmpty()) { \
|
||||
qFatal("Couldn't execute new dbus session"); \
|
||||
} \
|
||||
int pos = session.indexOf('='); \
|
||||
setenv("DBUS_SYSTEM_BUS_ADDRESS", session.right(session.size() - pos - 1).trimmed(), 1); \
|
||||
qDebug() << session.right(session.size() - pos - 1).trimmed(); \
|
||||
session = dbus.readLine(); \
|
||||
pos = session.indexOf('='); \
|
||||
QByteArray pid = session.right(session.size() - pos - 1).trimmed(); \
|
||||
QCoreApplication app( argc, argv ); \
|
||||
app.setApplicationName( QLatin1String("qttest") ); \
|
||||
TestObject tc; \
|
||||
int result = QTest::qExec( &tc, argc, argv ); \
|
||||
dbus.start("kill", QStringList() << "-9" << pid); \
|
||||
dbus.waitForFinished(); \
|
||||
return result; \
|
||||
}
|
||||
#endif //SOLID_QTEST_DBUS_H
|
||||
@@ -0,0 +1,532 @@
|
||||
/*
|
||||
SPDX-FileCopyrightText: 2005 Kevin Ottens <ervin@kde.org>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||
*/
|
||||
|
||||
#include <QSignalSpy>
|
||||
#include <QTest>
|
||||
|
||||
#include "solid/devices/managerbase_p.h"
|
||||
#include <solid/device.h>
|
||||
#include <solid/devicenotifier.h>
|
||||
#include <solid/genericinterface.h>
|
||||
#include <solid/predicate.h>
|
||||
#include <solid/processor.h>
|
||||
#include <solid/storageaccess.h>
|
||||
#include <solid/storagevolume.h>
|
||||
|
||||
#include <fakedevice.h>
|
||||
#include <fakemanager.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef FAKE_COMPUTER_XML
|
||||
#error "FAKE_COMPUTER_XML not set. An XML file describing a computer is required for this test"
|
||||
#endif
|
||||
|
||||
class SolidHwTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private Q_SLOTS:
|
||||
void initTestCase();
|
||||
void testAllDevices();
|
||||
void testDeviceBasicFeatures();
|
||||
void testManagerSignals();
|
||||
void testDeviceSignals();
|
||||
void testDeviceExistence();
|
||||
void testDeviceInterfaceIntrospection_data();
|
||||
void testDeviceInterfaceIntrospection();
|
||||
void testDeviceInterfaceIntrospectionCornerCases();
|
||||
void testDeviceInterfaces();
|
||||
void testInvalidPredicate();
|
||||
void testPredicate();
|
||||
void testQueryStorageVolumeOrProcessor();
|
||||
void testQueryStorageVolumeOrStorageAccess();
|
||||
void testQueryWithParentUdi();
|
||||
void testListFromTypeProcessor();
|
||||
void testListFromTypeInvalid();
|
||||
void testSetupTeardown();
|
||||
void testStorageAccessFromPath();
|
||||
void testStorageAccessFromPath_data();
|
||||
|
||||
private:
|
||||
Solid::Backends::Fake::FakeManager *fakeManager;
|
||||
};
|
||||
|
||||
QTEST_MAIN(SolidHwTest)
|
||||
|
||||
void SolidHwTest::initTestCase()
|
||||
{
|
||||
qputenv("SOLID_FAKEHW", FAKE_COMPUTER_XML);
|
||||
Solid::ManagerBasePrivate *manager = dynamic_cast<Solid::ManagerBasePrivate *>(Solid::DeviceNotifier::instance());
|
||||
fakeManager = qobject_cast<Solid::Backends::Fake::FakeManager *>(manager->managerBackends().first());
|
||||
}
|
||||
|
||||
void SolidHwTest::testAllDevices()
|
||||
{
|
||||
const QList<Solid::Device> devices = Solid::Device::allDevices();
|
||||
|
||||
// Verify that the framework reported correctly the devices available
|
||||
// in the backend.
|
||||
QStringList expected_udis;
|
||||
QStringList received_udis;
|
||||
|
||||
expected_udis = fakeManager->allDevices();
|
||||
std::sort(expected_udis.begin(), expected_udis.end());
|
||||
|
||||
for (const Solid::Device &dev : devices) {
|
||||
received_udis << dev.udi();
|
||||
}
|
||||
|
||||
std::sort(received_udis.begin(), received_udis.end());
|
||||
|
||||
QCOMPARE(expected_udis, received_udis);
|
||||
}
|
||||
|
||||
void SolidHwTest::testDeviceBasicFeatures()
|
||||
{
|
||||
// Retrieve a valid Device object
|
||||
Solid::Device valid_dev(QStringLiteral("/org/kde/solid/fakehw/storage_model_solid_writer"));
|
||||
|
||||
QCOMPARE(valid_dev.isValid(), true);
|
||||
|
||||
// A few attempts at creating invalid Device objects
|
||||
Solid::Device invalid_dev(QStringLiteral("uhoh? doesn't exist, I guess"));
|
||||
QCOMPARE(invalid_dev.isValid(), false);
|
||||
invalid_dev = Solid::Device(QString());
|
||||
QCOMPARE(invalid_dev.isValid(), false);
|
||||
invalid_dev = Solid::Device();
|
||||
QCOMPARE(invalid_dev.isValid(), false);
|
||||
|
||||
QCOMPARE(valid_dev.udi(), QStringLiteral("/org/kde/solid/fakehw/storage_model_solid_writer"));
|
||||
QCOMPARE(invalid_dev.udi(), QString());
|
||||
|
||||
// Query properties
|
||||
QCOMPARE(valid_dev.as<Solid::GenericInterface>()->propertyExists(QStringLiteral("name")), true);
|
||||
QCOMPARE(valid_dev.as<Solid::GenericInterface>()->propertyExists(QStringLiteral("foo.bar")), false);
|
||||
QCOMPARE((QObject *)invalid_dev.as<Solid::GenericInterface>(), (QObject *)nullptr);
|
||||
|
||||
QCOMPARE(valid_dev.as<Solid::GenericInterface>()->property(QStringLiteral("name")), QStringLiteral("Solid IDE DVD Writer"));
|
||||
QVERIFY(!valid_dev.as<Solid::GenericInterface>()->property(QStringLiteral("foo.bar")).isValid());
|
||||
|
||||
Solid::Backends::Fake::FakeDevice *fake_device = fakeManager->findDevice(QStringLiteral("/org/kde/solid/fakehw/storage_model_solid_writer"));
|
||||
QMap<QString, QVariant> expected_properties = fake_device->allProperties();
|
||||
|
||||
QCOMPARE(valid_dev.as<Solid::GenericInterface>()->allProperties(), expected_properties);
|
||||
|
||||
// Query device interfaces
|
||||
QCOMPARE(valid_dev.isDeviceInterface(Solid::DeviceInterface::StorageDrive), true);
|
||||
QCOMPARE(valid_dev.isDeviceInterface(Solid::DeviceInterface::OpticalDrive), true);
|
||||
QCOMPARE(valid_dev.isDeviceInterface(Solid::DeviceInterface::StorageVolume), false);
|
||||
|
||||
QCOMPARE(invalid_dev.isDeviceInterface(Solid::DeviceInterface::Unknown), false);
|
||||
QCOMPARE(invalid_dev.isDeviceInterface(Solid::DeviceInterface::StorageDrive), false);
|
||||
|
||||
// Query parent
|
||||
QCOMPARE(valid_dev.parentUdi(), QStringLiteral("/org/kde/solid/fakehw/pci_002_ide_1_0"));
|
||||
QCOMPARE(valid_dev.parent().udi(), Solid::Device(QStringLiteral("/org/kde/solid/fakehw/pci_002_ide_1_0")).udi());
|
||||
|
||||
QVERIFY(!invalid_dev.parent().isValid());
|
||||
QVERIFY(invalid_dev.parentUdi().isEmpty());
|
||||
|
||||
// Query vendor/product
|
||||
QCOMPARE(valid_dev.vendor(), QStringLiteral("Acme Corporation"));
|
||||
QCOMPARE(valid_dev.product(), QStringLiteral("Solid IDE DVD Writer"));
|
||||
|
||||
QCOMPARE(invalid_dev.vendor(), QString());
|
||||
QCOMPARE(invalid_dev.product(), QString());
|
||||
}
|
||||
|
||||
void SolidHwTest::testManagerSignals()
|
||||
{
|
||||
fakeManager->unplug(QStringLiteral("/org/kde/solid/fakehw/acpi_CPU0"));
|
||||
|
||||
// Heh, we missed a processor in this system ;-)
|
||||
// We're going to add this device, and check that the signal has been
|
||||
// properly emitted by the manager
|
||||
QSignalSpy added(Solid::DeviceNotifier::instance(), SIGNAL(deviceAdded(QString)));
|
||||
fakeManager->plug(QStringLiteral("/org/kde/solid/fakehw/acpi_CPU0"));
|
||||
QCOMPARE(added.count(), 1);
|
||||
QCOMPARE(added.at(0).at(0).toString(), QStringLiteral("/org/kde/solid/fakehw/acpi_CPU0"));
|
||||
|
||||
// Moreover we check that the device is really available
|
||||
Solid::Device cpu(QStringLiteral("/org/kde/solid/fakehw/acpi_CPU0"));
|
||||
QVERIFY(cpu.isValid());
|
||||
|
||||
// Finally we remove the device and spy the corresponding signal again
|
||||
QSignalSpy removed(Solid::DeviceNotifier::instance(), SIGNAL(deviceRemoved(QString)));
|
||||
fakeManager->unplug(QStringLiteral("/org/kde/solid/fakehw/acpi_CPU0"));
|
||||
QCOMPARE(added.count(), 1);
|
||||
QCOMPARE(added.at(0).at(0).toString(), QStringLiteral("/org/kde/solid/fakehw/acpi_CPU0"));
|
||||
|
||||
// The Device object should become automatically invalid
|
||||
QVERIFY(!cpu.isValid());
|
||||
|
||||
// Restore original state
|
||||
fakeManager->plug(QStringLiteral("/org/kde/solid/fakehw/acpi_CPU0"));
|
||||
}
|
||||
|
||||
void SolidHwTest::testDeviceSignals()
|
||||
{
|
||||
// A button is a nice device for testing state changes, isn't it?
|
||||
Solid::Backends::Fake::FakeDevice *fake = fakeManager->findDevice(QStringLiteral("/org/kde/solid/fakehw/platform_floppy_0_storage_virt_volume"));
|
||||
Solid::Device device(QStringLiteral("/org/kde/solid/fakehw/platform_floppy_0_storage_virt_volume"));
|
||||
|
||||
// We'll spy our floppy
|
||||
QSignalSpy condition_raised(device.as<Solid::GenericInterface>(), SIGNAL(conditionRaised(QString, QString)));
|
||||
QSignalSpy property_changed(device.as<Solid::GenericInterface>(), SIGNAL(propertyChanged(QMap<QString, int>)));
|
||||
|
||||
fake->setProperty(QStringLiteral("mountPoint"), QStringLiteral("/tmp.foo")); // The button is now pressed (modified property)
|
||||
fake->raiseCondition(QStringLiteral("Floppy Closed"), QStringLiteral("Why not?")); // Since it's a LID we notify this change
|
||||
fake->setProperty(QStringLiteral("hactar"), 42); // We add a property
|
||||
fake->removeProperty(QStringLiteral("hactar")); // We remove a property
|
||||
|
||||
// 3 property changes occurred in the device
|
||||
QCOMPARE(property_changed.count(), 3);
|
||||
|
||||
QMap<QString, int> changes;
|
||||
|
||||
// First one is a "PropertyModified" for "button.state"
|
||||
changes = property_changed.at(0).at(0).value<QMap<QString, int>>();
|
||||
QCOMPARE(changes.count(), 1);
|
||||
QVERIFY(changes.contains(QStringLiteral("mountPoint")));
|
||||
QCOMPARE(changes[QStringLiteral("mountPoint")], (int)Solid::GenericInterface::PropertyModified);
|
||||
|
||||
// Second one is a "PropertyAdded" for "hactar"
|
||||
changes = property_changed.at(1).at(0).value<QMap<QString, int>>();
|
||||
QCOMPARE(changes.count(), 1);
|
||||
QVERIFY(changes.contains(QStringLiteral("hactar")));
|
||||
QCOMPARE(changes[QStringLiteral("hactar")], (int)Solid::GenericInterface::PropertyAdded);
|
||||
|
||||
// Third one is a "PropertyRemoved" for "hactar"
|
||||
changes = property_changed.at(2).at(0).value<QMap<QString, int>>();
|
||||
QCOMPARE(changes.count(), 1);
|
||||
QVERIFY(changes.contains(QStringLiteral("hactar")));
|
||||
QCOMPARE(changes[QStringLiteral("hactar")], (int)Solid::GenericInterface::PropertyRemoved);
|
||||
|
||||
// Only one condition has been raised in the device
|
||||
QCOMPARE(condition_raised.count(), 1);
|
||||
|
||||
// It must be identical to the condition we raised by hand
|
||||
QCOMPARE(condition_raised.at(0).at(0).toString(), QStringLiteral("Floppy Closed"));
|
||||
QCOMPARE(condition_raised.at(0).at(1).toString(), QStringLiteral("Why not?"));
|
||||
}
|
||||
|
||||
void SolidHwTest::testDeviceExistence()
|
||||
{
|
||||
QCOMPARE(Solid::Device(QStringLiteral("/org/kde/solid/fakehw/platform_floppy_0_storage_virt_volume")).isValid(), true);
|
||||
QCOMPARE(Solid::Device(QStringLiteral("/org/kde/solid/fakehw/volume_label_SOLIDMAN_BEGINS")).isValid(), true);
|
||||
|
||||
// Note the extra space
|
||||
QCOMPARE(Solid::Device(QStringLiteral("/org/kde/solid/fakehw/computer ")).isValid(), false);
|
||||
QCOMPARE(Solid::Device(QStringLiteral("#'({(]")).isValid(), false);
|
||||
QCOMPARE(Solid::Device(QString()).isValid(), false);
|
||||
|
||||
// Now try to see if isValid() changes on plug/unplug events
|
||||
Solid::Device cpu(QStringLiteral("/org/kde/solid/fakehw/acpi_CPU0"));
|
||||
QVERIFY(cpu.isValid());
|
||||
fakeManager->unplug(QStringLiteral("/org/kde/solid/fakehw/acpi_CPU0"));
|
||||
QVERIFY(!cpu.isValid());
|
||||
fakeManager->plug(QStringLiteral("/org/kde/solid/fakehw/acpi_CPU0"));
|
||||
QVERIFY(cpu.isValid());
|
||||
}
|
||||
|
||||
void SolidHwTest::testDeviceInterfaces()
|
||||
{
|
||||
Solid::Device cpu(QStringLiteral("/org/kde/solid/fakehw/acpi_CPU0"));
|
||||
|
||||
Solid::DeviceInterface *iface = cpu.asDeviceInterface(Solid::DeviceInterface::Processor);
|
||||
Solid::DeviceInterface *processor = cpu.as<Solid::Processor>();
|
||||
|
||||
QVERIFY(cpu.isDeviceInterface(Solid::DeviceInterface::Processor));
|
||||
QVERIFY(iface != nullptr);
|
||||
QCOMPARE(iface, processor);
|
||||
|
||||
Solid::Device cpu2(QStringLiteral("/org/kde/solid/fakehw/acpi_CPU0"));
|
||||
QCOMPARE(cpu.as<Solid::Processor>(), cpu2.as<Solid::Processor>());
|
||||
QCOMPARE(cpu.as<Solid::GenericInterface>(), cpu2.as<Solid::GenericInterface>());
|
||||
|
||||
QPointer<Solid::Processor> p = cpu.as<Solid::Processor>();
|
||||
QVERIFY(p != nullptr);
|
||||
fakeManager->unplug(QStringLiteral("/org/kde/solid/fakehw/acpi_CPU0"));
|
||||
QVERIFY(p == nullptr);
|
||||
fakeManager->plug(QStringLiteral("/org/kde/solid/fakehw/acpi_CPU0"));
|
||||
|
||||
QPointer<Solid::StorageVolume> v;
|
||||
QPointer<Solid::StorageVolume> v2;
|
||||
{
|
||||
Solid::Device partition(QStringLiteral("/org/kde/solid/fakehw/volume_uuid_f00ba7"));
|
||||
v = partition.as<Solid::StorageVolume>();
|
||||
QVERIFY(v != nullptr);
|
||||
{
|
||||
Solid::Device partition2(QStringLiteral("/org/kde/solid/fakehw/volume_uuid_f00ba7"));
|
||||
v2 = partition2.as<Solid::StorageVolume>();
|
||||
QVERIFY(v2 != nullptr);
|
||||
QVERIFY(v == v2);
|
||||
}
|
||||
QVERIFY(v != nullptr);
|
||||
QVERIFY(v2 != nullptr);
|
||||
}
|
||||
QVERIFY(v != nullptr);
|
||||
QVERIFY(v2 != nullptr);
|
||||
fakeManager->unplug(QStringLiteral("/org/kde/solid/fakehw/volume_uuid_f00ba7"));
|
||||
QVERIFY(v == nullptr);
|
||||
QVERIFY(v2 == nullptr);
|
||||
fakeManager->plug(QStringLiteral("/org/kde/solid/fakehw/volume_uuid_f00ba7"));
|
||||
}
|
||||
|
||||
void SolidHwTest::testDeviceInterfaceIntrospection_data()
|
||||
{
|
||||
QTest::addColumn<QString>("name");
|
||||
QTest::addColumn<int>("value");
|
||||
|
||||
QTest::newRow("DeviceInterface: Unknown") << "Unknown" << (int)Solid::DeviceInterface::Unknown;
|
||||
QTest::newRow("DeviceInterface: Processor") << "Processor" << (int)Solid::DeviceInterface::Processor;
|
||||
QTest::newRow("DeviceInterface: Block") << "Block" << (int)Solid::DeviceInterface::Block;
|
||||
QTest::newRow("DeviceInterface: StorageDrive") << "StorageDrive" << (int)Solid::DeviceInterface::StorageDrive;
|
||||
QTest::newRow("DeviceInterface: OpticalDrive") << "OpticalDrive" << (int)Solid::DeviceInterface::OpticalDrive;
|
||||
QTest::newRow("DeviceInterface: StorageVolume") << "StorageVolume" << (int)Solid::DeviceInterface::StorageVolume;
|
||||
QTest::newRow("DeviceInterface: OpticalDisc") << "OpticalDisc" << (int)Solid::DeviceInterface::OpticalDisc;
|
||||
QTest::newRow("DeviceInterface: Camera") << "Camera" << (int)Solid::DeviceInterface::Camera;
|
||||
QTest::newRow("DeviceInterface: PortableMediaPlayer") << "PortableMediaPlayer" << (int)Solid::DeviceInterface::PortableMediaPlayer;
|
||||
QTest::newRow("DeviceInterface: Battery") << "Battery" << (int)Solid::DeviceInterface::Battery;
|
||||
}
|
||||
|
||||
void SolidHwTest::testDeviceInterfaceIntrospection()
|
||||
{
|
||||
QFETCH(QString, name);
|
||||
QFETCH(int, value);
|
||||
|
||||
QCOMPARE(Solid::DeviceInterface::typeToString((Solid::DeviceInterface::Type)value), name);
|
||||
QCOMPARE((int)Solid::DeviceInterface::stringToType(name), value);
|
||||
}
|
||||
|
||||
void SolidHwTest::testDeviceInterfaceIntrospectionCornerCases()
|
||||
{
|
||||
QCOMPARE(Solid::DeviceInterface::typeToString((Solid::DeviceInterface::Type)-1), QString());
|
||||
QCOMPARE((int)Solid::DeviceInterface::stringToType(QStringLiteral("blup")), -1);
|
||||
}
|
||||
|
||||
static QStringList to_string_list(const QList<Solid::Device> &list)
|
||||
{
|
||||
QStringList res;
|
||||
res.reserve(list.size());
|
||||
for (const Solid::Device &device : list) {
|
||||
res << device.udi();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void SolidHwTest::testInvalidPredicate()
|
||||
{
|
||||
QString str_pred = QStringLiteral("[[Processor.maxSpeed == 3201 AND Processor.canChangeFrequency == false] OR StorageVolume.mountPoint == '/media/blup']");
|
||||
// Since str_pred is canonicalized, fromString().toString() should be invariant
|
||||
QCOMPARE(Solid::Predicate::fromString(str_pred).toString(), str_pred);
|
||||
|
||||
// Invalid predicate
|
||||
str_pred = QStringLiteral("[StorageVolume.ignored == false AND OpticalDisc.isBlank == true AND OpticalDisc.discType & 'CdRecordable|CdRewritable']");
|
||||
QVERIFY(!Solid::Predicate::fromString(str_pred).isValid());
|
||||
}
|
||||
|
||||
void SolidHwTest::testPredicate()
|
||||
{
|
||||
Solid::Device dev(QStringLiteral("/org/kde/solid/fakehw/acpi_CPU0"));
|
||||
/* clang-format off */
|
||||
Solid::Predicate p1 = (Solid::Predicate(Solid::DeviceInterface::Processor, QStringLiteral("maxSpeed"), 3200)
|
||||
& Solid::Predicate(Solid::DeviceInterface::Processor, QStringLiteral("canChangeFrequency"), true));
|
||||
Solid::Predicate p2 = Solid::Predicate(Solid::DeviceInterface::Processor, QStringLiteral("maxSpeed"), 3200)
|
||||
& Solid::Predicate(Solid::DeviceInterface::Processor, QStringLiteral("canChangeFrequency"), false);
|
||||
Solid::Predicate p3 = Solid::Predicate(Solid::DeviceInterface::Processor, QStringLiteral("maxSpeed"), 3201)
|
||||
| Solid::Predicate(Solid::DeviceInterface::Processor, QStringLiteral("canChangeFrequency"), true);
|
||||
Solid::Predicate p4 = Solid::Predicate(Solid::DeviceInterface::Processor, QStringLiteral("maxSpeed"), 3201)
|
||||
| Solid::Predicate(Solid::DeviceInterface::Processor, QStringLiteral("canChangeFrequency"), false);
|
||||
Solid::Predicate p5 =
|
||||
Solid::Predicate::fromString(QStringLiteral("[[Processor.maxSpeed == 3201 AND Processor.canChangeFrequency == false] OR StorageVolume.mountPoint == '/media/blup']"));
|
||||
/* clang-format on */
|
||||
|
||||
QVERIFY(p1.matches(dev));
|
||||
QVERIFY(!p2.matches(dev));
|
||||
QVERIFY(p3.matches(dev));
|
||||
QVERIFY(!p4.matches(dev));
|
||||
|
||||
Solid::Predicate p6 = Solid::Predicate::fromString(QStringLiteral("StorageVolume.usage == 'Other'"));
|
||||
Solid::Predicate p7 = Solid::Predicate::fromString(QStringLiteral("StorageVolume.usage == %1").arg((int)Solid::StorageVolume::Other));
|
||||
QVERIFY(!p6.matches(dev));
|
||||
QVERIFY(!p7.matches(dev));
|
||||
dev = Solid::Device(QStringLiteral("/org/kde/solid/fakehw/volume_part2_size_1024"));
|
||||
QVERIFY(p6.matches(dev));
|
||||
QVERIFY(p7.matches(dev));
|
||||
|
||||
QList<Solid::Device> list;
|
||||
|
||||
QStringList cpuSet;
|
||||
cpuSet << QStringLiteral("/org/kde/solid/fakehw/acpi_CPU0") << QStringLiteral("/org/kde/solid/fakehw/acpi_CPU1");
|
||||
|
||||
list = Solid::Device::listFromQuery(p1);
|
||||
QCOMPARE(list.size(), 2);
|
||||
QCOMPARE(to_string_list(list), cpuSet);
|
||||
|
||||
list = Solid::Device::listFromQuery(p2);
|
||||
QCOMPARE(list.size(), 0);
|
||||
|
||||
list = Solid::Device::listFromQuery(p3);
|
||||
QCOMPARE(list.size(), 2);
|
||||
QCOMPARE(to_string_list(list), cpuSet);
|
||||
|
||||
list = Solid::Device::listFromQuery(p4);
|
||||
QCOMPARE(list.size(), 0);
|
||||
|
||||
list = Solid::Device::listFromQuery(QStringLiteral("[Processor.canChangeFrequency==true AND Processor.number==1]"));
|
||||
QCOMPARE(list.size(), 1);
|
||||
QCOMPARE(list.at(0).udi(), QStringLiteral("/org/kde/solid/fakehw/acpi_CPU1"));
|
||||
|
||||
// writeSpeeds is a QList, make sure we can match a single element.
|
||||
list = Solid::Device::listFromQuery(QStringLiteral("[OpticalDrive.writeSpeeds==2117 AND OpticalDrive.removable==true]"));
|
||||
QCOMPARE(list.size(), 1);
|
||||
QCOMPARE(list.at(0).udi(), QStringLiteral("/org/kde/solid/fakehw/storage_model_solid_writer"));
|
||||
}
|
||||
|
||||
void SolidHwTest::testQueryStorageVolumeOrProcessor()
|
||||
{
|
||||
auto list = Solid::Device::listFromQuery(QStringLiteral("[Processor.number==1 OR IS StorageVolume]"));
|
||||
QCOMPARE(list.size(), 13);
|
||||
|
||||
// make sure predicate case-insensitiveness is sane
|
||||
list = Solid::Device::listFromQuery(QStringLiteral("[Processor.number==1 or is StorageVolume]"));
|
||||
QCOMPARE(list.size(), 13);
|
||||
list = Solid::Device::listFromQuery(QStringLiteral("[Processor.number==1 oR Is StorageVolume]"));
|
||||
QCOMPARE(list.size(), 13);
|
||||
QStringList expected{QStringLiteral("/org/kde/solid/fakehw/acpi_CPU1"),
|
||||
QStringLiteral("/org/kde/solid/fakehw/platform_floppy_0_storage_virt_volume"),
|
||||
QStringLiteral("/org/kde/solid/fakehw/volume_0000_unmounted_storage"),
|
||||
QStringLiteral("/org/kde/solid/fakehw/volume_label_SOLIDMAN_BEGINS"),
|
||||
QStringLiteral("/org/kde/solid/fakehw/volume_part1_size_993284096"),
|
||||
QStringLiteral("/org/kde/solid/fakehw/volume_part2_size_1024"),
|
||||
QStringLiteral("/org/kde/solid/fakehw/volume_part5_size_1048576"),
|
||||
QStringLiteral("/org/kde/solid/fakehw/volume_uuid_5011"),
|
||||
QStringLiteral("/org/kde/solid/fakehw/volume_uuid_c0ffee"),
|
||||
QStringLiteral("/org/kde/solid/fakehw/volume_uuid_cleartext_data_0123"),
|
||||
QStringLiteral("/org/kde/solid/fakehw/volume_uuid_encrypted_0123"),
|
||||
QStringLiteral("/org/kde/solid/fakehw/volume_uuid_f00ba7"),
|
||||
QStringLiteral("/org/kde/solid/fakehw/volume_uuid_feedface")};
|
||||
QCOMPARE(to_string_list(list), expected);
|
||||
|
||||
list = Solid::Device::listFromQuery(QStringLiteral("[IS Processor OR IS StorageVolume]"));
|
||||
QCOMPARE(list.size(), 14);
|
||||
expected.prepend(QStringLiteral("/org/kde/solid/fakehw/acpi_CPU0"));
|
||||
QCOMPARE(to_string_list(list), expected);
|
||||
}
|
||||
|
||||
void SolidHwTest::testQueryStorageVolumeOrStorageAccess()
|
||||
{
|
||||
// the query from KFilePlacesModel
|
||||
const auto list = Solid::Device::listFromQuery(QStringLiteral( //
|
||||
"[[[[ StorageVolume.ignored == false AND [ StorageVolume.usage == 'FileSystem' OR StorageVolume.usage == 'Encrypted' ]]"
|
||||
" OR "
|
||||
"[ IS StorageAccess AND StorageDrive.driveType == 'Floppy' ]]"
|
||||
" OR "
|
||||
"OpticalDisc.availableContent & 'Audio' ]"
|
||||
" OR "
|
||||
"StorageAccess.ignored == false ]"));
|
||||
const QStringList expected{QStringLiteral("/org/kde/solid/fakehw/fstab/thehost/solidpath"),
|
||||
QStringLiteral("/org/kde/solid/fakehw/platform_floppy_0_storage_virt_volume"),
|
||||
QStringLiteral("/org/kde/solid/fakehw/volume_part1_size_993284096"),
|
||||
QStringLiteral("/org/kde/solid/fakehw/volume_uuid_5011"),
|
||||
QStringLiteral("/org/kde/solid/fakehw/volume_uuid_f00ba7")};
|
||||
QCOMPARE(to_string_list(list), expected);
|
||||
}
|
||||
|
||||
void SolidHwTest::testQueryWithParentUdi()
|
||||
{
|
||||
QString parentUdi = QStringLiteral("/org/kde/solid/fakehw/storage_model_solid_reader");
|
||||
Solid::DeviceInterface::Type ifaceType = Solid::DeviceInterface::Unknown;
|
||||
QCOMPARE(fakeManager->devicesFromQuery(parentUdi, ifaceType).size(), 1);
|
||||
QCOMPARE(fakeManager->devicesFromQuery(parentUdi, ifaceType).at(0), QStringLiteral("/org/kde/solid/fakehw/volume_label_SOLIDMAN_BEGINS"));
|
||||
|
||||
ifaceType = Solid::DeviceInterface::Processor;
|
||||
QCOMPARE(fakeManager->devicesFromQuery(parentUdi, ifaceType).size(), 0);
|
||||
|
||||
parentUdi = QStringLiteral("/org/kde/solid/fakehw/computer");
|
||||
QCOMPARE(fakeManager->devicesFromQuery(parentUdi, ifaceType).size(), 2);
|
||||
QCOMPARE(fakeManager->devicesFromQuery(parentUdi, ifaceType).at(0), QStringLiteral("/org/kde/solid/fakehw/acpi_CPU0"));
|
||||
QCOMPARE(fakeManager->devicesFromQuery(parentUdi, ifaceType).at(1), QStringLiteral("/org/kde/solid/fakehw/acpi_CPU1"));
|
||||
}
|
||||
|
||||
void SolidHwTest::testListFromTypeProcessor()
|
||||
{
|
||||
const auto ifaceType = Solid::DeviceInterface::Processor;
|
||||
const auto list = Solid::Device::listFromType(ifaceType, QString());
|
||||
QCOMPARE(list.size(), 2);
|
||||
QCOMPARE(list.at(0).udi(), QStringLiteral("/org/kde/solid/fakehw/acpi_CPU0"));
|
||||
QCOMPARE(list.at(1).udi(), QStringLiteral("/org/kde/solid/fakehw/acpi_CPU1"));
|
||||
}
|
||||
|
||||
void SolidHwTest::testListFromTypeInvalid()
|
||||
{
|
||||
const auto list = Solid::Device::listFromQuery(QStringLiteral("blup"), QString());
|
||||
QCOMPARE(list.size(), 0);
|
||||
}
|
||||
|
||||
void SolidHwTest::testSetupTeardown()
|
||||
{
|
||||
Solid::StorageAccess *access;
|
||||
{
|
||||
Solid::Device device(QStringLiteral("/org/kde/solid/fakehw/volume_part1_size_993284096"));
|
||||
access = device.as<Solid::StorageAccess>();
|
||||
}
|
||||
|
||||
QList<QVariant> args;
|
||||
QSignalSpy spy(access, SIGNAL(accessibilityChanged(bool, QString)));
|
||||
|
||||
access->teardown();
|
||||
|
||||
QCOMPARE(spy.count(), 1);
|
||||
args = spy.takeFirst();
|
||||
QCOMPARE(args.at(0).toBool(), false);
|
||||
|
||||
access->setup();
|
||||
|
||||
QCOMPARE(spy.count(), 1);
|
||||
args = spy.takeFirst();
|
||||
QCOMPARE(args.at(0).toBool(), true);
|
||||
}
|
||||
|
||||
void SolidHwTest::testStorageAccessFromPath()
|
||||
{
|
||||
QFETCH(QString, path);
|
||||
QFETCH(QString, deviceUdi);
|
||||
|
||||
const auto prefix = QStringLiteral("/org/kde/solid/fakehw/");
|
||||
|
||||
const Solid::Device device = Solid::Device::storageAccessFromPath(path);
|
||||
#if defined(Q_OS_WIN)
|
||||
// storageAccessFromPath has never been working correctly on Windows
|
||||
// Fixing this is left for someone with access to a Windows machine
|
||||
return;
|
||||
#endif
|
||||
|
||||
QVERIFY(device.isValid());
|
||||
QCOMPARE(device.udi(), prefix + deviceUdi);
|
||||
|
||||
auto storage = device.as<Solid::StorageAccess>();
|
||||
QVERIFY(storage);
|
||||
QVERIFY(!storage->filePath().isEmpty());
|
||||
QVERIFY(path.startsWith(storage->filePath()));
|
||||
}
|
||||
|
||||
void SolidHwTest::testStorageAccessFromPath_data()
|
||||
{
|
||||
QTest::addColumn<QString>("path");
|
||||
QTest::addColumn<QString>("deviceUdi");
|
||||
|
||||
QTest::addRow("Root") << QStringLiteral("/") << QStringLiteral("volume_uuid_feedface");
|
||||
QTest::addRow("Mount directory") << QStringLiteral("/media") << QStringLiteral("volume_uuid_feedface");
|
||||
QTest::addRow("NFS mount") << QStringLiteral("/media/nfs") << QStringLiteral("fstab/thehost/solidpath");
|
||||
QTest::addRow("Home directory") << QStringLiteral("/home") << QStringLiteral("volume_uuid_c0ffee");
|
||||
QTest::addRow("Other home") << QStringLiteral("/home_other") << QStringLiteral("volume_uuid_feedface");
|
||||
QTest::addRow("User home") << QStringLiteral("/home/user") << QStringLiteral("volume_uuid_c0ffee");
|
||||
QTest::addRow("LUKS") << QStringLiteral("/data") << QStringLiteral("volume_uuid_cleartext_data_0123");
|
||||
}
|
||||
|
||||
#include "solidhwtest.moc"
|
||||
@@ -0,0 +1,268 @@
|
||||
/*
|
||||
SPDX-FileCopyrightText: 2008 Kevin Ottens <ervin@kde.org>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||
*/
|
||||
|
||||
#include <QObject>
|
||||
#include <QThread>
|
||||
#include <QThreadPool>
|
||||
#include <qtconcurrentrun.h>
|
||||
|
||||
#include <QTest>
|
||||
|
||||
#include <solid/device.h>
|
||||
#include <solid/genericinterface.h>
|
||||
#include <solid/predicate.h>
|
||||
#include <solid/storagedrive.h>
|
||||
#include <solid/storagevolume.h>
|
||||
|
||||
class SolidMtTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private Q_SLOTS:
|
||||
void testWorkerThread();
|
||||
void testThreadedPredicate();
|
||||
void testTextPredicates_data();
|
||||
void testTextPredicates();
|
||||
void testTextPredicatesExtended();
|
||||
void testDeviceMatching();
|
||||
};
|
||||
|
||||
class WorkerThread : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
protected:
|
||||
void run() override
|
||||
{
|
||||
Solid::Device dev(QStringLiteral("/org/freedesktop/Hal/devices/computer"));
|
||||
|
||||
const QList<Solid::Device> driveList = Solid::Device::listFromType(Solid::DeviceInterface::StorageDrive);
|
||||
for (const Solid::Device &solidDevice : driveList) {
|
||||
const Solid::StorageDrive *solidDrive = solidDevice.as<Solid::StorageDrive>();
|
||||
Q_ASSERT(solidDrive);
|
||||
Q_UNUSED(solidDrive);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static void doPredicates()
|
||||
{
|
||||
Solid::Predicate p5 = Solid::Predicate::fromString(
|
||||
QStringLiteral("[[Processor.maxSpeed == 3201 AND Processor.canChangeFrequency == false] OR StorageVolume.mountPoint == '/media/blup']"));
|
||||
|
||||
Solid::Predicate p6 = Solid::Predicate::fromString(QStringLiteral("StorageVolume.usage == 'Other'"));
|
||||
Solid::Predicate p7 = Solid::Predicate::fromString(QStringLiteral("StorageVolume.usage == %1").arg((int)Solid::StorageVolume::Other));
|
||||
Solid::Predicate p8 = Solid::Predicate::fromString(QStringLiteral("StorageVolume.ignored == false"));
|
||||
}
|
||||
|
||||
QTEST_MAIN(SolidMtTest)
|
||||
|
||||
void SolidMtTest::testWorkerThread()
|
||||
{
|
||||
Solid::Device dev(QStringLiteral("/org/freedesktop/Hal/devices/acpi_ADP1"));
|
||||
|
||||
WorkerThread *wt = new WorkerThread;
|
||||
wt->start();
|
||||
wt->wait();
|
||||
|
||||
const QList<Solid::Device> driveList = Solid::Device::listFromType(Solid::DeviceInterface::StorageDrive);
|
||||
for (const Solid::Device &solidDevice : driveList) {
|
||||
const Solid::GenericInterface *solidDrive = solidDevice.as<Solid::GenericInterface>();
|
||||
Q_ASSERT(solidDrive);
|
||||
Q_UNUSED(solidDrive);
|
||||
}
|
||||
|
||||
delete wt;
|
||||
}
|
||||
|
||||
void SolidMtTest::testThreadedPredicate()
|
||||
{
|
||||
QThreadPool::globalInstance()->setMaxThreadCount(10);
|
||||
const QList<QFuture<void>> futures = {
|
||||
QtConcurrent::run(&doPredicates),
|
||||
QtConcurrent::run(&doPredicates),
|
||||
QtConcurrent::run(&doPredicates),
|
||||
QtConcurrent::run(&doPredicates),
|
||||
QtConcurrent::run(&doPredicates),
|
||||
QtConcurrent::run(&doPredicates),
|
||||
QtConcurrent::run(&doPredicates),
|
||||
QtConcurrent::run(&doPredicates),
|
||||
};
|
||||
for (QFuture<void> f : futures) {
|
||||
f.waitForFinished();
|
||||
}
|
||||
QThreadPool::globalInstance()->setMaxThreadCount(1); // delete those threads
|
||||
}
|
||||
|
||||
|
||||
void SolidMtTest::testTextPredicates_data()
|
||||
{
|
||||
QTest::addColumn<QString>("pstring");
|
||||
QTest::addColumn<bool>("isValidPredicate");
|
||||
|
||||
QTest::newRow("empty") << QString() << false;
|
||||
QTest::newRow("simple") << QStringLiteral("@") << true;
|
||||
QTest::newRow("and") << QStringLiteral("@ AND @") << false;
|
||||
QTest::newRow("[and]") << QStringLiteral("[@ AND @]") << true;
|
||||
QTest::newRow("[3and]") << QStringLiteral("[@ AND @ AND @]") << false;
|
||||
QTest::newRow("[[and]and]") << QStringLiteral("[[@ AND @] AND @]") << true;
|
||||
QTest::newRow("[and[and]]") << QStringLiteral("[@ AND [@ AND @]]") << true;
|
||||
QTest::newRow("[[and][and] (unbalance)") << QStringLiteral("[ [@ AND @] AND [@ AND @]") << false;
|
||||
QTest::newRow("[[and][and]]") << QStringLiteral("[ [@ AND @] AND [@ AND @] ]") << true;
|
||||
QTest::newRow("[[[and]and]and]") << QStringLiteral("[ [ [ @ AND @] AND @ ] AND @]") << true;
|
||||
}
|
||||
|
||||
/** @brief Check validity (and hence, parser-code) for a bunch of text predicates
|
||||
*
|
||||
*/
|
||||
void SolidMtTest::testTextPredicates()
|
||||
{
|
||||
QFETCH(QString, pstring);
|
||||
QFETCH(bool, isValidPredicate);
|
||||
|
||||
// The expressions contain @ as a placeholder, so they are
|
||||
// short enough to easily see the structure of the expression
|
||||
// in _data(); replace all those @s with an actual atom.
|
||||
const QString atom(QStringLiteral("StorageVolume.ignored == false"));
|
||||
while (pstring.contains(QLatin1Char('@'))) {
|
||||
pstring = pstring.replace(QLatin1Char('@'), atom);
|
||||
}
|
||||
|
||||
Solid::Predicate p = Solid::Predicate::fromString(pstring);
|
||||
QCOMPARE(p.isValid(), isValidPredicate);
|
||||
}
|
||||
|
||||
void SolidMtTest::testTextPredicatesExtended()
|
||||
{
|
||||
Solid::Predicate p = Solid::Predicate::fromString(QStringLiteral(
|
||||
"[[StorageVolume.ignored == false AND StorageVolume.usage == 'FileSystem'] AND [StorageVolume.ignored == false AND StorageDrive.removable == true]]"));
|
||||
QVERIFY(p.isValid());
|
||||
QCOMPARE(p.type(), Solid::Predicate::Conjunction);
|
||||
QCOMPARE(p.firstOperand().type(), Solid::Predicate::Conjunction);
|
||||
QCOMPARE(p.firstOperand().firstOperand().type(), Solid::Predicate::PropertyCheck);
|
||||
QCOMPARE(p.secondOperand().secondOperand().type(), Solid::Predicate::PropertyCheck);
|
||||
|
||||
QCOMPARE(p.firstOperand().firstOperand().propertyName(), QStringLiteral("ignored"));
|
||||
QCOMPARE(p.firstOperand().firstOperand().interfaceType(), Solid::DeviceInterface::StorageVolume);
|
||||
// Let's not call firstOperand() quite so much, and copy into a local atom
|
||||
{
|
||||
auto atom = p.firstOperand().firstOperand();
|
||||
QVERIFY(atom.isValid());
|
||||
QCOMPARE(atom.propertyName(), QStringLiteral("ignored"));
|
||||
QCOMPARE(atom.matchingValue().userType(), QMetaType::Bool);
|
||||
QCOMPARE(atom.matchingValue().toBool(), false);
|
||||
}
|
||||
{
|
||||
auto atom = p.firstOperand().secondOperand();
|
||||
QVERIFY(atom.isValid());
|
||||
QCOMPARE(atom.interfaceType(), Solid::DeviceInterface::StorageVolume);
|
||||
QCOMPARE(atom.propertyName(), QStringLiteral("usage"));
|
||||
QCOMPARE(atom.matchingValue().userType(), QMetaType::QString);
|
||||
QCOMPARE(atom.matchingValue().toString(), QStringLiteral("FileSystem"));
|
||||
}
|
||||
{
|
||||
auto atom = p.secondOperand().firstOperand();
|
||||
QVERIFY(atom.isValid());
|
||||
QCOMPARE(atom.interfaceType(), Solid::DeviceInterface::StorageVolume);
|
||||
QCOMPARE(atom.propertyName(), QStringLiteral("ignored"));
|
||||
QCOMPARE(atom.matchingValue().userType(), QMetaType::Bool);
|
||||
QCOMPARE(atom.matchingValue().toBool(), false);
|
||||
}
|
||||
{
|
||||
auto atom = p.secondOperand().secondOperand();
|
||||
QVERIFY(atom.isValid());
|
||||
QCOMPARE(atom.interfaceType(), Solid::DeviceInterface::StorageDrive);
|
||||
QCOMPARE(atom.propertyName(), QStringLiteral("removable"));
|
||||
QCOMPARE(atom.matchingValue().userType(), QMetaType::Bool);
|
||||
QCOMPARE(atom.matchingValue().toBool(), true);
|
||||
}
|
||||
}
|
||||
|
||||
void SolidMtTest::testDeviceMatching()
|
||||
{
|
||||
auto deviceList = Solid::Device::allDevices();
|
||||
QVERIFY(!deviceList.isEmpty());
|
||||
|
||||
Solid::Predicate volumesPredicate = Solid::Predicate::fromString(QStringLiteral("StorageVolume.ignored == false"));
|
||||
QVERIFY(volumesPredicate.isValid());
|
||||
|
||||
int volumes = 0;
|
||||
for (const auto &device : std::as_const(deviceList)) {
|
||||
if(volumesPredicate.matches(device))
|
||||
{
|
||||
volumes++;
|
||||
}
|
||||
}
|
||||
// If there are no removable volumes, that's fine; below we will be matching empty lists.
|
||||
// QVERIFY(volumes > 0);
|
||||
|
||||
// From the pre-parsed query
|
||||
{
|
||||
auto matchedDeviceList = Solid::Device::listFromQuery(volumesPredicate);
|
||||
QCOMPARE(matchedDeviceList.size(), volumes);
|
||||
}
|
||||
// Same from text again
|
||||
{
|
||||
auto matchedDeviceList = Solid::Device::listFromQuery(QStringLiteral("StorageVolume.ignored == false"));
|
||||
QCOMPARE(matchedDeviceList.size(), volumes);
|
||||
}
|
||||
|
||||
// Are there removables? Hope so.
|
||||
//
|
||||
// The removableFSVolumesPredicate is checking two incompatible things:
|
||||
// a given Solid::Device isn't a Volume and a Drive at the same time,
|
||||
// so it cannot match.
|
||||
{
|
||||
Solid::Predicate fsVolumesPredicate =
|
||||
Solid::Predicate::fromString(QStringLiteral("[StorageVolume.ignored == false AND StorageVolume.usage == 'FileSystem']"));
|
||||
Solid::Predicate removablePredicate = Solid::Predicate::fromString(QStringLiteral("StorageDrive.removable == true"));
|
||||
Solid::Predicate removableFSVolumesPredicate = Solid::Predicate::fromString(
|
||||
QStringLiteral("[[StorageVolume.ignored == false AND StorageVolume.usage == 'FileSystem'] AND StorageDrive.removable == true]"));
|
||||
volumes = 0;
|
||||
for (const auto &device : std::as_const(deviceList)) {
|
||||
qDebug() << device.displayName() << "fs?" << fsVolumesPredicate.matches(device) << "removable?" << removablePredicate.matches(device) << "removableFS?" << removableFSVolumesPredicate.matches(device);
|
||||
if (removableFSVolumesPredicate.matches(device))
|
||||
{
|
||||
volumes++;
|
||||
}
|
||||
}
|
||||
QCOMPARE(volumes, 0);
|
||||
|
||||
auto matchedDeviceList = Solid::Device::listFromQuery(removableFSVolumesPredicate);
|
||||
QCOMPARE(matchedDeviceList.size(), volumes);
|
||||
}
|
||||
|
||||
// Internally, the predicate is going to check interfaces,
|
||||
// so let's do that here as well. This will show no device is
|
||||
// both a Volume and a Drive.
|
||||
{
|
||||
const Solid::DeviceInterface::Type storageVolume = Solid::DeviceInterface::Type::StorageVolume;
|
||||
const Solid::DeviceInterface::Type storageDrive = Solid::DeviceInterface::Type::StorageDrive;
|
||||
|
||||
int volumeCount = 0;
|
||||
int driveCount = 0;
|
||||
int bothCount = 0;
|
||||
|
||||
for (const auto &device : std::as_const(deviceList)) {
|
||||
// Copied from internals in predicate.cpp:
|
||||
// const DeviceInterface *iface = device.asDeviceInterface(d->ifaceType);
|
||||
const Solid::DeviceInterface *volumeIface = device.asDeviceInterface(storageVolume);
|
||||
const Solid::DeviceInterface *driveIface = device.asDeviceInterface(storageDrive);
|
||||
volumeCount += volumeIface ? 1 : 0;
|
||||
driveCount += driveIface ? 1 : 0;
|
||||
bothCount += (volumeIface && driveIface) ? 1 : 0;
|
||||
}
|
||||
QCOMPARE(bothCount, 0);
|
||||
if (volumeCount + driveCount > 0)
|
||||
{
|
||||
// On Linux CI, there is no DBus connection, so no drives or volumes at all.
|
||||
// On a local machine, or on FreeBSD CI, there are volumes and/or drives,
|
||||
// so verify that there's at least one of each.
|
||||
QVERIFY(volumeCount > 0);
|
||||
QVERIFY(driveCount > 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#include "solidmttest.moc"
|
||||
Reference in New Issue
Block a user