File indexing completed on 2024-04-21 14:52:44

0001 /*
0002  * SPDX-FileCopyrightText: 2014-2015 David Rosca <nowrep@gmail.com>
0003  *
0004  * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005  */
0006 
0007 #include "managertest.h"
0008 #include "adapter.h"
0009 #include "autotests.h"
0010 #include "device.h"
0011 #include "initmanagerjob.h"
0012 #include "manager.h"
0013 
0014 #include <QDBusObjectPath>
0015 #include <QSignalSpy>
0016 #include <QTest>
0017 
0018 namespace BluezQt
0019 {
0020 extern void bluezqt_initFakeBluezTestRun();
0021 }
0022 
0023 using namespace BluezQt;
0024 
0025 void ManagerTest::initTestCase()
0026 {
0027     bluezqt_initFakeBluezTestRun();
0028     FakeBluez::start(); // to check that it works
0029     Autotests::registerMetatypes();
0030 }
0031 
0032 void ManagerTest::cleanup()
0033 {
0034     FakeBluez::stop();
0035 }
0036 
0037 void ManagerTest::bluezNotRunningTest()
0038 {
0039     // org.bluez is not running at all
0040     // expected: init successful
0041     auto manager = std::make_unique<Manager>();
0042     InitManagerJob *job = manager->init();
0043     job->exec();
0044 
0045     QVERIFY(!job->error());
0046     QVERIFY(manager->isInitialized());
0047     QVERIFY(!manager->isOperational());
0048     QVERIFY(!manager->isBluetoothOperational());
0049 }
0050 
0051 void ManagerTest::bluezNotExportingInterfacesTest()
0052 {
0053     // org.bluez is running, but it does not export any interfaces
0054     // expected: init error
0055     FakeBluez::start();
0056     FakeBluez::runTest(QStringLiteral("bluez-not-exporting-interfaces"));
0057 
0058     auto manager = std::make_unique<Manager>();
0059     InitManagerJob *job = manager->init();
0060     job->exec();
0061 
0062     QVERIFY(job->error());
0063     QVERIFY(!manager->isInitialized());
0064     QVERIFY(!manager->isOperational());
0065     QVERIFY(!manager->isBluetoothOperational());
0066 }
0067 
0068 void ManagerTest::bluezEmptyManagedObjectsTest()
0069 {
0070     // org.bluez exports ObjectManager, but there is no AgentManager1
0071     // expected: init error
0072     FakeBluez::start();
0073     FakeBluez::runTest(QStringLiteral("bluez-empty-managed-objects"));
0074 
0075     auto manager = std::make_unique<Manager>();
0076     InitManagerJob *job = manager->init();
0077     job->exec();
0078 
0079     QVERIFY(job->error());
0080     QVERIFY(!manager->isInitialized());
0081     QVERIFY(!manager->isOperational());
0082     QVERIFY(!manager->isBluetoothOperational());
0083 }
0084 
0085 void ManagerTest::bluezNoAdaptersTest()
0086 {
0087     // org.bluez exports ObjectManager with AgentManager1, but there are no adapters
0088     // expected: init successful
0089     FakeBluez::start();
0090     FakeBluez::runTest(QStringLiteral("bluez-no-adapters"));
0091 
0092     auto manager = std::make_unique<Manager>();
0093     InitManagerJob *job = manager->init();
0094     job->exec();
0095 
0096     QVERIFY(!job->error());
0097     QVERIFY(manager->isInitialized());
0098     QVERIFY(manager->isOperational());
0099     QVERIFY(!manager->isBluetoothOperational());
0100 }
0101 
0102 void ManagerTest::bluezShutdownTest()
0103 {
0104     // tests whether the adapter/device removed signals work correctly
0105 
0106     FakeBluez::start();
0107     FakeBluez::runTest(QStringLiteral("bluez-standard"));
0108 
0109     // Create adapters
0110     QDBusObjectPath adapter1path = QDBusObjectPath(QStringLiteral("/org/bluez/hci0"));
0111     QVariantMap adapterProps;
0112     adapterProps[QStringLiteral("Path")] = QVariant::fromValue(adapter1path);
0113     adapterProps[QStringLiteral("Address")] = QStringLiteral("1C:E5:C3:BC:94:7E");
0114     adapterProps[QStringLiteral("Name")] = QStringLiteral("TestAdapter");
0115     adapterProps[QStringLiteral("Powered")] = true;
0116     FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("create-adapter"), adapterProps);
0117 
0118     QDBusObjectPath adapter2path = QDBusObjectPath(QStringLiteral("/org/bluez/hci1"));
0119     adapterProps[QStringLiteral("Path")] = QVariant::fromValue(adapter2path);
0120     adapterProps[QStringLiteral("Address")] = QStringLiteral("2E:3A:C3:BC:85:7C");
0121     adapterProps[QStringLiteral("Name")] = QStringLiteral("TestAdapter2");
0122     FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("create-adapter"), adapterProps);
0123 
0124     // Create devices
0125     QVariantMap deviceProps;
0126     deviceProps[QStringLiteral("Path")] = QVariant::fromValue(QDBusObjectPath("/org/bluez/hci0/dev_40_79_6A_0C_39_75"));
0127     deviceProps[QStringLiteral("Adapter")] = QVariant::fromValue(adapter1path);
0128     deviceProps[QStringLiteral("Address")] = QStringLiteral("40:79:6A:0C:39:75");
0129     deviceProps[QStringLiteral("Name")] = QStringLiteral("TestDevice");
0130     FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("create-device"), deviceProps);
0131 
0132     deviceProps[QStringLiteral("Path")] = QVariant::fromValue(QDBusObjectPath("/org/bluez/hci1/dev_50_79_6A_0C_39_75"));
0133     deviceProps[QStringLiteral("Adapter")] = QVariant::fromValue(adapter2path);
0134     deviceProps[QStringLiteral("Address")] = QStringLiteral("50:79:6A:0C:39:75");
0135     deviceProps[QStringLiteral("Name")] = QStringLiteral("TestDevice2");
0136     FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("create-device"), deviceProps);
0137 
0138     auto manager = std::make_unique<Manager>();
0139 
0140     QSignalSpy btOperationalChangedSpy(manager.get(), SIGNAL(bluetoothOperationalChanged(bool)));
0141 
0142     InitManagerJob *job = manager->init();
0143     job->exec();
0144 
0145     QVERIFY(!job->error());
0146     QVERIFY(manager->isInitialized());
0147     QVERIFY(manager->isOperational());
0148     QVERIFY(manager->isBluetoothOperational());
0149     QCOMPARE(manager->adapters().count(), 2);
0150     QCOMPARE(manager->devices().count(), 2);
0151 
0152     QCOMPARE(btOperationalChangedSpy.count(), 1);
0153     QCOMPARE(btOperationalChangedSpy.first().first().toBool(), true);
0154 
0155     AdapterPtr adapter1 = manager->adapterForAddress(QStringLiteral("1C:E5:C3:BC:94:7E"));
0156     AdapterPtr adapter2 = manager->adapterForAddress(QStringLiteral("2E:3A:C3:BC:85:7C"));
0157     DevicePtr device1 = manager->deviceForAddress(QStringLiteral("40:79:6A:0C:39:75"));
0158     DevicePtr device2 = manager->deviceForAddress(QStringLiteral("50:79:6A:0C:39:75"));
0159 
0160     QVERIFY(adapter1);
0161     QVERIFY(adapter2);
0162     QVERIFY(device1);
0163     QVERIFY(device2);
0164 
0165     QSignalSpy allAdaptersRemovedSpy(manager.get(), SIGNAL(allAdaptersRemoved()));
0166     QSignalSpy adapterRemovedSpy(manager.get(), SIGNAL(adapterRemoved(AdapterPtr)));
0167     QSignalSpy device1RemovedSpy(adapter1.data(), SIGNAL(deviceRemoved(DevicePtr)));
0168     QSignalSpy device2RemovedSpy(adapter2.data(), SIGNAL(deviceRemoved(DevicePtr)));
0169 
0170     btOperationalChangedSpy.clear();
0171     FakeBluez::stop();
0172 
0173     // allAdaptersRemoved will be last signal
0174     QTRY_COMPARE(allAdaptersRemovedSpy.count(), 1);
0175 
0176     QCOMPARE(adapterRemovedSpy.count(), 2);
0177     QCOMPARE(device1RemovedSpy.count(), 1);
0178     QCOMPARE(device2RemovedSpy.count(), 1);
0179 
0180     QCOMPARE(btOperationalChangedSpy.count(), 1);
0181     QCOMPARE(btOperationalChangedSpy.first().first().toBool(), false);
0182 }
0183 
0184 void ManagerTest::usableAdapterTest()
0185 {
0186     FakeBluez::start();
0187     FakeBluez::runTest(QStringLiteral("bluez-standard"));
0188 
0189     // Create adapters
0190     QDBusObjectPath adapter1path = QDBusObjectPath(QStringLiteral("/org/bluez/hci0"));
0191     QVariantMap adapterProps;
0192     adapterProps[QStringLiteral("Path")] = QVariant::fromValue(adapter1path);
0193     adapterProps[QStringLiteral("Address")] = QStringLiteral("1C:E5:C3:BC:94:7E");
0194     adapterProps[QStringLiteral("Name")] = QStringLiteral("TestAdapter");
0195     adapterProps[QStringLiteral("Powered")] = false;
0196     FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("create-adapter"), adapterProps);
0197 
0198     QDBusObjectPath adapter2path = QDBusObjectPath(QStringLiteral("/org/bluez/hci1"));
0199     adapterProps[QStringLiteral("Path")] = QVariant::fromValue(adapter2path);
0200     adapterProps[QStringLiteral("Address")] = QStringLiteral("2E:3A:C3:BC:85:7C");
0201     adapterProps[QStringLiteral("Name")] = QStringLiteral("TestAdapter2");
0202     adapterProps[QStringLiteral("Powered")] = false;
0203     FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("create-adapter"), adapterProps);
0204 
0205     auto manager = std::make_unique<Manager>();
0206 
0207     QSignalSpy usableAdapterChangedSpy(manager.get(), SIGNAL(usableAdapterChanged(AdapterPtr)));
0208 
0209     InitManagerJob *job = manager->init();
0210     job->exec();
0211 
0212     QVERIFY(!job->error());
0213     QVERIFY(manager->isInitialized());
0214     QVERIFY(manager->isOperational());
0215     QVERIFY(!manager->isBluetoothOperational());
0216     QCOMPARE(usableAdapterChangedSpy.count(), 0);
0217     QCOMPARE(manager->adapters().count(), 2);
0218     QCOMPARE(manager->devices().count(), 0);
0219 
0220     QVariantMap properties;
0221     properties[QStringLiteral("Path")] = QVariant::fromValue(adapter1path);
0222     properties[QStringLiteral("Name")] = QStringLiteral("Powered");
0223     properties[QStringLiteral("Value")] = true;
0224     FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("change-adapter-property"), properties);
0225 
0226     QTRY_COMPARE(usableAdapterChangedSpy.count(), 1);
0227     QCOMPARE(manager->usableAdapter()->ubi(), adapter1path.path());
0228 
0229     usableAdapterChangedSpy.clear();
0230 
0231     properties[QStringLiteral("Value")] = false;
0232     FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("change-adapter-property"), properties);
0233 
0234     QTRY_COMPARE(usableAdapterChangedSpy.count(), 1);
0235     QVERIFY(manager->usableAdapter().isNull());
0236 
0237     usableAdapterChangedSpy.clear();
0238 
0239     properties[QStringLiteral("Path")] = QVariant::fromValue(adapter2path);
0240     properties[QStringLiteral("Value")] = true;
0241     FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("change-adapter-property"), properties);
0242 
0243     QTRY_COMPARE(usableAdapterChangedSpy.count(), 1);
0244     QCOMPARE(manager->usableAdapter()->ubi(), adapter2path.path());
0245 }
0246 
0247 void ManagerTest::deviceForAddressTest()
0248 {
0249     // tests whether the deviceForAddress correctly prefer powered adapters
0250 
0251     FakeBluez::start();
0252     FakeBluez::runTest(QStringLiteral("bluez-standard"));
0253 
0254     // Create adapters
0255     QDBusObjectPath adapter1path = QDBusObjectPath(QStringLiteral("/org/bluez/hci0"));
0256     QVariantMap adapterProps;
0257     adapterProps[QStringLiteral("Path")] = QVariant::fromValue(adapter1path);
0258     adapterProps[QStringLiteral("Address")] = QStringLiteral("1C:E5:C3:BC:94:7E");
0259     adapterProps[QStringLiteral("Name")] = QStringLiteral("TestAdapter");
0260     adapterProps[QStringLiteral("Powered")] = false;
0261     FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("create-adapter"), adapterProps);
0262 
0263     QDBusObjectPath adapter2path = QDBusObjectPath(QStringLiteral("/org/bluez/hci1"));
0264     adapterProps[QStringLiteral("Path")] = QVariant::fromValue(adapter2path);
0265     adapterProps[QStringLiteral("Address")] = QStringLiteral("2E:3A:C3:BC:85:7C");
0266     adapterProps[QStringLiteral("Name")] = QStringLiteral("TestAdapter2");
0267     adapterProps[QStringLiteral("Powered")] = true;
0268     FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("create-adapter"), adapterProps);
0269 
0270     // Create devices
0271     QVariantMap deviceProps;
0272     deviceProps[QStringLiteral("Path")] = QVariant::fromValue(QDBusObjectPath("/org/bluez/hci0/dev_40_79_6A_0C_39_75"));
0273     deviceProps[QStringLiteral("Adapter")] = QVariant::fromValue(adapter1path);
0274     deviceProps[QStringLiteral("Address")] = QStringLiteral("40:79:6A:0C:39:75");
0275     deviceProps[QStringLiteral("Name")] = QStringLiteral("TestDevice");
0276     FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("create-device"), deviceProps);
0277 
0278     deviceProps[QStringLiteral("Path")] = QVariant::fromValue(QDBusObjectPath("/org/bluez/hci1/dev_40_79_6A_0C_39_75"));
0279     deviceProps[QStringLiteral("Adapter")] = QVariant::fromValue(adapter2path);
0280     FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("create-device"), deviceProps);
0281 
0282     auto manager = std::make_unique<Manager>();
0283 
0284     InitManagerJob *job = manager->init();
0285     job->exec();
0286 
0287     QVERIFY(!job->error());
0288 
0289     QString address(QStringLiteral("40:79:6A:0C:39:75"));
0290     AdapterPtr adapter1 = manager->adapterForUbi(QStringLiteral("/org/bluez/hci0"));
0291     AdapterPtr adapter2 = manager->adapterForUbi(QStringLiteral("/org/bluez/hci1"));
0292 
0293     QVERIFY(adapter1);
0294     QVERIFY(adapter2);
0295 
0296     QSignalSpy adapter1Spy(adapter1.data(), SIGNAL(poweredChanged(bool)));
0297     QSignalSpy adapter2Spy(adapter2.data(), SIGNAL(poweredChanged(bool)));
0298 
0299     QCOMPARE(manager->deviceForAddress(address)->adapter(), adapter2);
0300 
0301     QVariantMap properties;
0302     properties[QStringLiteral("Path")] = QVariant::fromValue(adapter1path);
0303     properties[QStringLiteral("Name")] = QStringLiteral("Powered");
0304     properties[QStringLiteral("Value")] = true;
0305     FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("change-adapter-property"), properties);
0306 
0307     properties[QStringLiteral("Path")] = QVariant::fromValue(adapter2path);
0308     properties[QStringLiteral("Value")] = false;
0309     FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("change-adapter-property"), properties);
0310 
0311     QTRY_COMPARE(adapter1Spy.count(), 1);
0312     QTRY_COMPARE(adapter2Spy.count(), 1);
0313 
0314     QCOMPARE(manager->deviceForAddress(address)->adapter(), adapter1);
0315 
0316     properties[QStringLiteral("Path")] = QVariant::fromValue(adapter1path);
0317     properties[QStringLiteral("Value")] = false;
0318     FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("change-adapter-property"), properties);
0319 
0320     QTRY_COMPARE(adapter1Spy.count(), 2);
0321     QVERIFY(manager->deviceForAddress(address));
0322 }
0323 
0324 void ManagerTest::adapterWithDevicesRemovedTest()
0325 {
0326     // tests whether the devices are always removed from the adapter before removing adapter
0327 
0328     FakeBluez::start();
0329     FakeBluez::runTest(QStringLiteral("bluez-standard"));
0330 
0331     // Create adapters
0332     QDBusObjectPath adapter1path = QDBusObjectPath(QStringLiteral("/org/bluez/hci0"));
0333     QVariantMap adapterProps;
0334     adapterProps[QStringLiteral("Path")] = QVariant::fromValue(adapter1path);
0335     adapterProps[QStringLiteral("Address")] = QStringLiteral("1C:E5:C3:BC:94:7E");
0336     adapterProps[QStringLiteral("Name")] = QStringLiteral("TestAdapter");
0337     adapterProps[QStringLiteral("Powered")] = false;
0338     FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("create-adapter"), adapterProps);
0339 
0340     // Create devices
0341     QVariantMap deviceProps;
0342     deviceProps[QStringLiteral("Path")] = QVariant::fromValue(QDBusObjectPath("/org/bluez/hci0/dev_40_79_6A_0C_39_75"));
0343     deviceProps[QStringLiteral("Adapter")] = QVariant::fromValue(adapter1path);
0344     deviceProps[QStringLiteral("Address")] = QStringLiteral("40:79:6A:0C:39:75");
0345     deviceProps[QStringLiteral("Name")] = QStringLiteral("TestDevice");
0346     FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("create-device"), deviceProps);
0347 
0348     deviceProps[QStringLiteral("Path")] = QVariant::fromValue(QDBusObjectPath("/org/bluez/hci0/dev_50_79_6A_0C_39_75"));
0349     deviceProps[QStringLiteral("Adapter")] = QVariant::fromValue(adapter1path);
0350     deviceProps[QStringLiteral("Address")] = QStringLiteral("50:79:6A:0C:39:75");
0351     deviceProps[QStringLiteral("Name")] = QStringLiteral("TestDevice2");
0352     FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("create-device"), deviceProps);
0353 
0354     auto manager = std::make_unique<Manager>();
0355 
0356     InitManagerJob *job = manager->init();
0357     job->exec();
0358 
0359     QVERIFY(!job->error());
0360 
0361     AdapterPtr adapter = manager->adapterForAddress(QStringLiteral("1C:E5:C3:BC:94:7E"));
0362     DevicePtr device1 = manager->deviceForAddress(QStringLiteral("40:79:6A:0C:39:75"));
0363     DevicePtr device2 = manager->deviceForAddress(QStringLiteral("50:79:6A:0C:39:75"));
0364 
0365     QVERIFY(adapter);
0366     QVERIFY(device1);
0367     QVERIFY(device2);
0368 
0369     QSignalSpy adapterRemovedSpy(manager.get(), SIGNAL(adapterRemoved(AdapterPtr)));
0370     QSignalSpy deviceRemovedSpy(manager.get(), SIGNAL(deviceRemoved(DevicePtr)));
0371 
0372     QVariantMap properties;
0373     properties[QStringLiteral("Path")] = QVariant::fromValue(adapter1path);
0374     FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("remove-adapter"), properties);
0375 
0376     QTRY_COMPARE(adapterRemovedSpy.count(), 1);
0377     QTRY_COMPARE(deviceRemovedSpy.count(), 2);
0378     QCOMPARE(manager->adapters().count(), 0);
0379     QCOMPARE(manager->devices().count(), 0);
0380     QCOMPARE(adapter->devices().count(), 0);
0381 }
0382 
0383 void ManagerTest::bug364416()
0384 {
0385     // Bug 364416: Crash when device is added with adapter that is unknown to Manager
0386 
0387     FakeBluez::start();
0388     FakeBluez::runTest(QStringLiteral("bluez-standard"));
0389 
0390     auto manager = std::make_unique<Manager>();
0391 
0392     InitManagerJob *job = manager->init();
0393     job->exec();
0394 
0395     QVERIFY(!job->error());
0396 
0397     // Add device to invalid adapter
0398     QVariantMap deviceProps;
0399     deviceProps[QStringLiteral("Path")] = QVariant::fromValue(QDBusObjectPath("/org/bluez/hci0/dev_40_79_6A_0C_39_75"));
0400     deviceProps[QStringLiteral("Adapter")] = QVariant::fromValue(QDBusObjectPath(QStringLiteral("/org/bluez/hci0")));
0401     deviceProps[QStringLiteral("Address")] = QStringLiteral("40:79:6A:0C:39:75");
0402     deviceProps[QStringLiteral("Name")] = QStringLiteral("TestDevice");
0403     FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("create-device"), deviceProps);
0404 
0405     // Wait for Manager to receive the interfacesAdded signal
0406     QTest::qWait(100);
0407 }
0408 
0409 void ManagerTest::bug377405()
0410 {
0411     // Bug 377405: Property changes immediately after adapter is added are lost
0412 
0413     FakeBluez::start();
0414     FakeBluez::runTest(QStringLiteral("bluez-standard"));
0415 
0416     auto manager = std::make_unique<Manager>();
0417 
0418     InitManagerJob *job = manager->init();
0419     job->exec();
0420 
0421     QVERIFY(!job->error());
0422 
0423     FakeBluez::runAction(QStringLiteral("devicemanager"), QStringLiteral("bug377405"));
0424 
0425     // Adapter property Powered is changed to true immediately after being added
0426     QTRY_COMPARE(manager->isBluetoothOperational(), true);
0427 }
0428 
0429 QTEST_MAIN(ManagerTest)
0430 
0431 #include "moc_managertest.cpp"