/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtBluetooth module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and Digia. For licensing terms and ** conditions see http://qt.digia.com/licensing. For further information ** use the contact form at http://qt.digia.com/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Digia gives you certain additional ** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include /* * Some tests require a Bluetooth device within the vincinity of the test * machine executing this test. The tests require manual interaction * as pairing and file transfer requests must be accepted. * The remote device's address must be passed * via the BT_TEST_DEVICE env variable. The remote device must be * discoverable and the object push service must be accessible. Any **/ QT_USE_NAMESPACE_BLUETOOTH typedef QMap tst_QBluetoothTransferManager_QParameterMap; Q_DECLARE_METATYPE(tst_QBluetoothTransferManager_QParameterMap) static const int MaxConnectTime = 60 * 1000; // 1 minute in ms class tst_QBluetoothTransferManager : public QObject { Q_OBJECT public: tst_QBluetoothTransferManager(); ~tst_QBluetoothTransferManager(); private slots: void initTestCase(); void tst_construction(); void tst_request_data(); void tst_request(); void tst_sendFile_data(); void tst_sendFile(); void tst_sendBuffer_data(); void tst_sendBuffer(); public slots: void serviceDiscovered(const QBluetoothServiceInfo &info); void finished(); void error(QBluetoothServiceDiscoveryAgent::Error error); private: bool done_discovery; QBluetoothAddress remoteAddress; QBluetoothAddress foundAddress; }; tst_QBluetoothTransferManager::tst_QBluetoothTransferManager() { qRegisterMetaType("QBluetoothTransferReply*"); } tst_QBluetoothTransferManager::~tst_QBluetoothTransferManager() { } void tst_QBluetoothTransferManager::initTestCase() { const QString remote = qgetenv("BT_TEST_DEVICE"); if (!remote.isEmpty()) { remoteAddress = QBluetoothAddress(remote); QVERIFY(!remoteAddress.isNull()); qWarning() << "Using remote device " << remote << " for testing. Ensure that the device is discoverable for pairing requests"; } else { qWarning() << "Not using any remote device for testing. Set BT_TEST_DEVICE env to run manual tests involving a remote device"; } if (!QBluetoothLocalDevice::allDevices().count()) QSKIP("Skipping test due to missing Bluetooth device"); if (remoteAddress.isNull()) QSKIP("Remote upload test not possible. Set BT_TEST_DEVICE"); // start Bluetooth if not started QBluetoothLocalDevice *device = new QBluetoothLocalDevice(); device->powerOn(); delete device; // Go find an echo server for BTADDRESS QBluetoothServiceDiscoveryAgent *sda = new QBluetoothServiceDiscoveryAgent(this); connect(sda, SIGNAL(serviceDiscovered(QBluetoothServiceInfo)), this, SLOT(serviceDiscovered(QBluetoothServiceInfo))); connect(sda, SIGNAL(error(QBluetoothServiceDiscoveryAgent::Error)), this, SLOT(error(QBluetoothServiceDiscoveryAgent::Error))); connect(sda, SIGNAL(finished()), this, SLOT(finished())); qDebug() << "Starting discovery"; done_discovery = false; sda->setUuidFilter(QBluetoothUuid(QBluetoothUuid::ObexObjectPush)); sda->start(QBluetoothServiceDiscoveryAgent::MinimalDiscovery); for (int connectTime = MaxConnectTime; !done_discovery && connectTime > 0; connectTime -= 1000) QTest::qWait(1000); sda->stop(); if (foundAddress.isNull()) QFAIL("Unable to find test service/device"); delete sda; } void tst_QBluetoothTransferManager::error(QBluetoothServiceDiscoveryAgent::Error error) { qDebug() << "Received error" << error; done_discovery = true; } void tst_QBluetoothTransferManager::finished() { qDebug() << "Finished"; done_discovery = true; } void tst_QBluetoothTransferManager::serviceDiscovered(const QBluetoothServiceInfo &info) { qDebug() << "Found: " << info.device().name() << info.device().address().toString() << info.serviceName(); if (info.device().address() == remoteAddress) { foundAddress = remoteAddress; done_discovery = true; } } void tst_QBluetoothTransferManager::tst_construction() { QBluetoothTransferManager *manager = new QBluetoothTransferManager(); QVERIFY(manager); delete manager; } void tst_QBluetoothTransferManager::tst_request_data() { QTest::addColumn("address"); QTest::addColumn >("parameters"); QMap inparameters; inparameters.insert(QBluetoothTransferRequest::DescriptionAttribute, "Description"); inparameters.insert(QBluetoothTransferRequest::LengthAttribute, QVariant(1024)); inparameters.insert(QBluetoothTransferRequest::TypeAttribute, "OPP"); inparameters.insert(QBluetoothTransferRequest::NameAttribute, "name"); inparameters.insert(QBluetoothTransferRequest::TimeAttribute, QDateTime::currentDateTime()); QTest::newRow("TESTDATA") << QBluetoothAddress("00:11:22:33:44:55:66") << inparameters; } void tst_QBluetoothTransferManager::tst_request() { QFETCH(QBluetoothAddress, address); QFETCH(tst_QBluetoothTransferManager_QParameterMap, parameters); QBluetoothTransferRequest transferRequest(address); foreach (QBluetoothTransferRequest::Attribute key, parameters.keys()) QCOMPARE(transferRequest.attribute(key), QVariant()); foreach (QBluetoothTransferRequest::Attribute key, parameters.keys()) transferRequest.setAttribute((QBluetoothTransferRequest::Attribute)key, parameters[key]); QCOMPARE(transferRequest.address(), address); foreach (QBluetoothTransferRequest::Attribute key, parameters.keys()) QCOMPARE(transferRequest.attribute(key), parameters[key]); //test copy constructor QBluetoothTransferRequest constructorCopy = transferRequest; QVERIFY(constructorCopy == transferRequest); QVERIFY(!(constructorCopy != transferRequest)); QCOMPARE(constructorCopy.address(), address); foreach (QBluetoothTransferRequest::Attribute key, parameters.keys()) QCOMPARE(constructorCopy.attribute(key), parameters[key]); //test assignment operator QBluetoothTransferRequest request; QVERIFY(request.address().isNull()); foreach (QBluetoothTransferRequest::Attribute key, parameters.keys()) QCOMPARE(request.attribute(key), QVariant()); request = transferRequest; QCOMPARE(request.address(), address); foreach (QBluetoothTransferRequest::Attribute key, parameters.keys()) QCOMPARE(request.attribute(key), parameters[key]); //test that it's a true and independent copy constructorCopy.setAttribute(QBluetoothTransferRequest::DescriptionAttribute, "newDescription"); request.setAttribute(QBluetoothTransferRequest::TypeAttribute, "FTP"); QCOMPARE(constructorCopy.attribute(QBluetoothTransferRequest::DescriptionAttribute).toString(),QString("newDescription")); QCOMPARE(request.attribute(QBluetoothTransferRequest::DescriptionAttribute).toString(),QString("Description")); QCOMPARE(transferRequest.attribute(QBluetoothTransferRequest::DescriptionAttribute).toString(),QString("Description")); QCOMPARE(constructorCopy.attribute(QBluetoothTransferRequest::TypeAttribute).toString(),QString("OPP")); QCOMPARE(request.attribute(QBluetoothTransferRequest::TypeAttribute).toString(),QString("FTP")); QCOMPARE(transferRequest.attribute(QBluetoothTransferRequest::TypeAttribute).toString(),QString("OPP")); } void tst_QBluetoothTransferManager::tst_sendFile_data() { QTest::addColumn("deviceAddress"); QTest::addColumn("expectSuccess"); QTest::addColumn("isInvalidFile"); if (foundAddress.isNull()) { qDebug("Skipping send file test due to not finding remote device"); } else { QTest::newRow("Push to remote test device") << foundAddress << true << false; QTest::newRow("Push of non-existing file") << foundAddress << false << true; } QTest::newRow("Push to invalid address") << QBluetoothAddress() << false << false; QTest::newRow("Push to non-existend device") << QBluetoothAddress("11:22:33:44:55:66") << false << false; } void tst_QBluetoothTransferManager::tst_sendFile() { QFETCH(QBluetoothAddress, deviceAddress); QFETCH(bool, expectSuccess); QFETCH(bool, isInvalidFile); QBluetoothLocalDevice dev; if (expectSuccess) { dev.requestPairing(deviceAddress, QBluetoothLocalDevice::Paired); QTest::qWait(2000); QCOMPARE(dev.pairingStatus(deviceAddress), QBluetoothLocalDevice::Paired); } QBluetoothTransferRequest request(deviceAddress); QCOMPARE(request.address(), deviceAddress); QBluetoothTransferManager manager; QString fileHandle; if (!isInvalidFile) { fileHandle = QFINDTESTDATA("testfile.txt"); QVERIFY(!fileHandle.isEmpty()); } else { fileHandle = QFINDTESTDATA("arbitraryFileName.txt"); //file doesn't exist QVERIFY(fileHandle.isEmpty()); } QFile f(fileHandle); QCOMPARE(f.exists(), !isInvalidFile); qDebug() << "Transferring file to " << deviceAddress.toString(); if (expectSuccess) qDebug() << "Please accept Object push request on remote device"; QBluetoothTransferReply* reply = manager.put(request, &f); QSignalSpy finishedSpy(reply, SIGNAL(finished(QBluetoothTransferReply*))); QSignalSpy progressSpy(reply, SIGNAL(transferProgress(qint64,qint64))); QCOMPARE(reply->request(), request); QVERIFY(reply->manager() == &manager); QVERIFY(!reply->isFinished()); QVERIFY(reply->isRunning()); const int maxWaitTime = 20 * 1000; //20s for (int time = 0; time0); if (expectSuccess) { QVERIFY(progressSpy.count()>0); QCOMPARE(reply->error(), QBluetoothTransferReply::NoError); QCOMPARE(reply->errorString(), QString()); } else { QVERIFY(progressSpy.count() == 0); if (isInvalidFile) QVERIFY(reply->error() == QBluetoothTransferReply::FileNotFoundError); else QVERIFY(reply->error() != QBluetoothTransferReply::NoError); QVERIFY(!reply->errorString().isEmpty()); } QVERIFY(reply->isFinished()); QVERIFY(!reply->isRunning()); } void tst_QBluetoothTransferManager::tst_sendBuffer_data() { QTest::addColumn("deviceAddress"); QTest::addColumn("expectSuccess"); QTest::addColumn("data"); if (foundAddress.isNull()) qDebug("Skipping send file test due to not finding remote device"); else QTest::newRow("Push to remote test device") << foundAddress << true << QByteArray("This is a very long byte arry which we are going to access via a QBuffer"); ; //QTest::newRow("Push to invalid address") << QBluetoothAddress() << false; //QTest::newRow("Push to non-existend device") << QBluetoothAddress("11:22:33:44:55:66") << false; } void tst_QBluetoothTransferManager::tst_sendBuffer() { QFETCH(QBluetoothAddress, deviceAddress); QFETCH(bool, expectSuccess); QFETCH(QByteArray, data); QBuffer buffer; buffer.setData(data); buffer.open(QIODevice::ReadOnly); buffer.seek(0); QBluetoothLocalDevice dev; if (expectSuccess) { dev.requestPairing(deviceAddress, QBluetoothLocalDevice::Paired); QTest::qWait(2000); QCOMPARE(dev.pairingStatus(deviceAddress), QBluetoothLocalDevice::Paired); } QBluetoothTransferRequest request(deviceAddress); QCOMPARE(request.address(), deviceAddress); QBluetoothTransferManager manager; qDebug() << "Transferring test buffer to " << deviceAddress.toString(); if (expectSuccess) qDebug() << "Please accept Object push request on remote device"; QBluetoothTransferReply* reply = manager.put(request, &buffer); QSignalSpy finishedSpy(reply, SIGNAL(finished(QBluetoothTransferReply*))); QSignalSpy progressSpy(reply, SIGNAL(transferProgress(qint64,qint64))); QCOMPARE(reply->request(), request); QVERIFY(reply->manager() == &manager); QVERIFY(!reply->isFinished()); QVERIFY(reply->isRunning()); const int maxWaitTime = 20 * 1000; //20s for (int time = 0; time0); if (expectSuccess) { QVERIFY(progressSpy.count()>0); QCOMPARE(reply->error(), QBluetoothTransferReply::NoError); QCOMPARE(reply->errorString(), QString()); } else { QVERIFY(progressSpy.count() == 0); QVERIFY(reply->error() != QBluetoothTransferReply::NoError); QVERIFY(!reply->errorString().isEmpty()); } QVERIFY(reply->isFinished()); QVERIFY(!reply->isRunning()); } QTEST_MAIN(tst_QBluetoothTransferManager) #include "tst_qbluetoothtransfermanager.moc"