diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 1d5a9230c5873453fb57411c4b49b42ed5a76e6f..290a6e5f60c549244f327b0d147d62df46a0341a 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -669,7 +669,8 @@ HEADERS += \ src/qgcunittest/TCPLinkTest.h \ src/qgcunittest/TCPLoopBackServer.h \ src/qgcunittest/QGCUASFileManagerTest.h \ - src/qgcunittest/PX4RCCalibrationTest.h + src/qgcunittest/PX4RCCalibrationTest.h \ + src/qgcunittest/LinkManagerTest.h SOURCES += \ src/qgcunittest/UASUnitTest.cc \ @@ -684,8 +685,8 @@ SOURCES += \ src/qgcunittest/TCPLinkTest.cc \ src/qgcunittest/TCPLoopBackServer.cc \ src/qgcunittest/QGCUASFileManagerTest.cc \ - src/qgcunittest/PX4RCCalibrationTest.cc - + src/qgcunittest/PX4RCCalibrationTest.cc \ + src/qgcunittest/LinkManagerTest.cc } # diff --git a/src/qgcunittest/LinkManagerTest.cc b/src/qgcunittest/LinkManagerTest.cc index 98d369212e4c8ec5173ff4631a5328cf01a9fc7a..fac38c407d4b264ace3b6c6064396c3ab4b85773 100644 --- a/src/qgcunittest/LinkManagerTest.cc +++ b/src/qgcunittest/LinkManagerTest.cc @@ -1,409 +1,142 @@ -#include "UASUnitTest.h" -#include -#include -#include - -UASUnitTest::UASUnitTest() -{ -} -//This function is called after every test -void UASUnitTest::init() -{ - mav = new MAVLinkProtocol(); - uas = new UAS(mav, QThread::currentThread(), UASID); - uas->deleteSettings(); -} -//this function is called after every test -void UASUnitTest::cleanup() -{ - delete uas; - uas = NULL; - - delete mav; - mav = NULL; -} - -void UASUnitTest::getUASID_test() -{ - // Test a default ID of zero is assigned - UAS* uas2 = new UAS(mav, QThread::currentThread()); - QCOMPARE(uas2->getUASID(), 0); - delete uas2; - - // Test that the chosen ID was assigned at construction - QCOMPARE(uas->getUASID(), UASID); - - // Make sure that no other ID was set - QEXPECT_FAIL("", "When you set an ID it does not use the default ID of 0", Continue); - QCOMPARE(uas->getUASID(), 0); - - // Make sure that ID >= 0 - QCOMPARE(uas->getUASID(), 100); - -} - -void UASUnitTest::getUASName_test() -{ - // Test that the name is build as MAV + ID - QCOMPARE(uas->getUASName(), "MAV " + QString::number(UASID)); - -} - -void UASUnitTest::getUpTime_test() -{ - UAS* uas2 = new UAS(mav, QThread::currentThread()); - // Test that the uptime starts at zero to a - // precision of seconds - QCOMPARE(floor(uas2->getUptime()/1000.0), 0.0); - - // Sleep for three seconds - QTest::qSleep(3000); - - // Test that the up time is computed correctly to a - // precision of seconds - QCOMPARE(floor(uas2->getUptime()/1000.0), 3.0); - - delete uas2; -} - -void UASUnitTest::getCommunicationStatus_test() -{ - // Verify that upon construction the Comm status is disconnected - QCOMPARE(uas->getCommunicationStatus(), static_cast(UASInterface::COMM_DISCONNECTED)); -} - -void UASUnitTest::filterVoltage_test() -{ - float verificar=uas->filterVoltage(0.4f); - - // We allow the voltage returned to be within a small delta - const float allowedDelta = 0.05f; - const float desiredVoltage = 7.36f; - QVERIFY(verificar > (desiredVoltage - allowedDelta) && verificar < (desiredVoltage + allowedDelta)); -} - -void UASUnitTest:: getAutopilotType_test() -{ - int type = uas->getAutopilotType(); - // Verify that upon construction the autopilot is set to -1 - QCOMPARE(type, -1); -} - -void UASUnitTest::setAutopilotType_test() -{ - uas->setAutopilotType(2); - // Verify that the autopilot is set - QCOMPARE(uas->getAutopilotType(), 2); -} - -//verify that the correct status is returned if a certain statue is given to uas -void UASUnitTest::getStatusForCode_test() -{ - QString state, desc; - state = ""; - desc = ""; - - uas->getStatusForCode(MAV_STATE_UNINIT, state, desc); - QVERIFY(state == "UNINIT"); - - uas->getStatusForCode(MAV_STATE_UNINIT, state, desc); - QVERIFY(state == "UNINIT"); - - uas->getStatusForCode(MAV_STATE_BOOT, state, desc); - QVERIFY(state == "BOOT"); - - uas->getStatusForCode(MAV_STATE_CALIBRATING, state, desc); - QVERIFY(state == "CALIBRATING"); - - uas->getStatusForCode(MAV_STATE_ACTIVE, state, desc); - QVERIFY(state == "ACTIVE"); - - uas->getStatusForCode(MAV_STATE_STANDBY, state, desc); - QVERIFY(state == "STANDBY"); - - uas->getStatusForCode(MAV_STATE_CRITICAL, state, desc); - QVERIFY(state == "CRITICAL"); - - uas->getStatusForCode(MAV_STATE_EMERGENCY, state, desc); - QVERIFY(state == "EMERGENCY"); - - uas->getStatusForCode(MAV_STATE_POWEROFF, state, desc); - QVERIFY(state == "SHUTDOWN"); - - uas->getStatusForCode(5325, state, desc); - QVERIFY(state == "UNKNOWN"); -} - -void UASUnitTest::getLocalX_test() -{ - QCOMPARE(uas->getLocalX(), 0.0); -} -void UASUnitTest::getLocalY_test() -{ - QCOMPARE(uas->getLocalY(), 0.0); -} -void UASUnitTest::getLocalZ_test() -{ - QCOMPARE(uas->getLocalZ(), 0.0); -} -void UASUnitTest::getLatitude_test() -{ - QCOMPARE(uas->getLatitude(), 0.0); -} -void UASUnitTest::getLongitude_test() -{ - QCOMPARE(uas->getLongitude(), 0.0); -} -void UASUnitTest::getAltitudeAMSL_test() -{ - QCOMPARE(uas->getAltitudeAMSL(), 0.0); -} -void UASUnitTest::getAltitudeRelative_test() -{ - QCOMPARE(uas->getAltitudeRelative(), 0.0); -} -void UASUnitTest::getRoll_test() -{ - QCOMPARE(uas->getRoll(), 0.0); -} -void UASUnitTest::getPitch_test() -{ - QCOMPARE(uas->getPitch(), 0.0); -} -void UASUnitTest::getYaw_test() -{ - QCOMPARE(uas->getYaw(), 0.0); -} - -void UASUnitTest::getSelected_test() -{ - QCOMPARE(uas->getSelected(), false); -} - -void UASUnitTest::getSystemType_test() -{ //check that system type is set to MAV_TYPE_GENERIC when initialized - QCOMPARE(uas->getSystemType(), 0); - uas->setSystemType(13); - QCOMPARE(uas->getSystemType(), 13); -} - -void UASUnitTest::getAirframe_test() -{ - //when uas is constructed, airframe is set to QGC_AIRFRAME_GENERIC - QVERIFY(uas->getAirframe() == UASInterface::QGC_AIRFRAME_GENERIC); -} - -void UASUnitTest::setAirframe_test() -{ - //check at construction, that airframe=0 (GENERIC) - QVERIFY(uas->getAirframe() == UASInterface::QGC_AIRFRAME_GENERIC); - - //check that set airframe works - uas->setAirframe(UASInterface::QGC_AIRFRAME_HEXCOPTER); - QVERIFY(uas->getAirframe() == UASInterface::QGC_AIRFRAME_HEXCOPTER); - - //check that setAirframe will not assign a number to airframe, that is - //not defined in the enum - uas->setAirframe(UASInterface::QGC_AIRFRAME_END_OF_ENUM); - QVERIFY(uas->getAirframe() == UASInterface::QGC_AIRFRAME_HEXCOPTER); -} - -void UASUnitTest::getWaypointList_test() -{ - QList kk = uas->getWaypointManager()->getWaypointEditableList(); - QCOMPARE(kk.count(), 0); - - Waypoint* wp = new Waypoint(0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,false, false, MAV_FRAME_GLOBAL, MAV_CMD_MISSION_START, "blah"); - uas->getWaypointManager()->addWaypointEditable(wp, true); - - kk = uas->getWaypointManager()->getWaypointEditableList(); - QCOMPARE(kk.count(), 1); - - wp = new Waypoint(); - uas->getWaypointManager()->addWaypointEditable(wp, false); - - kk = uas->getWaypointManager()->getWaypointEditableList(); - QCOMPARE(kk.count(), 2); - - uas->getWaypointManager()->removeWaypoint(1); - kk = uas->getWaypointManager()->getWaypointEditableList(); - QCOMPARE(kk.count(), 1); - - uas->getWaypointManager()->removeWaypoint(0); - kk = uas->getWaypointManager()->getWaypointEditableList(); - QCOMPARE(kk.count(), 0); - - qDebug()<<"disconnect SIGNAL waypointListChanged"; - -} - -void UASUnitTest::getWaypoint_test() -{ - Waypoint* wp = new Waypoint(0,5.6,2.0,3.0,0.0,0.0,0.0,0.0,false, false, MAV_FRAME_GLOBAL, MAV_CMD_MISSION_START, "blah"); - - uas->getWaypointManager()->addWaypointEditable(wp, true); - - QList wpList = uas->getWaypointManager()->getWaypointEditableList(); - - QCOMPARE(wpList.count(), 1); - QCOMPARE(static_cast(0), static_cast(wpList.at(0))->getId()); - - Waypoint* wp3 = new Waypoint(1, 5.6, 2.0, 3.0); - uas->getWaypointManager()->addWaypointEditable(wp3, true); - wpList = uas->getWaypointManager()->getWaypointEditableList(); - Waypoint* wp2 = static_cast(wpList.at(0)); - - QCOMPARE(wpList.count(), 2); - QCOMPARE(wp3->getX(), wp2->getX()); - QCOMPARE(wp3->getY(), wp2->getY()); - QCOMPARE(wp3->getZ(), wp2->getZ()); - QCOMPARE(wpList.at(1)->getId(), static_cast(1)); - QCOMPARE(wp3->getFrame(), MAV_FRAME_GLOBAL); - QCOMPARE(wp3->getFrame(), wp2->getFrame()); - - delete wp3; - delete wp; -} - -void UASUnitTest::signalWayPoint_test() -{ - QSignalSpy spy(uas->getWaypointManager(), SIGNAL(waypointEditableListChanged())); - - Waypoint* wp = new Waypoint(0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,false, false, MAV_FRAME_GLOBAL, MAV_CMD_MISSION_START, "blah"); - uas->getWaypointManager()->addWaypointEditable(wp, true); - - QCOMPARE(spy.count(), 1); // 1 listChanged for add wayPoint - uas->getWaypointManager()->removeWaypoint(0); - QCOMPARE(spy.count(), 2); // 2 listChanged for remove wayPoint - - QSignalSpy spyDestroyed(uas->getWaypointManager(), SIGNAL(destroyed())); - QVERIFY(spyDestroyed.isValid()); - QCOMPARE( spyDestroyed.count(), 0 ); - - delete uas;// delete(destroyed) uas for validating - uas = NULL; - QCOMPARE(spyDestroyed.count(), 1);// count destroyed uas should are 1 - uas = new UAS(mav, QThread::currentThread(), UASID); - QSignalSpy spy2(uas->getWaypointManager(), SIGNAL(waypointEditableListChanged())); - QCOMPARE(spy2.count(), 0); - Waypoint* wp2 = new Waypoint(0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,false, false, MAV_FRAME_GLOBAL, MAV_CMD_MISSION_START, "blah"); - - uas->getWaypointManager()->addWaypointEditable(wp2, true); - QCOMPARE(spy2.count(), 1); - - uas->getWaypointManager()->clearWaypointList(); - QList wpList = uas->getWaypointManager()->getWaypointEditableList(); - QCOMPARE(wpList.count(), 1); - delete uas; - uas = NULL; - delete wp2; -} - -void UASUnitTest::signalUASLink_test() -{ - QSignalSpy spy(uas, SIGNAL(modeChanged(int,QString,QString))); - uas->setMode(2, 0); - QCOMPARE(spy.count(), 0);// not solve for UAS not receiving message from UAS - - QSignalSpy spyS(LinkManager::instance(), SIGNAL(newLink(LinkInterface*))); - SerialLink* link = new SerialLink(); - - LinkManager::instance()->add(link); - LinkManager::instance()->addProtocol(link, mav); - QCOMPARE(spyS.count(), 1); - - LinkManager::instance()->add(link); - LinkManager::instance()->addProtocol(link, mav); - QCOMPARE(spyS.count(), 1);// not add SerialLink, exist in list - - SerialLink* link2 = new SerialLink(); - LinkManager::instance()->add(link2); - LinkManager::instance()->addProtocol(link2, mav); - QCOMPARE(spyS.count(), 2);// add SerialLink, not exist in list - - QList links = LinkManager::instance()->getLinks(); - foreach(LinkInterface* link, links) - { - qDebug()<< link->getName(); - qDebug()<< QString::number(link->getId()); - QVERIFY(link != NULL); - uas->addLink(link); - } - - SerialLink* ff = static_cast(uas->getLinks()->at(0)); - - QCOMPARE(ff->isConnected(), false); - - QCOMPARE(ff->isRunning(), false); - - QCOMPARE(ff->isFinished(), false); - - QCOMPARE(links.count(), uas->getLinks()->count()); - QCOMPARE(uas->getLinks()->count(), 2); - - delete link2; - QCOMPARE(LinkManager::instance()->getLinks().count(), 1); - QCOMPARE(uas->getLinks()->count(), 1); - - QCOMPARE(static_cast(LinkManager::instance()->getLinks().at(0))->getId(), - static_cast(uas->getLinks()->at(0))->getId()); - - SerialLink* link3 = new SerialLink(); - LinkManager::instance()->add(link3); - LinkManager::instance()->addProtocol(link3, mav); - QCOMPARE(spyS.count(), 3); - QCOMPARE(LinkManager::instance()->getLinks().count(), 2); - - //all the links in LinkManager must be deleted because LinkManager::instance - //is static. - delete link3; - QCOMPARE(LinkManager::instance()->getLinks().count(), 1); - delete link; - - QCOMPARE(LinkManager::instance()->getLinks().count(), 0); -} - -void UASUnitTest::signalIdUASLink_test() -{ - - QCOMPARE(LinkManager::instance()->getLinks().count(), 0); - SerialLink* myLink = new SerialLink(); - myLink->setPortName("COM 17"); - LinkManager::instance()->add(myLink); - LinkManager::instance()->addProtocol(myLink, mav); - - SerialLink* myLink2 = new SerialLink(); - myLink2->setPortName("COM 18"); - LinkManager::instance()->add(myLink2); - LinkManager::instance()->addProtocol(myLink2, mav); - - SerialLink* myLink3 = new SerialLink(); - myLink3->setPortName("COM 19"); - LinkManager::instance()->add(myLink3); - LinkManager::instance()->addProtocol(myLink3, mav); - - SerialLink* myLink4 = new SerialLink(); - myLink4->setPortName("COM 20"); - LinkManager::instance()->add(myLink4); - LinkManager::instance()->addProtocol(myLink4, mav); - - QCOMPARE(LinkManager::instance()->getLinks().count(), 4); - - QList links = LinkManager::instance()->getLinks(); - - LinkInterface* a = static_cast(links.at(0)); - LinkInterface* b = static_cast(links.at(1)); - LinkInterface* c = static_cast(links.at(2)); - LinkInterface* d = static_cast(links.at(3)); - QCOMPARE(a->getName(), QString("COM 17")); - QCOMPARE(b->getName(), QString("COM 18")); - QCOMPARE(c->getName(), QString("COM 19")); - QCOMPARE(d->getName(), QString("COM 20")); - - delete myLink4; - delete myLink3; - delete myLink2; - delete myLink; - - QCOMPARE(LinkManager::instance()->getLinks().count(), 0); +/*===================================================================== + + QGroundControl Open Source Ground Control Station + + (c) 2009 - 2014 QGROUNDCONTROL PROJECT + + This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QGROUNDCONTROL. If not, see . + + ======================================================================*/ + +/// @file +/// @brief LinkManager Unit Test +/// +/// @author Don Gagne + +#include "LinkManagerTest.h" +#include "MockLink.h" + +LinkManagerTest::LinkManagerTest(void) : + _linkMgr(NULL), + _multiSpy(NULL) +{ + +} + +void LinkManagerTest::init(void) +{ + Q_ASSERT(_linkMgr == NULL); + Q_ASSERT(_multiSpy == NULL); + + _linkMgr = new LinkManager(NULL /* no parent */, false /* don't register singleton */); + Q_CHECK_PTR(_linkMgr); + + _rgSignals[newLinkSignalIndex] = SIGNAL(newLink(LinkInterface*)); + _rgSignals[linkDeletedSignalIndex] = SIGNAL(linkDeleted(LinkInterface*)); + + _multiSpy = new MultiSignalSpy(); + QCOMPARE(_multiSpy->init(_linkMgr, _rgSignals, _cSignals), true); +} + +void LinkManagerTest::cleanup(void) +{ + Q_ASSERT(_linkMgr); + Q_ASSERT(_multiSpy); + + delete _linkMgr; + delete _multiSpy; + + _linkMgr = NULL; + _multiSpy = NULL; +} + + +void LinkManagerTest::_instance_test(void) +{ + LinkManager *linkManager = new LinkManager(NULL /* no parent */, false /* don't register singleton */); + + // If the flag to not register singleton is not working this will cause QGCApplication to crash on + // desctrucion since it will try to de-reference a deleted singleton. + delete linkManager; +} + +void LinkManagerTest::_add_test(void) +{ + Q_ASSERT(_linkMgr); + Q_ASSERT(_linkMgr->getLinks().count() == 0); + + MockLink* link = new MockLink(); + _linkMgr->add(link); + + QList links = _linkMgr->getLinks(); + QCOMPARE(links.count(), 1); + QCOMPARE(dynamic_cast(links[0]), link); +} + +void LinkManagerTest::_delete_test(void) +{ + Q_ASSERT(_linkMgr); + Q_ASSERT(_linkMgr->getLinks().count() == 0); + + MockLink* link = new MockLink(); + _linkMgr->add(link); + _linkMgr->deleteLink(link); + + QCOMPARE(_linkMgr->getLinks().count(), 0); +} + +void LinkManagerTest::_addSignals_test(void) +{ + Q_ASSERT(_linkMgr); + Q_ASSERT(_linkMgr->getLinks().count() == 0); + Q_ASSERT(_multiSpy->checkNoSignals() == true); + + MockLink* link = new MockLink(); + _linkMgr->add(link); + + QCOMPARE(_multiSpy->checkOnlySignalByMask(newLinkSignalMask), true); + QSignalSpy* spy = _multiSpy->getSpyByIndex(newLinkSignalIndex); + + // Check signal argument + QList signalArgs = spy->takeFirst(); + QCOMPARE(signalArgs.count(), 1); + QObject* object = qvariant_cast(signalArgs[0]); + QVERIFY(object != NULL); + MockLink* signalLink = qobject_cast(object); + QCOMPARE(signalLink, link); +} + +void LinkManagerTest::_deleteSignals_test(void) +{ + Q_ASSERT(_linkMgr); + Q_ASSERT(_linkMgr->getLinks().count() == 0); + Q_ASSERT(_multiSpy->checkNoSignals() == true); + + MockLink* link = new MockLink(); + _linkMgr->add(link); + _multiSpy->clearAllSignals(); + + _linkMgr->deleteLink(link); + + QCOMPARE(_multiSpy->checkOnlySignalByMask(linkDeletedSignalMask), true); + QSignalSpy* spy = _multiSpy->getSpyByIndex(linkDeletedSignalIndex); + + // Best we can do is check the argument count. We can't check the contents of signal argument + // because the object has been deleted and any access to the variant to try to cast it back + // to MockLink* will cause the link to be de-referenced and hence crash. + QList signalArgs = spy->takeFirst(); + QCOMPARE(signalArgs.count(), 1); } diff --git a/src/qgcunittest/LinkManagerTest.h b/src/qgcunittest/LinkManagerTest.h index f636f8f9f7a123ab8e7182aad8f35c16fae8d24a..d388f3c375fa43b2f5b569f874dd9a391f6bd2cc 100644 --- a/src/qgcunittest/LinkManagerTest.h +++ b/src/qgcunittest/LinkManagerTest.h @@ -25,15 +25,17 @@ #define UASUNITTEST_H #include +#include +#include "AutoTest.h" #include "LinkManager.h" +#include "MultiSignalSpy.h" /// @file /// @brief LinkManager Unit Test /// /// @author Don Gagne - class LinkManagerTest : public QObject { Q_OBJECT @@ -42,13 +44,32 @@ public: LinkManagerTest(void); private slots: - void initTestCase(void); void init(void); void cleanup(void); - void _setUAS_test(void); - void _minRCChannels_test(void); - void _fullCalibration_test(void); + void _instance_test(void); + void _add_test(void); + void _delete_test(void); + void _addSignals_test(void); + void _deleteSignals_test(void); + +private: + enum { + newLinkSignalIndex = 0, + linkDeletedSignalIndex, + maxSignalIndex + }; + + enum { + newLinkSignalMask = 1 << newLinkSignalIndex, + linkDeletedSignalMask = 1 << linkDeletedSignalIndex, + }; + + LinkManager* _linkMgr; + MultiSignalSpy* _multiSpy; + static const size_t _cSignals = maxSignalIndex; + const char* _rgSignals[_cSignals]; + }; DECLARE_TEST(LinkManagerTest)