From 496b8297a7354951b38421de6b55ddf8ad79a307 Mon Sep 17 00:00:00 2001 From: Don Gagne Date: Wed, 3 Dec 2014 10:33:12 -0800 Subject: [PATCH] New Mavlink Log collection unit test --- qgroundcontrol.pro | 6 +- src/qgcunittest/MavlinkLogTest.cc | 210 ++++++++++++++++++++++++++++++ src/qgcunittest/MavlinkLogTest.h | 57 ++++++++ src/qgcunittest/MockLink.cc | 1 + 4 files changed, 272 insertions(+), 2 deletions(-) create mode 100644 src/qgcunittest/MavlinkLogTest.cc create mode 100644 src/qgcunittest/MavlinkLogTest.h diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index d63cc0f6e..638f3855e 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -654,7 +654,8 @@ HEADERS += \ src/qgcunittest/PX4RCCalibrationTest.h \ src/qgcunittest/LinkManagerTest.h \ src/qgcunittest/MainWindowTest.h \ - src/AutoPilotPlugins/PX4/Tests/FlightModeConfigTest.h + src/AutoPilotPlugins/PX4/Tests/FlightModeConfigTest.h \ + src/qgcunittest/MavlinkLogTest.h SOURCES += \ src/qgcunittest/UnitTest.cc \ @@ -675,7 +676,8 @@ SOURCES += \ src/qgcunittest/PX4RCCalibrationTest.cc \ src/qgcunittest/LinkManagerTest.cc \ src/qgcunittest/MainWindowTest.cc \ - src/AutoPilotPlugins/PX4/Tests/FlightModeConfigTest.cc + src/AutoPilotPlugins/PX4/Tests/FlightModeConfigTest.cc \ + src/qgcunittest/MavlinkLogTest.cc } # diff --git a/src/qgcunittest/MavlinkLogTest.cc b/src/qgcunittest/MavlinkLogTest.cc new file mode 100644 index 000000000..d04d4994f --- /dev/null +++ b/src/qgcunittest/MavlinkLogTest.cc @@ -0,0 +1,210 @@ +/*===================================================================== + + 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 Test for mavlink log collection +/// +/// @author Don Gagne + +#include "MavlinkLogTest.h" +#include "MainWindow.h" +#include "MockLink.h" + +UT_REGISTER_TEST(MavlinkLogTest) + +const char* MavlinkLogTest::_tempLogFileTemplate = "FlightDataXXXXXX"; ///< Template for temporary log file +const char* MavlinkLogTest::_logFileExtension = "mavlink"; ///< Extension for log files +const char* MavlinkLogTest::_saveLogFilename = "qgroundcontrol.mavlink.ut"; ///< Filename to save log files to + + +MavlinkLogTest::MavlinkLogTest(void) +{ + +} + +void MavlinkLogTest::init(void) +{ + UnitTest::init(); + + // Make sure temp directory is clear of mavlink logs + QDir tmpDir(QStandardPaths::writableLocation(QStandardPaths::TempLocation)); + QStringList logFiles(tmpDir.entryList(QStringList(QString("*.%1").arg(_logFileExtension)), QDir::Files)); + foreach(QString logFile, logFiles) { + bool success = tmpDir.remove(logFile); + Q_UNUSED(success); + Q_ASSERT(success); + } +} + +void MavlinkLogTest::cleanup(void) +{ + UnitTest::cleanup(); + + // Make sure no left over logs in temp directory + QDir tmpDir(QStandardPaths::writableLocation(QStandardPaths::TempLocation)); + QStringList logFiles(tmpDir.entryList(QStringList(QString("*.%1").arg(_logFileExtension)), QDir::Files)); + QCOMPARE(logFiles.count(), 0); +} + +void MavlinkLogTest::_bootLogDetectionCancel_test(void) +{ + // Create a fake mavlink log + + QTemporaryFile tempLogFile; + tempLogFile.setFileTemplate(QString("%1/%2.%3").arg(QStandardPaths::writableLocation(QStandardPaths::TempLocation)).arg(_tempLogFileTemplate).arg(_logFileExtension)); + tempLogFile.setAutoRemove(false); + + tempLogFile.open(); + tempLogFile.write("foo"); + tempLogFile.close(); + + // We should get a message box, followed by a getSaveFileName dialog. + setExpectedMessageBox(QMessageBox::Ok); + setExpectedFileDialog(getSaveFileName, QStringList()); + + MainWindow* mainWindow = MainWindow::_create(NULL, MainWindow::CUSTOM_MODE_PX4); + Q_CHECK_PTR(mainWindow); + + checkExpectedMessageBox(); + checkExpectedFileDialog(); + + mainWindow->close(); + + delete mainWindow; +} + +void MavlinkLogTest::_bootLogDetectionSave_test(void) +{ + // Create a fake mavlink log + + QTemporaryFile tempLogFile; + tempLogFile.setFileTemplate(QString("%1/%2.%3").arg(QStandardPaths::writableLocation(QStandardPaths::TempLocation)).arg(_tempLogFileTemplate).arg(_logFileExtension)); + tempLogFile.setAutoRemove(false); + + tempLogFile.open(); + tempLogFile.write("foo"); + tempLogFile.close(); + + // We should get a message box, followed by a getSaveFileName dialog. + setExpectedMessageBox(QMessageBox::Ok); + QDir logSaveDir(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)); + QString logSaveFile(logSaveDir.filePath(_saveLogFilename)); + setExpectedFileDialog(getSaveFileName, QStringList(logSaveFile)); + + MainWindow* mainWindow = MainWindow::_create(NULL, MainWindow::CUSTOM_MODE_PX4); + Q_CHECK_PTR(mainWindow); + + checkExpectedMessageBox(); + checkExpectedFileDialog(); + + // Make sure the file is there and delete it + QCOMPARE(logSaveDir.remove(_saveLogFilename), true); + + mainWindow->close(); + + delete mainWindow; +} + +void MavlinkLogTest::_bootLogDetectionZeroLength_test(void) +{ + // Create a fake mavlink log + + QTemporaryFile tempLogFile; + tempLogFile.setFileTemplate(QString("%1/%2.%3").arg(QStandardPaths::writableLocation(QStandardPaths::TempLocation)).arg(_tempLogFileTemplate).arg(_logFileExtension)); + tempLogFile.setAutoRemove(false); + + // Zero length file + tempLogFile.open(); + tempLogFile.close(); + + // Zero length log files should not generate any additional UI pop-ups. It should just be deleted silently. + MainWindow* mainWindow = MainWindow::_create(NULL, MainWindow::CUSTOM_MODE_PX4); + Q_CHECK_PTR(mainWindow); + + mainWindow->close(); + + delete mainWindow; +} + +void MavlinkLogTest::_connectLog_test(void) +{ + MainWindow* mainWindow = MainWindow::_create(NULL, MainWindow::CUSTOM_MODE_PX4); + Q_CHECK_PTR(mainWindow); + + LinkManager* linkMgr = LinkManager::instance(); + Q_CHECK_PTR(linkMgr); + + MockLink* link = new MockLink(); + Q_CHECK_PTR(link); + // FIXME: LinkManager/MainWindow needs to be re-architected so that you don't have to addLink to MainWindow to get things to work + mainWindow->addLink(link); + linkMgr->connectLink(link); + QTest::qWait(5000); // Give enough time for UI to settle and heartbeats to go through + + // On Disconnect: We should get a getSaveFileName dialog. + QDir logSaveDir(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)); + QString logSaveFile(logSaveDir.filePath(_saveLogFilename)); + setExpectedFileDialog(getSaveFileName, QStringList(logSaveFile)); + + linkMgr->disconnectLink(link); + QTest::qWait(1000); // Need to allow signals to move between threads + + checkExpectedFileDialog(); + + // Make sure the file is there and delete it + QCOMPARE(logSaveDir.remove(_saveLogFilename), true); + + // MainWindow deletes itself on close + mainWindow->close(); + QTest::qWait(1000); // Need to allow signals to move between threads to shutdown MainWindow +} + +void MavlinkLogTest::_connectLogWindowClose_test(void) +{ + MainWindow* mainWindow = MainWindow::_create(NULL, MainWindow::CUSTOM_MODE_PX4); + Q_CHECK_PTR(mainWindow); + + LinkManager* linkMgr = LinkManager::instance(); + Q_CHECK_PTR(linkMgr); + + MockLink* link = new MockLink(); + Q_CHECK_PTR(link); + // FIXME: LinkManager/MainWindow needs to be re-architected so that you don't have to addLink to MainWindow to get things to work + mainWindow->addLink(link); + linkMgr->connectLink(link); + QTest::qWait(5000); // Give enough time for UI to settle and heartbeats to go through + + // On Disconnect: We should get a getSaveFileName dialog. + QDir logSaveDir(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)); + QString logSaveFile(logSaveDir.filePath(_saveLogFilename)); + setExpectedFileDialog(getSaveFileName, QStringList(logSaveFile)); + + // MainWindow deletes itself on close + mainWindow->close(); + QTest::qWait(1000); // Need to allow signals to move between threads + + checkExpectedFileDialog(); + + // Make sure the file is there and delete it + QCOMPARE(logSaveDir.remove(_saveLogFilename), true); +} diff --git a/src/qgcunittest/MavlinkLogTest.h b/src/qgcunittest/MavlinkLogTest.h new file mode 100644 index 000000000..a9f4e1953 --- /dev/null +++ b/src/qgcunittest/MavlinkLogTest.h @@ -0,0 +1,57 @@ +/*===================================================================== + + 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 Test for mavlink log collection +/// +/// @author Don Gagne + +#ifndef MAVLINKLOGTEST_H +#define MAVLINKLOGTEST_H + +#include "UnitTest.h" + +class MavlinkLogTest : public UnitTest +{ + Q_OBJECT + +public: + MavlinkLogTest(void); + +private slots: + void init(void); + void cleanup(void); + + void _bootLogDetectionCancel_test(void); + void _bootLogDetectionSave_test(void); + void _bootLogDetectionZeroLength_test(void); + void _connectLog_test(void); + void _connectLogWindowClose_test(void); + +private: + static const char* _tempLogFileTemplate; ///< Template for temporary log file + static const char* _logFileExtension; ///< Extension for log files + static const char* _saveLogFilename; ///< Filename to save log files to +}; + +#endif diff --git a/src/qgcunittest/MockLink.cc b/src/qgcunittest/MockLink.cc index 6662cb796..73fefbbba 100644 --- a/src/qgcunittest/MockLink.cc +++ b/src/qgcunittest/MockLink.cc @@ -382,6 +382,7 @@ void MockLink::_handleParamRequestList(const mavlink_message_t& msg) mavlink_message_t responseMsg; char paramId[MAVLINK_MSG_ID_PARAM_VALUE_LEN]; + Q_ASSERT(param.key().length() <= MAVLINK_MSG_ID_PARAM_VALUE_LEN); strncpy(paramId, param.key().toLocal8Bit().constData(), MAVLINK_MSG_ID_PARAM_VALUE_LEN); mavlink_msg_param_value_pack(_vehicleSystemId, _vehicleComponentId, -- 2.22.0