Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Q
qgroundcontrol
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Valentin Platzgummer
qgroundcontrol
Commits
f19760e5
Commit
f19760e5
authored
Dec 29, 2013
by
Lorenz Meier
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #452 from DonLakeFlyer/TCPLinkUnitTest
TcpLink unit test
parents
9d42f680
f00d8adf
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
755 additions
and
139 deletions
+755
-139
qgroundcontrol.pro
qgroundcontrol.pro
+6
-2
SerialLink.cc
src/comm/SerialLink.cc
+2
-3
SerialLink.h
src/comm/SerialLink.h
+1
-4
TCPLink.cc
src/comm/TCPLink.cc
+89
-78
TCPLink.h
src/comm/TCPLink.h
+48
-51
MultiSignalSpy.cc
src/qgcunittest/MultiSignalSpy.cc
+230
-0
MultiSignalSpy.h
src/qgcunittest/MultiSignalSpy.h
+70
-0
TCPLinkTest.cc
src/qgcunittest/TCPLinkTest.cc
+218
-0
TCPLinkTest.h
src/qgcunittest/TCPLinkTest.h
+90
-0
QGCTCPLinkConfiguration.cc
src/ui/QGCTCPLinkConfiguration.cc
+1
-1
No files found.
qgroundcontrol.pro
View file @
f19760e5
...
@@ -751,13 +751,17 @@ CONFIG(debug, debug|release) {
...
@@ -751,13 +751,17 @@ CONFIG(debug, debug|release) {
src
/
qgcunittest
/
UASUnitTest
.
h
\
src
/
qgcunittest
/
UASUnitTest
.
h
\
src
/
qgcunittest
/
MockUASManager
.
h
\
src
/
qgcunittest
/
MockUASManager
.
h
\
src
/
qgcunittest
/
MockUAS
.
h
\
src
/
qgcunittest
/
MockUAS
.
h
\
src
/
qgcunittest
/
MockQGCUASParamManager
.
h
src
/
qgcunittest
/
MockQGCUASParamManager
.
h
\
src
/
qgcunittest
/
MultiSignalSpy
.
h
\
src
/
qgcunittest
/
TCPLinkTest
.
h
SOURCES
+=
\
SOURCES
+=
\
src
/
qgcunittest
/
UASUnitTest
.
cc
\
src
/
qgcunittest
/
UASUnitTest
.
cc
\
src
/
qgcunittest
/
MockUASManager
.
cc
\
src
/
qgcunittest
/
MockUASManager
.
cc
\
src
/
qgcunittest
/
MockUAS
.
cc
\
src
/
qgcunittest
/
MockUAS
.
cc
\
src
/
qgcunittest
/
MockQGCUASParamManager
.
cc
src
/
qgcunittest
/
MockQGCUASParamManager
.
cc
\
src
/
qgcunittest
/
MultiSignalSpy
.
cc
\
src
/
qgcunittest
/
TCPLinkTest
.
cc
}
}
#
Enable
Google
Earth
only
on
Mac
OS
and
Windows
with
Visual
Studio
compiler
#
Enable
Google
Earth
only
on
Mac
OS
and
Windows
with
Visual
Studio
compiler
...
...
src/comm/SerialLink.cc
View file @
f19760e5
...
@@ -413,8 +413,7 @@ bool SerialLink::hardwareConnect()
...
@@ -413,8 +413,7 @@ bool SerialLink::hardwareConnect()
}
}
QObject
::
connect
(
m_port
,
SIGNAL
(
aboutToClose
()),
this
,
SIGNAL
(
disconnected
()));
QObject
::
connect
(
m_port
,
SIGNAL
(
aboutToClose
()),
this
,
SIGNAL
(
disconnected
()));
QObject
::
connect
(
m_port
,
SIGNAL
(
error
(
SerialLinkPortError_t
)),
QObject
::
connect
(
m_port
,
SIGNAL
(
error
(
QSerialPort
::
SerialPortError
)),
this
,
SLOT
(
linkError
(
QSerialPort
::
SerialPortError
)));
this
,
SLOT
(
linkError
(
SerialLinkPortError_t
)));
// port->setCommTimeouts(QSerialPort::CtScheme_NonBlockingRead);
// port->setCommTimeouts(QSerialPort::CtScheme_NonBlockingRead);
...
@@ -444,7 +443,7 @@ bool SerialLink::hardwareConnect()
...
@@ -444,7 +443,7 @@ bool SerialLink::hardwareConnect()
return
true
;
// successful connection
return
true
;
// successful connection
}
}
void
SerialLink
::
linkError
(
SerialLinkPortError_t
error
)
void
SerialLink
::
linkError
(
QSerialPort
::
SerialPortError
error
)
{
{
qDebug
()
<<
error
;
qDebug
()
<<
error
;
}
}
...
...
src/comm/SerialLink.h
View file @
f19760e5
...
@@ -40,9 +40,6 @@ This file is part of the QGROUNDCONTROL project
...
@@ -40,9 +40,6 @@ This file is part of the QGROUNDCONTROL project
#include <configuration.h>
#include <configuration.h>
#include "SerialLinkInterface.h"
#include "SerialLinkInterface.h"
// convenience type for passing errors
typedef
QSerialPort
::
SerialPortError
SerialLinkPortError_t
;
/**
/**
* @brief The SerialLink class provides cross-platform access to serial links.
* @brief The SerialLink class provides cross-platform access to serial links.
* It takes care of the link management and provides a common API to higher
* It takes care of the link management and provides a common API to higher
...
@@ -137,7 +134,7 @@ public slots:
...
@@ -137,7 +134,7 @@ public slots:
bool
connect
();
bool
connect
();
bool
disconnect
();
bool
disconnect
();
void
linkError
(
SerialLinkPortError_t
error
);
void
linkError
(
QSerialPort
::
SerialPortError
error
);
protected:
protected:
quint64
m_bytesRead
;
quint64
m_bytesRead
;
...
...
src/comm/TCPLink.cc
View file @
f19760e5
...
@@ -21,13 +21,6 @@
...
@@ -21,13 +21,6 @@
======================================================================*/
======================================================================*/
/**
* @file
* @brief Definition of TCP connection (server) for unmanned vehicles
* @author Lorenz Meier <mavteam@student.ethz.ch>
*
*/
#include <QTimer>
#include <QTimer>
#include <QList>
#include <QList>
#include <QDebug>
#include <QDebug>
...
@@ -37,26 +30,29 @@
...
@@ -37,26 +30,29 @@
#include "LinkManager.h"
#include "LinkManager.h"
#include "QGC.h"
#include "QGC.h"
#include <QHostInfo>
#include <QHostInfo>
#include <QSignalSpy>
TCPLink
::
TCPLink
(
QHostAddress
hostAddress
,
quint16
socketPort
)
:
/// @file
host
(
hostAddress
),
/// @brief TCP link type for SITL support
port
(
socketPort
),
///
socket
(
NULL
),
/// @author Don Gagne <don@thegagnes.com>
socketIsConnected
(
false
)
TCPLink
::
TCPLink
(
QHostAddress
hostAddress
,
quint16
socketPort
)
:
_hostAddress
(
hostAddress
),
_port
(
socketPort
),
_socket
(
NULL
),
_socketIsConnected
(
false
)
{
{
// Set unique ID and add link to the list of links
_linkId
=
getNextLinkId
();
this
->
id
=
getNextLinkId
();
_resetName
();
this
->
name
=
tr
(
"TCP Link (port:%1)"
).
arg
(
this
->
port
);
emit
nameChanged
(
this
->
name
);
qDebug
()
<<
"TCP Created "
<<
this
->
name
;
qDebug
()
<<
"TCP Created "
<<
_
name
;
}
}
TCPLink
::~
TCPLink
()
TCPLink
::~
TCPLink
()
{
{
disconnect
();
disconnect
();
this
->
deleteLater
();
deleteLater
();
}
}
void
TCPLink
::
run
()
void
TCPLink
::
run
()
...
@@ -64,45 +60,47 @@ void TCPLink::run()
...
@@ -64,45 +60,47 @@ void TCPLink::run()
exec
();
exec
();
}
}
void
TCPLink
::
set
Address
(
const
QString
&
text
)
void
TCPLink
::
set
HostAddress
(
QHostAddress
hostAddress
)
{
{
setAddress
(
QHostAddress
(
text
));
bool
reconnect
=
false
;
}
if
(
this
->
isConnected
())
{
void
TCPLink
::
setAddress
(
QHostAddress
host
)
{
bool
reconnect
(
false
);
if
(
this
->
isConnected
())
{
disconnect
();
disconnect
();
reconnect
=
true
;
reconnect
=
true
;
}
}
this
->
host
=
host
;
if
(
reconnect
)
_hostAddress
=
hostAddress
;
{
_resetName
();
if
(
reconnect
)
{
connect
();
connect
();
}
}
}
}
void
TCPLink
::
setHostAddress
(
const
QString
&
hostAddress
)
{
setHostAddress
(
QHostAddress
(
hostAddress
));
}
void
TCPLink
::
setPort
(
int
port
)
void
TCPLink
::
setPort
(
int
port
)
{
{
bool
reconnect
(
false
)
;
bool
reconnect
=
false
;
if
(
this
->
isConnected
())
{
if
(
this
->
isConnected
())
{
disconnect
();
disconnect
();
reconnect
=
true
;
reconnect
=
true
;
}
}
this
->
port
=
port
;
this
->
name
=
tr
(
"TCP Link (port:%1)"
).
arg
(
this
->
port
)
;
_port
=
port
;
emit
nameChanged
(
this
->
name
);
_resetName
(
);
if
(
reconnect
)
{
if
(
reconnect
)
{
connect
();
connect
();
}
}
}
}
#ifdef TCPLINK_READWRITE_DEBUG
#ifdef TCPLINK_READWRITE_DEBUG
void
TCPLink
::
writeDebugBytes
(
const
char
*
data
,
qint16
size
)
void
TCPLink
::
_
writeDebugBytes
(
const
char
*
data
,
qint16
size
)
{
{
QString
bytes
;
QString
bytes
;
QString
ascii
;
QString
ascii
;
...
@@ -119,7 +117,7 @@ void TCPLink::writeDebugBytes(const char *data, qint16 size)
...
@@ -119,7 +117,7 @@ void TCPLink::writeDebugBytes(const char *data, qint16 size)
ascii
.
append
(
219
);
ascii
.
append
(
219
);
}
}
}
}
qDebug
()
<<
"Sent"
<<
size
<<
"bytes to"
<<
host
.
toString
()
<<
":"
<<
port
<<
"data:"
;
qDebug
()
<<
"Sent"
<<
size
<<
"bytes to"
<<
_hostAddress
.
toString
()
<<
":"
<<
_
port
<<
"data:"
;
qDebug
()
<<
bytes
;
qDebug
()
<<
bytes
;
qDebug
()
<<
"ASCII:"
<<
ascii
;
qDebug
()
<<
"ASCII:"
<<
ascii
;
}
}
...
@@ -128,9 +126,9 @@ void TCPLink::writeDebugBytes(const char *data, qint16 size)
...
@@ -128,9 +126,9 @@ void TCPLink::writeDebugBytes(const char *data, qint16 size)
void
TCPLink
::
writeBytes
(
const
char
*
data
,
qint64
size
)
void
TCPLink
::
writeBytes
(
const
char
*
data
,
qint64
size
)
{
{
#ifdef TCPLINK_READWRITE_DEBUG
#ifdef TCPLINK_READWRITE_DEBUG
writeDebugBytes
(
data
,
size
);
_
writeDebugBytes
(
data
,
size
);
#endif
#endif
socket
->
write
(
data
,
size
);
_
socket
->
write
(
data
,
size
);
// Log the amount and time written out for future data rate calculations.
// Log the amount and time written out for future data rate calculations.
QMutexLocker
dataRateLocker
(
&
dataRateMutex
);
QMutexLocker
dataRateLocker
(
&
dataRateMutex
);
...
@@ -145,14 +143,14 @@ void TCPLink::writeBytes(const char* data, qint64 size)
...
@@ -145,14 +143,14 @@ void TCPLink::writeBytes(const char* data, qint64 size)
**/
**/
void
TCPLink
::
readBytes
()
void
TCPLink
::
readBytes
()
{
{
qint64
byteCount
=
socket
->
bytesAvailable
();
qint64
byteCount
=
_
socket
->
bytesAvailable
();
if
(
byteCount
)
if
(
byteCount
)
{
{
QByteArray
buffer
;
QByteArray
buffer
;
buffer
.
resize
(
byteCount
);
buffer
.
resize
(
byteCount
);
socket
->
read
(
buffer
.
data
(),
buffer
.
size
());
_
socket
->
read
(
buffer
.
data
(),
buffer
.
size
());
emit
bytesReceived
(
this
,
buffer
);
emit
bytesReceived
(
this
,
buffer
);
...
@@ -166,7 +164,6 @@ void TCPLink::readBytes()
...
@@ -166,7 +164,6 @@ void TCPLink::readBytes()
}
}
}
}
/**
/**
* @brief Get the number of bytes to read.
* @brief Get the number of bytes to read.
*
*
...
@@ -174,7 +171,7 @@ void TCPLink::readBytes()
...
@@ -174,7 +171,7 @@ void TCPLink::readBytes()
**/
**/
qint64
TCPLink
::
bytesAvailable
()
qint64
TCPLink
::
bytesAvailable
()
{
{
return
socket
->
bytesAvailable
();
return
_
socket
->
bytesAvailable
();
}
}
/**
/**
...
@@ -184,15 +181,18 @@ qint64 TCPLink::bytesAvailable()
...
@@ -184,15 +181,18 @@ qint64 TCPLink::bytesAvailable()
**/
**/
bool
TCPLink
::
disconnect
()
bool
TCPLink
::
disconnect
()
{
{
this
->
quit
();
quit
();
this
->
wait
();
wait
();
if
(
socket
)
if
(
_
socket
)
{
{
socket
->
disconnect
();
_socket
->
disconnectFromHost
();
socketIsConnected
=
false
;
_socketIsConnected
=
false
;
delete
socket
;
delete
_socket
;
socket
=
NULL
;
_socket
=
NULL
;
emit
disconnected
();
emit
connected
(
false
);
}
}
return
true
;
return
true
;
...
@@ -205,42 +205,54 @@ bool TCPLink::disconnect()
...
@@ -205,42 +205,54 @@ bool TCPLink::disconnect()
**/
**/
bool
TCPLink
::
connect
()
bool
TCPLink
::
connect
()
{
{
if
(
this
->
isRunning
())
if
(
isRunning
())
{
{
this
->
quit
();
quit
();
this
->
wait
();
wait
();
}
}
bool
connected
=
this
->
hardwareConnect
();
bool
connected
=
_hardwareConnect
();
start
(
HighPriority
);
if
(
connected
)
{
start
(
HighPriority
);
}
return
connected
;
return
connected
;
}
}
bool
TCPLink
::
hardwareConnect
(
void
)
bool
TCPLink
::
_
hardwareConnect
(
void
)
{
{
socket
=
new
QTcpSocket
();
Q_ASSERT
(
_socket
==
NULL
);
_socket
=
new
QTcpSocket
();
QSignalSpy
errorSpy
(
_socket
,
SIGNAL
(
error
(
QAbstractSocket
::
SocketError
)));
socket
->
connectToHost
(
host
,
port
);
_socket
->
connectToHost
(
_hostAddress
,
_
port
);
QObject
::
connect
(
socket
,
SIGNAL
(
readyRead
()),
this
,
SLOT
(
readBytes
()));
QObject
::
connect
(
_
socket
,
SIGNAL
(
readyRead
()),
this
,
SLOT
(
readBytes
()));
QObject
::
connect
(
socket
,
SIGNAL
(
error
(
QAbstractSocket
::
SocketError
)),
this
,
SLOT
(
socketError
(
QAbstractSocket
::
SocketError
)));
QObject
::
connect
(
_socket
,
SIGNAL
(
error
(
QAbstractSocket
::
SocketError
)),
this
,
SLOT
(
_
socketError
(
QAbstractSocket
::
SocketError
)));
// Give the socket a second to connect to the other side otherwise error out
// Give the socket a second to connect to the other side otherwise error out
if
(
!
socket
->
waitForConnected
(
1000
))
if
(
!
_
socket
->
waitForConnected
(
1000
))
{
{
emit
communicationError
(
getName
(),
"connection failed"
);
// Whether a failed connection emits an error signal or not is platform specific.
// So in cases where it is not emitted, we emit one ourselves.
if
(
errorSpy
.
count
()
==
0
)
{
emit
communicationError
(
getName
(),
"Connection failed"
);
}
delete
_socket
;
_socket
=
NULL
;
return
false
;
return
false
;
}
}
socketIsConnected
=
true
;
_
socketIsConnected
=
true
;
emit
connected
(
true
);
emit
connected
(
true
);
emit
connected
();
return
true
;
return
true
;
}
}
void
TCPLink
::
socketError
(
QAbstractSocket
::
SocketError
socketError
)
void
TCPLink
::
_
socketError
(
QAbstractSocket
::
SocketError
socketError
)
{
{
Q_UNUSED
(
socketError
);
Q_UNUSED
(
socketError
);
emit
communicationError
(
getName
(),
"Error on socket: "
+
socket
->
errorString
());
emit
communicationError
(
getName
(),
"Error on socket: "
+
_
socket
->
errorString
());
}
}
/**
/**
...
@@ -250,26 +262,19 @@ void TCPLink::socketError(QAbstractSocket::SocketError socketError)
...
@@ -250,26 +262,19 @@ void TCPLink::socketError(QAbstractSocket::SocketError socketError)
**/
**/
bool
TCPLink
::
isConnected
()
const
bool
TCPLink
::
isConnected
()
const
{
{
return
socketIsConnected
;
return
_
socketIsConnected
;
}
}
int
TCPLink
::
getId
()
const
int
TCPLink
::
getId
()
const
{
{
return
i
d
;
return
_linkI
d
;
}
}
QString
TCPLink
::
getName
()
const
QString
TCPLink
::
getName
()
const
{
{
return
name
;
return
_name
;
}
void
TCPLink
::
setName
(
QString
name
)
{
this
->
name
=
name
;
emit
nameChanged
(
this
->
name
);
}
}
qint64
TCPLink
::
getConnectionSpeed
()
const
qint64
TCPLink
::
getConnectionSpeed
()
const
{
{
return
54000000
;
// 54 Mbit
return
54000000
;
// 54 Mbit
...
@@ -284,3 +289,9 @@ qint64 TCPLink::getCurrentOutDataRate() const
...
@@ -284,3 +289,9 @@ qint64 TCPLink::getCurrentOutDataRate() const
{
{
return
0
;
return
0
;
}
}
void
TCPLink
::
_resetName
(
void
)
{
_name
=
QString
(
"TCP Link (host:%1 port:%2)"
).
arg
(
_hostAddress
.
toString
()).
arg
(
_port
);
emit
nameChanged
(
_name
);
}
src/comm/TCPLink.h
View file @
f19760e5
...
@@ -21,12 +21,10 @@
...
@@ -21,12 +21,10 @@
======================================================================*/
======================================================================*/
/**
/// @file
* @file
/// @brief TCP link type for SITL support
* @brief TCP connection (server) for unmanned vehicles
///
* @author Lorenz Meier <mavteam@student.ethz.ch>
/// @author Don Gagne <don@thegagnes.com>
*
*/
#ifndef TCPLINK_H
#ifndef TCPLINK_H
#define TCPLINK_H
#define TCPLINK_H
...
@@ -50,66 +48,65 @@ public:
...
@@ -50,66 +48,65 @@ public:
TCPLink
(
QHostAddress
hostAddress
=
QHostAddress
::
LocalHost
,
quint16
socketPort
=
5760
);
TCPLink
(
QHostAddress
hostAddress
=
QHostAddress
::
LocalHost
,
quint16
socketPort
=
5760
);
~
TCPLink
();
~
TCPLink
();
void
requestReset
()
{
}
void
setHostAddress
(
QHostAddress
hostAddress
);
bool
isConnected
()
const
;
QHostAddress
getHostAddress
(
void
)
const
{
return
_hostAddress
;
}
qint64
bytesAvailable
();
quint16
getPort
(
void
)
const
{
return
_port
;
}
int
getPort
()
const
{
QTcpSocket
*
getSocket
(
void
)
{
return
_socket
;
}
return
port
;
}
QHostAddress
getHostAddress
()
const
{
return
host
;
}
QString
getName
()
const
;
// LinkInterface methods
int
getBaudRate
()
const
;
virtual
int
getId
(
void
)
const
;
int
getBaudRateType
()
const
;
virtual
QString
getName
(
void
)
const
;
int
getFlowType
()
const
;
virtual
bool
isConnected
(
void
)
const
;
int
getParityType
()
const
;
virtual
bool
connect
(
void
);
int
getDataBitsType
()
const
;
virtual
bool
disconnect
(
void
);
int
getStopBitsType
()
const
;
virtual
qint64
bytesAvailable
(
void
);
virtual
void
requestReset
(
void
)
{};
// Extensive statistics for scientific purposes
// Extensive statistics for scientific purposes
qint64
getConnectionSpeed
()
const
;
qint64
getConnectionSpeed
()
const
;
qint64
getCurrentInDataRate
()
const
;
qint64
getCurrentInDataRate
()
const
;
qint64
getCurrentOutDataRate
()
const
;
qint64
getCurrentOutDataRate
()
const
;
void
run
();
int
getId
()
const
;
public
slots
:
public
slots
:
void
setAddress
(
QHostAddress
host
);
void
setHostAddress
(
const
QString
&
hostAddress
);
void
setPort
(
int
port
);
void
setPort
(
int
port
);
void
readBytes
();
void
writeBytes
(
const
char
*
data
,
qint64
length
);
bool
connect
();
bool
disconnect
();
void
socketError
(
QAbstractSocket
::
SocketError
socketError
);
void
setAddress
(
const
QString
&
text
);
// From LinkInterface
virtual
void
writeBytes
(
const
char
*
data
,
qint64
length
);
protected
slots
:
void
_socketError
(
QAbstractSocket
::
SocketError
socketError
);
// From LinkInterface
virtual
void
readBytes
(
void
);
protected:
protected:
QString
name
;
// From LinkInterface->QThread
QHostAddress
host
;
virtual
void
run
(
void
);
quint16
port
;
int
id
;
QTcpSocket
*
socket
;
bool
socketIsConnected
;
QMutex
dataMutex
;
void
setName
(
QString
name
);
private:
private:
bool
hardwareConnect
(
void
);
void
_resetName
(
void
);
bool
_hardwareConnect
(
void
);
#ifdef TCPLINK_READWRITE_DEBUG
#ifdef TCPLINK_READWRITE_DEBUG
void
writeDebugBytes
(
const
char
*
data
,
qint16
size
);
void
_
writeDebugBytes
(
const
char
*
data
,
qint16
size
);
#endif
#endif
QString
_name
;
QHostAddress
_hostAddress
;
quint16
_port
;
int
_linkId
;
QTcpSocket
*
_socket
;
bool
_socketIsConnected
;
signals:
quint64
_bitsSentTotal
;
//Signals are defined by LinkInterface
quint64
_bitsSentCurrent
;
quint64
_bitsSentMax
;
quint64
_bitsReceivedTotal
;
quint64
_bitsReceivedCurrent
;
quint64
_bitsReceivedMax
;
quint64
_connectionStartTime
;
QMutex
_statisticsMutex
;
};
};
#endif // TCPLINK_H
#endif // TCPLINK_H
src/qgcunittest/MultiSignalSpy.cc
0 → 100644
View file @
f19760e5
/*=====================================================================
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 "MultiSignalSpy.h"
#include <QEventLoop>
#include <QCoreApplication>
#include <QDebug>
/// @file
/// @brief This class allows you to keep track of signal counts on a set of signals associated with an object.
/// Mainly used for writing object unit tests.
///
/// @author Don Gagne <don@thegagnes.com>
MultiSignalSpy
::
MultiSignalSpy
(
QObject
*
parent
)
:
QObject
(
parent
),
_signalEmitter
(
NULL
),
_rgSignals
(
NULL
),
_cSignals
(
0
)
{
}
MultiSignalSpy
::~
MultiSignalSpy
()
{
Q_ASSERT
(
_rgSignals
);
for
(
size_t
i
=
0
;
i
<
_cSignals
;
i
++
)
{
delete
_rgSpys
[
i
];
}
}
/// Initializes the class. Must be called once before use.
/// @return true if success, false for failure
bool
MultiSignalSpy
::
init
(
QObject
*
signalEmitter
,
///< [in] object which the signals are emitted from
const
char
**
rgSignals
,
///< [in] array of signals to spy on
size_t
cSignals
)
///< [in] numbers of signals in rgSignals
{
if
(
!
signalEmitter
||
!
rgSignals
||
cSignals
==
0
)
{
qDebug
()
<<
"Invalid arguments"
;
return
false
;
}
_signalEmitter
=
signalEmitter
;
_rgSignals
=
rgSignals
;
_cSignals
=
cSignals
;
// Allocate and connect QSignalSpy's
_rgSpys
=
new
QSignalSpy
*
[
_cSignals
];
Q_ASSERT
(
_rgSpys
!=
NULL
);
for
(
size_t
i
=
0
;
i
<
_cSignals
;
i
++
)
{
_rgSpys
[
i
]
=
new
QSignalSpy
(
_signalEmitter
,
_rgSignals
[
i
]);
if
(
_rgSpys
[
i
]
==
NULL
)
{
qDebug
()
<<
"Unabled to allocated QSignalSpy"
;
return
false
;
}
if
(
!
_rgSpys
[
i
]
->
isValid
())
{
qDebug
()
<<
"Invalid signal"
;
return
false
;
}
}
return
true
;
}
/// @param mask bit mask specifying which signals to check. The lowest order bit represents
/// index 0 into the rgSignals array and so on up the bit mask.
/// @return true if signal count = 1 for the specified signals
bool
MultiSignalSpy
::
checkSignalByMask
(
quint16
mask
)
{
for
(
size_t
i
=
0
;
i
<
_cSignals
;
i
++
)
{
if
((
1
<<
i
)
&
mask
)
{
QSignalSpy
*
spy
=
_rgSpys
[
i
];
Q_ASSERT
(
spy
!=
NULL
);
if
(
spy
->
count
()
!=
1
)
{
return
false
;
}
}
}
return
true
;
}
/// @return true if signal count = 1 for specified signals and signal count of 0
/// for all other signals
bool
MultiSignalSpy
::
checkOnlySignalByMask
(
quint16
mask
)
{
for
(
size_t
i
=
0
;
i
<
_cSignals
;
i
++
)
{
QSignalSpy
*
spy
=
_rgSpys
[
i
];
Q_ASSERT
(
spy
!=
NULL
);
if
((
1
<<
i
)
&
mask
)
{
if
(
spy
->
count
()
!=
1
)
{
return
false
;
}
}
else
{
if
(
spy
->
count
()
!=
0
)
{
return
false
;
}
}
}
return
true
;
}
/// @return true if signal count = 0 for specified signals
bool
MultiSignalSpy
::
checkNoSignalByMask
(
quint16
mask
)
{
for
(
size_t
i
=
0
;
i
<
_cSignals
;
i
++
)
{
if
((
1
<<
i
)
&
mask
)
{
QSignalSpy
*
spy
=
_rgSpys
[
i
];
Q_ASSERT
(
spy
!=
NULL
);
if
(
spy
->
count
()
!=
0
)
{
return
false
;
}
}
}
return
true
;
}
/// @return true if signal count = 0 on all signals
bool
MultiSignalSpy
::
checkNoSignals
(
void
)
{
return
checkNoSignalByMask
(
~
0
);
}
/// @return QSignalSpy for the specified signal
QSignalSpy
*
MultiSignalSpy
::
getSpyByIndex
(
quint16
index
)
{
Q_ASSERT
(
index
<
_cSignals
);
Q_ASSERT
(
_rgSpys
[
index
]
!=
NULL
);
return
_rgSpys
[
index
];
}
/// Sets the signal count to 0 for the specified signal
void
MultiSignalSpy
::
clearSignalByIndex
(
quint16
index
)
{
Q_ASSERT
(
index
<
_cSignals
);
Q_ASSERT
(
_rgSpys
[
index
]
!=
NULL
);
_rgSpys
[
index
]
->
clear
();
}
/// Sets the signal count to 0 for all specified signals
void
MultiSignalSpy
::
clearSignalsByMask
(
quint16
mask
)
{
for
(
size_t
i
=
0
;
i
<
_cSignals
;
i
++
)
{
if
((
1
<<
i
)
&
mask
)
{
QSignalSpy
*
spy
=
_rgSpys
[
i
];
Q_ASSERT
(
spy
!=
NULL
);
spy
->
clear
();
}
}
}
/// Sets the signal count to 0 for all signals
void
MultiSignalSpy
::
clearAllSignals
(
void
)
{
for
(
quint16
i
=
0
;
i
<
_cSignals
;
i
++
)
{
clearSignalByIndex
(
i
);
}
}
void
MultiSignalSpy
::
timerEvent
(
QTimerEvent
*
event
)
{
Q_UNUSED
(
event
);
_timeout
=
true
;
}
/// Waits the specified signal
/// @return false for timeout
bool
MultiSignalSpy
::
waitForSignalByIndex
(
quint16
index
,
///< [in] index of signal to wait on
int
msec
)
///< [in] numbers of milleconds to wait before timeout, -1 wait forever
{
// Check input parameters
if
(
msec
<
-
1
||
msec
==
0
)
return
false
;
// activate the timeout
_timeout
=
false
;
int
timerId
;
if
(
msec
!=
-
1
)
{
timerId
=
startTimer
(
msec
);
Q_ASSERT
(
timerId
);
}
else
{
timerId
=
0
;
}
// Begin waiting
QSignalSpy
*
spy
=
_rgSpys
[
index
];
Q_ASSERT
(
spy
);
while
(
spy
->
count
()
==
0
&&
!
_timeout
)
{
QCoreApplication
::
processEvents
(
QEventLoop
::
AllEvents
|
QEventLoop
::
WaitForMoreEvents
);
}
// Clean up and return status
if
(
timerId
)
{
killTimer
(
timerId
);
}
return
spy
->
count
()
!=
0
;
}
src/qgcunittest/MultiSignalSpy.h
0 → 100644
View file @
f19760e5
/*=====================================================================
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/>.
======================================================================*/
#ifndef MULTISIGNALSPY_H
#define MULTISIGNALSPY_H
#include <QObject>
#include <QSignalSpy>
/// @file
/// @brief This class allows you to keep track of signal counts on a set of signals associated with an object.
/// Mainly used for writing object unit tests.
///
/// @author Don Gagne <don@thegagnes.com>
class
MultiSignalSpy
:
public
QObject
{
Q_OBJECT
public:
MultiSignalSpy
(
QObject
*
parent
=
NULL
);
~
MultiSignalSpy
();
bool
init
(
QObject
*
signalEmitter
,
const
char
**
rgSignals
,
size_t
cSignals
);
bool
checkSignalByMask
(
quint16
mask
);
bool
checkOnlySignalByMask
(
quint16
mask
);
bool
checkNoSignalByMask
(
quint16
mask
);
bool
checkNoSignals
(
void
);
void
clearSignalByIndex
(
quint16
index
);
void
clearSignalsByMask
(
quint16
mask
);
void
clearAllSignals
(
void
);
bool
waitForSignalByIndex
(
quint16
index
,
int
msec
);
QSignalSpy
*
getSpyByIndex
(
quint16
index
);
private:
// QObject overrides
void
timerEvent
(
QTimerEvent
*
event
);
QObject
*
_signalEmitter
;
const
char
**
_rgSignals
;
QSignalSpy
**
_rgSpys
;
size_t
_cSignals
;
bool
_timeout
;
};
#endif
src/qgcunittest/TCPLinkTest.cc
0 → 100644
View file @
f19760e5
/*=====================================================================
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"
#include <QTcpServer>
/// @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
);
QCOMPARE
(
_link
->
connect
(),
false
);
// 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
QCOMPARE
(
_link
->
connect
(),
false
);
// 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
QTcpServer
*
server
=
new
QTcpServer
(
this
);
QCOMPARE
(
server
->
listen
(
_hostAddress
,
_port
),
true
);
// Connect to the server
QCOMPARE
(
_link
->
connect
(),
true
);
// Wait for the connection to come through on server side
QCOMPARE
(
server
->
waitForNewConnection
(
1000
),
true
);
QTcpSocket
*
serverSocket
=
server
->
nextPendingConnection
();
Q_ASSERT
(
serverSocket
);
// 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
);
_multiSpy
->
clearSignalsByMask
(
connectedSignalMask
);
// Test server->link data path
QByteArray
bytesOut
(
"test"
);
// Write data from server to link
serverSocket
->
write
(
bytesOut
);
// Make sure we get the bytesReceived signal, with the correct data
QCOMPARE
(
_multiSpy
->
waitForSignalByIndex
(
bytesReceivedSignalIndex
,
1000
),
true
);
QCOMPARE
(
_multiSpy
->
checkOnlySignalByMask
(
bytesReceivedSignalMask
),
true
);
arguments
=
_multiSpy
->
getSpyByIndex
(
bytesReceivedSignalIndex
)
->
takeFirst
();
QCOMPARE
(
arguments
.
at
(
1
),
QVariant
(
bytesOut
));
_multiSpy
->
clearSignalByIndex
(
bytesReceivedSignalIndex
);
// Test link->server data path
// Write data from link to server
_link
->
writeBytes
(
bytesOut
.
data
(),
bytesOut
.
size
());
QCOMPARE
(
_link
->
getSocket
()
->
waitForBytesWritten
(
1000
),
true
);
// Make sure we get readyRead on server
QCOMPARE
(
serverSocket
->
waitForReadyRead
(
1000
),
true
);
// Read the data and make sure it matches
QByteArray
bytesIn
=
serverSocket
->
read
(
bytesOut
.
size
()
+
100
);
QCOMPARE
(
bytesIn
,
bytesOut
);
// 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
);
_multiSpy
->
clearSignalsByMask
(
disconnectedSignalMask
);
// Make sure we get disconnected signals from the server side
QCOMPARE
(
serverSocket
->
waitForDisconnected
(
1000
),
true
);
// Try to connect again to make sure everything was cleaned up correctly from previous connection
// Connect to the server
QCOMPARE
(
_link
->
connect
(),
true
);
// Wait for the connection to come through on server side
QCOMPARE
(
server
->
waitForNewConnection
(
1000
),
true
);
serverSocket
=
server
->
nextPendingConnection
();
Q_ASSERT
(
serverSocket
);
// 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
->
clearSignalsByMask
(
connectedSignalMask
);
delete
server
;
}
src/qgcunittest/TCPLinkTest.h
0 → 100644
View file @
f19760e5
/*=====================================================================
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/>.
======================================================================*/
#ifndef TCPLINKTEST_H
#define TCPLINKTEST_H
#include <QObject>
#include <QtTest/QtTest>
#include <QApplication>
#include "AutoTest.h"
#include "TCPLink.h"
#include "MultiSignalSpy.h"
/// @file
/// @brief TCPLink class unit test
///
/// @author Don Gagne <don@thegagnes.com>
class
TCPLinkUnitTest
:
public
QObject
{
Q_OBJECT
public:
TCPLinkUnitTest
(
void
);
private
slots
:
void
init
(
void
);
void
cleanup
(
void
);
void
_properties_test
(
void
);
void
_nameChangedSignal_test
(
void
);
void
_connectFail_test
(
void
);
void
_connectSucceed_test
(
void
);
private:
enum
{
bytesReceivedSignalIndex
=
0
,
connectedSignalIndex
,
disconnectedSignalIndex
,
connected2SignalIndex
,
nameChangedSignalIndex
,
communicationErrorSignalIndex
,
communicationUpdateSignalIndex
,
deleteLinkSignalIndex
,
maxSignalIndex
};
enum
{
bytesReceivedSignalMask
=
1
<<
bytesReceivedSignalIndex
,
connectedSignalMask
=
1
<<
connectedSignalIndex
,
disconnectedSignalMask
=
1
<<
disconnectedSignalIndex
,
connected2SignalMask
=
1
<<
connected2SignalIndex
,
nameChangedSignalMask
=
1
<<
nameChangedSignalIndex
,
communicationErrorSignalMask
=
1
<<
communicationErrorSignalIndex
,
communicationUpdateSignalMask
=
1
<<
communicationUpdateSignalIndex
,
deleteLinkSignalMask
=
1
<<
deleteLinkSignalIndex
,
};
TCPLink
*
_link
;
QHostAddress
_hostAddress
;
quint16
_port
;
MultiSignalSpy
*
_multiSpy
;
static
const
size_t
_cSignals
=
maxSignalIndex
;
const
char
*
_rgSignals
[
_cSignals
];
};
DECLARE_TEST
(
TCPLinkUnitTest
)
#endif
src/ui/QGCTCPLinkConfiguration.cc
View file @
f19760e5
...
@@ -14,7 +14,7 @@ QGCTCPLinkConfiguration::QGCTCPLinkConfiguration(TCPLink* link, QWidget *parent)
...
@@ -14,7 +14,7 @@ QGCTCPLinkConfiguration::QGCTCPLinkConfiguration(TCPLink* link, QWidget *parent)
QString
addr
=
link
->
getHostAddress
().
toString
();
QString
addr
=
link
->
getHostAddress
().
toString
();
ui
->
hostAddressLineEdit
->
setText
(
addr
);
ui
->
hostAddressLineEdit
->
setText
(
addr
);
connect
(
ui
->
portSpinBox
,
SIGNAL
(
valueChanged
(
int
)),
link
,
SLOT
(
setPort
(
int
)));
connect
(
ui
->
portSpinBox
,
SIGNAL
(
valueChanged
(
int
)),
link
,
SLOT
(
setPort
(
int
)));
connect
(
ui
->
hostAddressLineEdit
,
SIGNAL
(
textChanged
(
const
QString
&
)),
link
,
SLOT
(
setAddress
(
const
QString
&
)));
connect
(
ui
->
hostAddressLineEdit
,
SIGNAL
(
textChanged
(
const
QString
&
)),
link
,
SLOT
(
set
Host
Address
(
const
QString
&
)));
}
}
QGCTCPLinkConfiguration
::~
QGCTCPLinkConfiguration
()
QGCTCPLinkConfiguration
::~
QGCTCPLinkConfiguration
()
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment