From a354431ba0d8c057bd360c0b23565b650814ffc3 Mon Sep 17 00:00:00 2001 From: Alex Blasche Date: Mon, 30 Jun 2014 12:32:18 +0200 Subject: Rewrite QLowEnergyCharacteristic unit test This change incorporates the change from QLECharacteristicInfo to QLECharacteristic. Change-Id: I0fc6d31b60975e3b0cccc7666df9c0555350f40f Reviewed-by: Fabian Bumberger --- .../qlowenergycharacteristic.pro | 9 + .../tst_qlowenergycharacteristic.cpp | 299 +++++++++++++++++++++ 2 files changed, 308 insertions(+) create mode 100644 tests/auto/qlowenergycharacteristic/qlowenergycharacteristic.pro create mode 100644 tests/auto/qlowenergycharacteristic/tst_qlowenergycharacteristic.cpp (limited to 'tests/auto/qlowenergycharacteristic') diff --git a/tests/auto/qlowenergycharacteristic/qlowenergycharacteristic.pro b/tests/auto/qlowenergycharacteristic/qlowenergycharacteristic.pro new file mode 100644 index 00000000..33302d60 --- /dev/null +++ b/tests/auto/qlowenergycharacteristic/qlowenergycharacteristic.pro @@ -0,0 +1,9 @@ +SOURCES += tst_qlowenergycharacteristic.cpp +TARGET = tst_qlowenergycharacteristic +CONFIG += testcase + +QT = core bluetooth testlib +DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 +blackberry { + LIBS += -lbtapi +} diff --git a/tests/auto/qlowenergycharacteristic/tst_qlowenergycharacteristic.cpp b/tests/auto/qlowenergycharacteristic/tst_qlowenergycharacteristic.cpp new file mode 100644 index 00000000..0c0cdb31 --- /dev/null +++ b/tests/auto/qlowenergycharacteristic/tst_qlowenergycharacteristic.cpp @@ -0,0 +1,299 @@ +/*************************************************************************** +** +** Copyright (C) 2013 BlackBerry Limited all rights reserved +** 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 + +QT_USE_NAMESPACE + +class tst_QLowEnergyCharacteristic : public QObject +{ + Q_OBJECT + +public: + tst_QLowEnergyCharacteristic(); + ~tst_QLowEnergyCharacteristic(); + +protected slots: + void serviceDiscovered(const QLowEnergyServiceInfo &info); + +private slots: + void initTestCase(); + void cleanupTestCase(); + void tst_constructionDefault(); + void tst_assignCompare(); + +private: + QBluetoothServiceDiscoveryAgent *agent; + QSet remoteLeDevices; + QLowEnergyControllerNew *globalControl; + QLowEnergyService *globalService; +}; + +tst_QLowEnergyCharacteristic::tst_QLowEnergyCharacteristic() : + globalControl(0), globalService(0) +{ + QLoggingCategory::setFilterRules(QStringLiteral("qt.bluetooth* = true")); +} + +tst_QLowEnergyCharacteristic::~tst_QLowEnergyCharacteristic() +{ +} + +void tst_QLowEnergyCharacteristic::initTestCase() +{ + if (QBluetoothLocalDevice::allDevices().isEmpty()) { + qWarning("No remote device discovered."); + return; + } + + // start Bluetooth if not started + QBluetoothLocalDevice device; + device.powerOn(); + + // find an arbitrary low energy device in vincinity + // find an arbitrary service with characteristic + + QBluetoothServiceDiscoveryAgent * agent = new QBluetoothServiceDiscoveryAgent(this); + connect(agent, SIGNAL(serviceDiscovered(QLowEnergyServiceInfo)), + SLOT(serviceDiscovered(QLowEnergyServiceInfo))); + + QSignalSpy spy(agent, SIGNAL(finished())); + // there should be no changes yet + QVERIFY(spy.isValid()); + QVERIFY(spy.isEmpty()); + + agent->start(QBluetoothServiceDiscoveryAgent::FullDiscovery); + QTRY_VERIFY_WITH_TIMEOUT(spy.count() > 0, 50000); + + // find first service with descriptor + QLowEnergyControllerNew *controller = 0; + foreach (const QString &remoteDevice, remoteLeDevices.toList()) { + controller = new QLowEnergyControllerNew(QBluetoothAddress(remoteDevice), this); + qDebug() << "Connecting to" << remoteDevice; + controller->connectToDevice(); + QTRY_IMPL(controller->state() != QLowEnergyControllerNew::ConnectingState, + 10000); + if (controller->state() != QLowEnergyControllerNew::ConnectedState) { + // any error and we skip + delete controller; + qDebug() << "Skipping device"; + continue; + } + + QSignalSpy discoveryFinishedSpy(controller, SIGNAL(discoveryFinished())); + controller->discoverServices(); + QTRY_VERIFY_WITH_TIMEOUT(discoveryFinishedSpy.count() == 1, 10000); + foreach (const QBluetoothUuid &leServiceUuid, controller->services()) { + QLowEnergyService *leService = controller->createServiceObject(leServiceUuid, this); + if (!leService) + continue; + + leService->discoverDetails(); + QTRY_VERIFY_WITH_TIMEOUT( + leService->state() == QLowEnergyService::ServiceDiscovered, 10000); + + QList chars = leService->characteristics(); + foreach (const QLowEnergyCharacteristic &ch, chars) { + if (!ch.descriptors().isEmpty()) { + globalService = leService; + globalControl = controller; + qWarning() << "Found service with descriptor" << remoteDevice + << globalService->serviceName() << globalService->serviceUuid(); + break; + } + } + + if (globalControl) + break; + else + delete leService; + } + + if (globalControl) + break; + + delete controller; + } + + if (!globalControl) { + qWarning() << "Test limited due to missing remote QLowEnergyDescriptor." + << "Please ensure the Bluetooth Low Energy device is advertising its services."; + } +} + +void tst_QLowEnergyCharacteristic::cleanupTestCase() +{ + if (globalControl) + globalControl->disconnectFromDevice(); +} + +void tst_QLowEnergyCharacteristic::serviceDiscovered(const QLowEnergyServiceInfo &info) +{ + remoteLeDevices.insert(info.device().address().toString()); +} + +void tst_QLowEnergyCharacteristic::tst_constructionDefault() +{ + QLowEnergyCharacteristic characteristic; + QVERIFY(!characteristic.isValid()); + QCOMPARE(characteristic.value(), QByteArray()); + QVERIFY(characteristic.uuid().isNull()); + QVERIFY(characteristic.handle() == 0); + QCOMPARE(characteristic.name(), QString()); + QCOMPARE(characteristic.descriptors().count(), 0); + QCOMPARE(characteristic.properties(), QLowEnergyCharacteristic::Unknown); + + QLowEnergyCharacteristic copyConstructed(characteristic); + QVERIFY(!copyConstructed.isValid()); + QCOMPARE(copyConstructed.value(), QByteArray()); + QVERIFY(copyConstructed.uuid().isNull()); + QVERIFY(copyConstructed.handle() == 0); + QCOMPARE(copyConstructed.name(), QString()); + QCOMPARE(copyConstructed.descriptors().count(), 0); + QCOMPARE(copyConstructed.properties(), QLowEnergyCharacteristic::Unknown); + + QLowEnergyCharacteristic assigned; + assigned = characteristic; + QVERIFY(!assigned.isValid()); + QCOMPARE(assigned.value(), QByteArray()); + QVERIFY(assigned.uuid().isNull()); + QVERIFY(assigned.handle() == 0); + QCOMPARE(assigned.name(), QString()); + QCOMPARE(assigned.descriptors().count(), 0); + QCOMPARE(assigned.properties(), QLowEnergyCharacteristic::Unknown); +} + +void tst_QLowEnergyCharacteristic::tst_assignCompare() +{ + if (!globalService) + QSKIP("No characteristic found."); + + QLowEnergyCharacteristic target; + QVERIFY(!target.isValid()); + QCOMPARE(target.value(), QByteArray()); + QVERIFY(target.uuid().isNull()); + QVERIFY(target.handle() == 0); + QCOMPARE(target.name(), QString()); + QCOMPARE(target.descriptors().count(), 0); + QCOMPARE(target.properties(), QLowEnergyCharacteristic::Unknown); + + int indexWithDescriptor = -1; + const QList chars = globalService->characteristics(); + QVERIFY(!chars.isEmpty()); + for (int i = 0; i < chars.count(); i++) { + if (chars[i].descriptors().count() > 0) { + indexWithDescriptor = i; + break; + } + } + + if (chars.isEmpty()) + QSKIP("No suitable characteristic found despite prior indication."); + + bool noDescriptors = (indexWithDescriptor == -1); + if (noDescriptors) + indexWithDescriptor = 0; // just choose one + + // test assignment operator + target = chars[indexWithDescriptor]; + QVERIFY(target.isValid()); + QVERIFY(!target.name().isEmpty()); + QVERIFY(target.handle() > 0); + QVERIFY(!target.uuid().isNull()); + QVERIFY(target.properties() != QLowEnergyCharacteristic::Unknown); + if (target.properties() & QLowEnergyCharacteristic::Read) + QVERIFY(!target.value().isEmpty()); + if (!noDescriptors) + QVERIFY(target.descriptors().count() > 0); + + QCOMPARE(target.isValid(), chars[indexWithDescriptor].isValid()); + QCOMPARE(target.name(), chars[indexWithDescriptor].name()); + QCOMPARE(target.handle(), chars[indexWithDescriptor].handle()); + QCOMPARE(target.uuid(), chars[indexWithDescriptor].uuid()); + QCOMPARE(target.value(), chars[indexWithDescriptor].value()); + QCOMPARE(target.properties(), chars[indexWithDescriptor].properties()); + QCOMPARE(target.descriptors().count(), + chars[indexWithDescriptor].descriptors().count()); + for (int i = 0; i < target.descriptors().count(); i++) { + const QLowEnergyDescriptor ref = chars[indexWithDescriptor].descriptors()[i]; + QCOMPARE(target.descriptors()[i].name(), ref.name()); + QCOMPARE(target.descriptors()[i].isValid(), ref.isValid()); + QCOMPARE(target.descriptors()[i].type(), ref.type()); + QCOMPARE(target.descriptors()[i].handle(), ref.handle()); + QCOMPARE(target.descriptors()[i].uuid(), ref.uuid()); + QCOMPARE(target.descriptors()[i].value(), ref.value()); + } + + // test copy constructor + QLowEnergyCharacteristic copyConstructed(target); + QCOMPARE(copyConstructed.isValid(), chars[indexWithDescriptor].isValid()); + QCOMPARE(copyConstructed.name(), chars[indexWithDescriptor].name()); + QCOMPARE(copyConstructed.handle(), chars[indexWithDescriptor].handle()); + QCOMPARE(copyConstructed.uuid(), chars[indexWithDescriptor].uuid()); + QCOMPARE(copyConstructed.value(), chars[indexWithDescriptor].value()); + QCOMPARE(copyConstructed.properties(), chars[indexWithDescriptor].properties()); + QCOMPARE(copyConstructed.descriptors().count(), + chars[indexWithDescriptor].descriptors().count()); + + // test invalidation + QLowEnergyCharacteristic invalid; + target = invalid; + QVERIFY(!target.isValid()); + QCOMPARE(target.value(), QByteArray()); + QVERIFY(target.uuid().isNull()); + QVERIFY(target.handle() == 0); + QCOMPARE(target.name(), QString()); + QCOMPARE(target.descriptors().count(), 0); + QCOMPARE(target.properties(), QLowEnergyCharacteristic::Unknown); +} + +QTEST_MAIN(tst_QLowEnergyCharacteristic) + +#include "tst_qlowenergycharacteristic.moc" -- cgit v1.2.3