Add coverage report support
This commit is contained in:
parent
538cb3d799
commit
f20173df9f
1
.gitignore
vendored
1
.gitignore
vendored
@ -71,3 +71,4 @@ Thumbs.db
|
|||||||
*.dll
|
*.dll
|
||||||
*.exe
|
*.exe
|
||||||
|
|
||||||
|
coverage-html
|
||||||
|
|||||||
12
README.md
12
README.md
@ -40,6 +40,18 @@ In order to run the test, you can call `make check` in the build directory or ru
|
|||||||
|
|
||||||
$ nymea-remoteproxy-tests
|
$ nymea-remoteproxy-tests
|
||||||
|
|
||||||
|
|
||||||
|
## Test coverage report
|
||||||
|
|
||||||
|
If you want to create a line coverage report from the tests simply run following command in the source directory:
|
||||||
|
|
||||||
|
|
||||||
|
$ apt install lcov
|
||||||
|
$ ./create-coverage-html.sh
|
||||||
|
|
||||||
|
The resulting coverage report will be place in the `coverage-html` directory.
|
||||||
|
|
||||||
|
|
||||||
# Usage
|
# Usage
|
||||||
|
|
||||||
In order to get information about the server you can start the command with the `--help` parameter.
|
In order to get information about the server you can start the command with the `--help` parameter.
|
||||||
|
|||||||
16
create-coverage-html.sh
Executable file
16
create-coverage-html.sh
Executable file
@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Export the library path for now
|
||||||
|
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$(pwd)/libnymea-remoteproxy:$(pwd)/libnymea-remoteproxyclient
|
||||||
|
|
||||||
|
# Build
|
||||||
|
qmake CONFIG+=coverage
|
||||||
|
make -j$(nproc)
|
||||||
|
make coverage-html
|
||||||
|
|
||||||
|
# Clean up source directory
|
||||||
|
rm -v libnymea-remoteproxy/libnymea-remoteproxy.so*
|
||||||
|
rm -v libnymea-remoteproxyclient/libnymea-remoteproxyclient.so*
|
||||||
|
rm -v server/nymea-remoteproxy
|
||||||
|
rm -v tests/nymea-remoteproxy-tests
|
||||||
|
make clean
|
||||||
@ -45,7 +45,8 @@ JsonReply *AuthenticationHandler::Authenticate(const QVariantMap ¶ms, const
|
|||||||
|
|
||||||
void AuthenticationHandler::onAuthenticationFinished()
|
void AuthenticationHandler::onAuthenticationFinished()
|
||||||
{
|
{
|
||||||
AuthenticationReply *authReply = static_cast<AuthenticationReply *>(sender());
|
//AuthenticationReply *authReply = static_cast<AuthenticationReply *>(sender());
|
||||||
JsonReply *jsonReply = m_runningAuthentications.value(authReply);
|
//JsonReply *jsonReply = m_runningAuthentications.take(authReply);
|
||||||
|
|
||||||
|
//emit asyncReply()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -155,3 +155,19 @@ void JsonRpcServer::setup()
|
|||||||
registerHandler(new AuthenticationHandler(this));
|
registerHandler(new AuthenticationHandler(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JsonRpcServer::clientConnected(const QUuid &clientId)
|
||||||
|
{
|
||||||
|
Q_UNUSED(clientId)
|
||||||
|
}
|
||||||
|
|
||||||
|
void JsonRpcServer::clientDisconnected(const QUuid &clientId)
|
||||||
|
{
|
||||||
|
Q_UNUSED(clientId)
|
||||||
|
}
|
||||||
|
|
||||||
|
void JsonRpcServer::processData(const QUuid &clientId, const QByteArray &data)
|
||||||
|
{
|
||||||
|
Q_UNUSED(clientId)
|
||||||
|
Q_UNUSED(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@ -46,8 +46,8 @@ private slots:
|
|||||||
void clientConnected(const QUuid &clientId);
|
void clientConnected(const QUuid &clientId);
|
||||||
void clientDisconnected(const QUuid &clientId);
|
void clientDisconnected(const QUuid &clientId);
|
||||||
void processData(const QUuid &clientId, const QByteArray &data);
|
void processData(const QUuid &clientId, const QByteArray &data);
|
||||||
void sendNotification(const QVariantMap ¶ms);
|
// void sendNotification(const QVariantMap ¶ms);
|
||||||
void asyncReplyFinished();
|
// void asyncReplyFinished();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -127,13 +127,13 @@ void WebSocketServer::onPing(quint64 elapsedTime, const QByteArray &payload)
|
|||||||
bool WebSocketServer::startServer()
|
bool WebSocketServer::startServer()
|
||||||
{
|
{
|
||||||
m_server = new QWebSocketServer(QCoreApplication::applicationName(), QWebSocketServer::SecureMode, this);
|
m_server = new QWebSocketServer(QCoreApplication::applicationName(), QWebSocketServer::SecureMode, this);
|
||||||
m_server->setSslConfiguration(m_sslConfiguration);
|
m_server->setSslConfiguration(sslConfiguration());
|
||||||
|
|
||||||
connect (m_server, &QWebSocketServer::newConnection, this, &WebSocketServer::onClientConnected);
|
connect (m_server, &QWebSocketServer::newConnection, this, &WebSocketServer::onClientConnected);
|
||||||
connect (m_server, &QWebSocketServer::acceptError, this, &WebSocketServer::onServerError);
|
connect (m_server, &QWebSocketServer::acceptError, this, &WebSocketServer::onServerError);
|
||||||
|
|
||||||
qCDebug(dcWebSocketServer()) << "Starting server" << m_server->serverName() << m_serverUrl.toString();
|
qCDebug(dcWebSocketServer()) << "Starting server" << m_server->serverName() << serverUrl().toString();
|
||||||
if (!m_server->listen(QHostAddress(m_serverUrl.host()), static_cast<quint16>(m_serverUrl.port()))) {
|
if (!m_server->listen(QHostAddress(m_serverUrl.host()), static_cast<quint16>(serverUrl().port()))) {
|
||||||
qCWarning(dcWebSocketServer()) << "Server" << m_server->serverName() << "could not listen on" << serverUrl().toString();
|
qCWarning(dcWebSocketServer()) << "Server" << m_server->serverName() << "could not listen on" << serverUrl().toString();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -151,7 +151,7 @@ bool WebSocketServer::stopServer()
|
|||||||
|
|
||||||
// Delete the server object
|
// Delete the server object
|
||||||
if (m_server) {
|
if (m_server) {
|
||||||
qCDebug(dcWebSocketServer()) << "Stop server" << m_server->serverName() << m_serverUrl.toString();
|
qCDebug(dcWebSocketServer()) << "Stop server" << m_server->serverName() << serverUrl().toString();
|
||||||
m_server->close();
|
m_server->close();
|
||||||
delete m_server;
|
delete m_server;
|
||||||
m_server = nullptr;
|
m_server = nullptr;
|
||||||
|
|||||||
@ -13,3 +13,54 @@ QMAKE_LFLAGS *= -std=c++11
|
|||||||
|
|
||||||
top_srcdir=$$PWD
|
top_srcdir=$$PWD
|
||||||
top_builddir=$$shadowed($$PWD)
|
top_builddir=$$shadowed($$PWD)
|
||||||
|
|
||||||
|
coverage {
|
||||||
|
message("Building with coverage report")
|
||||||
|
|
||||||
|
# Note: this works only if you build in the source dir
|
||||||
|
OBJECTS_DIR =
|
||||||
|
MOC_DIR =
|
||||||
|
|
||||||
|
LIBS += -lgcov
|
||||||
|
QMAKE_CXXFLAGS += --coverage
|
||||||
|
QMAKE_LDFLAGS += --coverage
|
||||||
|
|
||||||
|
QMAKE_EXTRA_TARGETS += coverage cov
|
||||||
|
QMAKE_EXTRA_TARGETS += clean-gcno clean-gcda coverage-html \
|
||||||
|
generate-coverage-html clean-coverage-html coverage-gcovr \
|
||||||
|
generate-gcovr generate-coverage-gcovr clean-coverage-gcovr
|
||||||
|
|
||||||
|
clean-gcno.commands = \
|
||||||
|
"@echo Removing old coverage instrumentation"; \
|
||||||
|
"find -name '*.gcno' -print | xargs -r rm"
|
||||||
|
|
||||||
|
clean-gcda.commands = \
|
||||||
|
"@echo Removing old coverage results"; \
|
||||||
|
"find -name '*.gcda' -print | xargs -r rm"
|
||||||
|
|
||||||
|
coverage-html.depends = clean-gcda check generate-coverage-html
|
||||||
|
|
||||||
|
generate-coverage-html.commands = \
|
||||||
|
"@echo Collecting coverage data"; \
|
||||||
|
"lcov --directory $${top_srcdir} --capture --output-file coverage.info --no-checksum --compat-libtool"; \
|
||||||
|
"lcov --extract coverage.info \"*/server/*.cpp\" --extract coverage.info \"*/libnymea-remoteproxy/*.cpp\" --extract coverage.info \"*/libnymea-remoteproxyclient/*.cpp\" -o coverage.info"; \
|
||||||
|
"lcov --remove coverage.info \"moc_*.cpp\" --remove coverage.info \"*/test/*\" -o coverage.info"; \
|
||||||
|
"LANG=C genhtml --prefix $${top_srcdir} --output-directory coverage-html --title \"nymea-remoteproxy coverage\" --legend --show-details coverage.info"
|
||||||
|
|
||||||
|
clean-coverage-html.depends = clean-gcda
|
||||||
|
clean-coverage-html.commands = \
|
||||||
|
"lcov --directory $${top_srcdir} -z"; \
|
||||||
|
"rm -rf coverage.info coverage-html"
|
||||||
|
|
||||||
|
coverage-gcovr.depends = clean-gcda check generate-coverage-gcovr
|
||||||
|
|
||||||
|
generate-coverage-gcovr.commands = \
|
||||||
|
"@echo Generating coverage GCOVR report"; \
|
||||||
|
"gcovr -x -r $${top_srcdir} -o $${top_srcdir}/coverage.xml -e \".*/moc_.*\" -e \"tests/.*\" -e \".*\\.h\""
|
||||||
|
|
||||||
|
clean-coverage-gcovr.depends = clean-gcda
|
||||||
|
clean-coverage-gcovr.commands = \
|
||||||
|
"rm -rf $${top_srcdir}/coverage.xml"
|
||||||
|
|
||||||
|
QMAKE_CLEAN += *.gcda *.gcno coverage.info coverage.xml
|
||||||
|
}
|
||||||
|
|||||||
@ -5,4 +5,3 @@ SUBDIRS += server libnymea-remoteproxy libnymea-remoteproxyclient tests
|
|||||||
|
|
||||||
server.depends = libnymea-remoteproxy
|
server.depends = libnymea-remoteproxy
|
||||||
tests.depends = libnymea-remoteproxy libnymea-remoteproxyclient
|
tests.depends = libnymea-remoteproxy libnymea-remoteproxyclient
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
#include <QMetaType>
|
#include <QMetaType>
|
||||||
#include <QSignalSpy>
|
#include <QSignalSpy>
|
||||||
|
#include <QWebSocket>
|
||||||
|
#include <QWebSocketServer>
|
||||||
|
|
||||||
RemoteProxyTests::RemoteProxyTests(QObject *parent) :
|
RemoteProxyTests::RemoteProxyTests(QObject *parent) :
|
||||||
QObject(parent)
|
QObject(parent)
|
||||||
@ -51,18 +53,30 @@ void RemoteProxyTests::restartEngine()
|
|||||||
QVERIFY(Engine::exists());
|
QVERIFY(Engine::exists());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RemoteProxyTests::startEngine()
|
||||||
|
{
|
||||||
|
if (!Engine::exists()) {
|
||||||
|
Engine::instance();
|
||||||
|
QVERIFY(Engine::exists());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void RemoteProxyTests::startServer()
|
void RemoteProxyTests::startServer()
|
||||||
{
|
{
|
||||||
restartEngine();
|
startEngine();
|
||||||
|
|
||||||
|
QString serverName = "nymea-remoteproxy-testserver";
|
||||||
|
Engine::instance()->setAuthenticationServerUrl(QUrl("https://localhost"));
|
||||||
|
Engine::instance()->setServerName(serverName);
|
||||||
Engine::instance()->setAuthenticator(m_authenticator);
|
Engine::instance()->setAuthenticator(m_authenticator);
|
||||||
Engine::instance()->setWebSocketServerPort(m_port);
|
Engine::instance()->setWebSocketServerPort(m_port);
|
||||||
Engine::instance()->setWebSocketServerHostAddress(QHostAddress::LocalHost);
|
Engine::instance()->setWebSocketServerHostAddress(QHostAddress::LocalHost);
|
||||||
Engine::instance()->setSslConfiguration(m_sslConfiguration);
|
Engine::instance()->setSslConfiguration(m_sslConfiguration);
|
||||||
Engine::instance()->start();
|
Engine::instance()->start();
|
||||||
|
|
||||||
|
QVERIFY(Engine::instance()->serverName() == serverName);
|
||||||
QVERIFY(Engine::instance()->running());
|
QVERIFY(Engine::instance()->running());
|
||||||
|
QVERIFY(Engine::instance()->webSocketServer()->running());
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteProxyTests::stopServer()
|
void RemoteProxyTests::stopServer()
|
||||||
@ -88,32 +102,73 @@ void RemoteProxyTests::cleanupTestCase()
|
|||||||
cleanUpEngine();
|
cleanUpEngine();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteProxyTests::authenticate()
|
|
||||||
{
|
|
||||||
// // Start the server
|
|
||||||
// startServer();
|
|
||||||
|
|
||||||
// // Connect to the server
|
|
||||||
// RemoteProxyConnector *connector = new RemoteProxyConnector(this);
|
|
||||||
// connector->setInsecureConnection(true);
|
|
||||||
|
|
||||||
// QSignalSpy spy(connector, &RemoteProxyConnector::connected);
|
|
||||||
// connector->connectServer(QHostAddress::LocalHost, m_port);
|
|
||||||
// spy.wait();
|
|
||||||
|
|
||||||
// connector->disconnectServer();
|
|
||||||
// connector->deleteLater();
|
|
||||||
// Engine::instance()->stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RemoteProxyTests::startStopServer()
|
void RemoteProxyTests::startStopServer()
|
||||||
{
|
{
|
||||||
restartEngine();
|
startEngine();
|
||||||
startServer();
|
startServer();
|
||||||
stopServer();
|
stopServer();
|
||||||
cleanUpEngine();
|
cleanUpEngine();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RemoteProxyTests::webserverConnectionBlocked()
|
||||||
|
{
|
||||||
|
// Create a dummy server which blocks the port
|
||||||
|
QWebSocketServer dummyServer("dummy-server", QWebSocketServer::NonSecureMode);
|
||||||
|
dummyServer.listen(QHostAddress::LocalHost, m_port);
|
||||||
|
|
||||||
|
// Start proxy webserver
|
||||||
|
Engine::instance()->setWebSocketServerPort(m_port);
|
||||||
|
Engine::instance()->setAuthenticator(m_authenticator);
|
||||||
|
Engine::instance()->setWebSocketServerHostAddress(QHostAddress::LocalHost);
|
||||||
|
Engine::instance()->setSslConfiguration(m_sslConfiguration);
|
||||||
|
Engine::instance()->start();
|
||||||
|
|
||||||
|
// Make sure the server is not running
|
||||||
|
QVERIFY(Engine::instance()->running());
|
||||||
|
QVERIFY(!Engine::instance()->webSocketServer()->running());
|
||||||
|
|
||||||
|
dummyServer.close();
|
||||||
|
|
||||||
|
// Try again
|
||||||
|
startServer();
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
stopServer();
|
||||||
|
cleanUpEngine();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoteProxyTests::webserverSocketVersion()
|
||||||
|
{
|
||||||
|
// Start the server
|
||||||
|
startServer();
|
||||||
|
|
||||||
|
QUrl serverUrl;
|
||||||
|
serverUrl.setScheme("wss");
|
||||||
|
serverUrl.setHost("localhost");
|
||||||
|
serverUrl.setPort(m_port);
|
||||||
|
|
||||||
|
// Create a websocket with invalid version
|
||||||
|
QWebSocket socket("tests", QWebSocketProtocol::Version8);
|
||||||
|
socket.open(serverUrl);
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
stopServer();
|
||||||
|
cleanUpEngine();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoteProxyTests::webserverConnection()
|
||||||
|
{
|
||||||
|
// Start the server
|
||||||
|
startServer();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
stopServer();
|
||||||
|
cleanUpEngine();
|
||||||
|
}
|
||||||
|
|
||||||
void RemoteProxyTests::sslConfigurations()
|
void RemoteProxyTests::sslConfigurations()
|
||||||
{
|
{
|
||||||
// Start the server
|
// Start the server
|
||||||
@ -147,4 +202,23 @@ void RemoteProxyTests::sslConfigurations()
|
|||||||
Engine::instance()->stop();
|
Engine::instance()->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RemoteProxyTests::authenticate()
|
||||||
|
{
|
||||||
|
// // Start the server
|
||||||
|
// startServer();
|
||||||
|
|
||||||
|
// // Connect to the server
|
||||||
|
// RemoteProxyConnector *connector = new RemoteProxyConnector(this);
|
||||||
|
// connector->setInsecureConnection(true);
|
||||||
|
|
||||||
|
// QSignalSpy spy(connector, &RemoteProxyConnector::connected);
|
||||||
|
// connector->connectServer(QHostAddress::LocalHost, m_port);
|
||||||
|
// spy.wait();
|
||||||
|
|
||||||
|
// connector->disconnectServer();
|
||||||
|
// connector->deleteLater();
|
||||||
|
// Engine::instance()->stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
QTEST_MAIN(RemoteProxyTests)
|
QTEST_MAIN(RemoteProxyTests)
|
||||||
|
|||||||
@ -25,6 +25,7 @@ private:
|
|||||||
|
|
||||||
void cleanUpEngine();
|
void cleanUpEngine();
|
||||||
void restartEngine();
|
void restartEngine();
|
||||||
|
void startEngine();
|
||||||
void startServer();
|
void startServer();
|
||||||
void stopServer();
|
void stopServer();
|
||||||
|
|
||||||
@ -35,8 +36,11 @@ protected slots:
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void startStopServer();
|
void startStopServer();
|
||||||
void authenticate();
|
void webserverConnectionBlocked();
|
||||||
|
void webserverSocketVersion();
|
||||||
|
void webserverConnection();
|
||||||
void sslConfigurations();
|
void sslConfigurations();
|
||||||
|
void authenticate();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user