Skip to content
This repository was archived by the owner on Mar 4, 2023. It is now read-only.

Commit 6e0152d

Browse files
committed
wip integration test
1 parent c88c9b3 commit 6e0152d

File tree

6 files changed

+259
-5
lines changed

6 files changed

+259
-5
lines changed

src/datasync/accountmanager.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ public Q_SLOTS:
173173
//! Is emitted when the accounts devices have been sent by the server
174174
void accountDevices(const QList<QtDataSync::DeviceInfo> &devices, QPrivateSignal);
175175
//! Is emitted when another device requests permission to be added to the current account
176-
void loginRequested(LoginRequest request, QPrivateSignal);
176+
void loginRequested(QtDataSync::LoginRequest request, QPrivateSignal);
177177
//! Is emitted when the partner accept the account import
178178
void importAccepted(QPrivateSignal);
179179
//! Is emitted when a device has been granted access to the current account

src/imports/qmldatasync/plugins.qmltypes

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ Module {
2020
}
2121
Signal {
2222
name: "loginRequested"
23-
Parameter { name: "request"; type: "LoginRequest" }
23+
Parameter { name: "request"; type: "QtDataSync::LoginRequest" }
2424
}
2525
Signal { name: "importAccepted" }
2626
Signal {
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
include(../tests.pri)
2+
3+
TARGET = tst_integration
4+
5+
SOURCES += \
6+
tst_integration.cpp
7+
8+
BUILD_BIN_DIR = $$shadowed($$dirname(_QMAKE_CONF_))/bin
9+
DEFINES += BUILD_BIN_DIR=\\\"$$BUILD_BIN_DIR/\\\"
10+
11+
!include(./setup.pri): SETUP_FILE = $$PWD/qdsapp.conf
12+
13+
DISTFILES += $$SETUP_FILE
14+
DEFINES += SETUP_FILE=\\\"$$SETUP_FILE\\\"
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[server]
2+
host=localhost
3+
port=14242
4+
5+
[database]
6+
name=QtDataSync
7+
host=localhost
8+
port=15432
9+
username=qtdatasync
10+
password=baum42
Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
#include <QString>
2+
#include <QtTest>
3+
#include <QCoreApplication>
4+
#include <testlib.h>
5+
#include <testdata.h>
6+
using namespace QtDataSync;
7+
8+
class IntegrationTest : public QObject
9+
{
10+
Q_OBJECT
11+
12+
private Q_SLOTS:
13+
void initTestCase();
14+
void cleanupTestCase();
15+
16+
void testPrepareData();
17+
void testAddAccount();
18+
19+
Q_SIGNALS:
20+
void unlock();
21+
22+
private:
23+
QProcess *server;
24+
25+
AccountManager *acc1;
26+
SyncManager *sync1;
27+
DataTypeStore<TestData> *store1;
28+
29+
AccountManager *acc2;
30+
SyncManager *sync2;
31+
DataTypeStore<TestData> *store2;
32+
};
33+
34+
void IntegrationTest::initTestCase()
35+
{
36+
QByteArray confPath { SETUP_FILE };
37+
QVERIFY(QFile::exists(QString::fromUtf8(confPath)));
38+
qputenv("QDSAPP_CONFIG_FILE", confPath);
39+
40+
#ifdef Q_OS_UNIX
41+
QString binPath { QStringLiteral(BUILD_BIN_DIR "qdsappd") };
42+
#elif Q_OS_WIN
43+
QString binPath { QStringLiteral(BUILD_BIN_DIR "qdsappsvc") };
44+
#else
45+
QString binPath { QStringLiteral(BUILD_BIN_DIR "qdsapp") };
46+
#endif
47+
QVERIFY(QFile::exists(binPath));
48+
49+
server = new QProcess(this);
50+
server->setProgram(binPath);
51+
server->setProcessChannelMode(QProcess::ForwardedErrorChannel);
52+
server->start();
53+
QVERIFY(server->waitForStarted(5000));
54+
QVERIFY(!server->waitForFinished(5000));
55+
56+
try {
57+
TestLib::init();
58+
qRegisterMetaType<LoginRequest>();
59+
60+
{
61+
QString setupName1 = QStringLiteral("setup1");
62+
Setup setup1;
63+
TestLib::setup(setup1);
64+
setup1.setLocalDir(setup1.localDir() + QLatin1Char('/') + setupName1)
65+
.setRemoteConfiguration(QUrl(QStringLiteral("ws://localhost:14242")));
66+
setup1.create(setupName1);
67+
68+
acc1 = new AccountManager(setupName1, this);
69+
QVERIFY(acc1->replica()->waitForSource(5000));
70+
sync1 = new SyncManager(setupName1, this);
71+
QVERIFY(acc1->replica()->waitForSource(5000));
72+
store1 = new DataTypeStore<TestData>(setupName1, this);
73+
}
74+
75+
{
76+
QString setupName2 = QStringLiteral("setup2");
77+
Setup setup2;
78+
TestLib::setup(setup2);
79+
setup2.setLocalDir(setup2.localDir() + QLatin1Char('/') + setupName2)
80+
.setRemoteConfiguration(QUrl(QStringLiteral("ws://localhost:14242")));
81+
setup2.create(setupName2);
82+
83+
acc2 = new AccountManager(setupName2, this);
84+
QVERIFY(acc2->replica()->waitForSource(5000));
85+
sync2 = new SyncManager(setupName2, this);
86+
QVERIFY(sync2->replica()->waitForSource(5000));
87+
store2 = new DataTypeStore<TestData>(setupName2, this);
88+
}
89+
} catch(QException &e) {
90+
QFAIL(e.what());
91+
}
92+
}
93+
94+
void IntegrationTest::cleanupTestCase()
95+
{
96+
delete store1;
97+
store1 = nullptr;
98+
delete sync1;
99+
sync1 = nullptr;
100+
delete acc1;
101+
acc1 = nullptr;
102+
delete store2;
103+
store2 = nullptr;
104+
delete sync2;
105+
sync2 = nullptr;
106+
delete acc2;
107+
acc2 = nullptr;
108+
Setup::removeSetup(DefaultSetup, true);
109+
110+
//send a signal to stop
111+
#ifdef Q_OS_UNIX
112+
server->terminate(); //same as kill(SIGTERM)
113+
#elif Q_OS_WIN
114+
GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, server->processId());
115+
#endif
116+
QVERIFY(server->waitForFinished(5000));
117+
QCOMPARE(server->exitStatus(), QProcess::NormalExit);
118+
QCOMPARE(server->exitCode(), 0);
119+
server->close();
120+
}
121+
122+
void IntegrationTest::testPrepareData()
123+
{
124+
try {
125+
QSignalSpy errorSpy(acc1, &AccountManager::lastErrorChanged);
126+
QSignalSpy devSpy(acc1, &AccountManager::deviceNameChanged);
127+
QSignalSpy unlockSpy(this, &IntegrationTest::unlock);
128+
129+
acc1->setDeviceName(QStringLiteral("master"));
130+
QVERIFY(devSpy.wait());
131+
QCOMPARE(devSpy.size(), 1);
132+
QCOMPARE(devSpy.takeFirst()[0].toString(), QStringLiteral("master"));
133+
134+
for(auto i = 0; i < 10; i++)
135+
store1->save(TestLib::generateData(i));
136+
QCOMPARE(store1->count(), 10);
137+
138+
sync1->runOnSynchronized([this](SyncManager::SyncState s) {
139+
QCOMPARE(s, SyncManager::Synchronized);
140+
emit unlock();
141+
}, false);
142+
QVERIFY(unlockSpy.wait());
143+
144+
QVERIFY(errorSpy.isEmpty());
145+
} catch(std::exception &e) {
146+
QFAIL(e.what());
147+
}
148+
try {
149+
QSignalSpy errorSpy(acc2, &AccountManager::lastErrorChanged);
150+
QSignalSpy devSpy(acc2, &AccountManager::deviceNameChanged);
151+
QSignalSpy unlockSpy(this, &IntegrationTest::unlock);
152+
153+
acc2->setDeviceName(QStringLiteral("partner"));
154+
QVERIFY(devSpy.wait());
155+
QCOMPARE(devSpy.size(), 1);
156+
QCOMPARE(devSpy.takeFirst()[0].toString(), QStringLiteral("partner"));
157+
158+
for(auto i = 10; i < 20; i++)
159+
store2->save(TestLib::generateData(i));
160+
QCOMPARE(store2->count(), 10);
161+
162+
sync2->runOnSynchronized([this](SyncManager::SyncState s) {
163+
QCOMPARE(s, SyncManager::Synchronized);
164+
emit unlock();
165+
}, false);
166+
QVERIFY(unlockSpy.wait());
167+
168+
QVERIFY(errorSpy.isEmpty());
169+
} catch(std::exception &e) {
170+
QFAIL(e.what());
171+
}
172+
}
173+
174+
void IntegrationTest::testAddAccount()
175+
{
176+
try {
177+
QSignalSpy error1Spy(acc1, &AccountManager::lastErrorChanged);
178+
QSignalSpy error2Spy(acc2, &AccountManager::lastErrorChanged);
179+
QSignalSpy fprintSpy(acc2, &AccountManager::deviceFingerprintChanged);
180+
QSignalSpy requestSpy(acc1, &AccountManager::loginRequested);
181+
QSignalSpy acceptSpy(acc2, &AccountManager::importAccepted);
182+
QSignalSpy grantSpy(acc1, &AccountManager::accountAccessGranted);
183+
184+
//export from acc1
185+
acc1->exportAccount(false, [this](QJsonObject exp) {
186+
acc2->importAccount(exp, [](bool ok, QString e) {
187+
QVERIFY2(ok, qUtf8Printable(e));
188+
}, true);
189+
}, [](QString e) {
190+
QFAIL(qUtf8Printable(e));
191+
});
192+
193+
//wait for acc2 fingerprint update
194+
QVERIFY(fprintSpy.wait());
195+
QCOMPARE(fprintSpy.size(), 1);
196+
197+
//wait and accept acc1 login request
198+
QVERIFY(requestSpy.wait());
199+
QCOMPARE(requestSpy.size(), 1);
200+
LoginRequest request = requestSpy.takeFirst()[0].value<LoginRequest>();
201+
QVERIFY(!request.handled());
202+
QCOMPARE(request.device().name(), acc2->deviceName());
203+
QCOMPARE(request.device().fingerprint(), acc2->deviceFingerprint());
204+
auto pId = request.device().deviceId();
205+
QVERIFY(!pId.isNull());
206+
request.accept();
207+
QVERIFY(request.handled());
208+
209+
//wait for accept
210+
if(acceptSpy.isEmpty())
211+
QVERIFY(acceptSpy.wait());
212+
QCOMPARE(acceptSpy.size(), 1);
213+
214+
//wait for grant
215+
if(grantSpy.isEmpty())
216+
QVERIFY(grantSpy.wait());
217+
QCOMPARE(grantSpy.size(), 1);
218+
QCOMPARE(grantSpy.takeFirst()[0].toUuid(), pId);
219+
220+
QVERIFY(error1Spy.isEmpty());
221+
QVERIFY(error2Spy.isEmpty());
222+
} catch(std::exception &e) {
223+
QFAIL(e.what());
224+
}
225+
}
226+
227+
QTEST_MAIN(IntegrationTest)
228+
229+
#include "tst_integration.moc"

tests/auto/datasync/datasync.pro

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ SUBDIRS += \
1212
TestMessages \
1313
TestKeystorePlugins \
1414
TestRemoteConnector \
15-
TestMigrationHelper
15+
TestMigrationHelper
1616

1717
CONFIG += ordered
1818

19-
include_server_tests: SUBDIRS += \
20-
TestAppServer
19+
include_server_tests: SUBDIRS += \
20+
TestAppServer \
21+
IntegrationTest

0 commit comments

Comments
 (0)