/* Copyright 2005 Kevin Ottens This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 6 of version 3 of the license. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "solidhwtest.h" #include #include #include #include #include #include #include #include #include #include #include "solid/managerbase_p.h" #include #include #include #ifndef FAKE_COMPUTER_XML #error "FAKE_COMPUTER_XML not set. An XML file describing a computer is required for this test" #endif QTEST_MAIN(SolidHwTest) void SolidHwTest::initTestCase() { setenv("SOLID_FAKEHW", FAKE_COMPUTER_XML, 1); Solid::ManagerBasePrivate *manager = dynamic_cast(Solid::DeviceNotifier::instance()); fakeManager = qobject_cast(manager->managerBackends().first()); } void SolidHwTest::testAllDevices() { QList devices = Solid::Device::allDevices(); // Verify that the framework reported correctly the devices available // in the backend. QStringList expected_udis, received_udis; expected_udis = fakeManager->allDevices(); foreach (const Solid::Device &dev , devices) { received_udis << dev.udi(); } QCOMPARE(expected_udis, received_udis); } void SolidHwTest::testDeviceBasicFeatures() { // Retrieve a valid Device object Solid::Device valid_dev("/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("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(), QString("/org/kde/solid/fakehw/storage_model_solid_writer")); QCOMPARE(invalid_dev.udi(), QString()); // 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(), QString("/org/kde/solid/fakehw/pci_002_ide_1_0")); QCOMPARE(valid_dev.parent().udi(), Solid::Device("/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(), QString("Acme Corporation")); QCOMPARE(valid_dev.product(), QString("Solid IDE DVD Writer")); QCOMPARE(invalid_dev.vendor(), QString()); QCOMPARE(invalid_dev.product(), QString()); } void SolidHwTest::testManagerSignals() { fakeManager->unplug("/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("/org/kde/solid/fakehw/acpi_CPU0"); QCOMPARE(added.count(), 1); QCOMPARE(added.at(0).at(0).toString(), QString("/org/kde/solid/fakehw/acpi_CPU0")); // Moreover we check that the device is really available Solid::Device cpu("/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("/org/kde/solid/fakehw/acpi_CPU0"); QCOMPARE(removed.count(), 1); QCOMPARE(removed.at(0).at(0).toString(), QString("/org/kde/solid/fakehw/acpi_CPU0")); // The Device object should become automatically invalid QVERIFY(!cpu.isValid()); // Restore original state fakeManager->plug("/org/kde/solid/fakehw/acpi_CPU0"); } void SolidHwTest::testDeviceExistence() { QCOMPARE(Solid::Device("/org/kde/solid/fakehw/volume_label_SOLIDMAN_BEGINS").isValid(), true); // Note the extra space QCOMPARE(Solid::Device("/org/kde/solid/fakehw/computer ").isValid(), false); QCOMPARE(Solid::Device("#'({(]").isValid(), false); QCOMPARE(Solid::Device(QString()).isValid(), false); // Now try to see if isValid() changes on plug/unplug events Solid::Device cpu("/org/kde/solid/fakehw/acpi_CPU0"); QVERIFY(cpu.isValid()); fakeManager->unplug("/org/kde/solid/fakehw/acpi_CPU0"); QVERIFY(!cpu.isValid()); fakeManager->plug("/org/kde/solid/fakehw/acpi_CPU0"); QVERIFY(cpu.isValid()); } void SolidHwTest::testDeviceInterfaces() { Solid::Device cpu("/org/kde/solid/fakehw/acpi_CPU0"); Solid::DeviceInterface *iface = cpu.asDeviceInterface(Solid::DeviceInterface::Processor); Solid::DeviceInterface *processor = cpu.as(); QVERIFY(cpu.isDeviceInterface(Solid::DeviceInterface::Processor)); QVERIFY(iface!=0); QCOMPARE(iface, processor); Solid::Device cpu2("/org/kde/solid/fakehw/acpi_CPU0"); QCOMPARE(cpu.as(), cpu2.as()); QPointer p = cpu.as(); QVERIFY(p!=0); fakeManager->unplug("/org/kde/solid/fakehw/acpi_CPU0"); QVERIFY(p==0); fakeManager->plug("/org/kde/solid/fakehw/acpi_CPU0"); QPointer v; QPointer v2; { Solid::Device partition("/org/kde/solid/fakehw/volume_uuid_f00ba7"); v = partition.as(); QVERIFY(v!=0); { Solid::Device partition2("/org/kde/solid/fakehw/volume_uuid_f00ba7"); v2 = partition2.as(); QVERIFY(v2!=0); QVERIFY(v==v2); } QVERIFY(v!=0); QVERIFY(v2!=0); } QVERIFY(v!=0); QVERIFY(v2!=0); fakeManager->unplug("/org/kde/solid/fakehw/volume_uuid_f00ba7"); QVERIFY(v==0); QVERIFY(v2==0); fakeManager->plug("/org/kde/solid/fakehw/volume_uuid_f00ba7"); } void SolidHwTest::testDeviceInterfaceIntrospection_data() { QTest::addColumn("name"); QTest::addColumn("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: NetworkInterface") << "NetworkInterface" << (int)Solid::DeviceInterface::NetworkInterface; QTest::newRow("DeviceInterface: AcAdapter") << "AcAdapter" << (int)Solid::DeviceInterface::AcAdapter; QTest::newRow("DeviceInterface: Battery") << "Battery" << (int)Solid::DeviceInterface::Battery; QTest::newRow("DeviceInterface: AudioInterface") << "AudioInterface" << (int)Solid::DeviceInterface::AudioInterface; QTest::newRow("DeviceInterface: Graphic") << "Graphic" << (int)Solid::DeviceInterface::Graphic; QTest::newRow("DeviceInterface: Input") << "Input" << (int)Solid::DeviceInterface::Input; QTest::newRow("DeviceInterface: Video") << "Video" << (int)Solid::DeviceInterface::Video; } 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("blup"), -1); } static QSet to_string_set(const QList &list) { QSet res; foreach (const Solid::Device &device, list) { res << device.udi(); } return res; } void SolidHwTest::testPredicate() { Solid::Device dev("/org/kde/solid/fakehw/acpi_CPU0"); Solid::Predicate p1 = Solid::Predicate(Solid::DeviceInterface::Processor, "maxSpeed", 3200) & Solid::Predicate(Solid::DeviceInterface::Processor, "canChangeFrequency", true); Solid::Predicate p2 = Solid::Predicate(Solid::DeviceInterface::Processor, "maxSpeed", 3200) & Solid::Predicate(Solid::DeviceInterface::Processor, "canChangeFrequency", false); Solid::Predicate p3 = Solid::Predicate(Solid::DeviceInterface::Processor, "maxSpeed", 3201) | Solid::Predicate(Solid::DeviceInterface::Processor, "canChangeFrequency", true); Solid::Predicate p4 = Solid::Predicate(Solid::DeviceInterface::Processor, "maxSpeed", 3201) | Solid::Predicate(Solid::DeviceInterface::Processor, "canChangeFrequency", false); Solid::Predicate p5 = Solid::Predicate::fromString("[[Processor.maxSpeed == 3201 AND Processor.canChangeFrequency == false] OR StorageVolume.mountPoint == '/media/blup']"); QVERIFY(p1.matches(dev)); QVERIFY(!p2.matches(dev)); QVERIFY(p3.matches(dev)); QVERIFY(!p4.matches(dev)); Solid::Predicate p6 = Solid::Predicate::fromString("StorageVolume.usage == 'Other'"); Solid::Predicate p7 = Solid::Predicate::fromString(QString("StorageVolume.usage == %1").arg((int)Solid::StorageVolume::Other)); QVERIFY(!p6.matches(dev)); QVERIFY(!p7.matches(dev)); dev = Solid::Device("/org/kde/solid/fakehw/volume_part2_size_1024"); QVERIFY(p6.matches(dev)); QVERIFY(p7.matches(dev)); Solid::Predicate p8 = Solid::Predicate::fromString("AudioInterface.deviceType == 'AudioInput|AudioOutput'"); Solid::Predicate p9 = Solid::Predicate::fromString("AudioInterface.deviceType == 'AudioInput'"); Solid::Predicate p10 = Solid::Predicate::fromString("AudioInterface.deviceType & 'AudioInput'"); Solid::Predicate p11 = Solid::Predicate::fromString("AudioInterface.deviceType & 'foobar'"); QVERIFY(!p8.matches(dev)); QVERIFY(!p9.matches(dev)); QVERIFY(!p10.matches(dev)); QVERIFY(!p11.matches(dev)); dev = Solid::Device("/org/kde/solid/fakehw/pci_8086_266e_oss_pcm_0"); QVERIFY(p8.matches(dev)); QVERIFY(!p9.matches(dev)); QVERIFY(p10.matches(dev)); QVERIFY(!p11.matches(dev)); QString str_pred = "[[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 = "[StorageVolume.ignored == false AND OpticalDisc.isBlank == true AND OpticalDisc.discType & 'CdRecordable|CdRewritable']"; QVERIFY(!Solid::Predicate::fromString(str_pred).isValid()); QString parentUdi = "/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), QString("/org/kde/solid/fakehw/volume_label_SOLIDMAN_BEGINS")); ifaceType = Solid::DeviceInterface::Processor; QCOMPARE(fakeManager->devicesFromQuery(parentUdi, ifaceType).size(), 0); parentUdi = "/org/kde/solid/fakehw/computer"; QCOMPARE(fakeManager->devicesFromQuery(parentUdi, ifaceType).size(), 2); QCOMPARE(fakeManager->devicesFromQuery(parentUdi, ifaceType).at(0), QString("/org/kde/solid/fakehw/acpi_CPU0")); QCOMPARE(fakeManager->devicesFromQuery(parentUdi, ifaceType).at(1), QString("/org/kde/solid/fakehw/acpi_CPU1")); parentUdi.clear(); ifaceType = Solid::DeviceInterface::Unknown; QList list; list = Solid::Device::listFromQuery(p1, parentUdi); QCOMPARE(list.size(), 2); QCOMPARE(list.at(0).udi(), QString("/org/kde/solid/fakehw/acpi_CPU0")); QCOMPARE(list.at(1).udi(), QString("/org/kde/solid/fakehw/acpi_CPU1")); list = Solid::Device::listFromQuery(p2, parentUdi); QCOMPARE(list.size(), 0); list = Solid::Device::listFromQuery(p3, parentUdi); QCOMPARE(list.size(), 2); QCOMPARE(list.at(0).udi(), QString("/org/kde/solid/fakehw/acpi_CPU0")); QCOMPARE(list.at(1).udi(), QString("/org/kde/solid/fakehw/acpi_CPU1")); list = Solid::Device::listFromQuery(p4, parentUdi); QCOMPARE(list.size(), 0); list = Solid::Device::listFromQuery("[Processor.canChangeFrequency==true AND Processor.number==1]", parentUdi); QCOMPARE(list.size(), 1); QCOMPARE(list.at(0).udi(), QString("/org/kde/solid/fakehw/acpi_CPU1")); list = Solid::Device::listFromQuery("[Processor.number==1 OR IS StorageVolume]", parentUdi); QCOMPARE(list.size(), 10); //make sure predicate case-insensitiveness is sane list = Solid::Device::listFromQuery("[Processor.number==1 or is StorageVolume]", parentUdi); QCOMPARE(list.size(), 10); list = Solid::Device::listFromQuery("[Processor.number==1 oR Is StorageVolume]", parentUdi); QCOMPARE(list.size(), 10); QSet set; QCOMPARE(list.size(), 10); set << "/org/kde/solid/fakehw/acpi_CPU1" << "/org/kde/solid/fakehw/platform_floppy_0_storage_virt_volume" << "/org/kde/solid/fakehw/volume_label_SOLIDMAN_BEGINS" << "/org/kde/solid/fakehw/volume_part1_size_993284096" << "/org/kde/solid/fakehw/volume_part2_size_1024" << "/org/kde/solid/fakehw/volume_part5_size_1048576" << "/org/kde/solid/fakehw/volume_uuid_5011" << "/org/kde/solid/fakehw/volume_uuid_c0ffee" << "/org/kde/solid/fakehw/volume_uuid_f00ba7" << "/org/kde/solid/fakehw/volume_uuid_feedface"; QCOMPARE(set, to_string_set(list)); list = Solid::Device::listFromQuery("[IS Processor OR IS StorageVolume]", parentUdi); QCOMPARE(list.size(), 11); set << "/org/kde/solid/fakehw/acpi_CPU0"; QCOMPARE(set, to_string_set(list)); ifaceType = Solid::DeviceInterface::Processor; list = Solid::Device::listFromType(ifaceType, parentUdi); QCOMPARE(list.size(), 2); QCOMPARE(list.at(0).udi(), QString("/org/kde/solid/fakehw/acpi_CPU0")); QCOMPARE(list.at(1).udi(), QString("/org/kde/solid/fakehw/acpi_CPU1")); ifaceType = Solid::DeviceInterface::Unknown; list = Solid::Device::listFromQuery("blup", parentUdi); QCOMPARE(list.size(), 0); } void SolidHwTest::testSetupTeardown() { Solid::StorageAccess *access; { Solid::Device device("/org/kde/solid/fakehw/volume_part1_size_993284096"); access = device.as(); } QList 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::slotPropertyChanged(const QStringList &changes) { m_changesList << changes; } #define SOLID_TEST_IFACE(UDI, DEVIFACE, SOLIFACE) \ { \ Solid::Device device(UDI); \ \ Solid::DeviceInterface *iface = device.asDeviceInterface(DEVIFACE); \ Solid::DeviceInterface *iface2 = device.as(); \ \ QVERIFY(device.isDeviceInterface(DEVIFACE)); \ QVERIFY(iface != 0); \ QCOMPARE(iface, iface2); \ \ QPointer p = device.as(); \ QVERIFY(p != 0); \ fakeManager->unplug(UDI); \ QVERIFY(p == 0); \ fakeManager->plug(UDI); \ } // any interface that is not tested with the test cases above should be tested // with this method void SolidHwTest::testMisc() { SOLID_TEST_IFACE("/org/kde/solid/fakehw/pci_10de_0fc1_card0", Solid::DeviceInterface::Graphic, Solid::Graphic); { Solid::Device device("/org/kde/solid/fakehw/pci_10de_0fc1_card0"); Solid::Graphic* deviceptr = device.as(); QCOMPARE(deviceptr->driver(), QString("nouveau")); } SOLID_TEST_IFACE("/org/kde/solid/fakehw/pci_0000_001d_input0", Solid::DeviceInterface::Input, Solid::Input); { Solid::Device device("/org/kde/solid/fakehw/pci_0000_001d_input0"); Solid::Input* deviceptr = device.as(); QCOMPARE(deviceptr->driver(), QString("usbhid")); QCOMPARE(deviceptr->inputType(), Solid::Input::Mouse); } SOLID_TEST_IFACE("/org/kde/solid/fakehw/pci_01ed_f0c1_video0", Solid::DeviceInterface::Video, Solid::Video); { Solid::Device device("/org/kde/solid/fakehw/pci_01ed_f0c1_video0"); Solid::Video* deviceptr = device.as(); QCOMPARE(deviceptr->supportedProtocols(), QStringList() << QString("video4linux")); QCOMPARE(deviceptr->supportedDrivers(), QStringList() << QString("video4linux2")); QCOMPARE(deviceptr->driverHandle("foo"), QVariant("/dev/video0")); } SOLID_TEST_IFACE("/org/kde/solid/fakehw/pci_ed01_c1f0_radio0", Solid::DeviceInterface::Video, Solid::Video); { Solid::Device device("/org/kde/solid/fakehw/pci_ed01_c1f0_radio0"); Solid::Video* deviceptr = device.as(); QCOMPARE(deviceptr->supportedProtocols(), QStringList() << QString("video4linux")); QCOMPARE(deviceptr->supportedDrivers(), QStringList() << QString("video4linux1")); QCOMPARE(deviceptr->driverHandle("bar"), QVariant("/dev/radio0")); } } #include "moc_solidhwtest.cpp"