Newer
Older
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
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 <http://www.gnu.org/licenses/>.
======================================================================*/
#include "TCPLinkTest.h"
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
/// @file
/// @brief TCPLink class unit test
///
/// @author Don Gagne <don@thegagnes.com>
TCPLinkUnitTest::TCPLinkUnitTest(void) :
_link(NULL),
_hostAddress(QHostAddress::LocalHost),
_port(5760),
_multiSpy(NULL)
{
}
// Called before every test
void TCPLinkUnitTest::init(void)
{
Q_ASSERT(_link == NULL);
Q_ASSERT(_multiSpy == NULL);
_link = new TCPLink(_hostAddress, _port);
Q_ASSERT(_link != NULL);
_rgSignals[bytesReceivedSignalIndex] = SIGNAL(bytesReceived(LinkInterface*, QByteArray));
_rgSignals[connectedSignalIndex] = SIGNAL(connected(void));
_rgSignals[disconnectedSignalIndex] = SIGNAL(disconnected(void));
_rgSignals[connected2SignalIndex] = SIGNAL(connected(bool));
_rgSignals[nameChangedSignalIndex] = SIGNAL(nameChanged(QString));
_rgSignals[communicationErrorSignalIndex] = SIGNAL(communicationError(const QString&, const QString&));
_rgSignals[communicationUpdateSignalIndex] = SIGNAL(communicationUpdate(const QString&, const QString&));
_rgSignals[deleteLinkSignalIndex] = SIGNAL(deleteLink(LinkInterface* const));
_multiSpy = new MultiSignalSpy();
QCOMPARE(_multiSpy->init(_link, _rgSignals, _cSignals), true);
}
// Called after every test
void TCPLinkUnitTest::cleanup(void)
{
Q_ASSERT(_multiSpy);
Q_ASSERT(_link);
delete _multiSpy;
delete _link;
_multiSpy = NULL;
_link = NULL;
}
void TCPLinkUnitTest::_properties_test(void)
{
Q_ASSERT(_link);
Q_ASSERT(_multiSpy);
Q_ASSERT(_multiSpy->checkNoSignals() == true);
// Make sure we get the right values back
QHostAddress hostAddressOut;
quint16 portOut;
hostAddressOut = _link->getHostAddress();
QCOMPARE(_hostAddress, hostAddressOut);
portOut = _link->getPort();
QCOMPARE(_port, portOut);
}
void TCPLinkUnitTest::_nameChangedSignal_test(void)
{
Q_ASSERT(_link);
Q_ASSERT(_multiSpy);
Q_ASSERT(_multiSpy->checkNoSignals() == true);
_link->setHostAddress(QHostAddress("127.1.1.1"));
QCOMPARE(_multiSpy->checkOnlySignalByMask(nameChangedSignalMask), true);
_multiSpy->clearSignalByIndex(nameChangedSignalIndex);
_link->setPort(42);
QCOMPARE(_multiSpy->checkOnlySignalByMask(nameChangedSignalMask), true);
_multiSpy->clearSignalByIndex(nameChangedSignalIndex);
}
void TCPLinkUnitTest::_connectFail_test(void)
{
Q_ASSERT(_link);
Q_ASSERT(_multiSpy);
Q_ASSERT(_multiSpy->checkNoSignals() == true);
// With the new threading model connect will always succeed. We only get an error signal
// for a failed connected.
QCOMPARE(_link->connect(), true);
// Make sure we get a linkError signal with the right link name
QCOMPARE(_multiSpy->waitForSignalByIndex(communicationErrorSignalIndex, 1000), true);
QCOMPARE(_multiSpy->checkOnlySignalByMask(communicationErrorSignalMask), true);
QList<QVariant> arguments = _multiSpy->getSpyByIndex(communicationErrorSignalIndex)->takeFirst();
QCOMPARE(arguments.at(0).toString(), _link->getName());
_multiSpy->clearSignalByIndex(communicationErrorSignalIndex);
// Try to connect again to make sure everything was cleaned up correctly from previous failed connection
// Make sure we get a linkError signal with the right link name
QCOMPARE(_multiSpy->waitForSignalByIndex(communicationErrorSignalIndex, 1000), true);
QCOMPARE(_multiSpy->checkOnlySignalByMask(communicationErrorSignalMask), true);
arguments = _multiSpy->getSpyByIndex(communicationErrorSignalIndex)->takeFirst();
QCOMPARE(arguments.at(0).toString(), _link->getName());
_multiSpy->clearSignalByIndex(communicationErrorSignalIndex);
}
void TCPLinkUnitTest::_connectSucceed_test(void)
{
Q_ASSERT(_link);
Q_ASSERT(_multiSpy);
Q_ASSERT(_multiSpy->checkNoSignals() == true);
// Start the server side
TCPLoopBackServer* server = new TCPLoopBackServer(_hostAddress, _port);
Q_CHECK_PTR(server);
// Connect to the server
QCOMPARE(_link->connect(), true);
// Make sure we get the two different connected signals
QCOMPARE(_multiSpy->waitForSignalByIndex(connectedSignalIndex, 1000), true);
QCOMPARE(_multiSpy->checkOnlySignalByMask(connectedSignalMask | connected2SignalMask), true);
QList<QVariant> arguments = _multiSpy->getSpyByIndex(connected2SignalIndex)->takeFirst();
QCOMPARE(arguments.at(0).toBool(), true);
const char* bytesWrittenSignal = SIGNAL(bytesWritten(qint64));
MultiSignalSpy bytesWrittenSpy;
QCOMPARE(bytesWrittenSpy.init(_link->getSocket(), &bytesWrittenSignal, 1), true);
_multiSpy->clearAllSignals();
// We emit this signal such that it will be queued and run on the TCPLink thread. This in turn
// allows the TCPLink object to pump the bytes through.
connect(this, SIGNAL(waitForBytesWritten(int)), _link, SLOT(waitForBytesWritten(int)));
emit waitForBytesWritten(1000);
// Check for loopback, both from signal received and actual bytes returned
QCOMPARE(_multiSpy->waitForSignalByIndex(bytesReceivedSignalIndex, 1000), true);
QCOMPARE(_multiSpy->checkOnlySignalByMask(bytesReceivedSignalMask), true);
arguments = _multiSpy->getSpyByIndex(bytesReceivedSignalIndex)->takeFirst();
QVERIFY(arguments.at(1).toByteArray() == bytesOut);
_multiSpy->clearAllSignals();
// Disconnect the link
_link->disconnect();
// Make sure we get the disconnected signals on link side
QCOMPARE(_multiSpy->waitForSignalByIndex(disconnectedSignalIndex, 1000), true);
QCOMPARE(_multiSpy->checkOnlySignalByMask(disconnectedSignalMask | connected2SignalMask), true);
arguments = _multiSpy->getSpyByIndex(connected2SignalIndex)->takeFirst();
QCOMPARE(arguments.at(0).toBool(), false);
// Try to connect again to make sure everything was cleaned up correctly from previous connection
// Connect to the server
QCOMPARE(_link->connect(), true);
// Make sure we get the two different connected signals
QCOMPARE(_multiSpy->waitForSignalByIndex(connectedSignalIndex, 1000), true);
QCOMPARE(_multiSpy->checkOnlySignalByMask(connectedSignalMask | connected2SignalMask), true);
arguments = _multiSpy->getSpyByIndex(connected2SignalIndex)->takeFirst();
QCOMPARE(arguments.at(0).toBool(), true);
_multiSpy->clearAllSignals();
server->quit();
QTest::qWait(500); // Wait a little for server thread to terminate