| /**************************************************************************** |
| ** |
| ** Copyright (C) 2016 The Qt Company Ltd. |
| ** Contact: https://www.qt.io/licensing/ |
| ** |
| ** This file is part of the QtBluetooth module of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ |
| ** 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 The Qt Company. For licensing terms |
| ** and conditions see https://www.qt.io/terms-conditions. For further |
| ** information use the contact form at https://www.qt.io/contact-us. |
| ** |
| ** GNU General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU |
| ** General Public License version 3 as published by the Free Software |
| ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
| ** included in the packaging of this file. Please review the following |
| ** information to ensure the GNU General Public License requirements will |
| ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
| ** |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| #include <QtTest/QtTest> |
| |
| #include <QDebug> |
| #include <QMap> |
| #include <QTextStream> |
| |
| #include <qbluetoothtransferrequest.h> |
| #include <qbluetoothtransfermanager.h> |
| #include <qbluetoothtransferreply.h> |
| #include <qbluetoothaddress.h> |
| #include <qbluetoothlocaldevice.h> |
| |
| #include <qbluetoothdeviceinfo.h> |
| #include <qbluetoothserviceinfo.h> |
| #include <qbluetoothservicediscoveryagent.h> |
| |
| /* |
| * 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 |
| |
| typedef QMap<QBluetoothTransferRequest::Attribute,QVariant> 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(); |
| |
| void tst_sendNullPointer(); |
| private: |
| QBluetoothAddress remoteAddress; |
| }; |
| |
| tst_QBluetoothTransferManager::tst_QBluetoothTransferManager() |
| { |
| } |
| |
| 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"; |
| QSKIP("Remote upload test not possible. Set BT_TEST_DEVICE"); |
| } |
| |
| if (!QBluetoothLocalDevice::allDevices().count()) |
| QSKIP("Skipping test due to missing Bluetooth device"); |
| |
| // start Bluetooth if not started |
| QBluetoothLocalDevice *device = new QBluetoothLocalDevice(); |
| device->powerOn(); |
| delete device; |
| } |
| |
| void tst_QBluetoothTransferManager::tst_construction() |
| { |
| QBluetoothTransferManager *manager = new QBluetoothTransferManager(); |
| |
| QVERIFY(manager); |
| delete manager; |
| } |
| |
| void tst_QBluetoothTransferManager::tst_request_data() |
| { |
| QTest::addColumn<QBluetoothAddress>("address"); |
| QTest::addColumn<QMap<QBluetoothTransferRequest::Attribute, QVariant> >("parameters"); |
| |
| QMap<QBluetoothTransferRequest::Attribute, QVariant> 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); |
| const QList<QBluetoothTransferRequest::Attribute> attributes = parameters.keys(); |
| for (QBluetoothTransferRequest::Attribute key : attributes) |
| QCOMPARE(transferRequest.attribute(key), QVariant()); |
| |
| for (QBluetoothTransferRequest::Attribute key : attributes) |
| transferRequest.setAttribute((QBluetoothTransferRequest::Attribute)key, parameters[key]); |
| |
| QCOMPARE(transferRequest.address(), address); |
| for (QBluetoothTransferRequest::Attribute key : attributes) |
| QCOMPARE(transferRequest.attribute(key), parameters[key]); |
| |
| //test copy constructor |
| QBluetoothTransferRequest constructorCopy = transferRequest; |
| QVERIFY(constructorCopy == transferRequest); |
| QVERIFY(!(constructorCopy != transferRequest)); |
| QCOMPARE(constructorCopy.address(), address); |
| for (QBluetoothTransferRequest::Attribute key : attributes) |
| QCOMPARE(constructorCopy.attribute(key), parameters[key]); |
| |
| //test assignment operator |
| QBluetoothTransferRequest request; |
| QVERIFY(request.address().isNull()); |
| for (QBluetoothTransferRequest::Attribute key : attributes) |
| QCOMPARE(request.attribute(key), QVariant()); |
| request = transferRequest; |
| QCOMPARE(request.address(), address); |
| for (QBluetoothTransferRequest::Attribute key : attributes) |
| 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<QBluetoothAddress>("deviceAddress"); |
| QTest::addColumn<bool>("expectSuccess"); |
| QTest::addColumn<bool>("isInvalidFile"); |
| |
| QTest::newRow("Push to remote test device") << remoteAddress << true << false; |
| QTest::newRow("Push of non-existing file") << remoteAddress << 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(5000); |
| 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 = ("arbitraryFileName.txt"); //file doesn't exist |
| } |
| 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))); |
| QSignalSpy errorSpy(reply, SIGNAL(error(QBluetoothTransferReply::TransferError))); |
| |
| QCOMPARE(reply->request(), request); |
| QVERIFY(reply->manager() == &manager); |
| QVERIFY(!reply->isFinished()); |
| QVERIFY(reply->isRunning()); |
| |
| const int maxWaitTime = 20 * 1000; //20s |
| for (int time = 0; |
| time<maxWaitTime && (finishedSpy.count()==0); |
| time+=1000) { |
| QTest::qWait(1000); //if interval |
| } |
| |
| QVERIFY(finishedSpy.count()>0); |
| if (expectSuccess) { |
| QVERIFY(progressSpy.count()>0); |
| QCOMPARE(reply->error(), QBluetoothTransferReply::NoError); |
| QCOMPARE(reply->errorString(), QString()); |
| QVERIFY(errorSpy.isEmpty()); |
| } else { |
| QVERIFY(progressSpy.count() == 0); |
| if (isInvalidFile) |
| QVERIFY(reply->error() == QBluetoothTransferReply::FileNotFoundError); |
| else |
| QVERIFY(reply->error() != QBluetoothTransferReply::NoError); |
| QVERIFY(!reply->errorString().isEmpty()); |
| QCOMPARE(errorSpy.count(), 1); |
| } |
| |
| QVERIFY(reply->isFinished()); |
| QVERIFY(!reply->isRunning()); |
| } |
| |
| void tst_QBluetoothTransferManager::tst_sendBuffer_data() |
| { |
| |
| QTest::addColumn<QBluetoothAddress>("deviceAddress"); |
| QTest::addColumn<bool>("expectSuccess"); |
| QTest::addColumn<QByteArray>("data"); |
| |
| QTest::newRow("Push to remote test device") << remoteAddress << true << |
| QByteArray("This is a very long byte array which we are going to access via a QBuffer"); ; |
| QTest::newRow("Push to invalid address") << QBluetoothAddress() << false << QByteArray("test"); |
| QTest::newRow("Push to non-existend device") << QBluetoothAddress("11:22:33:44:55:66") << false << QByteArray("test"); |
| } |
| |
| |
| |
| 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))); |
| QSignalSpy errorSpy(reply, SIGNAL(error(QBluetoothTransferReply::TransferError))); |
| |
| QCOMPARE(reply->request(), request); |
| QVERIFY(reply->manager() == &manager); |
| QVERIFY(!reply->isFinished()); |
| QVERIFY(reply->isRunning()); |
| |
| const int maxWaitTime = 20 * 1000; //20s |
| for (int time = 0; |
| time<maxWaitTime && (finishedSpy.count()==0); |
| time+=10000) { |
| QTest::qWait(10000); //if interval |
| } |
| |
| QVERIFY(finishedSpy.count()>0); |
| if (expectSuccess) { |
| QVERIFY(progressSpy.count()>0); |
| QVERIFY(errorSpy.isEmpty()); |
| QCOMPARE(reply->error(), QBluetoothTransferReply::NoError); |
| QCOMPARE(reply->errorString(), QString()); |
| } else { |
| QVERIFY(progressSpy.count() == 0); |
| QVERIFY(reply->error() != QBluetoothTransferReply::NoError); |
| QVERIFY(!reply->errorString().isEmpty()); |
| QCOMPARE(errorSpy.count(), 1); |
| } |
| |
| QVERIFY(reply->isFinished()); |
| QVERIFY(!reply->isRunning()); |
| } |
| |
| void tst_QBluetoothTransferManager::tst_sendNullPointer() |
| { |
| QBluetoothTransferRequest request(remoteAddress); |
| QBluetoothTransferManager manager; |
| QBluetoothTransferReply *reply = manager.put(request, 0); |
| |
| QVERIFY(reply); |
| QCOMPARE(reply->isFinished(), true); |
| QCOMPARE(reply->isRunning(), false); |
| QCOMPARE(reply->manager(), &manager); |
| QCOMPARE(reply->request(), request); |
| QCOMPARE(reply->error(), QBluetoothTransferReply::FileNotFoundError); |
| } |
| |
| QTEST_MAIN(tst_QBluetoothTransferManager) |
| |
| #include "tst_qbluetoothtransfermanager.moc" |