1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
/// @file
/// @brief Test for mavlink log collection
///
/// @author Don Gagne <don@thegagnes.com>
#include "MavlinkLogTest.h"
#include "MainWindow.h"
#include "MockLink.h"
#include "QGCTemporaryFile.h"
#include "QGCApplication.h"
#include "UAS.h"
#include "MultiVehicleManager.h"
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(const QString &logFile, logFiles) {
bool success = tmpDir.remove(logFile);
Q_UNUSED(success);
Q_ASSERT(success);
}
}
void MavlinkLogTest::cleanup(void)
{
// 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);
UnitTest::cleanup();
}
void MavlinkLogTest::_createTempLogFile(bool zeroLength)
{
QGCTemporaryFile tempLogFile(QString("%1.%2").arg(_tempLogFileTemplate).arg(_logFileExtension));
tempLogFile.open();
if (!zeroLength) {
tempLogFile.write("foo");
}
tempLogFile.close();
}
void MavlinkLogTest::_bootLogDetectionCancel_test(void)
{
// Create a fake mavlink log
_createTempLogFile(false);
// We should get a message box, followed by a getSaveFileName dialog.
setExpectedMessageBox(QMessageBox::Ok);
setExpectedFileDialog(getSaveFileName, QStringList());
// Kick the protocol to check for lost log files and wait for signals to move through
connect(this, &MavlinkLogTest::checkForLostLogFiles, qgcApp()->toolbox()->mavlinkProtocol(), &MAVLinkProtocol::checkForLostLogFiles);
emit checkForLostLogFiles();
QTest::qWait(1000);
checkExpectedMessageBox();
checkExpectedFileDialog();
}
void MavlinkLogTest::_bootLogDetectionSave_test(void)
{
// Create a fake mavlink log
_createTempLogFile(false);
// We should get a message box, followed by a getSaveFileName dialog.
setExpectedMessageBox(QMessageBox::Ok);
QDir logSaveDir(QStandardPaths::writableLocation(QStandardPaths::TempLocation));
QString logSaveFile(logSaveDir.filePath(_saveLogFilename));
setExpectedFileDialog(getSaveFileName, QStringList(logSaveFile));
// Kick the protocol to check for lost log files and wait for signals to move through
connect(this, &MavlinkLogTest::checkForLostLogFiles, qgcApp()->toolbox()->mavlinkProtocol(), &MAVLinkProtocol::checkForLostLogFiles);
emit checkForLostLogFiles();
QTest::qWait(1000);
checkExpectedMessageBox();
checkExpectedFileDialog();
// Make sure the file is there and delete it
QCOMPARE(logSaveDir.remove(_saveLogFilename), true);
}
void MavlinkLogTest::_bootLogDetectionZeroLength_test(void)
{
// Create a fake empty mavlink log
_createTempLogFile(true);
// Kick the protocol to check for lost log files and wait for signals to move through
connect(this, &MavlinkLogTest::checkForLostLogFiles, qgcApp()->toolbox()->mavlinkProtocol(), &MAVLinkProtocol::checkForLostLogFiles);
emit checkForLostLogFiles();
QTest::qWait(1000);
// Zero length log files should not generate any additional UI pop-ups. It should just be deleted silently.
}
void MavlinkLogTest::_connectLogWorker(bool arm)
{
_connectMockLink();
QDir logSaveDir;
if (arm) {
qgcApp()->toolbox()->multiVehicleManager()->activeVehicle()->setArmed(true);
QTest::qWait(500); // Wait long enough for heartbeat to come through
// On Disconnect: We should get a getSaveFileName dialog.
logSaveDir.setPath(QStandardPaths::writableLocation(QStandardPaths::TempLocation));
QString logSaveFile(logSaveDir.filePath(_saveLogFilename));
setExpectedFileDialog(getSaveFileName, QStringList(logSaveFile));
}
_disconnectMockLink();
if (arm) {
checkExpectedFileDialog();
// Make sure the file is there and delete it
QCOMPARE(logSaveDir.remove(_saveLogFilename), true);
}
}
void MavlinkLogTest::_connectLogNoArm_test(void)
{
_connectLogWorker(false);
}
void MavlinkLogTest::_connectLogArm_test(void)
{
_connectLogWorker(true);
}
void MavlinkLogTest::_deleteTempLogFiles_test(void)
{
// Verify that the MAVLinkProtocol::deleteTempLogFiles api works correctly
_createTempLogFile(false);
MAVLinkProtocol::deleteTempLogFiles();
QDir tmpDir(QStandardPaths::writableLocation(QStandardPaths::TempLocation));
QStringList logFiles(tmpDir.entryList(QStringList(QString("*.%1").arg(_logFileExtension)), QDir::Files));
QCOMPARE(logFiles.count(), 0);
}