summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTarja Sundqvist <tarja.sundqvist@qt.io>2022-11-10 22:42:45 +0200
committerTarja Sundqvist <tarja.sundqvist@qt.io>2022-11-10 22:42:45 +0200
commit929c7ad0676f084b9ecc469cd47a307596923cb3 (patch)
tree410d666e76f7fffb49d8af13e1ae4e2325dce1c6
parent5f2a598a9134167a0da2efcbf1249fc167ae3750 (diff)
parent5457ac36446f0c34e7fa371ad8982c6cfa54c9c4 (diff)
Merge remote-tracking branch 'origin/tqtc/lts-5.15.8' into tqtc/lts-5.15-opensourcev5.15.8-lts-lgpl
-rw-r--r--.qmake.conf2
-rw-r--r--src/remoteobjects/qconnection_tcpip_backend.cpp2
-rw-r--r--src/remoteobjects/qremoteobjectabstractitemmodelreplica.cpp7
-rw-r--r--src/remoteobjects/qremoteobjectsource.cpp8
-rw-r--r--tests/auto/auto.pro2
-rw-r--r--tests/auto/modelview/tst_modelview.cpp29
-rw-r--r--tests/auto/reconnect/client/client.pro11
-rw-r--r--tests/auto/reconnect/client/main.cpp63
-rw-r--r--tests/auto/reconnect/reconnect.pro2
-rw-r--r--tests/auto/reconnect/server/main.cpp79
-rw-r--r--tests/auto/reconnect/server/server.pro11
-rw-r--r--tests/auto/reconnect/tst/tst.pro12
-rw-r--r--tests/auto/reconnect/tst/tst_reconnect.cpp87
13 files changed, 308 insertions, 7 deletions
diff --git a/.qmake.conf b/.qmake.conf
index f1a6b2b..2120d27 100644
--- a/.qmake.conf
+++ b/.qmake.conf
@@ -4,6 +4,6 @@ CONFIG += qt_example_installs
DEFINES += QT_NO_JAVA_STYLE_ITERATORS
DEFINES += QT_NO_FOREACH
-MODULE_VERSION = 5.15.7
+MODULE_VERSION = 5.15.8
QTRO_SOURCE_TREE = $$PWD
diff --git a/src/remoteobjects/qconnection_tcpip_backend.cpp b/src/remoteobjects/qconnection_tcpip_backend.cpp
index d53db0d..42b3d85 100644
--- a/src/remoteobjects/qconnection_tcpip_backend.cpp
+++ b/src/remoteobjects/qconnection_tcpip_backend.cpp
@@ -162,7 +162,7 @@ ServerIoDevice *TcpServerImpl::configureNewConnection()
if (!m_server.isListening())
return nullptr;
- return new TcpServerIo(m_server.nextPendingConnection());
+ return new TcpServerIo(m_server.nextPendingConnection(), this);
}
bool TcpServerImpl::hasPendingConnections() const
diff --git a/src/remoteobjects/qremoteobjectabstractitemmodelreplica.cpp b/src/remoteobjects/qremoteobjectabstractitemmodelreplica.cpp
index cfcaf3c..91c34ab 100644
--- a/src/remoteobjects/qremoteobjectabstractitemmodelreplica.cpp
+++ b/src/remoteobjects/qremoteobjectabstractitemmodelreplica.cpp
@@ -268,6 +268,8 @@ void QAbstractItemModelReplicaImplementation::onRowsInserted(const IndexList &pa
auto parentItem = cacheData(parentIndex);
q->beginInsertRows(parentIndex, start, end);
parentItem->insertChildren(start, end);
+ for (int i = start; i <= end; ++i)
+ m_headerData[1].append(CacheEntry());
q->endInsertRows();
if (!parentItem->hasChildren && parentItem->columnCount > 0) {
parentItem->hasChildren = true;
@@ -294,6 +296,8 @@ void QAbstractItemModelReplicaImplementation::onColumnsInserted(const IndexList
return;
q->beginInsertColumns(parentIndex, start, end);
parentItem->columnCount += end - start + 1;
+ for (int i = start; i <= end; ++i)
+ m_headerData[0].append(CacheEntry());
q->endInsertColumns();
if (!parentItem->hasChildren && parentItem->children.size() > 0) {
parentItem->hasChildren = true;
@@ -315,6 +319,7 @@ void QAbstractItemModelReplicaImplementation::onRowsRemoved(const IndexList &par
q->beginRemoveRows(parentIndex, start, end);
if (parentItem)
parentItem->removeChildren(start, end);
+ m_headerData[1].erase(m_headerData[1].begin() + start, m_headerData[1].begin() + end + 1);
q->endRemoveRows();
}
@@ -673,7 +678,7 @@ void QAbstractItemModelReplicaImplementation::onHeaderDataChanged(Qt::Orientatio
// TODO clean cache
const int index = orientation == Qt::Horizontal ? 0 : 1;
QVector<CacheEntry> &entries = m_headerData[index];
- for (int i = first; i < last; ++i )
+ for (int i = first; i <= last && i < entries.size(); ++i )
entries[i].data.clear();
emit q->headerDataChanged(orientation, first, last);
}
diff --git a/src/remoteobjects/qremoteobjectsource.cpp b/src/remoteobjects/qremoteobjectsource.cpp
index a16884c..c0e2754 100644
--- a/src/remoteobjects/qremoteobjectsource.cpp
+++ b/src/remoteobjects/qremoteobjectsource.cpp
@@ -75,8 +75,11 @@ QByteArray QtPrivate::qtro_classinfo_signature(const QMetaObject *metaObject)
return QByteArray{};
}
-inline bool qtro_is_cloned_method(const QMetaObject *mobj, int local_method_index)
+inline bool qtro_is_cloned_method(const QMetaObject *mobj, int index)
{
+ int local_method_index = index - mobj->methodOffset();
+ if (local_method_index < 0 && mobj->superClass())
+ return qtro_is_cloned_method(mobj->superClass(), index);
const auto priv = reinterpret_cast<const QtPrivate::QMetaObjectPrivate*>(mobj->d.data);
Q_ASSERT(local_method_index < priv->methodCount);
int handle = priv->methodData + 5 * local_method_index;
@@ -191,9 +194,8 @@ void QRemoteObjectSourceBase::setConnections()
const auto targetMeta = isAdapter ? m_adapter->metaObject() : meta;
// don't connect cloned signals, or we end up with multiple emissions
- if (qtro_is_cloned_method(targetMeta, sourceIndex - targetMeta->methodOffset()))
+ if (qtro_is_cloned_method(targetMeta, sourceIndex))
continue;
-
// This basically connects the parent Signals (note, all dynamic properties have onChange
//notifications, thus signals) to us. Normally each Signal is mapped to a unique index,
//but since we are forwarding them all, we keep the offset constant.
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro
index 69ca9f1..628ccb6 100644
--- a/tests/auto/auto.pro
+++ b/tests/auto/auto.pro
@@ -24,4 +24,4 @@ SUBDIRS += \
contains(QT_CONFIG, ssl): SUBDIRS += external_IODevice
qtHaveModule(qml): SUBDIRS += qml
-qtConfig(process): SUBDIRS += integration_multiprocess proxy_multiprocess integration_external restart
+qtConfig(process): SUBDIRS += integration_multiprocess proxy_multiprocess integration_external restart reconnect
diff --git a/tests/auto/modelview/tst_modelview.cpp b/tests/auto/modelview/tst_modelview.cpp
index a4064a9..df09a0b 100644
--- a/tests/auto/modelview/tst_modelview.cpp
+++ b/tests/auto/modelview/tst_modelview.cpp
@@ -499,6 +499,7 @@ private slots:
void testInitialData();
void testInitialDataTree();
void testHeaderData();
+ void testHeaderDataChange();
void testFlags();
void testDataChanged();
void testDataChangedTree();
@@ -650,6 +651,34 @@ void TestModelView::testHeaderData()
QCOMPARE(model->headerData(i, Qt::Horizontal, Qt::DisplayRole), m_sourceModel.headerData(i, Qt::Horizontal, Qt::DisplayRole));
}
+void TestModelView::testHeaderDataChange()
+{
+ _SETUP_TEST_
+ QString newHeader = QStringLiteral("New header name");
+ QScopedPointer<QAbstractItemModelReplica> model(client.acquireModel("test"));
+
+ FetchData f(model.data());
+ QVERIFY(f.fetchAndWait(MODELTEST_WAIT_TIME));
+ QVERIFY(model->headerData(0, Qt::Horizontal, Qt::DisplayRole).toString() != newHeader);
+
+ QSignalSpy spyHeader(model.data(), &QAbstractItemModelReplica::headerDataChanged);
+ m_sourceModel.setHeaderData(0, Qt::Horizontal, newHeader, Qt::DisplayRole);
+ spyHeader.wait();
+ QTRY_COMPARE(model->headerData(0, Qt::Horizontal, Qt::DisplayRole).toString(), newHeader);
+
+ spyHeader.clear();
+ m_sourceModel.setHeaderData(1, Qt::Horizontal, newHeader, Qt::DisplayRole);
+ spyHeader.wait();
+ QTRY_COMPARE(model->headerData(1, Qt::Horizontal, Qt::DisplayRole).toString(), newHeader);
+
+ QString anotherHeader = QStringLiteral("Modified header name");
+ m_sourceModel.setHeaderData(0, Qt::Horizontal, anotherHeader, Qt::DisplayRole);
+ spyHeader.wait();
+
+ QTRY_COMPARE(model->headerData(0, Qt::Horizontal, Qt::DisplayRole).toString(), anotherHeader);
+ QCOMPARE(model->headerData(1, Qt::Horizontal, Qt::DisplayRole).toString(), newHeader);
+}
+
void TestModelView::testDataChangedTree()
{
_SETUP_TEST_
diff --git a/tests/auto/reconnect/client/client.pro b/tests/auto/reconnect/client/client.pro
new file mode 100644
index 0000000..7b0b0a9
--- /dev/null
+++ b/tests/auto/reconnect/client/client.pro
@@ -0,0 +1,11 @@
+TEMPLATE = app
+TARGET = qtro_reconnect_client
+
+DESTDIR = ./
+
+QT += testlib remoteobjects
+QT -= gui
+
+CONFIG -= app_bundle
+
+SOURCES += main.cpp
diff --git a/tests/auto/reconnect/client/main.cpp b/tests/auto/reconnect/client/main.cpp
new file mode 100644
index 0000000..1aa4f6e
--- /dev/null
+++ b/tests/auto/reconnect/client/main.cpp
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtRemoteObjects module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QCoreApplication>
+#include <QtTest/QtTest>
+#include <QtRemoteObjects/qremoteobjectnode.h>
+
+class tst_Client_Process : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void testRun()
+ {
+ const QString url = qEnvironmentVariable("RO_URL");
+ QRemoteObjectNode node;
+ node.connectToNode(QUrl(url));
+ QRemoteObjectDynamicReplica *ro = node.acquireDynamic("SourceObj");
+
+ QSignalSpy initSpy(ro, &QRemoteObjectDynamicReplica::initialized);
+ QVERIFY(initSpy.wait());
+ QSignalSpy pongSpy(ro, SIGNAL(pong()));
+ QMetaObject::invokeMethod(ro, "ping");
+ QVERIFY(pongSpy.wait());
+ QMetaObject::invokeMethod(ro, "ping");
+
+ QVERIFY(initSpy.wait());
+ QMetaObject::invokeMethod(ro, "ping");
+ QVERIFY(pongSpy.wait());
+ QMetaObject::invokeMethod(ro, "ping");
+ QTest::qWait(100);
+ delete ro;
+ }
+};
+
+QTEST_MAIN(tst_Client_Process)
+
+#include "main.moc"
diff --git a/tests/auto/reconnect/reconnect.pro b/tests/auto/reconnect/reconnect.pro
new file mode 100644
index 0000000..0e6ecf4
--- /dev/null
+++ b/tests/auto/reconnect/reconnect.pro
@@ -0,0 +1,2 @@
+TEMPLATE = subdirs
+SUBDIRS = client server tst
diff --git a/tests/auto/reconnect/server/main.cpp b/tests/auto/reconnect/server/main.cpp
new file mode 100644
index 0000000..d1f3f4c
--- /dev/null
+++ b/tests/auto/reconnect/server/main.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtRemoteObjects module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QCoreApplication>
+#include <QtTest/QtTest>
+#include <QtRemoteObjects/qremoteobjectnode.h>
+#include <QtRemoteObjects/qremoteobjectsource.h>
+
+
+class SourceObj : public QObject
+{
+ Q_OBJECT
+
+public Q_SLOTS:
+ void ping() { ++m_pingCount; };
+
+Q_SIGNALS:
+ void pong();
+
+public:
+ int m_pingCount = 0;
+};
+
+class tst_Server_Process : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void testRun()
+ {
+ const QString url = qEnvironmentVariable("RO_URL");
+ QRemoteObjectHost *srcNode = new QRemoteObjectHost(QUrl(url));
+ SourceObj so;
+ so.setObjectName(QStringLiteral("SourceObj"));
+ srcNode->enableRemoting(&so);
+
+ QTRY_VERIFY(so.m_pingCount == 1);
+ emit so.pong();
+ QTRY_VERIFY(so.m_pingCount == 2);
+ delete srcNode;
+
+ srcNode = new QRemoteObjectHost(QUrl(url));
+ srcNode->enableRemoting(&so);
+
+ QTRY_VERIFY(so.m_pingCount == 3);
+ emit so.pong();
+ QTRY_VERIFY(so.m_pingCount == 4);
+ delete srcNode;
+ }
+};
+
+QTEST_MAIN(tst_Server_Process)
+
+#include "main.moc"
diff --git a/tests/auto/reconnect/server/server.pro b/tests/auto/reconnect/server/server.pro
new file mode 100644
index 0000000..ff39e9e
--- /dev/null
+++ b/tests/auto/reconnect/server/server.pro
@@ -0,0 +1,11 @@
+TEMPLATE = app
+TARGET = qtro_reconnect_server
+
+DESTDIR = ./
+
+QT += testlib remoteobjects
+QT -= gui
+
+CONFIG -= app_bundle
+
+SOURCES += main.cpp
diff --git a/tests/auto/reconnect/tst/tst.pro b/tests/auto/reconnect/tst/tst.pro
new file mode 100644
index 0000000..6ec45d3
--- /dev/null
+++ b/tests/auto/reconnect/tst/tst.pro
@@ -0,0 +1,12 @@
+TEMAPLATE=app
+TARGET = tst_reconnect
+
+DESTDIR = ./
+
+QT += testlib remoteobjects
+QT -= gui
+
+CONFIG += testcase
+CONFIG -= app_bundle
+
+SOURCES += tst_reconnect.cpp
diff --git a/tests/auto/reconnect/tst/tst_reconnect.cpp b/tests/auto/reconnect/tst/tst_reconnect.cpp
new file mode 100644
index 0000000..b4461d2
--- /dev/null
+++ b/tests/auto/reconnect/tst/tst_reconnect.cpp
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtRemoteObjects module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include <QStandardPaths>
+#include <QProcess>
+
+
+static QString findExecutable(const QString &executableName, const QString &searchPath)
+{
+ const QString path = QStandardPaths::findExecutable(executableName, { searchPath });
+ if (!path.isEmpty())
+ return path;
+
+ qWarning() << "Could not find executable:" << executableName << "in" << searchPath;
+ return QString();
+}
+
+
+class tst_Reconnect: public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void testRun_data()
+ {
+ QTest::addColumn<QString>("url");
+ QTest::addRow("local") << QStringLiteral("local:replica");
+ QTest::addRow("tcp") << QStringLiteral("tcp://127.0.0.1:65217");
+ }
+
+ void testRun()
+ {
+ QFETCH(QString, url);
+
+ QProcess serverProc;
+ serverProc.setProcessChannelMode(QProcess::ForwardedChannels);
+ QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
+ env.insert("RO_URL", url);
+ serverProc.setProcessEnvironment(env);
+ const QString appDir = QCoreApplication::applicationDirPath();
+ serverProc.start(findExecutable("qtro_reconnect_server", appDir + QLatin1String("/../server/")), QStringList());
+ QVERIFY(serverProc.waitForStarted());
+
+ QProcess clientProc;
+ clientProc.setProcessChannelMode(QProcess::ForwardedChannels);
+ clientProc.setProcessEnvironment(env);
+ clientProc.start(findExecutable("qtro_reconnect_client", appDir + QLatin1String("/../client/")), QStringList());
+ qDebug() << "Started server and client process on:" << url;
+ QVERIFY(clientProc.waitForStarted());
+
+ QVERIFY(clientProc.waitForFinished());
+ QVERIFY(serverProc.waitForFinished());
+
+ QCOMPARE(serverProc.exitCode(), 0);
+ QCOMPARE(clientProc.exitCode(), 0);
+ }
+};
+
+QTEST_MAIN(tst_Reconnect)
+
+#include "tst_reconnect.moc"