tst_qlocalsocket: get rid of QtScript dependency
Removing the lackey executable that needs QtScript to be built. This was a qscript bastard that was able to run a client and a server script. It's replaced by a C++ version with the same functionality. Nice side effect: the two second wait per test row could be removed. The client executable is now waiting for the server to be created. Task-number: QTBUG-24142 Change-Id: I135b75abf6620d3b0af50dc226ea8c81c2bf4149 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com> Reviewed-by: Rohan McGovern <rohan.mcgovern@nokia.com>
This commit is contained in:
parent
0510fc149e
commit
c54a2dca16
@ -1,2 +1 @@
|
|||||||
tst_qlocalsocket
|
tst_qlocalsocket
|
||||||
lackey/lackey.exe
|
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
#include(../src/src.pri)
|
|
||||||
|
|
||||||
QT = core script network testlib
|
|
||||||
|
|
||||||
DESTDIR = ./
|
|
||||||
|
|
||||||
win32: CONFIG += console
|
|
||||||
mac:CONFIG -= app_bundle
|
|
||||||
|
|
||||||
DEFINES += QLOCALSERVER_DEBUG
|
|
||||||
DEFINES += QLOCALSOCKET_DEBUG
|
|
||||||
|
|
||||||
SOURCES += main.cpp
|
|
||||||
TARGET = lackey
|
|
||||||
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
|
|
@ -1,296 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
|
||||||
** Contact: http://www.qt-project.org/legal
|
|
||||||
**
|
|
||||||
** This file is part of the test suite of the Qt Toolkit.
|
|
||||||
**
|
|
||||||
** $QT_BEGIN_LICENSE:LGPL$
|
|
||||||
** Commercial License Usage
|
|
||||||
** Licensees holding valid commercial Qt licenses may use this file in
|
|
||||||
** accordance with the commercial license agreement provided with the
|
|
||||||
** Software or, alternatively, in accordance with the terms contained in
|
|
||||||
** a written agreement between you and Digia. For licensing terms and
|
|
||||||
** conditions see http://qt.digia.com/licensing. For further information
|
|
||||||
** use the contact form at http://qt.digia.com/contact-us.
|
|
||||||
**
|
|
||||||
** GNU Lesser General Public License Usage
|
|
||||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
|
||||||
** General Public License version 2.1 as published by the Free Software
|
|
||||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
|
||||||
** packaging of this file. Please review the following information to
|
|
||||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
|
||||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
|
||||||
**
|
|
||||||
** In addition, as a special exception, Digia gives you certain additional
|
|
||||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
** GNU General Public License Usage
|
|
||||||
** Alternatively, this file may be used under the terms of the GNU
|
|
||||||
** General Public License version 3.0 as published by the Free Software
|
|
||||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
|
||||||
** packaging of this file. Please review the following information to
|
|
||||||
** ensure the GNU General Public License version 3.0 requirements will be
|
|
||||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
|
||||||
**
|
|
||||||
**
|
|
||||||
** $QT_END_LICENSE$
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
#include <qscriptengine.h>
|
|
||||||
#include <QFile>
|
|
||||||
#include <QTest>
|
|
||||||
|
|
||||||
#include <qlocalsocket.h>
|
|
||||||
#include <qlocalserver.h>
|
|
||||||
|
|
||||||
class QScriptLocalSocket : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
Q_PROPERTY(QString serverName WRITE connectToServer READ serverName)
|
|
||||||
|
|
||||||
public:
|
|
||||||
QScriptLocalSocket(QObject *parent = 0) : QObject(parent)
|
|
||||||
{
|
|
||||||
lc = new QLocalSocket(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
QString serverName()
|
|
||||||
{
|
|
||||||
return lc->serverName();
|
|
||||||
}
|
|
||||||
|
|
||||||
void connectToServer(const QString &name) {
|
|
||||||
lc->connectToServer(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sleep(int x) const
|
|
||||||
{
|
|
||||||
QTest::qSleep(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isConnected() {
|
|
||||||
return (lc->state() == QLocalSocket::ConnectedState);
|
|
||||||
}
|
|
||||||
|
|
||||||
void open() {
|
|
||||||
lc->open(QIODevice::ReadWrite);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool waitForConnected() {
|
|
||||||
return lc->waitForConnected(100000);
|
|
||||||
}
|
|
||||||
void waitForReadyRead() {
|
|
||||||
lc->waitForReadyRead();
|
|
||||||
}
|
|
||||||
|
|
||||||
void write(const QString &string) {
|
|
||||||
QTextStream out(lc);
|
|
||||||
out << string << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool waitForBytesWritten(int t = 3000) {
|
|
||||||
return lc->waitForBytesWritten(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString readLine() {
|
|
||||||
QTextStream in(lc);
|
|
||||||
return in.readLine();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString errorString() {
|
|
||||||
return lc->errorString();
|
|
||||||
}
|
|
||||||
|
|
||||||
void close() {
|
|
||||||
lc->close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
QLocalSocket *lc;
|
|
||||||
};
|
|
||||||
|
|
||||||
class QScriptLocalServer : public QLocalServer
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
Q_PROPERTY(int maxPendingConnections WRITE setMaxPendingConnections READ maxPendingConnections)
|
|
||||||
Q_PROPERTY(QString name WRITE listen READ serverName)
|
|
||||||
Q_PROPERTY(bool listening READ isListening)
|
|
||||||
|
|
||||||
public:
|
|
||||||
QScriptLocalServer(QObject *parent = 0) : QLocalServer(parent)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
bool listen(const QString &name) {
|
|
||||||
if (!QLocalServer::listen(name)) {
|
|
||||||
if (serverError() == QAbstractSocket::AddressInUseError) {
|
|
||||||
QFile::remove(serverName());
|
|
||||||
return QLocalServer::listen(name);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
QScriptLocalSocket *nextConnection() {
|
|
||||||
QLocalSocket *other = nextPendingConnection();
|
|
||||||
QScriptLocalSocket *s = new QScriptLocalSocket(this);
|
|
||||||
delete s->lc;
|
|
||||||
s->lc = other;
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool waitForNewConnection() {
|
|
||||||
return QLocalServer::waitForNewConnection(30000);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString errorString() {
|
|
||||||
return QLocalServer::errorString();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
static QScriptValue _q_ScriptValueFromQObject(QScriptEngine *engine, T* const &in)
|
|
||||||
{
|
|
||||||
return engine->newQObject(in);
|
|
||||||
}
|
|
||||||
template <typename T>
|
|
||||||
static void _q_ScriptValueToQObject(const QScriptValue &v, T* &out)
|
|
||||||
{ out = qobject_cast<T*>(v.toQObject());
|
|
||||||
}
|
|
||||||
template <typename T>
|
|
||||||
static int _q_ScriptRegisterQObjectMetaType(QScriptEngine *engine, const QScriptValue &prototype)
|
|
||||||
{
|
|
||||||
return qScriptRegisterMetaType<T*>(engine, _q_ScriptValueFromQObject<T>, _q_ScriptValueToQObject<T>, prototype);
|
|
||||||
}
|
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
|
||||||
Q_SCRIPT_DECLARE_QMETAOBJECT(QScriptLocalSocket, QObject*);
|
|
||||||
Q_SCRIPT_DECLARE_QMETAOBJECT(QScriptLocalServer, QObject*);
|
|
||||||
QT_END_NAMESPACE
|
|
||||||
|
|
||||||
static void interactive(QScriptEngine &eng)
|
|
||||||
{
|
|
||||||
QTextStream qin(stdin, QFile::ReadOnly);
|
|
||||||
|
|
||||||
const char *qscript_prompt = "qs> ";
|
|
||||||
const char *dot_prompt = ".... ";
|
|
||||||
const char *prompt = qscript_prompt;
|
|
||||||
|
|
||||||
QString code;
|
|
||||||
|
|
||||||
forever {
|
|
||||||
QString line;
|
|
||||||
|
|
||||||
printf("%s", prompt);
|
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
line = qin.readLine();
|
|
||||||
if (line.isNull())
|
|
||||||
break;
|
|
||||||
|
|
||||||
code += line;
|
|
||||||
code += QLatin1Char('\n');
|
|
||||||
|
|
||||||
if (line.trimmed().isEmpty()) {
|
|
||||||
continue;
|
|
||||||
|
|
||||||
} else if (! eng.canEvaluate(code)) {
|
|
||||||
prompt = dot_prompt;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
QScriptValue result = eng.evaluate(code);
|
|
||||||
code.clear();
|
|
||||||
prompt = qscript_prompt;
|
|
||||||
if (!result.isUndefined())
|
|
||||||
fprintf(stderr, "%s\n", qPrintable(result.toString()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Q_DECLARE_METATYPE(QScriptLocalSocket*)
|
|
||||||
Q_DECLARE_METATYPE(QScriptLocalServer*)
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
QCoreApplication app(argc, argv);
|
|
||||||
QScriptEngine eng;
|
|
||||||
QScriptValue globalObject = eng.globalObject();
|
|
||||||
|
|
||||||
_q_ScriptRegisterQObjectMetaType<QScriptLocalServer>(&eng, QScriptValue());
|
|
||||||
|
|
||||||
QScriptValue lss = qScriptValueFromQMetaObject<QScriptLocalServer>(&eng);
|
|
||||||
eng.globalObject().setProperty("QScriptLocalServer", lss);
|
|
||||||
|
|
||||||
_q_ScriptRegisterQObjectMetaType<QScriptLocalSocket>(&eng, QScriptValue());
|
|
||||||
|
|
||||||
QScriptValue lsc = qScriptValueFromQMetaObject<QScriptLocalSocket>(&eng);
|
|
||||||
eng.globalObject().setProperty("QScriptLocalSocket", lsc);
|
|
||||||
|
|
||||||
if (! *++argv) {
|
|
||||||
interactive(eng);
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList arguments;
|
|
||||||
for (int i = 0; i < argc - 1; ++i)
|
|
||||||
arguments << QString::fromLocal8Bit(argv[i]);
|
|
||||||
|
|
||||||
while (!arguments.isEmpty()) {
|
|
||||||
QString fn = arguments.takeFirst();
|
|
||||||
|
|
||||||
if (fn == QLatin1String("-i")) {
|
|
||||||
interactive(eng);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString contents;
|
|
||||||
|
|
||||||
if (fn == QLatin1String("-")) {
|
|
||||||
QTextStream stream(stdin, QFile::ReadOnly);
|
|
||||||
contents = stream.readAll();
|
|
||||||
} else {
|
|
||||||
QFile file(fn);
|
|
||||||
if (!file.exists()) {
|
|
||||||
fprintf(stderr, "%s doesn't exists\n", qPrintable(fn));
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
if (file.open(QFile::ReadOnly)) {
|
|
||||||
QTextStream stream(&file);
|
|
||||||
contents = stream.readAll();
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (contents.isEmpty())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (contents[0] == '#') {
|
|
||||||
contents.prepend("//");
|
|
||||||
QScriptValue args = eng.newArray();
|
|
||||||
args.setProperty("0", QScriptValue(&eng, fn));
|
|
||||||
int i = 1;
|
|
||||||
while (!arguments.isEmpty())
|
|
||||||
args.setProperty(i++, QScriptValue(&eng, arguments.takeFirst()));
|
|
||||||
eng.currentContext()->activationObject().setProperty("args", args);
|
|
||||||
}
|
|
||||||
QScriptValue r = eng.evaluate(contents);
|
|
||||||
if (eng.hasUncaughtException()) {
|
|
||||||
int line = eng.uncaughtExceptionLineNumber();
|
|
||||||
fprintf(stderr, "%d: %s\n\t%s\n\n", line, qPrintable(fn), qPrintable(r.toString()));
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
if (r.isNumber())
|
|
||||||
return r.toInt32();
|
|
||||||
}
|
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "main.moc"
|
|
@ -1,35 +0,0 @@
|
|||||||
#/bin/qscript
|
|
||||||
function QVERIFY(x, socket) {
|
|
||||||
if (!(x)) {
|
|
||||||
throw(socket.errorString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var socket = new QScriptLocalSocket;
|
|
||||||
var tries = 0;
|
|
||||||
do {
|
|
||||||
socket.serverName = "qlocalsocket_autotest";
|
|
||||||
if ((socket.errorString() != "QLocalSocket::connectToServer: Invalid name")
|
|
||||||
&& (socket.errorString() != "QLocalSocket::connectToServer: Connection refused"))
|
|
||||||
break;
|
|
||||||
socket.sleep(1);
|
|
||||||
++tries;
|
|
||||||
print("isConnected:", socket.isConnected());
|
|
||||||
} while ((socket.errorString() == "QLocalSocket::connectToServer: Invalid name"
|
|
||||||
|| (socket.errorString() == "QlocalSocket::connectToServer: Connection refused"))
|
|
||||||
&& tries < 5000);
|
|
||||||
if (tries == 5000) {
|
|
||||||
print("too many tries, exiting");
|
|
||||||
} else {
|
|
||||||
socket.waitForConnected();
|
|
||||||
//print("isConnected:", socket.isConnected());
|
|
||||||
if (!socket.isConnected())
|
|
||||||
print("Not Connected:", socket.errorString());
|
|
||||||
socket.waitForReadyRead();
|
|
||||||
var text = socket.readLine();
|
|
||||||
var testLine = "test";
|
|
||||||
QVERIFY((text == testLine), socket);
|
|
||||||
QVERIFY((socket.errorString() == "Unknown error"), socket);
|
|
||||||
socket.close();
|
|
||||||
//print("client: exiting", text);
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
#/bin/qscript
|
|
||||||
function QVERIFY(x, server) {
|
|
||||||
if (!(x)) {
|
|
||||||
throw(server.errorString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var server = new QScriptLocalServer;
|
|
||||||
QVERIFY(server.listen("qlocalsocket_autotest"), server);
|
|
||||||
var done = args[1];
|
|
||||||
var testLine = "test";
|
|
||||||
while (done > 0) {
|
|
||||||
QVERIFY(server.waitForNewConnection(), server);
|
|
||||||
var serverSocket = server.nextConnection();
|
|
||||||
serverSocket.write(testLine);
|
|
||||||
QVERIFY(serverSocket.waitForBytesWritten(), serverSocket);
|
|
||||||
QVERIFY(serverSocket.errorString() == ""
|
|
||||||
||serverSocket.errorString() == "Unknown error", serverSocket);
|
|
||||||
--done;
|
|
||||||
}
|
|
@ -1,2 +1,2 @@
|
|||||||
TEMPLATE = subdirs
|
TEMPLATE = subdirs
|
||||||
SUBDIRS = test # lackey should be moved to the QtScript module
|
SUBDIRS = test socketprocess
|
||||||
|
150
tests/auto/network/socket/qlocalsocket/socketprocess/main.cpp
Normal file
150
tests/auto/network/socket/qlocalsocket/socketprocess/main.cpp
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the test suite of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Digia. For licensing terms and
|
||||||
|
** conditions see http://qt.digia.com/licensing. For further information
|
||||||
|
** use the contact form at http://qt.digia.com/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 2.1 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||||
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Digia gives you certain additional
|
||||||
|
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3.0 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU General Public License version 3.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include <qcoreapplication.h>
|
||||||
|
#include <qlocalsocket.h>
|
||||||
|
#include <qlocalserver.h>
|
||||||
|
#include <qsystemsemaphore.h>
|
||||||
|
|
||||||
|
const QString serverName = QStringLiteral("qlocalsocket_autotest");
|
||||||
|
const QByteArray testData("test");
|
||||||
|
QSystemSemaphore *semaphore = 0;
|
||||||
|
|
||||||
|
bool runServer(int numberOfConnections)
|
||||||
|
{
|
||||||
|
QLocalServer *server = new QLocalServer(qApp);
|
||||||
|
if (!server->removeServer(serverName)) {
|
||||||
|
fprintf(stderr, "server: cannot remove server: %s\n", qPrintable(server->errorString()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
printf("server: listen on \"%s\"\n", qPrintable(serverName));
|
||||||
|
if (!server->listen(serverName)) {
|
||||||
|
fprintf(stderr, "server: listen failed: %s\n", qPrintable(server->errorString()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
semaphore->release();
|
||||||
|
for (int i = 1; i <= numberOfConnections; ++i) {
|
||||||
|
printf("server: wait for connection %d\n", i);
|
||||||
|
if (!server->waitForNewConnection(30000)) {
|
||||||
|
semaphore->acquire();
|
||||||
|
fprintf(stderr, "server: waitForNewConnection failed: %s\n",
|
||||||
|
qPrintable(server->errorString()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
QLocalSocket *socket = server->nextPendingConnection();
|
||||||
|
printf("server: writing \"%s\"\n", testData.data());
|
||||||
|
socket->write(testData);
|
||||||
|
if (!socket->waitForBytesWritten()) {
|
||||||
|
semaphore->acquire();
|
||||||
|
fprintf(stderr, "server: waitForBytesWritten failed: %s\n",
|
||||||
|
qPrintable(socket->errorString()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
printf("server: data written\n");
|
||||||
|
if (socket->error() != QLocalSocket::UnknownSocketError) {
|
||||||
|
semaphore->acquire();
|
||||||
|
fprintf(stderr, "server: socket error %d\n", socket->error());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
semaphore->acquire();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool runClient()
|
||||||
|
{
|
||||||
|
semaphore->acquire(); // wait until the server is up and running
|
||||||
|
semaphore->release();
|
||||||
|
|
||||||
|
QLocalSocket socket;
|
||||||
|
printf("client: connecting to \"%s\"\n", qPrintable(serverName));
|
||||||
|
socket.connectToServer(serverName, QLocalSocket::ReadWrite);
|
||||||
|
if (!socket.waitForConnected()) {
|
||||||
|
fprintf(stderr, "client: waitForConnected failed: %s\n",
|
||||||
|
qPrintable(socket.errorString()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
printf("client: connected\n");
|
||||||
|
if (!socket.waitForReadyRead()) {
|
||||||
|
fprintf(stderr, "client: waitForReadyRead failed: %s\n",
|
||||||
|
qPrintable(socket.errorString()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
printf("client: data is available for reading\n");
|
||||||
|
const QByteArray data = socket.readLine();
|
||||||
|
printf("client: received \"%s\"\n", data.data());
|
||||||
|
if (data != testData) {
|
||||||
|
fprintf(stderr, "client: received unexpected data\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
QCoreApplication app(argc, argv);
|
||||||
|
QSystemSemaphore s("tst_qlocalsocket_socketprocess");
|
||||||
|
semaphore = &s;
|
||||||
|
if (argc < 2)
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
if (strcmp(argv[1], "--server") == 0) {
|
||||||
|
if (argc < 3) {
|
||||||
|
fprintf(stderr, "--server needs the number of incoming connections\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
bool ok;
|
||||||
|
int n = QByteArray(argv[2]).toInt(&ok);
|
||||||
|
if (!ok) {
|
||||||
|
fprintf(stderr, "Cannot convert %s to a number.\n", argv[2]);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
if (!runServer(n))
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
} else if (strcmp(argv[1], "--client") == 0) {
|
||||||
|
if (!runClient())
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "unknown command line option: %s\n", argv[1]);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
QT = core network testlib
|
||||||
|
|
||||||
|
DESTDIR = ./
|
||||||
|
TARGET = socketprocess
|
||||||
|
|
||||||
|
win32:CONFIG += console
|
||||||
|
mac:CONFIG -= app_bundle
|
||||||
|
|
||||||
|
SOURCES += main.cpp
|
@ -735,53 +735,73 @@ void tst_QLocalSocket::processConnection_data()
|
|||||||
{
|
{
|
||||||
QTest::addColumn<int>("processes");
|
QTest::addColumn<int>("processes");
|
||||||
QTest::newRow("1 client") << 1;
|
QTest::newRow("1 client") << 1;
|
||||||
#ifndef Q_OS_WIN
|
|
||||||
QTest::newRow("2 clients") << 2;
|
QTest::newRow("2 clients") << 2;
|
||||||
QTest::newRow("5 clients") << 5;
|
QTest::newRow("5 clients") << 5;
|
||||||
#endif
|
|
||||||
QTest::newRow("30 clients") << 30;
|
QTest::newRow("30 clients") << 30;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ProcessOutputDumper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ProcessOutputDumper(QProcess *p = 0)
|
||||||
|
: process(p)
|
||||||
|
{}
|
||||||
|
|
||||||
|
~ProcessOutputDumper()
|
||||||
|
{
|
||||||
|
if (process)
|
||||||
|
fputs(process->readAll().data(), stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
process = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
QProcess *process;
|
||||||
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Create external processes that produce and consume.
|
Create external processes that produce and consume.
|
||||||
*/
|
*/
|
||||||
void tst_QLocalSocket::processConnection()
|
void tst_QLocalSocket::processConnection()
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
# define EXE_SUFFIX ".exe"
|
const QString exeSuffix = QStringLiteral(".exe");
|
||||||
#else
|
#else
|
||||||
# define EXE_SUFFIX
|
const QString exeSuffix;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ### lackey is currently not build
|
QString socketProcess = QStringLiteral("socketprocess/socketprocess") + exeSuffix;
|
||||||
QEXPECT_FAIL("", "lackey is currently not built due to qscript dependency, QTBUG-24142", Abort);
|
QVERIFY(QFile::exists(socketProcess));
|
||||||
QVERIFY(QFile::exists("lackey/lackey" EXE_SUFFIX));
|
|
||||||
|
|
||||||
QFETCH(int, processes);
|
QFETCH(int, processes);
|
||||||
QStringList serverArguments = QStringList() << SRCDIR "lackey/scripts/server.js" << QString::number(processes);
|
QStringList serverArguments = QStringList() << "--server" << QString::number(processes);
|
||||||
QProcess producer;
|
QProcess producer;
|
||||||
producer.setProcessChannelMode(QProcess::ForwardedChannels);
|
ProcessOutputDumper producerOutputDumper(&producer);
|
||||||
QList<QProcess*> consumers;
|
QList<QProcess*> consumers;
|
||||||
producer.start("lackey/lackey", serverArguments);
|
producer.start(socketProcess, serverArguments);
|
||||||
QVERIFY2(producer.waitForStarted(-1), qPrintable(producer.errorString()));
|
QVERIFY2(producer.waitForStarted(-1), qPrintable(producer.errorString()));
|
||||||
QTest::qWait(2000);
|
|
||||||
for (int i = 0; i < processes; ++i) {
|
for (int i = 0; i < processes; ++i) {
|
||||||
QStringList arguments = QStringList() << SRCDIR "lackey/scripts/client.js";
|
QStringList arguments = QStringList() << "--client";
|
||||||
QProcess *p = new QProcess;
|
QProcess *p = new QProcess;
|
||||||
p->setProcessChannelMode(QProcess::ForwardedChannels);
|
|
||||||
consumers.append(p);
|
consumers.append(p);
|
||||||
p->start("lackey/lackey", arguments);
|
p->start(socketProcess, arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!consumers.isEmpty()) {
|
while (!consumers.isEmpty()) {
|
||||||
consumers.first()->waitForFinished(20000);
|
|
||||||
QCOMPARE(consumers.first()->exitStatus(), QProcess::NormalExit);
|
|
||||||
QCOMPARE(consumers.first()->exitCode(), 0);
|
|
||||||
QProcess *consumer = consumers.takeFirst();
|
QProcess *consumer = consumers.takeFirst();
|
||||||
|
ProcessOutputDumper consumerOutputDumper(consumer);
|
||||||
|
consumer->waitForFinished(20000);
|
||||||
|
QCOMPARE(consumer->exitStatus(), QProcess::NormalExit);
|
||||||
|
QCOMPARE(consumer->exitCode(), 0);
|
||||||
|
consumerOutputDumper.clear();
|
||||||
consumer->terminate();
|
consumer->terminate();
|
||||||
delete consumer;
|
delete consumer;
|
||||||
}
|
}
|
||||||
producer.waitForFinished(15000);
|
producer.waitForFinished(15000);
|
||||||
|
producerOutputDumper.clear();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user