tst_qlocalsocket: get rid of QtScript dependency
authorJoerg Bornemann <joerg.bornemann@digia.com>
Tue, 16 Oct 2012 08:34:44 +0000 (10:34 +0200)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Fri, 19 Oct 2012 00:43:05 +0000 (02:43 +0200)
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>
tests/auto/network/socket/qlocalsocket/.gitignore
tests/auto/network/socket/qlocalsocket/lackey/lackey.pro [deleted file]
tests/auto/network/socket/qlocalsocket/lackey/main.cpp [deleted file]
tests/auto/network/socket/qlocalsocket/lackey/scripts/client.js [deleted file]
tests/auto/network/socket/qlocalsocket/lackey/scripts/server.js [deleted file]
tests/auto/network/socket/qlocalsocket/qlocalsocket.pro
tests/auto/network/socket/qlocalsocket/socketprocess/main.cpp [new file with mode: 0644]
tests/auto/network/socket/qlocalsocket/socketprocess/socketprocess.pro [new file with mode: 0644]
tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp

diff --git a/tests/auto/network/socket/qlocalsocket/lackey/lackey.pro b/tests/auto/network/socket/qlocalsocket/lackey/lackey.pro
deleted file mode 100644 (file)
index 6e69732..0000000
+++ /dev/null
@@ -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
diff --git a/tests/auto/network/socket/qlocalsocket/lackey/main.cpp b/tests/auto/network/socket/qlocalsocket/lackey/main.cpp
deleted file mode 100644 (file)
index 112bf05..0000000
+++ /dev/null
@@ -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"
diff --git a/tests/auto/network/socket/qlocalsocket/lackey/scripts/client.js b/tests/auto/network/socket/qlocalsocket/lackey/scripts/client.js
deleted file mode 100755 (executable)
index 76cc0b9..0000000
+++ /dev/null
@@ -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);
-}
diff --git a/tests/auto/network/socket/qlocalsocket/lackey/scripts/server.js b/tests/auto/network/socket/qlocalsocket/lackey/scripts/server.js
deleted file mode 100644 (file)
index 98a83bc..0000000
+++ /dev/null
@@ -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;
-}
index fb09dd6..cbf5d16 100644 (file)
@@ -1,2 +1,2 @@
 TEMPLATE = subdirs
-SUBDIRS = test # lackey should be moved to the QtScript module
+SUBDIRS = test socketprocess
diff --git a/tests/auto/network/socket/qlocalsocket/socketprocess/main.cpp b/tests/auto/network/socket/qlocalsocket/socketprocess/main.cpp
new file mode 100644 (file)
index 0000000..de78f9a
--- /dev/null
@@ -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;
+}
diff --git a/tests/auto/network/socket/qlocalsocket/socketprocess/socketprocess.pro b/tests/auto/network/socket/qlocalsocket/socketprocess/socketprocess.pro
new file mode 100644 (file)
index 0000000..643c4c5
--- /dev/null
@@ -0,0 +1,9 @@
+QT = core network testlib
+
+DESTDIR = ./
+TARGET = socketprocess
+
+win32:CONFIG += console
+mac:CONFIG -= app_bundle
+
+SOURCES += main.cpp
index 8bcb8cc..4f6fc46 100644 (file)
@@ -735,53 +735,73 @@ void tst_QLocalSocket::processConnection_data()
 {
     QTest::addColumn<int>("processes");
     QTest::newRow("1 client") << 1;
-#ifndef Q_OS_WIN
     QTest::newRow("2 clients") << 2;
     QTest::newRow("5 clients") << 5;
-#endif
     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.
  */
 void tst_QLocalSocket::processConnection()
 {
 #ifdef Q_OS_WIN
-#  define EXE_SUFFIX ".exe"
+    const QString exeSuffix = QStringLiteral(".exe");
 #else
-#  define EXE_SUFFIX
+    const QString exeSuffix;
 #endif
 
-// ### lackey is currently not build
-    QEXPECT_FAIL("", "lackey is currently not built due to qscript dependency, QTBUG-24142", Abort);
-    QVERIFY(QFile::exists("lackey/lackey" EXE_SUFFIX));
+    QString socketProcess = QStringLiteral("socketprocess/socketprocess") + exeSuffix;
+    QVERIFY(QFile::exists(socketProcess));
 
     QFETCH(int, processes);
-    QStringList serverArguments = QStringList() << SRCDIR "lackey/scripts/server.js" << QString::number(processes);
+    QStringList serverArguments = QStringList() << "--server" << QString::number(processes);
     QProcess producer;
-    producer.setProcessChannelMode(QProcess::ForwardedChannels);
+    ProcessOutputDumper producerOutputDumper(&producer);
     QList<QProcess*> consumers;
-    producer.start("lackey/lackey", serverArguments);
+    producer.start(socketProcess, serverArguments);
     QVERIFY2(producer.waitForStarted(-1), qPrintable(producer.errorString()));
-    QTest::qWait(2000);
     for (int i = 0; i < processes; ++i) {
-       QStringList arguments = QStringList() << SRCDIR "lackey/scripts/client.js";
+        QStringList arguments = QStringList() << "--client";
         QProcess *p = new QProcess;
-        p->setProcessChannelMode(QProcess::ForwardedChannels);
         consumers.append(p);
-        p->start("lackey/lackey", arguments);
+        p->start(socketProcess, arguments);
     }
 
     while (!consumers.isEmpty()) {
-        consumers.first()->waitForFinished(20000);
-        QCOMPARE(consumers.first()->exitStatus(), QProcess::NormalExit);
-        QCOMPARE(consumers.first()->exitCode(), 0);
         QProcess *consumer = consumers.takeFirst();
+        ProcessOutputDumper consumerOutputDumper(consumer);
+        consumer->waitForFinished(20000);
+        QCOMPARE(consumer->exitStatus(), QProcess::NormalExit);
+        QCOMPARE(consumer->exitCode(), 0);
+        consumerOutputDumper.clear();
         consumer->terminate();
         delete consumer;
     }
     producer.waitForFinished(15000);
+    producerOutputDumper.clear();
 }
 #endif